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