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