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