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