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