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