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