789725baa21d98239856f0aacbe6bbf16886288d
[open-ath9k-htc-firmware.git] / target_firmware / wlan / if_ath.c
1 #include <adf_os_types.h>
2 #include <adf_os_pci.h>
3 #include <adf_os_dma.h>
4 #include <adf_os_timer.h>
5 #include <adf_os_lock.h>
6 #include <adf_os_io.h>
7 #include <adf_os_mem.h>
8 #include <adf_os_util.h>
9 #include <adf_os_stdtypes.h>
10 #include <adf_os_defer.h>
11 #include <adf_os_atomic.h>
12 #include <adf_nbuf.h>
13 #include <adf_net.h>
14 #include <adf_net_wcmd.h>
15 #include <adf_os_irq.h>
16
17 #include <if_ath_pci.h>
18 #include "if_ethersubr.h"
19 #include "if_llc.h"
20 #include "ieee80211_var.h"
21 #include "ieee80211_proto.h"
22 #include "if_athrate.h"
23 #include "if_athvar.h"
24 #include "ah_desc.h"
25
26 static a_int32_t ath_numrxbufs = -1;
27 static a_int32_t ath_numrxdescs = -1;
28
29 #if defined(PROJECT_MAGPIE)
30 uint32_t *init_htc_handle = 0;
31 #endif
32
33 #define RX_ENDPOINT_ID 3
34 #define ATH_CABQ_HANDLING_THRESHOLD 9000
35 #define UAPSDQ_NUM   9
36 #define CABQ_NUM     8
37
38 void wmi_event(wmi_handle_t handle, WMI_EVENT_ID evt_id, A_UINT8 *buffer, a_int32_t Length);
39 void owl_tgt_tx_tasklet(TQUEUE_ARG data);
40 static void ath_tgt_send_beacon(struct ath_softc_tgt *sc,adf_nbuf_t bc_hdr,adf_nbuf_t nbuf,HTC_ENDPOINT_ID EndPt);
41 void wmi_cmd_rsp(void *pContext, WMI_COMMAND_ID cmd_id, A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length);
42 static void ath_hal_reg_write_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen);
43 extern struct ath_buf * ath_tgt_tx_prepare(struct ath_softc_tgt *sc, adf_nbuf_t skb, ath_data_hdr_t *dh);
44 extern void  ath_tgt_send_mgt(struct ath_softc_tgt *sc,adf_nbuf_t mgt_hdr, adf_nbuf_t skb,HTC_ENDPOINT_ID EndPt);
45 extern HAL_BOOL ath_hal_wait(struct ath_hal *ah, a_uint32_t reg, a_uint32_t mask, a_uint32_t val);
46 extern void owltgt_tx_processq(struct ath_softc_tgt *sc, struct ath_txq *txq,  owl_txq_state_t txqstate);
47 void owl_tgt_node_init(struct ath_node_target * an);
48 void ath_tgt_tx_sched_normal(struct ath_softc_tgt *sc, struct ath_buf *bf);
49 void ath_tgt_tx_sched_nonaggr(struct ath_softc_tgt *sc,struct ath_buf * bf_host);
50
51 /*************/
52 /* Utilities */
53 /*************/
54
55 #undef adf_os_cpu_to_le16
56
57 static a_uint16_t adf_os_cpu_to_le16(a_uint16_t x)
58 {
59         return ((((x) & 0xff00) >> 8) |   (((x) & 0x00ff) << 8));
60 }
61
62 /*
63  * Extend a 32 bit TSF to 64 bit, taking wrapping into account.
64  */
65 static u_int64_t ath_extend_tsf(struct ath_softc_tgt *sc, u_int32_t rstamp)
66 {
67         u_int64_t tsf;
68         u_int32_t tsf_low;
69         u_int64_t tsf64;
70
71         tsf = ath_hal_gettsf64(sc->sc_ah);
72         tsf_low = tsf & 0xffffffff;
73         tsf64 = (tsf & ~0xffffffffULL) | rstamp;
74
75         if (rstamp > tsf_low && (rstamp - tsf_low > 0x10000000))
76                 tsf64 -= 0x100000000ULL;
77
78         if (rstamp < tsf_low && (tsf_low - rstamp > 0x10000000))
79                 tsf64 += 0x100000000ULL;
80
81         return tsf64;
82 }
83
84 static a_int32_t ath_rate_setup(struct ath_softc_tgt *sc, a_uint32_t mode)
85 {
86         struct ath_hal *ah = sc->sc_ah;
87         const HAL_RATE_TABLE *rt;
88
89         switch (mode) {
90         case IEEE80211_MODE_11NA:
91                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11NA);
92                 break;
93         case IEEE80211_MODE_11NG:
94                 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11NG);
95                 break;
96         default:
97                 return 0;
98         }
99         rt = sc->sc_rates[mode];
100         if (rt == NULL)
101                 return 0;
102
103         return 1;
104 }
105
106 static void ath_setcurmode(struct ath_softc_tgt *sc,
107                            enum ieee80211_phymode mode)
108 {
109         const HAL_RATE_TABLE *rt;
110         a_int32_t i;
111
112         adf_os_mem_set(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
113
114         rt = sc->sc_rates[mode];
115         adf_os_assert(rt != NULL);
116
117         for (i = 0; i < rt->rateCount; i++) {
118                 sc->sc_rixmap[rt->info[i].rateCode] = i;
119         }
120
121         sc->sc_currates = rt;
122         sc->sc_curmode = mode;
123         sc->sc_protrix = ((mode == IEEE80211_MODE_11NG) ? 3 : 0);
124
125 }
126
127 void wmi_event(wmi_handle_t handle, WMI_EVENT_ID evt_id,
128                A_UINT8 *buffer, a_int32_t Length)
129 {
130         adf_nbuf_t netbuf = ADF_NBUF_NULL;
131         a_uint8_t *pData;
132
133         netbuf = WMI_AllocEvent(handle, WMI_EVT_CLASS_CMD_EVENT,
134                                 sizeof(WMI_CMD_HDR) + Length);
135
136         if (netbuf == ADF_NBUF_NULL) {
137                 adf_os_print("Buf null\n");
138                 return;
139         }
140
141         if (buffer != NULL && Length != 0 && Length < WMI_SVC_MAX_BUFFERED_EVENT_SIZE) {
142                 pData = adf_nbuf_put_tail(netbuf, Length);
143                 adf_os_mem_copy(pData, buffer, Length);
144         }
145
146         WMI_SendEvent(handle, netbuf, evt_id, 0, Length);
147 }
148
149 void wmi_cmd_rsp(void *pContext, WMI_COMMAND_ID cmd_id, A_UINT16 SeqNo,
150                  A_UINT8 *buffer, a_int32_t Length)
151 {
152         adf_nbuf_t netbuf = ADF_NBUF_NULL;
153         A_UINT8 *pData;
154
155         netbuf = WMI_AllocEvent(pContext, WMI_EVT_CLASS_CMD_REPLY,
156                                 sizeof(WMI_CMD_HDR) + Length);
157
158         if (netbuf == ADF_NBUF_NULL) {
159                 adf_os_assert(0);
160                 return;
161         }
162
163         if (Length != 0 && buffer != NULL) {
164                 pData = (A_UINT8 *)adf_nbuf_put_tail(netbuf, Length);
165                 adf_os_mem_copy(pData, buffer, Length);
166         }
167
168         WMI_SendEvent(pContext, netbuf, cmd_id, SeqNo, Length);
169 }
170
171 static void ath_node_vdelete_tgt(struct ath_softc_tgt *sc, a_uint8_t vap_index)
172 {
173         a_int32_t i;
174
175         for (i = 0; i < TARGET_NODE_MAX; i++) {
176                 if(sc->sc_sta[i].ni.ni_vapindex == vap_index)
177                         sc->sc_sta[i].an_valid = 0;
178         }
179 }
180
181 a_uint8_t ath_get_minrateidx(struct ath_softc_tgt *sc, struct ath_vap_target *avp)
182 {
183         if (sc->sc_curmode == IEEE80211_MODE_11NG)
184                 return avp->av_minrateidx[0];
185         else if (sc->sc_curmode == IEEE80211_MODE_11NA)
186                 return avp->av_minrateidx[1];
187
188         return 0;
189 }
190
191 /******/
192 /* RX */
193 /******/
194
195 static adf_nbuf_t ath_alloc_skb_align(struct ath_softc_tgt *sc,
196                                       a_uint32_t size, a_uint32_t align)
197 {
198         adf_nbuf_t skb;
199
200         skb = BUF_Pool_alloc_buf_align(sc->pool_handle, POOL_ID_WLAN_RX_BUF,
201                                        RX_HEADER_SPACE, align);
202         return skb;
203 }
204
205 static a_int32_t ath_rxdesc_init(struct ath_softc_tgt *sc, struct ath_rx_desc *ds)
206 {
207         struct ath_hal *ah = sc->sc_ah;
208         struct ath_rx_desc *ds_held;
209         a_uint8_t *anbdata;
210         a_uint32_t anblen;
211
212         if (!sc->sc_rxdesc_held) {
213                 sc->sc_rxdesc_held = ds;
214                 return 0;
215         }
216
217         ds_held = sc->sc_rxdesc_held;
218         sc->sc_rxdesc_held = ds;
219         ds = ds_held;
220
221         if (ds->ds_nbuf == ADF_NBUF_NULL) {
222                 ds->ds_nbuf = ath_alloc_skb_align(sc, sc->sc_rxbufsize, sc->sc_cachelsz);
223                 if (ds->ds_nbuf == ADF_NBUF_NULL) {
224                         sc->sc_rxdesc_held = ds;
225                         sc->sc_rx_stats.ast_rx_nobuf++;
226                         return ENOMEM;
227                 }
228                 adf_nbuf_map(sc->sc_dev, ds->ds_dmap, ds->ds_nbuf, ADF_OS_DMA_FROM_DEVICE);
229                 adf_nbuf_dmamap_info(ds->ds_dmap, &ds->ds_dmap_info);
230                 ds->ds_data = ds->ds_dmap_info.dma_segs[0].paddr;
231         }
232
233         ds->ds_link = 0;
234         adf_nbuf_peek_header(ds->ds_nbuf, &anbdata, &anblen);
235
236         ath_hal_setuprxdesc(ah, ds,
237                             adf_nbuf_tailroom(ds->ds_nbuf),
238                             0);
239
240         if (sc->sc_rxlink == NULL) {
241                 ath_hal_putrxbuf(ah, ds->ds_daddr);
242         }
243         else {
244                 *sc->sc_rxlink = ds->ds_daddr;
245         }
246         sc->sc_rxlink = &ds->ds_link;
247         ath_hal_rxena(ah);
248
249         return 0;
250 }
251
252 static void ath_rx_complete(struct ath_softc_tgt *sc, adf_nbuf_t buf)
253 {
254         struct ath_rx_desc *ds;
255         adf_nbuf_t buf_tmp;
256         adf_nbuf_queue_t nbuf_head;
257
258         adf_nbuf_split_to_frag(buf, &nbuf_head);
259         ds = asf_tailq_first(&sc->sc_rxdesc_idle);
260
261         while (ds) {
262                 struct ath_rx_desc *ds_tmp;
263                 buf_tmp = adf_nbuf_queue_remove(&nbuf_head);
264
265                 if (buf_tmp == NULL) {
266                         break;
267                 }
268
269                 BUF_Pool_free_buf(sc->pool_handle, POOL_ID_WLAN_RX_BUF, buf_tmp);
270
271                 ds_tmp = ds;
272                 ds = asf_tailq_next(ds, ds_list);
273
274                 ath_rxdesc_init(sc, ds_tmp);
275
276                 asf_tailq_remove(&sc->sc_rxdesc_idle, ds_tmp, ds_list);
277                 asf_tailq_insert_tail(&sc->sc_rxdesc, ds_tmp, ds_list);
278         }
279 }
280
281 static void tgt_HTCSendCompleteHandler(HTC_ENDPOINT_ID Endpt, adf_nbuf_t buf, void *ServiceCtx)
282 {
283         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
284
285         if (Endpt == RX_ENDPOINT_ID) {
286                 sc->sc_rx_stats.ast_rx_done++;
287                 ath_rx_complete(sc, buf);
288         }
289 }
290
291 static void ath_uapsd_processtriggers(struct ath_softc_tgt *sc)
292 {
293         struct ath_hal *ah = sc->sc_ah;
294         struct ath_rx_buf *bf = NULL;
295         struct ath_rx_desc *ds, *ds_head, *ds_tail, *ds_tmp;
296         a_int32_t retval;
297         a_uint32_t cnt = 0;
298         a_uint16_t frame_len = 0;
299         a_uint64_t tsf;
300
301 #define PA2DESC(_sc, _pa)                                               \
302         ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc +         \
303                              ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
304
305         tsf = ath_hal_gettsf64(ah);
306         bf = asf_tailq_first(&sc->sc_rxbuf);
307
308         ds = asf_tailq_first(&sc->sc_rxdesc);
309         ds_head = ds;
310
311         while(ds) {
312                 ++cnt;
313
314                 if (cnt == ath_numrxbufs - 1) {
315                         adf_os_print("VERY LONG PACKET!!!!!\n");
316                         ds_tail = ds;
317                         ds_tmp = ds_head;
318                         while (ds_tmp) {
319                                 struct ath_rx_desc *ds_rmv;
320                                 adf_nbuf_unmap(sc->sc_dev, ds_tmp->ds_dmap, ADF_OS_DMA_FROM_DEVICE);
321                                 ds_rmv = ds_tmp;
322                                 ds_tmp = asf_tailq_next(ds_tmp, ds_list);
323
324                                 if (ds_tmp == NULL) {
325                                         adf_os_print("ds_tmp is NULL\n");
326                                         adf_os_assert(0);
327                                 }
328
329                                 BUF_Pool_free_buf(sc->pool_handle, POOL_ID_WLAN_RX_BUF, ds_rmv->ds_nbuf);
330                                 ds_rmv->ds_nbuf = ADF_NBUF_NULL;
331
332                                 if (ath_rxdesc_init(sc, ds_rmv) == 0) {
333                                         asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
334                                         asf_tailq_insert_tail(&sc->sc_rxdesc, ds_rmv, ds_list);
335                                 }
336                                 else {
337                                         asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
338                                         asf_tailq_insert_tail(&sc->sc_rxdesc_idle, ds_rmv, ds_list);
339                                 }
340
341                                 if (ds_rmv == ds_tail) {
342                                         break;
343                                 }
344                         }
345                         break;
346                 }
347
348                 if (ds->ds_link == NULL) {
349                         break;
350                 }
351
352                 if (bf->bf_status & ATH_BUFSTATUS_DONE) {
353                         continue;
354                 }
355
356                 retval = ath_hal_rxprocdescfast(ah, ds, ds->ds_daddr,
357                                                 PA2DESC(sc, ds->ds_link), &bf->bf_rx_status);
358                 if (HAL_EINPROGRESS == retval) {
359                         break;
360                 }
361
362                 if (adf_nbuf_len(ds->ds_nbuf) == 0) {
363                         adf_nbuf_put_tail(ds->ds_nbuf, bf->bf_rx_status.rs_datalen);
364                 }
365
366                 frame_len += bf->bf_rx_status.rs_datalen;
367
368                 if (bf->bf_rx_status.rs_more == 0) {
369                         adf_nbuf_queue_t nbuf_head;
370                         adf_nbuf_queue_init(&nbuf_head);
371
372                         cnt = 0;
373
374                         ds_tail = ds;
375                         ds = asf_tailq_next(ds, ds_list);
376
377                         ds_tmp = ds_head;
378                         ds_head = asf_tailq_next(ds_tail, ds_list);
379
380                         while (ds_tmp) {
381                                 struct ath_rx_desc *ds_rmv;
382
383                                 adf_nbuf_unmap(sc->sc_dev, ds_tmp->ds_dmap, ADF_OS_DMA_FROM_DEVICE);
384                                 adf_nbuf_queue_add(&nbuf_head, ds_tmp->ds_nbuf);
385                                 ds_tmp->ds_nbuf = ADF_NBUF_NULL;
386
387                                 ds_rmv = ds_tmp;
388                                 ds_tmp = asf_tailq_next(ds_tmp, ds_list);
389                                 if (ds_tmp == NULL) {
390                                         adf_os_assert(0);
391                                 }
392
393                                 if (ath_rxdesc_init(sc, ds_rmv) == 0) {
394                                         asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
395                                         asf_tailq_insert_tail(&sc->sc_rxdesc, ds_rmv, ds_list);
396                                 }  else {
397                                         asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
398                                         asf_tailq_insert_tail(&sc->sc_rxdesc_idle, ds_rmv, ds_list);
399                                 }
400
401                                 if (ds_rmv == ds_tail) {
402                                         break;
403                                 }
404                         }
405
406
407                         bf->bf_rx_status.rs_datalen = frame_len;
408                         frame_len = 0;
409
410                         bf->bf_skb = adf_nbuf_create_frm_frag(&nbuf_head);
411
412                         bf->bf_status |= ATH_BUFSTATUS_DONE;
413
414                         bf = asf_tailq_next(bf, bf_list);
415                 }
416                 else {
417                         ds = asf_tailq_next(ds, ds_list);
418                 }
419         }
420
421 #undef PA2DESC
422 }
423
424 static a_int32_t ath_startrecv(struct ath_softc_tgt *sc)
425 {
426         struct ath_hal *ah = sc->sc_ah;
427         struct ath_rx_desc *ds;
428
429         sc->sc_rxbufsize = 1024+512+128;
430         sc->sc_rxlink = NULL;
431
432         sc->sc_rxdesc_held = NULL;
433
434         asf_tailq_foreach(ds, &sc->sc_rxdesc, ds_list) {
435                 a_int32_t error = ath_rxdesc_init(sc, ds);
436                 if (error != 0) {
437                         return error;
438                 }
439         }
440
441         ds = asf_tailq_first(&sc->sc_rxdesc);
442         ath_hal_putrxbuf(ah, ds->ds_daddr);
443
444         return 0;
445 }
446
447 static void ath_tgt_rx_tasklet(TQUEUE_ARG data)
448 {
449         struct ath_softc_tgt *sc  = (struct ath_softc_tgt *)data;
450         struct ath_rx_buf *bf = NULL;
451         struct ath_hal *ah = sc->sc_ah;
452         struct rx_frame_header *rxhdr;
453         struct ieee80211_frame *wh;
454         struct ath_rx_status *rxstats;
455         adf_nbuf_t skb = ADF_NBUF_NULL;
456
457         do {
458                 bf = asf_tailq_first(&sc->sc_rxbuf);
459                 if (bf == NULL) {
460                         break;
461                 }
462
463                 if (!(bf->bf_status & ATH_BUFSTATUS_DONE)) {
464                         break;
465                 }
466
467                 skb = bf->bf_skb;
468                 if (skb == NULL) {
469                         continue;
470                 }
471
472                 asf_tailq_remove(&sc->sc_rxbuf, bf, bf_list);
473
474                 bf->bf_skb = NULL;
475
476                 rxhdr = (struct rx_frame_header *)adf_nbuf_push_head(skb,
477                                                      sizeof(struct rx_frame_header));
478                 rxstats = (struct ath_rx_status *)(&rxhdr->rx_stats[0]);
479                 adf_os_mem_copy(rxstats, &(bf->bf_rx_status),
480                                 sizeof(struct ath_rx_status));
481
482                 rxstats->rs_tstamp = ath_extend_tsf(sc, (u_int32_t)rxstats->rs_tstamp);
483
484                 HTC_SendMsg(sc->tgt_htc_handle, RX_ENDPOINT_ID, skb);
485                 sc->sc_rx_stats.ast_rx_send++;
486
487         next_buf:
488                 bf->bf_status &= ~ATH_BUFSTATUS_DONE;
489                 asf_tailq_insert_tail(&sc->sc_rxbuf, bf, bf_list);
490
491         } while(1);
492
493         sc->sc_imask |= HAL_INT_RX;
494         ath_hal_intrset(ah, sc->sc_imask);
495 }
496
497 /*******************/
498 /* Beacon Handling */
499 /*******************/
500
501 /*
502  * Setup the beacon frame for transmit.
503  * FIXME: Short Preamble.
504  */
505 static void ath_beacon_setup(struct ath_softc_tgt *sc,
506                              struct ath_buf *bf,
507                              struct ath_vap_target *avp)
508 {
509         adf_nbuf_t skb = bf->bf_skb;
510         struct ath_hal *ah = sc->sc_ah;
511         struct ath_desc *ds;
512         a_int32_t flags, antenna;
513         const HAL_RATE_TABLE *rt;
514         a_uint8_t rix, rate;
515         HAL_11N_RATE_SERIES series[4] = {{ 0 }};
516
517         flags = HAL_TXDESC_NOACK;
518
519         ds = bf->bf_desc;
520         ds->ds_link = 0;
521         ds->ds_data = bf->bf_dmamap_info.dma_segs[0].paddr;
522
523         rix = ath_get_minrateidx(sc, avp);
524         rt  = sc->sc_currates;
525         rate = rt->info[rix].rateCode;
526
527         ath_hal_setuptxdesc(ah, ds
528                             , adf_nbuf_len(skb) + IEEE80211_CRC_LEN
529                             , sizeof(struct ieee80211_frame)
530                             , HAL_PKT_TYPE_BEACON
531                             , MAX_RATE_POWER
532                             , rate, 1
533                             , HAL_TXKEYIX_INVALID
534                             , 0
535                             , flags
536                             , 0
537                             , 0
538                             , 0
539                             , 0
540                             , ATH_COMP_PROC_NO_COMP_NO_CCS);
541
542         ath_hal_filltxdesc(ah, ds
543                            , asf_roundup(adf_nbuf_len(skb), 4)
544                            , AH_TRUE
545                            , AH_TRUE
546                            , ds);
547
548         series[0].Tries = 1;
549         series[0].Rate = rate;
550         series[0].ChSel = sc->sc_ic.ic_tx_chainmask;
551         series[0].RateFlags = 0;
552         ath_hal_set11n_ratescenario(ah, ds, 0, 0, 0, series, 4, 0);
553 }
554
555 static void ath_tgt_send_beacon(struct ath_softc_tgt *sc, adf_nbuf_t bc_hdr,
556                                 adf_nbuf_t nbuf, HTC_ENDPOINT_ID EndPt)
557 {
558         struct ath_hal *ah = sc->sc_ah;
559         struct ath_tx_buf *bf;
560         a_uint8_t vap_index, *anbdata;
561         ath_beacon_hdr_t *bhdr;
562         struct ieee80211vap_target  *vap;
563         a_uint32_t anblen;
564         struct ieee80211_frame *wh;
565
566         if (!bc_hdr) {
567                 adf_nbuf_peek_header(nbuf, &anbdata, &anblen);
568                 bhdr = (ath_beacon_hdr_t *)anbdata;
569         } else {
570                 adf_os_print("found bc_hdr! 0x%x\n", bc_hdr);
571         }
572
573         vap_index = bhdr->vap_index;
574         adf_os_assert(vap_index < TARGET_VAP_MAX);
575         vap = &sc->sc_vap[vap_index];
576
577         wh = (struct ieee80211_frame *)adf_nbuf_pull_head(nbuf,
578                                                   sizeof(ath_beacon_hdr_t));
579
580         bf = sc->sc_vap[vap_index].av_bcbuf;
581         adf_os_assert(bf);
582         bf->bf_endpt = EndPt;
583
584         if (bf->bf_skb) {
585                 adf_nbuf_unmap(sc->sc_dev, bf->bf_dmamap, ADF_OS_DMA_TO_DEVICE);
586                 adf_nbuf_push_head(bf->bf_skb, sizeof(ath_beacon_hdr_t));
587                 ath_free_tx_skb(sc->tgt_htc_handle, bf->bf_endpt, bf->bf_skb);
588         }
589
590         bf->bf_skb = nbuf;
591
592         adf_nbuf_map(sc->sc_dev, bf->bf_dmamap, nbuf, ADF_OS_DMA_TO_DEVICE);
593         adf_nbuf_dmamap_info(bf->bf_dmamap,&bf->bf_dmamap_info);
594
595         ath_beacon_setup(sc, bf, &sc->sc_vap[vap_index]);
596         ath_hal_stoptxdma(ah, sc->sc_bhalq);
597         ath_hal_puttxbuf(ah, sc->sc_bhalq, ATH_BUF_GET_DESC_PHY_ADDR(bf));
598         ath_hal_txstart(ah, sc->sc_bhalq);
599 }
600
601 /******/
602 /* TX */
603 /******/
604
605 static void ath_tx_stopdma(struct ath_softc_tgt *sc, struct ath_txq *txq)
606 {
607         struct ath_hal *ah = sc->sc_ah;
608
609         (void) ath_hal_stoptxdma(ah, txq->axq_qnum);
610 }
611
612 static void owltgt_txq_drain(struct ath_softc_tgt *sc, struct ath_txq *txq)
613 {
614         owltgt_tx_processq(sc, txq, OWL_TXQ_STOPPED);
615 }
616
617 static void ath_tx_draintxq(struct ath_softc_tgt *sc, struct ath_txq *txq)
618 {
619         owltgt_txq_drain(sc, txq);
620 }
621
622 static void ath_draintxq(struct ath_softc_tgt *sc, HAL_BOOL drain_softq)
623 {
624         struct ath_hal *ah = sc->sc_ah;
625         a_uint16_t i;
626         struct ath_txq *txq = NULL;
627         struct ath_atx_tid *tid = NULL;
628
629         ath_tx_status_clear(sc);
630         sc->sc_tx_draining = 1;
631
632         (void) ath_hal_stoptxdma(ah, sc->sc_bhalq);
633
634         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
635                 if (ATH_TXQ_SETUP(sc, i))
636                         ath_tx_stopdma(sc, ATH_TXQ(sc, i));
637
638         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
639                 if (ATH_TXQ_SETUP(sc, i)) {
640                         owltgt_tx_processq(sc, ATH_TXQ(sc,i), OWL_TXQ_STOPPED);
641
642                         txq = ATH_TXQ(sc,i);
643                         while (!asf_tailq_empty(&txq->axq_tidq)){
644                                 TAILQ_DEQ(&txq->axq_tidq, tid, tid_qelem);
645                                 if(tid == NULL)
646                                         break;
647                                 tid->sched = AH_FALSE;
648                                 ath_tgt_tid_drain(sc,tid);
649                         }
650                 }
651
652         sc->sc_tx_draining = 0;
653 }
654
655 static void ath_tgt_txq_setup(struct ath_softc_tgt *sc)
656 {
657         a_int32_t qnum;
658         struct ath_txq *txq;
659
660         sc->sc_txqsetup=0;
661
662         for (qnum=0;qnum<HAL_NUM_TX_QUEUES;qnum++) {
663                 txq= &sc->sc_txq[qnum];
664                 txq->axq_qnum = qnum;
665                 txq->axq_link = NULL;
666                 asf_tailq_init(&txq->axq_q);
667                 txq->axq_depth = 0;
668                 txq->axq_linkbuf = NULL;
669                 asf_tailq_init(&txq->axq_tidq);
670                 sc->sc_txqsetup |= 1<<qnum;
671         }
672
673         sc->sc_uapsdq  = &sc->sc_txq[UAPSDQ_NUM];
674         sc->sc_cabq    = &sc->sc_txq[CABQ_NUM];
675
676         sc->sc_ac2q[WME_AC_BE]  = &sc->sc_txq[0];
677         sc->sc_ac2q[WME_AC_BK]  = &sc->sc_txq[1];
678         sc->sc_ac2q[WME_AC_VI]  = &sc->sc_txq[2];
679         sc->sc_ac2q[WME_AC_VO]  = &sc->sc_txq[3];
680
681         return;
682 #undef N
683 }
684
685 static void tgt_HTCRecv_beaconhandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
686                                       adf_nbuf_t buf, void *ServiceCtx)
687 {
688         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
689
690         ath_tgt_send_beacon(sc, hdr_buf, buf, EndPt);
691 }
692
693 static void tgt_HTCRecv_uapsdhandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
694                                      adf_nbuf_t buf, void *ServiceCtx)
695 {
696 }
697
698 static void tgt_HTCRecv_mgmthandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
699                                     adf_nbuf_t buf, void *ServiceCtx)
700 {
701         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
702
703         ath_tgt_send_mgt(sc,hdr_buf,buf,EndPt);
704 }
705
706 static void tgt_HTCRecvMessageHandler(HTC_ENDPOINT_ID EndPt,
707                                       adf_nbuf_t hdr_buf, adf_nbuf_t buf,
708                                       void *ServiceCtx)
709 {
710         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
711         struct ath_tx_buf *bf;
712         a_uint8_t *data;
713         a_uint32_t len;
714         ath_data_hdr_t *dh;
715         struct ath_node_target *an;
716         struct ath_atx_tid *tid;
717
718         if (!hdr_buf) {
719                 adf_nbuf_peek_header(buf, &data, &len);
720                 adf_nbuf_pull_head(buf, sizeof(ath_data_hdr_t));
721         } else {
722                 adf_nbuf_peek_header(hdr_buf, &data, &len);
723         }
724
725         adf_os_assert(len >= sizeof(ath_data_hdr_t));
726         dh = (ath_data_hdr_t *)data;
727
728         an = &sc->sc_sta[dh->ni_index];
729         tid = ATH_AN_2_TID(an, dh->tidno);
730
731         sc->sc_tx_stats.tx_tgt++;
732
733         bf = ath_tgt_tx_prepare(sc, buf, dh);
734         if (!bf) {
735                 ath_free_tx_skb(sc->tgt_htc_handle,EndPt,buf);
736                 return;
737         }
738
739         bf->bf_endpt = EndPt;
740         bf->bf_cookie = dh->cookie;
741
742         if (tid->flag & TID_AGGR_ENABLED)
743                 ath_tgt_handle_aggr(sc, bf);
744         else
745                 ath_tgt_handle_normal(sc, bf);
746 }
747
748 static void tgt_HTCRecv_cabhandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
749                                    adf_nbuf_t buf, void *ServiceCtx)
750 {
751         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
752         struct ath_hal *ah = sc->sc_ah;
753         a_uint64_t tsf;
754         a_uint32_t tmp;
755
756 #ifdef ATH_ENABLE_CABQ
757         tsf = ath_hal_gettsf64(ah);
758         tmp = tsf - sc->sc_swba_tsf;
759
760         if ( tmp > ATH_CABQ_HANDLING_THRESHOLD ) {
761                 HTC_ReturnBuffers(sc->tgt_htc_handle, EndPt, buf);
762                 return;
763         }
764
765         tgt_HTCRecvMessageHandler(EndPt, hdr_buf, buf, ServiceCtx);
766 #endif
767 }
768
769 /***********************/
770 /* Descriptor Handling */
771 /***********************/
772
773 static a_int32_t ath_descdma_setup(struct ath_softc_tgt *sc,
774                                    struct ath_descdma *dd, ath_bufhead *head,
775                                    const char *name, a_int32_t nbuf, a_int32_t ndesc,
776                                    a_uint32_t bfSize, a_uint32_t descSize)
777 {
778 #define DS2PHYS(_dd, _ds)                                               \
779         ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
780
781         struct ath_desc *ds;
782         struct ath_buf *bf;
783         a_int32_t i, bsize, error;
784         a_uint8_t *bf_addr;
785         a_uint8_t *ds_addr;
786
787         dd->dd_name = name;
788         dd->dd_desc_len = descSize * nbuf * ndesc;
789
790         dd->dd_desc = adf_os_dmamem_alloc(sc->sc_dev,
791                                   dd->dd_desc_len, 1, &dd->dd_desc_dmamap);
792         dd->dd_desc_paddr = adf_os_dmamem_map2addr(dd->dd_desc_dmamap);
793         if (dd->dd_desc == NULL) {
794                 error = -ENOMEM;
795                 goto fail;
796         }
797         ds = dd->dd_desc;
798
799         bsize = bfSize * nbuf;
800         bf = adf_os_mem_alloc(bsize);
801         if (bf == NULL) {
802                 error = -ENOMEM;
803                 goto fail2;
804         }
805         adf_os_mem_set(bf, 0, bsize);
806         dd->dd_bufptr = bf;
807
808         bf_addr = (a_uint8_t *)bf;
809         ds_addr = (a_uint8_t *)ds;
810
811         asf_tailq_init(head);
812
813         for (i = 0; i < nbuf; i++) {
814                 a_int32_t j;
815
816                 if (adf_nbuf_dmamap_create( sc->sc_dev, &bf->bf_dmamap) != A_STATUS_OK) {
817                         goto fail2;
818                 }
819
820                 bf->bf_desc = bf->bf_descarr = bf->bf_lastds = ds;
821                 for (j = 0; j < ndesc; j++)
822                         ATH_BUF_SET_DESC_PHY_ADDR_WITH_IDX(bf, j, (ds_addr + (j*descSize)));
823
824                 ATH_BUF_SET_DESC_PHY_ADDR(bf, ATH_BUF_GET_DESC_PHY_ADDR_WITH_IDX(bf, 0));
825
826                 adf_nbuf_queue_init(&bf->bf_skbhead);
827                 asf_tailq_insert_tail(head, bf, bf_list);
828
829                 bf_addr += bfSize;
830                 ds_addr += (ndesc * descSize);
831                 bf = (struct ath_buf *)bf_addr;
832                 ds = (struct ath_desc *)ds_addr;
833         }
834
835         return 0;
836 fail2:
837         adf_os_dmamem_free(sc->sc_dev, dd->dd_desc_len,
838                            1, dd->dd_desc, dd->dd_desc_dmamap);
839 fail:
840         adf_os_mem_set(dd, 0, sizeof(*dd));
841         adf_os_assert(0);
842         return error;
843
844 #undef DS2PHYS
845 }
846
847 static void ath_descdma_cleanup(struct ath_softc_tgt *sc,
848                                 struct ath_descdma *dd,
849                                 ath_bufhead *head, a_int32_t dir)
850 {
851         struct ath_tx_buf *bf;
852         struct ieee80211_node *ni;
853
854         asf_tailq_foreach(bf, head, bf_list) {
855                 if (adf_nbuf_queue_len(&bf->bf_skbhead) != 0) {
856                         adf_nbuf_unmap(sc->sc_dev, bf->bf_dmamap, dir);
857                         while(adf_nbuf_queue_len(&bf->bf_skbhead) != 0) {
858                                 ath_free_rx_skb(sc,
859                                         adf_nbuf_queue_remove(&bf->bf_skbhead));
860                         }
861                         bf->bf_skb = NULL;
862                 } else if (bf->bf_skb != NULL) {
863                         adf_nbuf_unmap(sc->sc_dev,bf->bf_dmamap, dir);
864                         ath_free_rx_skb(sc, bf->bf_skb);
865                         bf->bf_skb = NULL;
866                 }
867
868                 adf_nbuf_dmamap_destroy(sc->sc_dev, bf->bf_dmamap);
869
870                 ni = bf->bf_node;
871                 bf->bf_node = NULL;
872         }
873
874         adf_os_dmamem_free(sc->sc_dev, dd->dd_desc_len,
875                            1, dd->dd_desc, dd->dd_desc_dmamap);
876
877         asf_tailq_init(head);
878         adf_os_mem_free(dd->dd_bufptr);
879         adf_os_mem_set(dd, 0, sizeof(*dd));
880 }
881
882 static a_int32_t ath_desc_alloc(struct ath_softc_tgt *sc)
883 {
884 #define DS2PHYS(_dd, _ds)                                               \
885         ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
886
887         a_int32_t error;
888         struct ath_tx_buf *bf;
889
890         if(ath_numrxbufs == -1)
891                 ath_numrxbufs = ATH_RXBUF;
892
893         if (ath_numrxdescs == -1)
894                 ath_numrxdescs = ATH_RXDESC;
895
896         error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
897                                   "rx", ath_numrxdescs, 1,
898                                   sizeof(struct ath_rx_buf),
899                                   sizeof(struct ath_rx_desc));
900         if (error != 0)
901                 return error;
902
903         a_uint32_t i;
904         struct ath_descdma *dd = &sc->sc_rxdma;
905         struct ath_rx_desc *ds = dd->dd_desc;
906         struct ath_rx_desc *ds_prev = NULL;
907
908         asf_tailq_init(&sc->sc_rxdesc);
909         asf_tailq_init(&sc->sc_rxdesc_idle);
910
911         for (i = 0; i < ath_numrxdescs; i++, ds++) {
912
913                 if (ds->ds_nbuf != ADF_NBUF_NULL) {
914                         ds->ds_nbuf = ADF_NBUF_NULL;
915                 }
916
917                 if (adf_nbuf_dmamap_create(sc->sc_dev, &ds->ds_dmap) != A_STATUS_OK) {
918                         adf_os_assert(0);
919                 }
920
921                 ds->ds_daddr = DS2PHYS(&sc->sc_rxdma, ds);
922
923                 if (ds_prev) {
924                         ds_prev->ds_link = ds->ds_daddr;
925                 }
926
927                 ds->ds_link = 0;
928                 ds_prev = ds;
929
930                 asf_tailq_insert_tail(&sc->sc_rxdesc, ds, ds_list);
931         }
932
933         error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
934                                   "tx", ATH_TXBUF + 1, ATH_TXDESC,
935                                   sizeof(struct ath_tx_buf),
936                                   sizeof(struct ath_tx_desc));
937         if (error != 0) {
938                 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
939                                     ADF_OS_DMA_FROM_DEVICE);
940                 return error;
941         }
942
943         error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
944                                   "beacon", ATH_BCBUF, 1,
945                                   sizeof(struct ath_tx_buf),
946                                   sizeof(struct ath_tx_desc));
947         if (error != 0) {
948                 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
949                                     ADF_OS_DMA_TO_DEVICE);
950                 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
951                                     ADF_OS_DMA_FROM_DEVICE);
952                 return error;
953         }
954
955         bf = asf_tailq_first(&sc->sc_txbuf);
956         bf->bf_isaggr = bf->bf_isretried = bf->bf_retries = 0;
957         asf_tailq_remove(&sc->sc_txbuf, bf, bf_list);
958
959         sc->sc_txbuf_held = bf;
960
961         return 0;
962
963 #undef DS2PHYS
964 }
965
966 static void ath_desc_free(struct ath_softc_tgt *sc)
967 {
968         asf_tailq_insert_tail(&sc->sc_txbuf, sc->sc_txbuf_held, bf_list);
969
970         sc->sc_txbuf_held = NULL;
971
972         if (sc->sc_txdma.dd_desc_len != 0)
973                 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
974                                     ADF_OS_DMA_TO_DEVICE);
975         if (sc->sc_rxdma.dd_desc_len != 0)
976                 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
977                                     ADF_OS_DMA_FROM_DEVICE);
978 }
979
980 /**********************/
981 /* Interrupt Handling */
982 /**********************/
983
984 adf_os_irq_resp_t ath_intr(adf_drv_handle_t hdl)
985 {
986         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)hdl;
987         struct ath_hal *ah = sc->sc_ah;
988         struct ieee80211com_target *ic = &sc->sc_ic;
989         HAL_INT status;
990
991         if (sc->sc_invalid)
992                 return ADF_OS_IRQ_NONE;
993
994         if (!ath_hal_intrpend(ah))
995                 return ADF_OS_IRQ_NONE;
996
997         ath_hal_getisr(ah, &status);
998
999         status &= sc->sc_imask;
1000
1001         if (status & HAL_INT_FATAL) {
1002                 ath_hal_intrset(ah, 0);
1003                 ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_fataltq);
1004         } else {
1005                 if (status & HAL_INT_SWBA) {
1006                         WMI_SWBA_EVENT swbaEvt;
1007                         struct ath_txq *txq = ATH_TXQ(sc, 8);
1008
1009                         swbaEvt.tsf = ath_hal_gettsf64(ah);
1010                         swbaEvt.beaconPendingCount = ath_hal_numtxpending(ah, sc->sc_bhalq);
1011                         sc->sc_swba_tsf = ath_hal_gettsf64(ah);
1012
1013                         wmi_event(sc->tgt_wmi_handle,
1014                                   WMI_SWBA_EVENTID,
1015                                   &swbaEvt,
1016                                   sizeof(WMI_SWBA_EVENT));
1017
1018                         ath_tx_draintxq(sc, txq);
1019                 }
1020
1021                 if (status & HAL_INT_RXORN)
1022                         sc->sc_int_stats.ast_rxorn++;
1023
1024                 if (status & HAL_INT_RXEOL)
1025                         sc->sc_int_stats.ast_rxeol++;
1026
1027                 if (status & (HAL_INT_RX | HAL_INT_RXEOL | HAL_INT_RXORN)) {
1028                         if (status & HAL_INT_RX)
1029                                 sc->sc_int_stats.ast_rx++;
1030
1031                         ath_uapsd_processtriggers(sc);
1032
1033                         sc->sc_imask &= ~HAL_INT_RX;
1034                         ath_hal_intrset(ah, sc->sc_imask);
1035
1036                         ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_rxtq);
1037                 }
1038
1039                 if (status & HAL_INT_TXURN) {
1040                         sc->sc_int_stats.ast_txurn++;
1041                         ath_hal_updatetxtriglevel(ah, AH_TRUE);
1042                 }
1043
1044                 ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_txtq);
1045
1046                 if (status & HAL_INT_BMISS) {
1047                         ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_bmisstq);
1048                 }
1049
1050                 if (status & HAL_INT_GTT)
1051                         sc->sc_int_stats.ast_txto++;
1052
1053                 if (status & HAL_INT_CST)
1054                         sc->sc_int_stats.ast_cst++;
1055         }
1056
1057         return ADF_OS_IRQ_HANDLED;
1058 }
1059
1060 static void ath_fatal_tasklet(TQUEUE_ARG data )
1061 {
1062         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)data;
1063
1064         wmi_event(sc->tgt_wmi_handle, WMI_FATAL_EVENTID, NULL, 0);
1065 }
1066
1067 static void ath_bmiss_tasklet(TQUEUE_ARG data)
1068 {
1069         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)data;
1070
1071         wmi_event(sc->tgt_wmi_handle, WMI_BMISS_EVENTID, NULL, 0);
1072 }
1073
1074 /****************/
1075 /* WMI Commands */
1076 /****************/
1077
1078 static void ath_enable_intr_tgt(void *Context, A_UINT16 Command,
1079                                 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1080 {
1081         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1082         struct ath_hal *ah = sc->sc_ah;
1083         a_uint32_t intr;
1084
1085         if (data)
1086                 intr = (*(a_uint32_t *)data);
1087
1088         intr = adf_os_ntohl(intr);
1089
1090         if (intr & HAL_INT_SWBA) {
1091                 sc->sc_imask |= HAL_INT_SWBA;
1092         } else {
1093                 sc->sc_imask &= ~HAL_INT_SWBA;
1094         }
1095
1096         if (intr & HAL_INT_BMISS) {
1097                 sc->sc_imask |= HAL_INT_BMISS;
1098         }
1099
1100         ath_hal_intrset(ah, sc->sc_imask);
1101         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo,NULL, 0);
1102 }
1103
1104 static void ath_init_tgt(void *Context, A_UINT16 Command,
1105                          A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1106 {
1107         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1108         struct ath_hal *ah = sc->sc_ah;
1109         a_uint32_t stbcsupport;
1110
1111         sc->sc_imask = HAL_INT_RX | HAL_INT_TX
1112                 | HAL_INT_RXEOL | HAL_INT_RXORN
1113                 | HAL_INT_FATAL | HAL_INT_GLOBAL;
1114
1115         sc->sc_imask |= HAL_INT_GTT;
1116
1117         if (ath_hal_htsupported(ah))
1118                 sc->sc_imask |= HAL_INT_CST;
1119
1120 #ifdef MAGPIE_MERLIN
1121         if (ath_hal_txstbcsupport(ah, &stbcsupport))
1122                 sc->sc_txstbcsupport = stbcsupport;
1123
1124         if (ath_hal_rxstbcsupport(ah, &stbcsupport))
1125                 sc->sc_rxstbcsupport = stbcsupport;
1126 #endif
1127         adf_os_setup_intr(sc->sc_dev, ath_intr);
1128         ath_hal_intrset(ah, sc->sc_imask);
1129
1130         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1131 }
1132
1133 static void ath_int_stats_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1134                               A_UINT8 *data, a_int32_t datalen)
1135 {
1136         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1137
1138         struct fusion_stats {
1139                 a_uint32_t ast_rx;
1140                 a_uint32_t ast_rxorn;
1141                 a_uint32_t ast_rxeol;
1142                 a_uint32_t ast_txurn;
1143                 a_uint32_t ast_txto;
1144                 a_uint32_t ast_cst;
1145         };
1146
1147         struct fusion_stats stats;
1148
1149         stats.ast_rx = sc->sc_int_stats.ast_rx;
1150         stats.ast_rxorn = sc->sc_int_stats.ast_rxorn;
1151         stats.ast_rxeol = sc->sc_int_stats.ast_rxeol;
1152         stats.ast_txurn = sc->sc_int_stats.ast_txurn;
1153         stats.ast_txto = sc->sc_int_stats.ast_txto;
1154         stats.ast_cst = sc->sc_int_stats.ast_cst;
1155
1156         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &stats, sizeof(stats));
1157 }
1158
1159 static void ath_tx_stats_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1160                              A_UINT8 *data, a_int32_t datalen)
1161 {
1162         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1163
1164         struct fusion_stats {
1165                 a_uint32_t   ast_tx_xretries;
1166                 a_uint32_t   ast_tx_fifoerr;
1167                 a_uint32_t   ast_tx_filtered;
1168                 a_uint32_t   ast_tx_timer_exp;
1169                 a_uint32_t   ast_tx_shortretry;
1170                 a_uint32_t   ast_tx_longretry;
1171
1172                 a_uint32_t   tx_qnull;
1173                 a_uint32_t   tx_noskbs;
1174                 a_uint32_t   tx_nobufs;
1175         };
1176
1177         struct fusion_stats stats;
1178
1179         stats.ast_tx_xretries = sc->sc_tx_stats.ast_tx_xretries;
1180         stats.ast_tx_fifoerr = sc->sc_tx_stats.ast_tx_fifoerr;
1181         stats.ast_tx_filtered = sc->sc_tx_stats.ast_tx_filtered;
1182         stats.ast_tx_timer_exp = sc->sc_tx_stats.ast_tx_timer_exp;
1183         stats.ast_tx_shortretry = sc->sc_tx_stats.ast_tx_shortretry;
1184         stats.ast_tx_longretry = sc->sc_tx_stats.ast_tx_longretry;
1185         stats.tx_qnull = sc->sc_tx_stats.tx_qnull;
1186         stats.tx_noskbs = sc->sc_tx_stats.tx_noskbs;
1187         stats.tx_nobufs = sc->sc_tx_stats.tx_nobufs;
1188
1189         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &stats, sizeof(stats));
1190 }
1191
1192 static void ath_rx_stats_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1193                              A_UINT8 *data, a_int32_t datalen)
1194 {
1195         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1196
1197         struct fusion_stats {
1198                 a_uint32_t   ast_rx_nobuf;
1199                 a_uint32_t   ast_rx_send;
1200                 a_uint32_t   ast_rx_done;
1201         };
1202
1203         struct fusion_stats stats;
1204
1205         stats.ast_rx_nobuf = sc->sc_rx_stats.ast_rx_nobuf;
1206         stats.ast_rx_send = sc->sc_rx_stats.ast_rx_send;
1207         stats.ast_rx_done = sc->sc_rx_stats.ast_rx_done;
1208
1209         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &stats, sizeof(stats));
1210 }
1211
1212 static void ath_get_tgt_version(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1213                                 A_UINT8 *data, a_int32_t datalen)
1214 {
1215         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1216         struct wmi_fw_version ver;
1217
1218         ver.major = ATH_VERSION_MAJOR;
1219         ver.minor = ATH_VERSION_MINOR;
1220
1221         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &ver, sizeof(ver));
1222 }
1223
1224 static void ath_enable_aggr_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1225                                 A_UINT8 *data, a_int32_t datalen)
1226 {
1227         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1228         struct ath_aggr_info *aggr = (struct ath_aggr_info *)data;
1229         a_uint8_t nodeindex = aggr->nodeindex;
1230         a_uint8_t tidno = aggr->tidno;
1231         struct ath_node_target *an = NULL ;
1232         struct ath_atx_tid  *tid = NULL;
1233
1234         if (nodeindex >= TARGET_NODE_MAX) {
1235                 goto done;
1236         }
1237
1238         an = &sc->sc_sta[nodeindex];
1239         if (!an->an_valid) {
1240                 goto done;
1241         }
1242
1243         if (tidno >= WME_NUM_TID) {
1244                 adf_os_print("[%s] enable_aggr with invalid tid %d(node = %d)\n",
1245                              __FUNCTION__, tidno, nodeindex);
1246                 goto done;
1247         }
1248
1249         tid = ATH_AN_2_TID(an, tidno);
1250
1251         if (aggr->aggr_enable) {
1252                 tid->flag |= TID_AGGR_ENABLED;
1253         } else if ( tid->flag & TID_AGGR_ENABLED ) {
1254                 tid->flag &= ~TID_AGGR_ENABLED;
1255                 ath_tgt_tx_cleanup(sc, an, tid, 1);
1256         }
1257 done:
1258         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1259 }
1260
1261 static void ath_ic_update_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1262                               A_UINT8 *data, a_int32_t datalen)
1263 {
1264         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1265         struct ieee80211com_target *ic = (struct ieee80211com_target * )data;
1266         struct ieee80211com_target *ictgt = &sc->sc_ic ;
1267
1268         adf_os_mem_copy(ictgt, ic, sizeof(struct  ieee80211com_target));
1269
1270         ictgt->ic_ampdu_limit         = adf_os_ntohl(ic->ic_ampdu_limit);
1271
1272         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1273 }
1274
1275 static void ath_vap_create_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo,
1276                                A_UINT8 *data, a_int32_t datalen)
1277 {
1278         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1279         struct ieee80211vap_target *vap;
1280         a_uint8_t vap_index;
1281
1282         vap = (struct ieee80211vap_target *)data;
1283
1284         vap->iv_rtsthreshold    = adf_os_ntohs(vap->iv_rtsthreshold);
1285         vap->iv_opmode          = adf_os_ntohl(vap->iv_opmode);
1286
1287         vap_index = vap->iv_vapindex;
1288
1289         adf_os_assert(sc->sc_vap[vap_index].av_valid == 0);
1290
1291         adf_os_mem_copy(&(sc->sc_vap[vap_index].av_vap), vap,
1292                         VAP_TARGET_SIZE);
1293
1294         sc->sc_vap[vap_index].av_bcbuf = asf_tailq_first(&(sc->sc_bbuf));
1295         sc->sc_vap[vap_index].av_valid = 1;
1296
1297         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1298 }
1299
1300 static void ath_node_create_tgt(void *Context, A_UINT16 Command,
1301                                 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1302 {
1303         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1304         struct ieee80211_node_target *node;
1305         a_uint8_t vap_index;
1306         a_uint8_t node_index;
1307
1308         node = (struct ieee80211_node_target *)data;
1309
1310         node_index = node->ni_nodeindex;
1311
1312         node->ni_htcap = adf_os_ntohs(node->ni_htcap);
1313         node->ni_flags = adf_os_ntohs(node->ni_flags);
1314         node->ni_maxampdu = adf_os_ntohs(node->ni_maxampdu);
1315
1316         adf_os_mem_copy(&(sc->sc_sta[node_index].ni), node,
1317                         NODE_TARGET_SIZE);
1318
1319         vap_index = sc->sc_sta[node_index].ni.ni_vapindex;
1320         sc->sc_sta[node_index].ni.ni_vap = &(sc->sc_vap[vap_index].av_vap);
1321         if(sc->sc_sta[node_index].ni.ni_is_vapnode == 1)
1322                 sc->sc_vap[vap_index].av_vap.iv_nodeindex = node_index;
1323
1324         sc->sc_sta[node_index].an_valid = 1;
1325         sc->sc_sta[node_index].ni.ni_txseqmgmt = 0;
1326         sc->sc_sta[node_index].ni.ni_iv16 = 0;
1327         sc->sc_sta[node_index].ni.ni_iv32 = 0;
1328
1329         owl_tgt_node_init(&sc->sc_sta[node_index]);
1330
1331         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1332 }
1333
1334 static void ath_node_cleanup_tgt(void *Context, A_UINT16 Command,
1335                                  A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1336 {
1337         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1338         a_uint8_t node_index;
1339         a_uint8_t *nodedata;
1340
1341         nodedata = (a_uint8_t *)data;
1342         node_index = *nodedata;
1343         sc->sc_sta[node_index].an_valid = 0;
1344
1345         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1346 }
1347
1348 static void ath_node_update_tgt(void *Context, A_UINT16 Command,
1349                                 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1350 {
1351         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1352         struct ieee80211_node_target *node;
1353         a_uint8_t vap_index;
1354         a_uint8_t node_index;
1355
1356         node = (struct ieee80211_node_target *)data;
1357
1358         node_index = node->ni_nodeindex;
1359
1360         node->ni_htcap = adf_os_ntohs(node->ni_htcap);
1361         node->ni_flags = adf_os_ntohs(node->ni_flags);
1362         node->ni_maxampdu = adf_os_ntohs(node->ni_maxampdu);
1363
1364         adf_os_mem_copy(&(sc->sc_sta[node_index].ni), node,
1365                         NODE_TARGET_SIZE);
1366
1367         vap_index = sc->sc_sta[node_index].ni.ni_vapindex;
1368         sc->sc_sta[node_index].ni.ni_vap = &(sc->sc_vap[vap_index].av_vap);
1369
1370         sc->sc_sta[node_index].ni.ni_txseqmgmt = 0;
1371         sc->sc_sta[node_index].ni.ni_iv16 = 0;
1372         sc->sc_sta[node_index].ni.ni_iv32 = 0;
1373
1374         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1375 }
1376
1377 static void ath_hal_reg_read_tgt(void *Context, A_UINT16 Command,
1378                                  A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1379 {
1380         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1381         struct ath_hal *ah = sc->sc_ah;
1382         a_uint32_t addr;
1383         a_uint32_t val[32];
1384         int i;
1385
1386         for (i = 0; i < datalen; i += sizeof(a_int32_t)) {
1387                 addr = *(a_uint32_t *)(data + i);
1388                 addr = adf_os_ntohl(addr);
1389
1390                 if ((addr & 0xffffe000) == 0x2000) {
1391                         /* SEEPROM */
1392                         ath_hal_reg_read_target(ah, addr);
1393                         if (!ath_hal_wait(ah, 0x407c, 0x00030000, 0)) {
1394                                 adf_os_print("SEEPROM Read fail: 0x%08x\n", addr);
1395                         }
1396                         val[i/sizeof(a_int32_t)] = (ath_hal_reg_read_target(ah, 0x407c) & 0x0000ffff);
1397                 } else if (addr > 0xffff) {
1398                         val[i/sizeof(a_int32_t)] = *(a_uint32_t *)addr;
1399                 } else
1400                         val[i/sizeof(a_int32_t)] = ath_hal_reg_read_target(ah, addr);
1401
1402                 val[i/sizeof(a_int32_t)] = adf_os_ntohl(val[i/sizeof(a_int32_t)]);
1403         }
1404
1405         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &val[0], datalen);
1406 }
1407
1408 static void ath_hal_reg_write_tgt(void *Context, A_UINT16 Command,
1409                                   A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1410 {
1411         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1412         struct ath_hal *ah = sc->sc_ah;
1413         int i;
1414         struct registerWrite {
1415                 a_uint32_t reg;
1416                 a_uint32_t val;
1417         }*t;
1418
1419         for (i = 0; i < datalen; i += sizeof(struct registerWrite)) {
1420                 t = (struct registerWrite *)(data+i);
1421
1422                 if( t->reg > 0xffff ) {
1423                         a_uint32_t *pReg = (a_uint32_t *)t->reg;
1424
1425                         *pReg = t->val;
1426
1427 #if defined(PROJECT_K2)
1428                         if( t->reg == 0x50040 ) {
1429                                 static uint8_t flg=0;
1430
1431                                 if( flg == 0 ) {
1432                                         A_CLOCK_INIT(117);
1433                                         A_UART_HWINIT(117*1000*1000, 19200);
1434                                         flg = 1;
1435                                 }
1436                         }
1437 #endif
1438                 } else {
1439 #if defined(PROJECT_K2)
1440                         if( t->reg == 0x7014 ) {
1441                                 static uint8_t resetPLL = 0;
1442                                 a_uint32_t *pReg;
1443
1444                                 if( resetPLL == 0 ) {
1445                                         t->reg = 0x50044;
1446                                         pReg = (a_uint32_t *)t->reg;
1447                                         *pReg = 0;
1448                                         ath_hal_reg_write_target(ah, 0x786c,
1449                                                  ath_hal_reg_read_target(ah,0x786c) | 0x6000000);
1450                                         ath_hal_reg_write_target(ah, 0x786c,
1451                                                  ath_hal_reg_read_target(ah,0x786c) & (~0x6000000));
1452                                         *pReg = 0x20;
1453                                         resetPLL = 1;
1454                                 }
1455                                 t->reg = 0x7014;
1456                         }
1457 #elif defined(PROJECT_MAGPIE) && !defined (FPGA)
1458                         if( t->reg == 0x7014 ){
1459                                 static uint8_t resetPLL = 0;
1460
1461                                 if( resetPLL == 0 ) {
1462                                         ath_hal_reg_write_target(ah, 0x7890,
1463                                                  ath_hal_reg_read_target(ah,0x7890) | 0x1800000);
1464                                         ath_hal_reg_write_target(ah, 0x7890,
1465                                                  ath_hal_reg_read_target(ah,0x7890) & (~0x1800000));
1466                                         resetPLL = 1;
1467                                 }
1468                         }
1469 #endif
1470                         ath_hal_reg_write_target(ah,t->reg,t->val);
1471                 }
1472         }
1473
1474         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1475 }
1476
1477 static void ath_vap_delete_tgt(void *Context, A_UINT16 Command,
1478                                A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1479 {
1480         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1481         a_uint8_t vap_index;
1482
1483         vap_index = *(a_uint8_t *)data;
1484
1485         sc->sc_vap[vap_index].av_valid = 0;
1486         sc->sc_vap[vap_index].av_bcbuf = NULL;
1487         ath_node_vdelete_tgt(sc, vap_index);
1488         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1489 }
1490
1491 static void ath_disable_intr_tgt(void *Context, A_UINT16 Command,
1492                                  A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1493 {
1494         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1495         struct ath_hal *ah = sc->sc_ah;
1496
1497         ath_hal_intrset(ah, 0);
1498         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo,NULL, 0);
1499 }
1500
1501 static void ath_flushrecv_tgt(void *Context, A_UINT16 Command,
1502                               A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1503 {
1504         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1505         struct ath_buf *bf;
1506
1507         asf_tailq_foreach(bf, &sc->sc_rxbuf, bf_list)
1508                 if (bf->bf_skb != NULL) {
1509                         adf_nbuf_unmap(sc->sc_dev, bf->bf_dmamap,
1510                                        ADF_OS_DMA_FROM_DEVICE);
1511                         ath_free_rx_skb(sc, adf_nbuf_queue_remove(&bf->bf_skbhead));
1512                         bf->bf_skb = NULL;
1513                 }
1514
1515         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1516 }
1517
1518 static void ath_tx_draintxq_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo,
1519                                 A_UINT8 *data, a_int32_t datalen)
1520 {
1521         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1522         a_uint32_t q = *(a_uint32_t *)data;
1523         struct ath_txq *txq = NULL;
1524
1525         q = adf_os_ntohl(q);
1526         txq = ATH_TXQ(sc, q);
1527
1528         ath_tx_draintxq(sc, txq);
1529         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1530 }
1531
1532 static void ath_draintxq_tgt(void *Context, A_UINT16 Command,
1533                              A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1534 {
1535         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1536         HAL_BOOL b = (HAL_BOOL) *(a_int32_t *)data;
1537
1538         ath_draintxq(Context, b);
1539         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1540 }
1541
1542 static void ath_aborttx_dma_tgt(void *Context, A_UINT16 Command,
1543                                 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1544 {
1545         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1546
1547         ath_hal_aborttxdma(sc->sc_ah);
1548         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1549 }
1550
1551 static void ath_aborttxq_tgt(void *Context, A_UINT16 Command,
1552                              A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1553 {
1554
1555         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1556         a_uint16_t i;
1557
1558         for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
1559                 if (ATH_TXQ_SETUP(sc, i))
1560                         ath_tx_draintxq(sc, ATH_TXQ(sc,i));
1561         }
1562
1563         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1564 }
1565
1566 static void ath_stop_tx_dma_tgt(void *Context, A_UINT16 Command,
1567                                 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1568 {
1569         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1570         struct ath_hal *ah = sc->sc_ah;
1571         a_uint32_t q;
1572
1573         if (data)
1574                 q = *(a_uint32_t *)data;
1575
1576         q = adf_os_ntohl(q);
1577         ath_hal_stoptxdma(ah, q);
1578         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1579 }
1580
1581 static void ath_startrecv_tgt(void *Context, A_UINT16 Command,
1582                               A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1583 {
1584
1585         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1586
1587         ath_startrecv(sc);
1588         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1589 }
1590
1591 static void ath_stoprecv_tgt(void *Context, A_UINT16 Command,
1592                              A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1593 {
1594         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1595         struct ath_hal *ah = sc->sc_ah;
1596
1597         ath_hal_stoppcurecv(ah);
1598         ath_hal_setrxfilter(ah, 0);
1599         ath_hal_stopdmarecv(ah);
1600
1601         sc->sc_rxlink = NULL;
1602         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1603 }
1604
1605 static void ath_setcurmode_tgt(void *Context, A_UINT16 Command,
1606                                A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1607 {
1608         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1609         a_uint16_t mode;
1610         struct ath_hal *ah = sc->sc_ah;
1611
1612         mode= *((a_uint16_t *)data);
1613         mode = adf_os_ntohs(mode);
1614
1615         ath_setcurmode(sc, mode);
1616
1617         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1618 }
1619
1620 static a_uint32_t ath_detach_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo,
1621                                  A_UINT8 *data, a_int32_t datalen)
1622 {
1623         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1624         struct ath_hal *ah = sc->sc_ah;
1625
1626         ath_desc_free(sc);
1627         ath_hal_detach(ah);
1628         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1629         adf_os_mem_free(sc);
1630 }
1631
1632 static void handle_echo_command(void *pContext, A_UINT16 Command,
1633                                 A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1634 {
1635         wmi_cmd_rsp(pContext, WMI_ECHO_CMDID, SeqNo, buffer, Length);
1636 }
1637
1638 static void handle_rc_state_change_cmd(void *Context, A_UINT16 Command,
1639                                        A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1640
1641 {
1642         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1643         struct wmi_rc_state_change_cmd *wmi_data = (struct wmi_rc_state_change_cmd *)buffer;
1644
1645         a_uint32_t capflag = adf_os_ntohl(wmi_data->capflag);
1646
1647         ath_rate_newstate(sc, &sc->sc_vap[wmi_data->vap_index].av_vap,
1648                           wmi_data->vap_state,
1649                           capflag,
1650                           &wmi_data->rs);
1651
1652         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1653 }
1654
1655 static void handle_rc_rate_update_cmd(void *Context, A_UINT16 Command,
1656                                       A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1657 {
1658         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1659         struct wmi_rc_rate_update_cmd *wmi_data = (struct wmi_rc_rate_update_cmd *)buffer;
1660
1661         a_uint32_t capflag = adf_os_ntohl(wmi_data->capflag);
1662
1663         ath_rate_node_update(sc, &sc->sc_sta[wmi_data->node_index],
1664                              wmi_data->isNew,
1665                              capflag,
1666                              &wmi_data->rs);
1667
1668         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1669 }
1670
1671 static void dispatch_magpie_sys_cmds(void *pContext, A_UINT16 Command,
1672                                      A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1673 {
1674         adf_os_assert(0);
1675 }
1676
1677 static void ath_rc_mask_tgt(void *Context, A_UINT16 Command,
1678                             A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1679 {
1680         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1681         struct wmi_rc_rate_mask_cmd *wmi_data = (struct wmi_rc_rate_mask_cmd *)buffer;
1682         int idx, band, i;
1683
1684         idx = wmi_data->vap_index;
1685         band = wmi_data->band;
1686
1687         sc->sc_vap[idx].av_rate_mask[band] = adf_os_ntohl(wmi_data->mask);
1688
1689         if (sc->sc_vap[idx].av_rate_mask[band]) {
1690                 for (i = 0; i < RATE_TABLE_SIZE; i++) {
1691                         if ((1 << i) & sc->sc_vap[idx].av_rate_mask[band]) {
1692                                 sc->sc_vap[idx].av_minrateidx[band] = i;
1693                                 break;
1694                         }
1695                 }
1696         } else {
1697                 sc->sc_vap[idx].av_minrateidx[band] = 0;
1698         }
1699
1700         wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1701 }
1702
1703 static WMI_DISPATCH_ENTRY Magpie_Sys_DispatchEntries[] =
1704 {
1705         {handle_echo_command,         WMI_ECHO_CMDID,               0},
1706         {dispatch_magpie_sys_cmds,    WMI_ACCESS_MEMORY_CMDID,      0},
1707         {ath_get_tgt_version,         WMI_GET_FW_VERSION,           0},
1708         {ath_disable_intr_tgt,        WMI_DISABLE_INTR_CMDID,       0},
1709         {ath_enable_intr_tgt,         WMI_ENABLE_INTR_CMDID,        0},
1710         {ath_init_tgt,                WMI_ATH_INIT_CMDID,           0},
1711         {ath_aborttxq_tgt,            WMI_ABORT_TXQ_CMDID,          0},
1712         {ath_stop_tx_dma_tgt,         WMI_STOP_TX_DMA_CMDID,        0},
1713         {ath_aborttx_dma_tgt,         WMI_ABORT_TX_DMA_CMDID,       0},
1714         {ath_tx_draintxq_tgt,         WMI_DRAIN_TXQ_CMDID,          0},
1715         {ath_draintxq_tgt,            WMI_DRAIN_TXQ_ALL_CMDID,      0},
1716         {ath_startrecv_tgt,           WMI_START_RECV_CMDID,         0},
1717         {ath_stoprecv_tgt,            WMI_STOP_RECV_CMDID,          0},
1718         {ath_flushrecv_tgt,           WMI_FLUSH_RECV_CMDID,         0},
1719         {ath_setcurmode_tgt,          WMI_SET_MODE_CMDID,           0},
1720         {ath_node_create_tgt,         WMI_NODE_CREATE_CMDID,        0},
1721         {ath_node_cleanup_tgt,        WMI_NODE_REMOVE_CMDID,        0},
1722         {ath_vap_delete_tgt,          WMI_VAP_REMOVE_CMDID,         0},
1723         {ath_vap_create_tgt,          WMI_VAP_CREATE_CMDID,         0},
1724         {ath_hal_reg_read_tgt,        WMI_REG_READ_CMDID,           0},
1725         {ath_hal_reg_write_tgt,       WMI_REG_WRITE_CMDID,          0},
1726         {handle_rc_state_change_cmd,  WMI_RC_STATE_CHANGE_CMDID,    0},
1727         {handle_rc_rate_update_cmd,   WMI_RC_RATE_UPDATE_CMDID,     0},
1728         {ath_ic_update_tgt,           WMI_TARGET_IC_UPDATE_CMDID,   0},
1729         {ath_enable_aggr_tgt,         WMI_TX_AGGR_ENABLE_CMDID,     0},
1730         {ath_detach_tgt,              WMI_TGT_DETACH_CMDID,         0},
1731         {ath_node_update_tgt,         WMI_NODE_UPDATE_CMDID,        0},
1732         {ath_int_stats_tgt,           WMI_INT_STATS_CMDID,          0},
1733         {ath_tx_stats_tgt,            WMI_TX_STATS_CMDID,           0},
1734         {ath_rx_stats_tgt,            WMI_RX_STATS_CMDID,           0},
1735         {ath_rc_mask_tgt,             WMI_BITRATE_MASK_CMDID,       0},
1736 };
1737
1738 /*****************/
1739 /* Init / Deinit */
1740 /*****************/
1741
1742 static void htc_setup_comp(void)
1743 {
1744 }
1745
1746 static A_UINT8 tgt_ServiceConnect(HTC_SERVICE *pService,
1747                                   HTC_ENDPOINT_ID eid,
1748                                   A_UINT8 *pDataIn,
1749                                   a_int32_t LengthIn,
1750                                   A_UINT8 *pDataOut,
1751                                   a_int32_t *pLengthOut)
1752 {
1753         struct ath_softc_tgt *sc = (struct ath_softc_tgt *)pService->ServiceCtx;
1754
1755         switch(pService->ServiceID) {
1756         case WMI_CONTROL_SVC:
1757                 sc->wmi_command_ep= eid;
1758                 break;
1759         case WMI_BEACON_SVC:
1760                 sc->beacon_ep= eid;
1761                 break;
1762         case WMI_CAB_SVC:
1763                 sc->cab_ep= eid;
1764                 break;
1765         case WMI_UAPSD_SVC:
1766                 sc->uapsd_ep= eid;
1767                 break;
1768         case WMI_MGMT_SVC:
1769                 sc->mgmt_ep= eid;
1770                 break;
1771         case WMI_DATA_VO_SVC:
1772                 sc->data_VO_ep = eid;
1773                 break;
1774         case WMI_DATA_VI_SVC:
1775                 sc->data_VI_ep = eid;
1776                 break;
1777         case WMI_DATA_BE_SVC:
1778                 sc->data_BE_ep = eid;
1779                 break;
1780         case WMI_DATA_BK_SVC:
1781                 sc->data_BK_ep = eid;
1782                 break;
1783         default:
1784                 adf_os_assert(0);
1785         }
1786
1787         return HTC_SERVICE_SUCCESS;
1788 }
1789
1790 static void tgt_reg_service(struct ath_softc_tgt *sc, HTC_SERVICE *svc,
1791                             int svcId, HTC_SERVICE_ProcessRecvMsg recvMsg)
1792 {
1793         svc->ProcessRecvMsg = recvMsg;
1794         svc->ProcessSendBufferComplete = tgt_HTCSendCompleteHandler;
1795         svc->ProcessConnect = tgt_ServiceConnect;
1796         svc->MaxSvcMsgSize = 1600;
1797         svc->TrailerSpcCheckLimit = 0;
1798         svc->ServiceID = svcId;
1799         svc->ServiceCtx = sc;
1800         HTC_RegisterService(sc->tgt_htc_handle, svc);
1801 }
1802
1803 static void tgt_hif_htc_wmi_init(struct ath_softc_tgt *sc)
1804 {
1805         HTC_CONFIG htc_conf;
1806         WMI_SVC_CONFIG wmiConfig;
1807         WMI_DISPATCH_TABLE *Magpie_Sys_Commands_Tbl;
1808
1809         /* Init dynamic buf pool */
1810         sc->pool_handle = BUF_Pool_init(sc->sc_hdl);
1811
1812         /* Init target-side HIF */
1813         sc->tgt_hif_handle = HIF_init(0);
1814
1815         /* Init target-side HTC */
1816         htc_conf.HIFHandle = sc->tgt_hif_handle;
1817         htc_conf.CreditSize = 320;
1818         htc_conf.CreditNumber = ATH_TXBUF;
1819         htc_conf.OSHandle = sc->sc_hdl;
1820         htc_conf.PoolHandle = sc->pool_handle;
1821         sc->tgt_htc_handle = HTC_init(htc_setup_comp, &htc_conf);
1822 #if defined(PROJECT_MAGPIE)
1823         init_htc_handle = sc->tgt_htc_handle;
1824 #endif
1825
1826         tgt_reg_service(sc, &sc->htc_beacon_service, WMI_BEACON_SVC, tgt_HTCRecv_beaconhandler);
1827         tgt_reg_service(sc, &sc->htc_cab_service, WMI_CAB_SVC, tgt_HTCRecv_cabhandler);
1828         tgt_reg_service(sc, &sc->htc_uapsd_service, WMI_UAPSD_SVC, tgt_HTCRecv_uapsdhandler);
1829         tgt_reg_service(sc, &sc->htc_mgmt_service, WMI_MGMT_SVC, tgt_HTCRecv_mgmthandler);
1830         tgt_reg_service(sc, &sc->htc_data_BE_service, WMI_DATA_BE_SVC, tgt_HTCRecvMessageHandler);
1831         tgt_reg_service(sc, &sc->htc_data_BK_service, WMI_DATA_BK_SVC, tgt_HTCRecvMessageHandler);
1832         tgt_reg_service(sc, &sc->htc_data_VI_service, WMI_DATA_VI_SVC, tgt_HTCRecvMessageHandler);
1833         tgt_reg_service(sc, &sc->htc_data_VO_service, WMI_DATA_VO_SVC, tgt_HTCRecvMessageHandler);
1834
1835         /* Init target-side WMI */
1836         Magpie_Sys_Commands_Tbl = (WMI_DISPATCH_TABLE *)adf_os_mem_alloc(sizeof(WMI_DISPATCH_TABLE));
1837         adf_os_mem_zero(Magpie_Sys_Commands_Tbl, sizeof(WMI_DISPATCH_TABLE));
1838         Magpie_Sys_Commands_Tbl->NumberOfEntries = WMI_DISPATCH_ENTRY_COUNT(Magpie_Sys_DispatchEntries);
1839         Magpie_Sys_Commands_Tbl->pTable = Magpie_Sys_DispatchEntries;
1840
1841         adf_os_mem_zero(&wmiConfig, sizeof(WMI_SVC_CONFIG));
1842         wmiConfig.HtcHandle = sc->tgt_htc_handle;
1843         wmiConfig.PoolHandle = sc->pool_handle;
1844         wmiConfig.MaxCmdReplyEvts = ATH_WMI_MAX_CMD_REPLY;
1845         wmiConfig.MaxEventEvts = ATH_WMI_MAX_EVENTS;
1846
1847         sc->tgt_wmi_handle = WMI_Init(&wmiConfig);
1848         Magpie_Sys_Commands_Tbl->pContext = sc;
1849         WMI_RegisterDispatchTable(sc->tgt_wmi_handle, Magpie_Sys_Commands_Tbl);
1850
1851         HTC_NotifyTargetInserted(sc->tgt_htc_handle);
1852
1853         /* Start HTC messages exchange */
1854         HTC_Ready(sc->tgt_htc_handle);
1855 }
1856
1857 a_int32_t ath_tgt_attach(a_uint32_t devid,a_uint32_t mem_start,
1858                          struct ath_softc_tgt *sc, adf_os_device_t osdev)
1859 {
1860         struct ath_hal *ah;
1861         HAL_STATUS status;
1862         a_int32_t error = 0, i, flags = 0;
1863         a_uint8_t csz;
1864
1865         adf_os_pci_config_read8(osdev, ATH_PCI_CACHE_LINE_SIZE, &csz);
1866
1867         if (csz == 0)
1868                 csz = 16;
1869         sc->sc_cachelsz = csz << 2;
1870
1871         sc->sc_dev = osdev;
1872         sc->sc_hdl = osdev;
1873
1874         ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_rxtq, ath_tgt_rx_tasklet, sc);
1875         ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_txtq, owl_tgt_tx_tasklet, sc);
1876         ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_bmisstq, ath_bmiss_tasklet, sc);
1877         ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_fataltq, ath_fatal_tasklet, sc);
1878
1879         flags |= AH_USE_EEPROM;
1880         ah = _ath_hal_attach_tgt(devid,sc,sc->sc_dev,mem_start, flags, &status);
1881         if (ah == NULL) {
1882                 error = ENXIO;
1883                 goto bad;
1884         }
1885         sc->sc_ah = ah;
1886
1887         tgt_hif_htc_wmi_init(sc);
1888
1889         sc->sc_bhalq = HAL_NUM_TX_QUEUES - 1;
1890
1891         ath_rate_setup(sc, IEEE80211_MODE_11NA);
1892         ath_rate_setup(sc, IEEE80211_MODE_11NG);
1893
1894         sc->sc_rc = ath_rate_attach(sc);
1895         if (sc->sc_rc == NULL) {
1896                 error = EIO;
1897                 goto bad2;
1898         }
1899
1900         for (i=0; i < TARGET_NODE_MAX; i++) {
1901                 sc->sc_sta[i].an_rcnode = adf_os_mem_alloc(sc->sc_rc->arc_space);
1902         }
1903
1904         error = ath_desc_alloc(sc);
1905         if (error != 0) {
1906                 goto bad;
1907         }
1908
1909         BUF_Pool_create_pool(sc->pool_handle, POOL_ID_WLAN_RX_BUF, ath_numrxdescs, 1664);
1910
1911         ath_tgt_txq_setup(sc);
1912         sc->sc_imask =0;
1913         ath_hal_intrset(ah,0);
1914
1915         return 0;
1916 bad:
1917 bad2:
1918         ath_desc_free(sc);
1919         if (ah)
1920                 ath_hal_detach(ah);
1921 }
1922
1923 static void tgt_hif_htc_wmi_shutdown(struct ath_softc_tgt *sc)
1924 {
1925         HTC_NotifyTargetDetached(sc->tgt_htc_handle);
1926
1927         WMI_Shutdown(sc->tgt_wmi_handle);
1928         HTC_Shutdown(sc->tgt_htc_handle);
1929         HIF_shutdown(sc->tgt_hif_handle);
1930         BUF_Pool_shutdown(sc->pool_handle);
1931 }
1932
1933 a_int32_t ath_detach(struct ath_softc_tgt *sc)
1934 {
1935         tgt_hif_htc_wmi_shutdown(sc);
1936 }