1 #include <adf_os_types.h>
2 #include <adf_os_pci.h>
3 #include <adf_os_dma.h>
4 #include <adf_os_timer.h>
5 #include <adf_os_lock.h>
7 #include <adf_os_mem.h>
8 #include <adf_os_util.h>
9 #include <adf_os_stdtypes.h>
10 #include <adf_os_defer.h>
11 #include <adf_os_atomic.h>
14 #include <adf_net_wcmd.h>
15 #include <adf_os_irq.h>
17 #include <if_ath_pci.h>
18 #include "if_ethersubr.h"
20 #include "ieee80211_var.h"
21 #include "ieee80211_proto.h"
22 #include "if_athrate.h"
23 #include "if_athvar.h"
26 static a_int32_t ath_numrxbufs = -1;
27 static a_int32_t ath_numrxdescs = -1;
29 #if defined(PROJECT_MAGPIE)
30 uint32_t *init_htc_handle = 0;
33 #define RX_ENDPOINT_ID 3
34 #define ATH_CABQ_HANDLING_THRESHOLD 9000
38 void wmi_event(wmi_handle_t handle, WMI_EVENT_ID evt_id, A_UINT8 *buffer, a_int32_t Length);
39 void owl_tgt_tx_tasklet(TQUEUE_ARG data);
40 static void ath_tgt_send_beacon(struct ath_softc_tgt *sc,adf_nbuf_t bc_hdr,adf_nbuf_t nbuf,HTC_ENDPOINT_ID EndPt);
41 void wmi_cmd_rsp(void *pContext, WMI_COMMAND_ID cmd_id, A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length);
42 static void ath_hal_reg_write_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen);
43 extern struct ath_buf * ath_tgt_tx_prepare(struct ath_softc_tgt *sc, adf_nbuf_t skb, ath_data_hdr_t *dh);
44 extern void ath_tgt_send_mgt(struct ath_softc_tgt *sc,adf_nbuf_t mgt_hdr, adf_nbuf_t skb,HTC_ENDPOINT_ID EndPt);
45 extern HAL_BOOL ath_hal_wait(struct ath_hal *ah, a_uint32_t reg, a_uint32_t mask, a_uint32_t val);
46 extern void owltgt_tx_processq(struct ath_softc_tgt *sc, struct ath_txq *txq, owl_txq_state_t txqstate);
47 void owl_tgt_node_init(struct ath_node_target * an);
48 void ath_tgt_tx_sched_normal(struct ath_softc_tgt *sc, struct ath_buf *bf);
49 void ath_tgt_tx_sched_nonaggr(struct ath_softc_tgt *sc,struct ath_buf * bf_host);
55 #undef adf_os_cpu_to_le16
57 static a_uint16_t adf_os_cpu_to_le16(a_uint16_t x)
59 return ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8));
63 * Extend a 32 bit TSF to 64 bit, taking wrapping into account.
65 static u_int64_t ath_extend_tsf(struct ath_softc_tgt *sc, u_int32_t rstamp)
71 tsf = ath_hal_gettsf64(sc->sc_ah);
72 tsf_low = tsf & 0xffffffff;
73 tsf64 = (tsf & ~0xffffffffULL) | rstamp;
75 if (rstamp > tsf_low && (rstamp - tsf_low > 0x10000000))
76 tsf64 -= 0x100000000ULL;
78 if (rstamp < tsf_low && (tsf_low - rstamp > 0x10000000))
79 tsf64 += 0x100000000ULL;
84 static a_int32_t ath_rate_setup(struct ath_softc_tgt *sc, a_uint32_t mode)
86 struct ath_hal *ah = sc->sc_ah;
87 const HAL_RATE_TABLE *rt;
90 case IEEE80211_MODE_11NA:
91 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11NA);
93 case IEEE80211_MODE_11NG:
94 sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11NG);
99 rt = sc->sc_rates[mode];
106 static void ath_setcurmode(struct ath_softc_tgt *sc,
107 enum ieee80211_phymode mode)
109 const HAL_RATE_TABLE *rt;
112 adf_os_mem_set(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
114 rt = sc->sc_rates[mode];
115 adf_os_assert(rt != NULL);
117 for (i = 0; i < rt->rateCount; i++) {
118 sc->sc_rixmap[rt->info[i].rateCode] = i;
121 sc->sc_currates = rt;
122 sc->sc_curmode = mode;
123 sc->sc_protrix = ((mode == IEEE80211_MODE_11NG) ? 3 : 0);
127 void wmi_event(wmi_handle_t handle, WMI_EVENT_ID evt_id,
128 A_UINT8 *buffer, a_int32_t Length)
130 adf_nbuf_t netbuf = ADF_NBUF_NULL;
133 netbuf = WMI_AllocEvent(handle, WMI_EVT_CLASS_CMD_EVENT,
134 sizeof(WMI_CMD_HDR) + Length);
136 if (netbuf == ADF_NBUF_NULL) {
137 adf_os_print("Buf null\n");
141 if (buffer != NULL && Length != 0 && Length < WMI_SVC_MAX_BUFFERED_EVENT_SIZE) {
142 pData = adf_nbuf_put_tail(netbuf, Length);
143 adf_os_mem_copy(pData, buffer, Length);
146 WMI_SendEvent(handle, netbuf, evt_id, 0, Length);
149 void wmi_cmd_rsp(void *pContext, WMI_COMMAND_ID cmd_id, A_UINT16 SeqNo,
150 A_UINT8 *buffer, a_int32_t Length)
152 adf_nbuf_t netbuf = ADF_NBUF_NULL;
155 netbuf = WMI_AllocEvent(pContext, WMI_EVT_CLASS_CMD_REPLY,
156 sizeof(WMI_CMD_HDR) + Length);
158 if (netbuf == ADF_NBUF_NULL) {
163 if (Length != 0 && buffer != NULL) {
164 pData = (A_UINT8 *)adf_nbuf_put_tail(netbuf, Length);
165 adf_os_mem_copy(pData, buffer, Length);
168 WMI_SendEvent(pContext, netbuf, cmd_id, SeqNo, Length);
171 static void ath_node_vdelete_tgt(struct ath_softc_tgt *sc, a_uint8_t vap_index)
175 for (i = 0; i < TARGET_NODE_MAX; i++) {
176 if(sc->sc_sta[i].ni.ni_vapindex == vap_index)
177 sc->sc_sta[i].an_valid = 0;
181 a_uint8_t ath_get_minrateidx(struct ath_softc_tgt *sc, struct ath_vap_target *avp)
183 if (sc->sc_curmode == IEEE80211_MODE_11NG)
184 return avp->av_minrateidx[0];
185 else if (sc->sc_curmode == IEEE80211_MODE_11NA)
186 return avp->av_minrateidx[1];
195 static adf_nbuf_t ath_alloc_skb_align(struct ath_softc_tgt *sc,
196 a_uint32_t size, a_uint32_t align)
200 skb = BUF_Pool_alloc_buf_align(sc->pool_handle, POOL_ID_WLAN_RX_BUF,
201 RX_HEADER_SPACE, align);
205 static a_int32_t ath_rxdesc_init(struct ath_softc_tgt *sc, struct ath_rx_desc *ds)
207 struct ath_hal *ah = sc->sc_ah;
208 struct ath_rx_desc *ds_held;
212 if (!sc->sc_rxdesc_held) {
213 sc->sc_rxdesc_held = ds;
217 ds_held = sc->sc_rxdesc_held;
218 sc->sc_rxdesc_held = ds;
221 if (ds->ds_nbuf == ADF_NBUF_NULL) {
222 ds->ds_nbuf = ath_alloc_skb_align(sc, sc->sc_rxbufsize, sc->sc_cachelsz);
223 if (ds->ds_nbuf == ADF_NBUF_NULL) {
224 sc->sc_rxdesc_held = ds;
225 sc->sc_rx_stats.ast_rx_nobuf++;
228 adf_nbuf_map(sc->sc_dev, ds->ds_dmap, ds->ds_nbuf, ADF_OS_DMA_FROM_DEVICE);
229 adf_nbuf_dmamap_info(ds->ds_dmap, &ds->ds_dmap_info);
230 ds->ds_data = ds->ds_dmap_info.dma_segs[0].paddr;
234 adf_nbuf_peek_header(ds->ds_nbuf, &anbdata, &anblen);
236 ath_hal_setuprxdesc(ah, ds,
237 adf_nbuf_tailroom(ds->ds_nbuf),
240 if (sc->sc_rxlink == NULL) {
241 ath_hal_putrxbuf(ah, ds->ds_daddr);
244 *sc->sc_rxlink = ds->ds_daddr;
246 sc->sc_rxlink = &ds->ds_link;
252 static void ath_rx_complete(struct ath_softc_tgt *sc, adf_nbuf_t buf)
254 struct ath_rx_desc *ds;
256 adf_nbuf_queue_t nbuf_head;
258 adf_nbuf_split_to_frag(buf, &nbuf_head);
259 ds = asf_tailq_first(&sc->sc_rxdesc_idle);
262 struct ath_rx_desc *ds_tmp;
263 buf_tmp = adf_nbuf_queue_remove(&nbuf_head);
265 if (buf_tmp == NULL) {
269 BUF_Pool_free_buf(sc->pool_handle, POOL_ID_WLAN_RX_BUF, buf_tmp);
272 ds = asf_tailq_next(ds, ds_list);
274 ath_rxdesc_init(sc, ds_tmp);
276 asf_tailq_remove(&sc->sc_rxdesc_idle, ds_tmp, ds_list);
277 asf_tailq_insert_tail(&sc->sc_rxdesc, ds_tmp, ds_list);
281 static void tgt_HTCSendCompleteHandler(HTC_ENDPOINT_ID Endpt, adf_nbuf_t buf, void *ServiceCtx)
283 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
285 if (Endpt == RX_ENDPOINT_ID) {
286 sc->sc_rx_stats.ast_rx_done++;
287 ath_rx_complete(sc, buf);
291 static void ath_uapsd_processtriggers(struct ath_softc_tgt *sc)
293 struct ath_hal *ah = sc->sc_ah;
294 struct ath_rx_buf *bf = NULL;
295 struct ath_rx_desc *ds, *ds_head, *ds_tail, *ds_tmp;
298 a_uint16_t frame_len = 0;
301 #define PA2DESC(_sc, _pa) \
302 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
303 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
305 tsf = ath_hal_gettsf64(ah);
306 bf = asf_tailq_first(&sc->sc_rxbuf);
308 ds = asf_tailq_first(&sc->sc_rxdesc);
314 if (cnt == ath_numrxbufs - 1) {
315 adf_os_print("VERY LONG PACKET!!!!!\n");
319 struct ath_rx_desc *ds_rmv;
320 adf_nbuf_unmap(sc->sc_dev, ds_tmp->ds_dmap, ADF_OS_DMA_FROM_DEVICE);
322 ds_tmp = asf_tailq_next(ds_tmp, ds_list);
324 if (ds_tmp == NULL) {
325 adf_os_print("ds_tmp is NULL\n");
329 BUF_Pool_free_buf(sc->pool_handle, POOL_ID_WLAN_RX_BUF, ds_rmv->ds_nbuf);
330 ds_rmv->ds_nbuf = ADF_NBUF_NULL;
332 if (ath_rxdesc_init(sc, ds_rmv) == 0) {
333 asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
334 asf_tailq_insert_tail(&sc->sc_rxdesc, ds_rmv, ds_list);
337 asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
338 asf_tailq_insert_tail(&sc->sc_rxdesc_idle, ds_rmv, ds_list);
341 if (ds_rmv == ds_tail) {
348 if (ds->ds_link == NULL) {
352 if (bf->bf_status & ATH_BUFSTATUS_DONE) {
356 retval = ath_hal_rxprocdescfast(ah, ds, ds->ds_daddr,
357 PA2DESC(sc, ds->ds_link), &bf->bf_rx_status);
358 if (HAL_EINPROGRESS == retval) {
362 if (adf_nbuf_len(ds->ds_nbuf) == 0) {
363 adf_nbuf_put_tail(ds->ds_nbuf, bf->bf_rx_status.rs_datalen);
366 frame_len += bf->bf_rx_status.rs_datalen;
368 if (bf->bf_rx_status.rs_more == 0) {
369 adf_nbuf_queue_t nbuf_head;
370 adf_nbuf_queue_init(&nbuf_head);
375 ds = asf_tailq_next(ds, ds_list);
378 ds_head = asf_tailq_next(ds_tail, ds_list);
381 struct ath_rx_desc *ds_rmv;
383 adf_nbuf_unmap(sc->sc_dev, ds_tmp->ds_dmap, ADF_OS_DMA_FROM_DEVICE);
384 adf_nbuf_queue_add(&nbuf_head, ds_tmp->ds_nbuf);
385 ds_tmp->ds_nbuf = ADF_NBUF_NULL;
388 ds_tmp = asf_tailq_next(ds_tmp, ds_list);
389 if (ds_tmp == NULL) {
393 if (ath_rxdesc_init(sc, ds_rmv) == 0) {
394 asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
395 asf_tailq_insert_tail(&sc->sc_rxdesc, ds_rmv, ds_list);
397 asf_tailq_remove(&sc->sc_rxdesc, ds_rmv, ds_list);
398 asf_tailq_insert_tail(&sc->sc_rxdesc_idle, ds_rmv, ds_list);
401 if (ds_rmv == ds_tail) {
407 bf->bf_rx_status.rs_datalen = frame_len;
410 bf->bf_skb = adf_nbuf_create_frm_frag(&nbuf_head);
412 bf->bf_status |= ATH_BUFSTATUS_DONE;
414 bf = asf_tailq_next(bf, bf_list);
417 ds = asf_tailq_next(ds, ds_list);
424 static a_int32_t ath_startrecv(struct ath_softc_tgt *sc)
426 struct ath_hal *ah = sc->sc_ah;
427 struct ath_rx_desc *ds;
429 sc->sc_rxbufsize = 1024+512+128;
430 sc->sc_rxlink = NULL;
432 sc->sc_rxdesc_held = NULL;
434 asf_tailq_foreach(ds, &sc->sc_rxdesc, ds_list) {
435 a_int32_t error = ath_rxdesc_init(sc, ds);
441 ds = asf_tailq_first(&sc->sc_rxdesc);
442 ath_hal_putrxbuf(ah, ds->ds_daddr);
447 static void ath_tgt_rx_tasklet(TQUEUE_ARG data)
449 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)data;
450 struct ath_rx_buf *bf = NULL;
451 struct ath_hal *ah = sc->sc_ah;
452 struct rx_frame_header *rxhdr;
453 struct ieee80211_frame *wh;
454 struct ath_rx_status *rxstats;
455 adf_nbuf_t skb = ADF_NBUF_NULL;
458 bf = asf_tailq_first(&sc->sc_rxbuf);
463 if (!(bf->bf_status & ATH_BUFSTATUS_DONE)) {
472 asf_tailq_remove(&sc->sc_rxbuf, bf, bf_list);
476 rxhdr = (struct rx_frame_header *)adf_nbuf_push_head(skb,
477 sizeof(struct rx_frame_header));
478 rxstats = (struct ath_rx_status *)(&rxhdr->rx_stats[0]);
479 adf_os_mem_copy(rxstats, &(bf->bf_rx_status),
480 sizeof(struct ath_rx_status));
482 rxstats->rs_tstamp = ath_extend_tsf(sc, (u_int32_t)rxstats->rs_tstamp);
484 HTC_SendMsg(sc->tgt_htc_handle, RX_ENDPOINT_ID, skb);
485 sc->sc_rx_stats.ast_rx_send++;
488 bf->bf_status &= ~ATH_BUFSTATUS_DONE;
489 asf_tailq_insert_tail(&sc->sc_rxbuf, bf, bf_list);
493 sc->sc_imask |= HAL_INT_RX;
494 ath_hal_intrset(ah, sc->sc_imask);
497 /*******************/
498 /* Beacon Handling */
499 /*******************/
502 * Setup the beacon frame for transmit.
503 * FIXME: Short Preamble.
505 static void ath_beacon_setup(struct ath_softc_tgt *sc,
507 struct ath_vap_target *avp)
509 adf_nbuf_t skb = bf->bf_skb;
510 struct ath_hal *ah = sc->sc_ah;
512 a_int32_t flags, antenna;
513 const HAL_RATE_TABLE *rt;
515 HAL_11N_RATE_SERIES series[4] = {{ 0 }};
517 flags = HAL_TXDESC_NOACK;
521 ds->ds_data = bf->bf_dmamap_info.dma_segs[0].paddr;
523 rix = ath_get_minrateidx(sc, avp);
524 rt = sc->sc_currates;
525 rate = rt->info[rix].rateCode;
527 ath_hal_setuptxdesc(ah, ds
528 , adf_nbuf_len(skb) + IEEE80211_CRC_LEN
529 , sizeof(struct ieee80211_frame)
530 , HAL_PKT_TYPE_BEACON
533 , HAL_TXKEYIX_INVALID
540 , ATH_COMP_PROC_NO_COMP_NO_CCS);
542 ath_hal_filltxdesc(ah, ds
543 , asf_roundup(adf_nbuf_len(skb), 4)
549 series[0].Rate = rate;
550 series[0].ChSel = sc->sc_ic.ic_tx_chainmask;
551 series[0].RateFlags = 0;
552 ath_hal_set11n_ratescenario(ah, ds, 0, 0, 0, series, 4, 0);
555 static void ath_tgt_send_beacon(struct ath_softc_tgt *sc, adf_nbuf_t bc_hdr,
556 adf_nbuf_t nbuf, HTC_ENDPOINT_ID EndPt)
558 struct ath_hal *ah = sc->sc_ah;
559 struct ath_tx_buf *bf;
560 a_uint8_t vap_index, *anbdata;
561 ath_beacon_hdr_t *bhdr;
562 struct ieee80211vap_target *vap;
564 struct ieee80211_frame *wh;
567 adf_nbuf_peek_header(nbuf, &anbdata, &anblen);
568 bhdr = (ath_beacon_hdr_t *)anbdata;
570 adf_os_print("found bc_hdr! 0x%x\n", bc_hdr);
573 vap_index = bhdr->vap_index;
574 adf_os_assert(vap_index < TARGET_VAP_MAX);
575 vap = &sc->sc_vap[vap_index];
577 wh = (struct ieee80211_frame *)adf_nbuf_pull_head(nbuf,
578 sizeof(ath_beacon_hdr_t));
580 bf = sc->sc_vap[vap_index].av_bcbuf;
582 bf->bf_endpt = EndPt;
585 adf_nbuf_unmap(sc->sc_dev, bf->bf_dmamap, ADF_OS_DMA_TO_DEVICE);
586 adf_nbuf_push_head(bf->bf_skb, sizeof(ath_beacon_hdr_t));
587 ath_free_tx_skb(sc->tgt_htc_handle, bf->bf_endpt, bf->bf_skb);
592 adf_nbuf_map(sc->sc_dev, bf->bf_dmamap, nbuf, ADF_OS_DMA_TO_DEVICE);
593 adf_nbuf_dmamap_info(bf->bf_dmamap,&bf->bf_dmamap_info);
595 ath_beacon_setup(sc, bf, &sc->sc_vap[vap_index]);
596 ath_hal_stoptxdma(ah, sc->sc_bhalq);
597 ath_hal_puttxbuf(ah, sc->sc_bhalq, ATH_BUF_GET_DESC_PHY_ADDR(bf));
598 ath_hal_txstart(ah, sc->sc_bhalq);
605 static void ath_tx_stopdma(struct ath_softc_tgt *sc, struct ath_txq *txq)
607 struct ath_hal *ah = sc->sc_ah;
609 (void) ath_hal_stoptxdma(ah, txq->axq_qnum);
612 static void owltgt_txq_drain(struct ath_softc_tgt *sc, struct ath_txq *txq)
614 owltgt_tx_processq(sc, txq, OWL_TXQ_STOPPED);
617 static void ath_tx_draintxq(struct ath_softc_tgt *sc, struct ath_txq *txq)
619 owltgt_txq_drain(sc, txq);
622 static void ath_draintxq(struct ath_softc_tgt *sc, HAL_BOOL drain_softq)
624 struct ath_hal *ah = sc->sc_ah;
626 struct ath_txq *txq = NULL;
627 struct ath_atx_tid *tid = NULL;
629 ath_tx_status_clear(sc);
630 sc->sc_tx_draining = 1;
632 (void) ath_hal_stoptxdma(ah, sc->sc_bhalq);
634 for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
635 if (ATH_TXQ_SETUP(sc, i))
636 ath_tx_stopdma(sc, ATH_TXQ(sc, i));
638 for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
639 if (ATH_TXQ_SETUP(sc, i)) {
640 owltgt_tx_processq(sc, ATH_TXQ(sc,i), OWL_TXQ_STOPPED);
643 while (!asf_tailq_empty(&txq->axq_tidq)){
644 TAILQ_DEQ(&txq->axq_tidq, tid, tid_qelem);
647 tid->sched = AH_FALSE;
648 ath_tgt_tid_drain(sc,tid);
652 sc->sc_tx_draining = 0;
655 static void ath_tgt_txq_setup(struct ath_softc_tgt *sc)
662 for (qnum=0;qnum<HAL_NUM_TX_QUEUES;qnum++) {
663 txq= &sc->sc_txq[qnum];
664 txq->axq_qnum = qnum;
665 txq->axq_link = NULL;
666 asf_tailq_init(&txq->axq_q);
668 txq->axq_linkbuf = NULL;
669 asf_tailq_init(&txq->axq_tidq);
670 sc->sc_txqsetup |= 1<<qnum;
673 sc->sc_uapsdq = &sc->sc_txq[UAPSDQ_NUM];
674 sc->sc_cabq = &sc->sc_txq[CABQ_NUM];
676 sc->sc_ac2q[WME_AC_BE] = &sc->sc_txq[0];
677 sc->sc_ac2q[WME_AC_BK] = &sc->sc_txq[1];
678 sc->sc_ac2q[WME_AC_VI] = &sc->sc_txq[2];
679 sc->sc_ac2q[WME_AC_VO] = &sc->sc_txq[3];
685 static void tgt_HTCRecv_beaconhandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
686 adf_nbuf_t buf, void *ServiceCtx)
688 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
690 ath_tgt_send_beacon(sc, hdr_buf, buf, EndPt);
693 static void tgt_HTCRecv_uapsdhandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
694 adf_nbuf_t buf, void *ServiceCtx)
698 static void tgt_HTCRecv_mgmthandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
699 adf_nbuf_t buf, void *ServiceCtx)
701 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
703 ath_tgt_send_mgt(sc,hdr_buf,buf,EndPt);
706 static void tgt_HTCRecvMessageHandler(HTC_ENDPOINT_ID EndPt,
707 adf_nbuf_t hdr_buf, adf_nbuf_t buf,
710 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
711 struct ath_tx_buf *bf;
715 struct ath_node_target *an;
716 struct ath_atx_tid *tid;
719 adf_nbuf_peek_header(buf, &data, &len);
720 adf_nbuf_pull_head(buf, sizeof(ath_data_hdr_t));
722 adf_nbuf_peek_header(hdr_buf, &data, &len);
725 adf_os_assert(len >= sizeof(ath_data_hdr_t));
726 dh = (ath_data_hdr_t *)data;
728 an = &sc->sc_sta[dh->ni_index];
729 tid = ATH_AN_2_TID(an, dh->tidno);
731 sc->sc_tx_stats.tx_tgt++;
733 bf = ath_tgt_tx_prepare(sc, buf, dh);
735 ath_free_tx_skb(sc->tgt_htc_handle,EndPt,buf);
739 bf->bf_endpt = EndPt;
740 bf->bf_cookie = dh->cookie;
742 if (tid->flag & TID_AGGR_ENABLED)
743 ath_tgt_handle_aggr(sc, bf);
745 ath_tgt_handle_normal(sc, bf);
748 static void tgt_HTCRecv_cabhandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf,
749 adf_nbuf_t buf, void *ServiceCtx)
751 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)ServiceCtx;
752 struct ath_hal *ah = sc->sc_ah;
756 #ifdef ATH_ENABLE_CABQ
757 tsf = ath_hal_gettsf64(ah);
758 tmp = tsf - sc->sc_swba_tsf;
760 if ( tmp > ATH_CABQ_HANDLING_THRESHOLD ) {
761 HTC_ReturnBuffers(sc->tgt_htc_handle, EndPt, buf);
765 tgt_HTCRecvMessageHandler(EndPt, hdr_buf, buf, ServiceCtx);
769 /***********************/
770 /* Descriptor Handling */
771 /***********************/
773 static a_int32_t ath_descdma_setup(struct ath_softc_tgt *sc,
774 struct ath_descdma *dd, ath_bufhead *head,
775 const char *name, a_int32_t nbuf, a_int32_t ndesc,
776 a_uint32_t bfSize, a_uint32_t descSize)
778 #define DS2PHYS(_dd, _ds) \
779 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
783 a_int32_t i, bsize, error;
788 dd->dd_desc_len = descSize * nbuf * ndesc;
790 dd->dd_desc = adf_os_dmamem_alloc(sc->sc_dev,
791 dd->dd_desc_len, 1, &dd->dd_desc_dmamap);
792 dd->dd_desc_paddr = adf_os_dmamem_map2addr(dd->dd_desc_dmamap);
793 if (dd->dd_desc == NULL) {
799 bsize = bfSize * nbuf;
800 bf = adf_os_mem_alloc(bsize);
805 adf_os_mem_set(bf, 0, bsize);
808 bf_addr = (a_uint8_t *)bf;
809 ds_addr = (a_uint8_t *)ds;
811 asf_tailq_init(head);
813 for (i = 0; i < nbuf; i++) {
816 if (adf_nbuf_dmamap_create( sc->sc_dev, &bf->bf_dmamap) != A_STATUS_OK) {
820 bf->bf_desc = bf->bf_descarr = bf->bf_lastds = ds;
821 for (j = 0; j < ndesc; j++)
822 ATH_BUF_SET_DESC_PHY_ADDR_WITH_IDX(bf, j, (ds_addr + (j*descSize)));
824 ATH_BUF_SET_DESC_PHY_ADDR(bf, ATH_BUF_GET_DESC_PHY_ADDR_WITH_IDX(bf, 0));
826 adf_nbuf_queue_init(&bf->bf_skbhead);
827 asf_tailq_insert_tail(head, bf, bf_list);
830 ds_addr += (ndesc * descSize);
831 bf = (struct ath_buf *)bf_addr;
832 ds = (struct ath_desc *)ds_addr;
837 adf_os_dmamem_free(sc->sc_dev, dd->dd_desc_len,
838 1, dd->dd_desc, dd->dd_desc_dmamap);
840 adf_os_mem_set(dd, 0, sizeof(*dd));
847 static void ath_descdma_cleanup(struct ath_softc_tgt *sc,
848 struct ath_descdma *dd,
849 ath_bufhead *head, a_int32_t dir)
851 struct ath_tx_buf *bf;
852 struct ieee80211_node *ni;
854 asf_tailq_foreach(bf, head, bf_list) {
855 if (adf_nbuf_queue_len(&bf->bf_skbhead) != 0) {
856 adf_nbuf_unmap(sc->sc_dev, bf->bf_dmamap, dir);
857 while(adf_nbuf_queue_len(&bf->bf_skbhead) != 0) {
859 adf_nbuf_queue_remove(&bf->bf_skbhead));
862 } else if (bf->bf_skb != NULL) {
863 adf_nbuf_unmap(sc->sc_dev,bf->bf_dmamap, dir);
864 ath_free_rx_skb(sc, bf->bf_skb);
868 adf_nbuf_dmamap_destroy(sc->sc_dev, bf->bf_dmamap);
874 adf_os_dmamem_free(sc->sc_dev, dd->dd_desc_len,
875 1, dd->dd_desc, dd->dd_desc_dmamap);
877 asf_tailq_init(head);
878 adf_os_mem_free(dd->dd_bufptr);
879 adf_os_mem_set(dd, 0, sizeof(*dd));
882 static a_int32_t ath_desc_alloc(struct ath_softc_tgt *sc)
884 #define DS2PHYS(_dd, _ds) \
885 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
888 struct ath_tx_buf *bf;
890 if(ath_numrxbufs == -1)
891 ath_numrxbufs = ATH_RXBUF;
893 if (ath_numrxdescs == -1)
894 ath_numrxdescs = ATH_RXDESC;
896 error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
897 "rx", ath_numrxdescs, 1,
898 sizeof(struct ath_rx_buf),
899 sizeof(struct ath_rx_desc));
904 struct ath_descdma *dd = &sc->sc_rxdma;
905 struct ath_rx_desc *ds = dd->dd_desc;
906 struct ath_rx_desc *ds_prev = NULL;
908 asf_tailq_init(&sc->sc_rxdesc);
909 asf_tailq_init(&sc->sc_rxdesc_idle);
911 for (i = 0; i < ath_numrxdescs; i++, ds++) {
913 if (ds->ds_nbuf != ADF_NBUF_NULL) {
914 ds->ds_nbuf = ADF_NBUF_NULL;
917 if (adf_nbuf_dmamap_create(sc->sc_dev, &ds->ds_dmap) != A_STATUS_OK) {
921 ds->ds_daddr = DS2PHYS(&sc->sc_rxdma, ds);
924 ds_prev->ds_link = ds->ds_daddr;
930 asf_tailq_insert_tail(&sc->sc_rxdesc, ds, ds_list);
933 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
934 "tx", ATH_TXBUF + 1, ATH_TXDESC,
935 sizeof(struct ath_tx_buf),
936 sizeof(struct ath_tx_desc));
938 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
939 ADF_OS_DMA_FROM_DEVICE);
943 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
944 "beacon", ATH_BCBUF, 1,
945 sizeof(struct ath_tx_buf),
946 sizeof(struct ath_tx_desc));
948 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
949 ADF_OS_DMA_TO_DEVICE);
950 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
951 ADF_OS_DMA_FROM_DEVICE);
955 bf = asf_tailq_first(&sc->sc_txbuf);
956 bf->bf_isaggr = bf->bf_isretried = bf->bf_retries = 0;
957 asf_tailq_remove(&sc->sc_txbuf, bf, bf_list);
959 sc->sc_txbuf_held = bf;
966 static void ath_desc_free(struct ath_softc_tgt *sc)
968 asf_tailq_insert_tail(&sc->sc_txbuf, sc->sc_txbuf_held, bf_list);
970 sc->sc_txbuf_held = NULL;
972 if (sc->sc_txdma.dd_desc_len != 0)
973 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
974 ADF_OS_DMA_TO_DEVICE);
975 if (sc->sc_rxdma.dd_desc_len != 0)
976 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
977 ADF_OS_DMA_FROM_DEVICE);
980 /**********************/
981 /* Interrupt Handling */
982 /**********************/
984 adf_os_irq_resp_t ath_intr(adf_drv_handle_t hdl)
986 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)hdl;
987 struct ath_hal *ah = sc->sc_ah;
988 struct ieee80211com_target *ic = &sc->sc_ic;
992 return ADF_OS_IRQ_NONE;
994 if (!ath_hal_intrpend(ah))
995 return ADF_OS_IRQ_NONE;
997 ath_hal_getisr(ah, &status);
999 status &= sc->sc_imask;
1001 if (status & HAL_INT_FATAL) {
1002 ath_hal_intrset(ah, 0);
1003 ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_fataltq);
1005 if (status & HAL_INT_SWBA) {
1006 WMI_SWBA_EVENT swbaEvt;
1007 struct ath_txq *txq = ATH_TXQ(sc, 8);
1009 swbaEvt.tsf = ath_hal_gettsf64(ah);
1010 swbaEvt.beaconPendingCount = ath_hal_numtxpending(ah, sc->sc_bhalq);
1011 sc->sc_swba_tsf = ath_hal_gettsf64(ah);
1013 wmi_event(sc->tgt_wmi_handle,
1016 sizeof(WMI_SWBA_EVENT));
1018 ath_tx_draintxq(sc, txq);
1021 if (status & HAL_INT_RXORN)
1022 sc->sc_int_stats.ast_rxorn++;
1024 if (status & HAL_INT_RXEOL)
1025 sc->sc_int_stats.ast_rxeol++;
1027 if (status & (HAL_INT_RX | HAL_INT_RXEOL | HAL_INT_RXORN)) {
1028 if (status & HAL_INT_RX)
1029 sc->sc_int_stats.ast_rx++;
1031 ath_uapsd_processtriggers(sc);
1033 sc->sc_imask &= ~HAL_INT_RX;
1034 ath_hal_intrset(ah, sc->sc_imask);
1036 ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_rxtq);
1039 if (status & HAL_INT_TXURN) {
1040 sc->sc_int_stats.ast_txurn++;
1041 ath_hal_updatetxtriglevel(ah, AH_TRUE);
1044 ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_txtq);
1046 if (status & HAL_INT_BMISS) {
1047 ATH_SCHEDULE_TQUEUE(sc->sc_dev, &sc->sc_bmisstq);
1050 if (status & HAL_INT_GTT)
1051 sc->sc_int_stats.ast_txto++;
1053 if (status & HAL_INT_CST)
1054 sc->sc_int_stats.ast_cst++;
1057 return ADF_OS_IRQ_HANDLED;
1060 static void ath_fatal_tasklet(TQUEUE_ARG data )
1062 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)data;
1064 wmi_event(sc->tgt_wmi_handle, WMI_FATAL_EVENTID, NULL, 0);
1067 static void ath_bmiss_tasklet(TQUEUE_ARG data)
1069 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)data;
1071 wmi_event(sc->tgt_wmi_handle, WMI_BMISS_EVENTID, NULL, 0);
1078 static void ath_enable_intr_tgt(void *Context, A_UINT16 Command,
1079 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1081 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1082 struct ath_hal *ah = sc->sc_ah;
1086 intr = (*(a_uint32_t *)data);
1088 intr = adf_os_ntohl(intr);
1090 if (intr & HAL_INT_SWBA) {
1091 sc->sc_imask |= HAL_INT_SWBA;
1093 sc->sc_imask &= ~HAL_INT_SWBA;
1096 if (intr & HAL_INT_BMISS) {
1097 sc->sc_imask |= HAL_INT_BMISS;
1100 ath_hal_intrset(ah, sc->sc_imask);
1101 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo,NULL, 0);
1104 static void ath_init_tgt(void *Context, A_UINT16 Command,
1105 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1107 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1108 struct ath_hal *ah = sc->sc_ah;
1109 a_uint32_t stbcsupport;
1111 sc->sc_imask = HAL_INT_RX | HAL_INT_TX
1112 | HAL_INT_RXEOL | HAL_INT_RXORN
1113 | HAL_INT_FATAL | HAL_INT_GLOBAL;
1115 sc->sc_imask |= HAL_INT_GTT;
1117 if (ath_hal_htsupported(ah))
1118 sc->sc_imask |= HAL_INT_CST;
1120 #ifdef MAGPIE_MERLIN
1121 if (ath_hal_txstbcsupport(ah, &stbcsupport))
1122 sc->sc_txstbcsupport = stbcsupport;
1124 if (ath_hal_rxstbcsupport(ah, &stbcsupport))
1125 sc->sc_rxstbcsupport = stbcsupport;
1127 adf_os_setup_intr(sc->sc_dev, ath_intr);
1128 ath_hal_intrset(ah, sc->sc_imask);
1130 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1133 static void ath_int_stats_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1134 A_UINT8 *data, a_int32_t datalen)
1136 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1138 struct fusion_stats {
1140 a_uint32_t ast_rxorn;
1141 a_uint32_t ast_rxeol;
1142 a_uint32_t ast_txurn;
1143 a_uint32_t ast_txto;
1147 struct fusion_stats stats;
1149 stats.ast_rx = sc->sc_int_stats.ast_rx;
1150 stats.ast_rxorn = sc->sc_int_stats.ast_rxorn;
1151 stats.ast_rxeol = sc->sc_int_stats.ast_rxeol;
1152 stats.ast_txurn = sc->sc_int_stats.ast_txurn;
1153 stats.ast_txto = sc->sc_int_stats.ast_txto;
1154 stats.ast_cst = sc->sc_int_stats.ast_cst;
1156 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &stats, sizeof(stats));
1159 static void ath_tx_stats_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1160 A_UINT8 *data, a_int32_t datalen)
1162 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1164 struct fusion_stats {
1165 a_uint32_t ast_tx_xretries;
1166 a_uint32_t ast_tx_fifoerr;
1167 a_uint32_t ast_tx_filtered;
1168 a_uint32_t ast_tx_timer_exp;
1169 a_uint32_t ast_tx_shortretry;
1170 a_uint32_t ast_tx_longretry;
1172 a_uint32_t tx_qnull;
1173 a_uint32_t tx_noskbs;
1174 a_uint32_t tx_nobufs;
1177 struct fusion_stats stats;
1179 stats.ast_tx_xretries = sc->sc_tx_stats.ast_tx_xretries;
1180 stats.ast_tx_fifoerr = sc->sc_tx_stats.ast_tx_fifoerr;
1181 stats.ast_tx_filtered = sc->sc_tx_stats.ast_tx_filtered;
1182 stats.ast_tx_timer_exp = sc->sc_tx_stats.ast_tx_timer_exp;
1183 stats.ast_tx_shortretry = sc->sc_tx_stats.ast_tx_shortretry;
1184 stats.ast_tx_longretry = sc->sc_tx_stats.ast_tx_longretry;
1185 stats.tx_qnull = sc->sc_tx_stats.tx_qnull;
1186 stats.tx_noskbs = sc->sc_tx_stats.tx_noskbs;
1187 stats.tx_nobufs = sc->sc_tx_stats.tx_nobufs;
1189 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &stats, sizeof(stats));
1192 static void ath_rx_stats_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1193 A_UINT8 *data, a_int32_t datalen)
1195 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1197 struct fusion_stats {
1198 a_uint32_t ast_rx_nobuf;
1199 a_uint32_t ast_rx_send;
1200 a_uint32_t ast_rx_done;
1203 struct fusion_stats stats;
1205 stats.ast_rx_nobuf = sc->sc_rx_stats.ast_rx_nobuf;
1206 stats.ast_rx_send = sc->sc_rx_stats.ast_rx_send;
1207 stats.ast_rx_done = sc->sc_rx_stats.ast_rx_done;
1209 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &stats, sizeof(stats));
1212 static void ath_get_tgt_version(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1213 A_UINT8 *data, a_int32_t datalen)
1215 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1216 struct wmi_fw_version ver;
1218 ver.major = ATH_VERSION_MAJOR;
1219 ver.minor = ATH_VERSION_MINOR;
1221 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &ver, sizeof(ver));
1224 static void ath_enable_aggr_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1225 A_UINT8 *data, a_int32_t datalen)
1227 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1228 struct ath_aggr_info *aggr = (struct ath_aggr_info *)data;
1229 a_uint8_t nodeindex = aggr->nodeindex;
1230 a_uint8_t tidno = aggr->tidno;
1231 struct ath_node_target *an = NULL ;
1232 struct ath_atx_tid *tid = NULL;
1234 if (nodeindex >= TARGET_NODE_MAX) {
1238 an = &sc->sc_sta[nodeindex];
1239 if (!an->an_valid) {
1243 if (tidno >= WME_NUM_TID) {
1244 adf_os_print("[%s] enable_aggr with invalid tid %d(node = %d)\n",
1245 __FUNCTION__, tidno, nodeindex);
1249 tid = ATH_AN_2_TID(an, tidno);
1251 if (aggr->aggr_enable) {
1252 tid->flag |= TID_AGGR_ENABLED;
1253 } else if ( tid->flag & TID_AGGR_ENABLED ) {
1254 tid->flag &= ~TID_AGGR_ENABLED;
1255 ath_tgt_tx_cleanup(sc, an, tid, 1);
1258 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1261 static void ath_ic_update_tgt(void *Context,A_UINT16 Command, A_UINT16 SeqNo,
1262 A_UINT8 *data, a_int32_t datalen)
1264 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1265 struct ieee80211com_target *ic = (struct ieee80211com_target * )data;
1266 struct ieee80211com_target *ictgt = &sc->sc_ic ;
1268 adf_os_mem_copy(ictgt, ic, sizeof(struct ieee80211com_target));
1270 ictgt->ic_ampdu_limit = adf_os_ntohl(ic->ic_ampdu_limit);
1272 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1275 static void ath_vap_create_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo,
1276 A_UINT8 *data, a_int32_t datalen)
1278 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1279 struct ieee80211vap_target *vap;
1280 a_uint8_t vap_index;
1282 vap = (struct ieee80211vap_target *)data;
1284 vap->iv_rtsthreshold = adf_os_ntohs(vap->iv_rtsthreshold);
1285 vap->iv_opmode = adf_os_ntohl(vap->iv_opmode);
1287 vap_index = vap->iv_vapindex;
1289 adf_os_assert(sc->sc_vap[vap_index].av_valid == 0);
1291 adf_os_mem_copy(&(sc->sc_vap[vap_index].av_vap), vap,
1294 sc->sc_vap[vap_index].av_bcbuf = asf_tailq_first(&(sc->sc_bbuf));
1295 sc->sc_vap[vap_index].av_valid = 1;
1297 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1300 static void ath_node_create_tgt(void *Context, A_UINT16 Command,
1301 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1303 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1304 struct ieee80211_node_target *node;
1305 a_uint8_t vap_index;
1306 a_uint8_t node_index;
1308 node = (struct ieee80211_node_target *)data;
1310 node_index = node->ni_nodeindex;
1312 node->ni_htcap = adf_os_ntohs(node->ni_htcap);
1313 node->ni_flags = adf_os_ntohs(node->ni_flags);
1314 node->ni_maxampdu = adf_os_ntohs(node->ni_maxampdu);
1316 adf_os_mem_copy(&(sc->sc_sta[node_index].ni), node,
1319 vap_index = sc->sc_sta[node_index].ni.ni_vapindex;
1320 sc->sc_sta[node_index].ni.ni_vap = &(sc->sc_vap[vap_index].av_vap);
1321 if(sc->sc_sta[node_index].ni.ni_is_vapnode == 1)
1322 sc->sc_vap[vap_index].av_vap.iv_nodeindex = node_index;
1324 sc->sc_sta[node_index].an_valid = 1;
1325 sc->sc_sta[node_index].ni.ni_txseqmgmt = 0;
1326 sc->sc_sta[node_index].ni.ni_iv16 = 0;
1327 sc->sc_sta[node_index].ni.ni_iv32 = 0;
1329 owl_tgt_node_init(&sc->sc_sta[node_index]);
1331 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1334 static void ath_node_cleanup_tgt(void *Context, A_UINT16 Command,
1335 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1337 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1338 a_uint8_t node_index;
1339 a_uint8_t *nodedata;
1341 nodedata = (a_uint8_t *)data;
1342 node_index = *nodedata;
1343 sc->sc_sta[node_index].an_valid = 0;
1345 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1348 static void ath_node_update_tgt(void *Context, A_UINT16 Command,
1349 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1351 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1352 struct ieee80211_node_target *node;
1353 a_uint8_t vap_index;
1354 a_uint8_t node_index;
1356 node = (struct ieee80211_node_target *)data;
1358 node_index = node->ni_nodeindex;
1360 node->ni_htcap = adf_os_ntohs(node->ni_htcap);
1361 node->ni_flags = adf_os_ntohs(node->ni_flags);
1362 node->ni_maxampdu = adf_os_ntohs(node->ni_maxampdu);
1364 adf_os_mem_copy(&(sc->sc_sta[node_index].ni), node,
1367 vap_index = sc->sc_sta[node_index].ni.ni_vapindex;
1368 sc->sc_sta[node_index].ni.ni_vap = &(sc->sc_vap[vap_index].av_vap);
1370 sc->sc_sta[node_index].ni.ni_txseqmgmt = 0;
1371 sc->sc_sta[node_index].ni.ni_iv16 = 0;
1372 sc->sc_sta[node_index].ni.ni_iv32 = 0;
1374 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1377 static void ath_hal_reg_read_tgt(void *Context, A_UINT16 Command,
1378 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1380 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1381 struct ath_hal *ah = sc->sc_ah;
1386 for (i = 0; i < datalen; i += sizeof(a_int32_t)) {
1387 addr = *(a_uint32_t *)(data + i);
1388 addr = adf_os_ntohl(addr);
1390 if ((addr & 0xffffe000) == 0x2000) {
1392 ath_hal_reg_read_target(ah, addr);
1393 if (!ath_hal_wait(ah, 0x407c, 0x00030000, 0)) {
1394 adf_os_print("SEEPROM Read fail: 0x%08x\n", addr);
1396 val[i/sizeof(a_int32_t)] = (ath_hal_reg_read_target(ah, 0x407c) & 0x0000ffff);
1397 } else if (addr > 0xffff) {
1398 val[i/sizeof(a_int32_t)] = *(a_uint32_t *)addr;
1400 val[i/sizeof(a_int32_t)] = ath_hal_reg_read_target(ah, addr);
1402 val[i/sizeof(a_int32_t)] = adf_os_ntohl(val[i/sizeof(a_int32_t)]);
1405 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, &val[0], datalen);
1408 static void ath_hal_reg_write_tgt(void *Context, A_UINT16 Command,
1409 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1411 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1412 struct ath_hal *ah = sc->sc_ah;
1414 struct registerWrite {
1419 for (i = 0; i < datalen; i += sizeof(struct registerWrite)) {
1420 t = (struct registerWrite *)(data+i);
1422 if( t->reg > 0xffff ) {
1423 a_uint32_t *pReg = (a_uint32_t *)t->reg;
1427 #if defined(PROJECT_K2)
1428 if( t->reg == 0x50040 ) {
1429 static uint8_t flg=0;
1433 A_UART_HWINIT(117*1000*1000, 19200);
1439 #if defined(PROJECT_K2)
1440 if( t->reg == 0x7014 ) {
1441 static uint8_t resetPLL = 0;
1444 if( resetPLL == 0 ) {
1446 pReg = (a_uint32_t *)t->reg;
1448 ath_hal_reg_write_target(ah, 0x786c,
1449 ath_hal_reg_read_target(ah,0x786c) | 0x6000000);
1450 ath_hal_reg_write_target(ah, 0x786c,
1451 ath_hal_reg_read_target(ah,0x786c) & (~0x6000000));
1457 #elif defined(PROJECT_MAGPIE) && !defined (FPGA)
1458 if( t->reg == 0x7014 ){
1459 static uint8_t resetPLL = 0;
1461 if( resetPLL == 0 ) {
1462 ath_hal_reg_write_target(ah, 0x7890,
1463 ath_hal_reg_read_target(ah,0x7890) | 0x1800000);
1464 ath_hal_reg_write_target(ah, 0x7890,
1465 ath_hal_reg_read_target(ah,0x7890) & (~0x1800000));
1470 ath_hal_reg_write_target(ah,t->reg,t->val);
1474 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1477 static void ath_vap_delete_tgt(void *Context, A_UINT16 Command,
1478 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1480 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1481 a_uint8_t vap_index;
1483 vap_index = *(a_uint8_t *)data;
1485 sc->sc_vap[vap_index].av_valid = 0;
1486 sc->sc_vap[vap_index].av_bcbuf = NULL;
1487 ath_node_vdelete_tgt(sc, vap_index);
1488 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1491 static void ath_disable_intr_tgt(void *Context, A_UINT16 Command,
1492 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1494 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1495 struct ath_hal *ah = sc->sc_ah;
1497 ath_hal_intrset(ah, 0);
1498 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo,NULL, 0);
1501 static void ath_flushrecv_tgt(void *Context, A_UINT16 Command,
1502 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1504 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1507 asf_tailq_foreach(bf, &sc->sc_rxbuf, bf_list)
1508 if (bf->bf_skb != NULL) {
1509 adf_nbuf_unmap(sc->sc_dev, bf->bf_dmamap,
1510 ADF_OS_DMA_FROM_DEVICE);
1511 ath_free_rx_skb(sc, adf_nbuf_queue_remove(&bf->bf_skbhead));
1515 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1518 static void ath_tx_draintxq_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo,
1519 A_UINT8 *data, a_int32_t datalen)
1521 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1522 a_uint32_t q = *(a_uint32_t *)data;
1523 struct ath_txq *txq = NULL;
1525 q = adf_os_ntohl(q);
1526 txq = ATH_TXQ(sc, q);
1528 ath_tx_draintxq(sc, txq);
1529 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1532 static void ath_draintxq_tgt(void *Context, A_UINT16 Command,
1533 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1535 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1536 HAL_BOOL b = (HAL_BOOL) *(a_int32_t *)data;
1538 ath_draintxq(Context, b);
1539 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1542 static void ath_aborttx_dma_tgt(void *Context, A_UINT16 Command,
1543 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1545 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1547 ath_hal_aborttxdma(sc->sc_ah);
1548 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1551 static void ath_aborttxq_tgt(void *Context, A_UINT16 Command,
1552 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1555 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1558 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
1559 if (ATH_TXQ_SETUP(sc, i))
1560 ath_tx_draintxq(sc, ATH_TXQ(sc,i));
1563 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1566 static void ath_stop_tx_dma_tgt(void *Context, A_UINT16 Command,
1567 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1569 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1570 struct ath_hal *ah = sc->sc_ah;
1574 q = *(a_uint32_t *)data;
1576 q = adf_os_ntohl(q);
1577 ath_hal_stoptxdma(ah, q);
1578 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1581 static void ath_startrecv_tgt(void *Context, A_UINT16 Command,
1582 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1585 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1588 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1591 static void ath_stoprecv_tgt(void *Context, A_UINT16 Command,
1592 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1594 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1595 struct ath_hal *ah = sc->sc_ah;
1597 ath_hal_stoppcurecv(ah);
1598 ath_hal_setrxfilter(ah, 0);
1599 ath_hal_stopdmarecv(ah);
1601 sc->sc_rxlink = NULL;
1602 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1605 static void ath_setcurmode_tgt(void *Context, A_UINT16 Command,
1606 A_UINT16 SeqNo, A_UINT8 *data, a_int32_t datalen)
1608 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1610 struct ath_hal *ah = sc->sc_ah;
1612 mode= *((a_uint16_t *)data);
1613 mode = adf_os_ntohs(mode);
1615 ath_setcurmode(sc, mode);
1617 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1620 static a_uint32_t ath_detach_tgt(void *Context, A_UINT16 Command, A_UINT16 SeqNo,
1621 A_UINT8 *data, a_int32_t datalen)
1623 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1624 struct ath_hal *ah = sc->sc_ah;
1628 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1629 adf_os_mem_free(sc);
1632 static void handle_echo_command(void *pContext, A_UINT16 Command,
1633 A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1635 wmi_cmd_rsp(pContext, WMI_ECHO_CMDID, SeqNo, buffer, Length);
1638 static void handle_rc_state_change_cmd(void *Context, A_UINT16 Command,
1639 A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1642 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1643 struct wmi_rc_state_change_cmd *wmi_data = (struct wmi_rc_state_change_cmd *)buffer;
1645 a_uint32_t capflag = adf_os_ntohl(wmi_data->capflag);
1647 ath_rate_newstate(sc, &sc->sc_vap[wmi_data->vap_index].av_vap,
1648 wmi_data->vap_state,
1652 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1655 static void handle_rc_rate_update_cmd(void *Context, A_UINT16 Command,
1656 A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1658 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1659 struct wmi_rc_rate_update_cmd *wmi_data = (struct wmi_rc_rate_update_cmd *)buffer;
1661 a_uint32_t capflag = adf_os_ntohl(wmi_data->capflag);
1663 ath_rate_node_update(sc, &sc->sc_sta[wmi_data->node_index],
1668 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1671 static void dispatch_magpie_sys_cmds(void *pContext, A_UINT16 Command,
1672 A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1677 static void ath_rc_mask_tgt(void *Context, A_UINT16 Command,
1678 A_UINT16 SeqNo, A_UINT8 *buffer, a_int32_t Length)
1680 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)Context;
1681 struct wmi_rc_rate_mask_cmd *wmi_data = (struct wmi_rc_rate_mask_cmd *)buffer;
1684 idx = wmi_data->vap_index;
1685 band = wmi_data->band;
1687 sc->sc_vap[idx].av_rate_mask[band] = adf_os_ntohl(wmi_data->mask);
1689 if (sc->sc_vap[idx].av_rate_mask[band]) {
1690 for (i = 0; i < RATE_TABLE_SIZE; i++) {
1691 if ((1 << i) & sc->sc_vap[idx].av_rate_mask[band]) {
1692 sc->sc_vap[idx].av_minrateidx[band] = i;
1697 sc->sc_vap[idx].av_minrateidx[band] = 0;
1700 wmi_cmd_rsp(sc->tgt_wmi_handle, Command, SeqNo, NULL, 0);
1703 static WMI_DISPATCH_ENTRY Magpie_Sys_DispatchEntries[] =
1705 {handle_echo_command, WMI_ECHO_CMDID, 0},
1706 {dispatch_magpie_sys_cmds, WMI_ACCESS_MEMORY_CMDID, 0},
1707 {ath_get_tgt_version, WMI_GET_FW_VERSION, 0},
1708 {ath_disable_intr_tgt, WMI_DISABLE_INTR_CMDID, 0},
1709 {ath_enable_intr_tgt, WMI_ENABLE_INTR_CMDID, 0},
1710 {ath_init_tgt, WMI_ATH_INIT_CMDID, 0},
1711 {ath_aborttxq_tgt, WMI_ABORT_TXQ_CMDID, 0},
1712 {ath_stop_tx_dma_tgt, WMI_STOP_TX_DMA_CMDID, 0},
1713 {ath_aborttx_dma_tgt, WMI_ABORT_TX_DMA_CMDID, 0},
1714 {ath_tx_draintxq_tgt, WMI_DRAIN_TXQ_CMDID, 0},
1715 {ath_draintxq_tgt, WMI_DRAIN_TXQ_ALL_CMDID, 0},
1716 {ath_startrecv_tgt, WMI_START_RECV_CMDID, 0},
1717 {ath_stoprecv_tgt, WMI_STOP_RECV_CMDID, 0},
1718 {ath_flushrecv_tgt, WMI_FLUSH_RECV_CMDID, 0},
1719 {ath_setcurmode_tgt, WMI_SET_MODE_CMDID, 0},
1720 {ath_node_create_tgt, WMI_NODE_CREATE_CMDID, 0},
1721 {ath_node_cleanup_tgt, WMI_NODE_REMOVE_CMDID, 0},
1722 {ath_vap_delete_tgt, WMI_VAP_REMOVE_CMDID, 0},
1723 {ath_vap_create_tgt, WMI_VAP_CREATE_CMDID, 0},
1724 {ath_hal_reg_read_tgt, WMI_REG_READ_CMDID, 0},
1725 {ath_hal_reg_write_tgt, WMI_REG_WRITE_CMDID, 0},
1726 {handle_rc_state_change_cmd, WMI_RC_STATE_CHANGE_CMDID, 0},
1727 {handle_rc_rate_update_cmd, WMI_RC_RATE_UPDATE_CMDID, 0},
1728 {ath_ic_update_tgt, WMI_TARGET_IC_UPDATE_CMDID, 0},
1729 {ath_enable_aggr_tgt, WMI_TX_AGGR_ENABLE_CMDID, 0},
1730 {ath_detach_tgt, WMI_TGT_DETACH_CMDID, 0},
1731 {ath_node_update_tgt, WMI_NODE_UPDATE_CMDID, 0},
1732 {ath_int_stats_tgt, WMI_INT_STATS_CMDID, 0},
1733 {ath_tx_stats_tgt, WMI_TX_STATS_CMDID, 0},
1734 {ath_rx_stats_tgt, WMI_RX_STATS_CMDID, 0},
1735 {ath_rc_mask_tgt, WMI_BITRATE_MASK_CMDID, 0},
1742 static void htc_setup_comp(void)
1746 static A_UINT8 tgt_ServiceConnect(HTC_SERVICE *pService,
1747 HTC_ENDPOINT_ID eid,
1751 a_int32_t *pLengthOut)
1753 struct ath_softc_tgt *sc = (struct ath_softc_tgt *)pService->ServiceCtx;
1755 switch(pService->ServiceID) {
1756 case WMI_CONTROL_SVC:
1757 sc->wmi_command_ep= eid;
1759 case WMI_BEACON_SVC:
1771 case WMI_DATA_VO_SVC:
1772 sc->data_VO_ep = eid;
1774 case WMI_DATA_VI_SVC:
1775 sc->data_VI_ep = eid;
1777 case WMI_DATA_BE_SVC:
1778 sc->data_BE_ep = eid;
1780 case WMI_DATA_BK_SVC:
1781 sc->data_BK_ep = eid;
1787 return HTC_SERVICE_SUCCESS;
1790 static void tgt_reg_service(struct ath_softc_tgt *sc, HTC_SERVICE *svc,
1791 int svcId, HTC_SERVICE_ProcessRecvMsg recvMsg)
1793 svc->ProcessRecvMsg = recvMsg;
1794 svc->ProcessSendBufferComplete = tgt_HTCSendCompleteHandler;
1795 svc->ProcessConnect = tgt_ServiceConnect;
1796 svc->MaxSvcMsgSize = 1600;
1797 svc->TrailerSpcCheckLimit = 0;
1798 svc->ServiceID = svcId;
1799 svc->ServiceCtx = sc;
1800 HTC_RegisterService(sc->tgt_htc_handle, svc);
1803 static void tgt_hif_htc_wmi_init(struct ath_softc_tgt *sc)
1805 HTC_CONFIG htc_conf;
1806 WMI_SVC_CONFIG wmiConfig;
1807 WMI_DISPATCH_TABLE *Magpie_Sys_Commands_Tbl;
1809 /* Init dynamic buf pool */
1810 sc->pool_handle = BUF_Pool_init(sc->sc_hdl);
1812 /* Init target-side HIF */
1813 sc->tgt_hif_handle = HIF_init(0);
1815 /* Init target-side HTC */
1816 htc_conf.HIFHandle = sc->tgt_hif_handle;
1817 htc_conf.CreditSize = 320;
1818 htc_conf.CreditNumber = ATH_TXBUF;
1819 htc_conf.OSHandle = sc->sc_hdl;
1820 htc_conf.PoolHandle = sc->pool_handle;
1821 sc->tgt_htc_handle = HTC_init(htc_setup_comp, &htc_conf);
1822 #if defined(PROJECT_MAGPIE)
1823 init_htc_handle = sc->tgt_htc_handle;
1826 tgt_reg_service(sc, &sc->htc_beacon_service, WMI_BEACON_SVC, tgt_HTCRecv_beaconhandler);
1827 tgt_reg_service(sc, &sc->htc_cab_service, WMI_CAB_SVC, tgt_HTCRecv_cabhandler);
1828 tgt_reg_service(sc, &sc->htc_uapsd_service, WMI_UAPSD_SVC, tgt_HTCRecv_uapsdhandler);
1829 tgt_reg_service(sc, &sc->htc_mgmt_service, WMI_MGMT_SVC, tgt_HTCRecv_mgmthandler);
1830 tgt_reg_service(sc, &sc->htc_data_BE_service, WMI_DATA_BE_SVC, tgt_HTCRecvMessageHandler);
1831 tgt_reg_service(sc, &sc->htc_data_BK_service, WMI_DATA_BK_SVC, tgt_HTCRecvMessageHandler);
1832 tgt_reg_service(sc, &sc->htc_data_VI_service, WMI_DATA_VI_SVC, tgt_HTCRecvMessageHandler);
1833 tgt_reg_service(sc, &sc->htc_data_VO_service, WMI_DATA_VO_SVC, tgt_HTCRecvMessageHandler);
1835 /* Init target-side WMI */
1836 Magpie_Sys_Commands_Tbl = (WMI_DISPATCH_TABLE *)adf_os_mem_alloc(sizeof(WMI_DISPATCH_TABLE));
1837 adf_os_mem_zero(Magpie_Sys_Commands_Tbl, sizeof(WMI_DISPATCH_TABLE));
1838 Magpie_Sys_Commands_Tbl->NumberOfEntries = WMI_DISPATCH_ENTRY_COUNT(Magpie_Sys_DispatchEntries);
1839 Magpie_Sys_Commands_Tbl->pTable = Magpie_Sys_DispatchEntries;
1841 adf_os_mem_zero(&wmiConfig, sizeof(WMI_SVC_CONFIG));
1842 wmiConfig.HtcHandle = sc->tgt_htc_handle;
1843 wmiConfig.PoolHandle = sc->pool_handle;
1844 wmiConfig.MaxCmdReplyEvts = ATH_WMI_MAX_CMD_REPLY;
1845 wmiConfig.MaxEventEvts = ATH_WMI_MAX_EVENTS;
1847 sc->tgt_wmi_handle = WMI_Init(&wmiConfig);
1848 Magpie_Sys_Commands_Tbl->pContext = sc;
1849 WMI_RegisterDispatchTable(sc->tgt_wmi_handle, Magpie_Sys_Commands_Tbl);
1851 HTC_NotifyTargetInserted(sc->tgt_htc_handle);
1853 /* Start HTC messages exchange */
1854 HTC_Ready(sc->tgt_htc_handle);
1857 a_int32_t ath_tgt_attach(a_uint32_t devid,a_uint32_t mem_start,
1858 struct ath_softc_tgt *sc, adf_os_device_t osdev)
1862 a_int32_t error = 0, i, flags = 0;
1865 adf_os_pci_config_read8(osdev, ATH_PCI_CACHE_LINE_SIZE, &csz);
1869 sc->sc_cachelsz = csz << 2;
1874 ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_rxtq, ath_tgt_rx_tasklet, sc);
1875 ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_txtq, owl_tgt_tx_tasklet, sc);
1876 ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_bmisstq, ath_bmiss_tasklet, sc);
1877 ATH_INIT_TQUEUE(sc->sc_dev, &sc->sc_fataltq, ath_fatal_tasklet, sc);
1879 flags |= AH_USE_EEPROM;
1880 ah = _ath_hal_attach_tgt(devid,sc,sc->sc_dev,mem_start, flags, &status);
1887 tgt_hif_htc_wmi_init(sc);
1889 sc->sc_bhalq = HAL_NUM_TX_QUEUES - 1;
1891 ath_rate_setup(sc, IEEE80211_MODE_11NA);
1892 ath_rate_setup(sc, IEEE80211_MODE_11NG);
1894 sc->sc_rc = ath_rate_attach(sc);
1895 if (sc->sc_rc == NULL) {
1900 for (i=0; i < TARGET_NODE_MAX; i++) {
1901 sc->sc_sta[i].an_rcnode = adf_os_mem_alloc(sc->sc_rc->arc_space);
1904 error = ath_desc_alloc(sc);
1909 BUF_Pool_create_pool(sc->pool_handle, POOL_ID_WLAN_RX_BUF, ath_numrxdescs, 1664);
1911 ath_tgt_txq_setup(sc);
1913 ath_hal_intrset(ah,0);
1923 static void tgt_hif_htc_wmi_shutdown(struct ath_softc_tgt *sc)
1925 HTC_NotifyTargetDetached(sc->tgt_htc_handle);
1927 WMI_Shutdown(sc->tgt_wmi_handle);
1928 HTC_Shutdown(sc->tgt_htc_handle);
1929 HIF_shutdown(sc->tgt_hif_handle);
1930 BUF_Pool_shutdown(sc->pool_handle);
1933 a_int32_t ath_detach(struct ath_softc_tgt *sc)
1935 tgt_hif_htc_wmi_shutdown(sc);