diff options
author | sam <sam@FreeBSD.org> | 2009-06-29 18:42:54 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2009-06-29 18:42:54 +0000 |
commit | 49f1934625b5e0ef669dd50385840fa4a71a85f3 (patch) | |
tree | 1b2eadb8b21a84c4711cffb083bbed9554b26d05 /sys/dev/mwl | |
parent | a0406a12532b60a577e09907c61942649ac1c59f (diff) | |
download | FreeBSD-src-49f1934625b5e0ef669dd50385840fa4a71a85f3.zip FreeBSD-src-49f1934625b5e0ef669dd50385840fa4a71a85f3.tar.gz |
Update to 3.6.2.2 firmware (latest w/o host-based power save support):
o new tx ack queue (not used right now)
o proxy-sta related changes (no proxy sta in driver)
o explicit dwds ena/dis (needed only with proxy sta)
o cleanup BA policy handling
o new ampdu aggressive mode support
o CFEnd use now controllable
Approved by: re (kensmith)
Diffstat (limited to 'sys/dev/mwl')
-rw-r--r-- | sys/dev/mwl/if_mwl.c | 214 | ||||
-rw-r--r-- | sys/dev/mwl/if_mwlvar.h | 4 | ||||
-rw-r--r-- | sys/dev/mwl/mwlhal.c | 121 | ||||
-rw-r--r-- | sys/dev/mwl/mwlhal.h | 40 | ||||
-rw-r--r-- | sys/dev/mwl/mwlreg.h | 43 |
5 files changed, 292 insertions, 130 deletions
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index bc366db..ca3c96c 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -876,6 +876,7 @@ mwl_radar_proc(void *arg, int pending) __func__, pending); sc->sc_stats.mst_radardetect++; + /* XXX stop h/w BA streams? */ IEEE80211_LOCK(ic); ieee80211_dfs_notify_radar(ic, ic->ic_curchan); @@ -991,13 +992,13 @@ mwl_setupdma(struct mwl_softc *sc) WR4(sc, sc->sc_hwspecs.rxDescRead, sc->sc_hwdma.rxDescRead); WR4(sc, sc->sc_hwspecs.rxDescWrite, sc->sc_hwdma.rxDescRead); - for (i = 0; i < MWL_NUM_TX_QUEUES; i++) { + for (i = 0; i < MWL_NUM_TX_QUEUES-MWL_NUM_ACK_QUEUES; i++) { struct mwl_txq *txq = &sc->sc_txq[i]; sc->sc_hwdma.wcbBase[i] = txq->dma.dd_desc_paddr; WR4(sc, sc->sc_hwspecs.wcbBase[i], sc->sc_hwdma.wcbBase[i]); } sc->sc_hwdma.maxNumTxWcb = mwl_txbuf; - sc->sc_hwdma.maxNumWCB = MWL_NUM_TX_QUEUES; + sc->sc_hwdma.maxNumWCB = MWL_NUM_TX_QUEUES-MWL_NUM_ACK_QUEUES; error = mwl_hal_sethwdma(sc->sc_mh, &sc->sc_hwdma); if (error != 0) { @@ -1057,7 +1058,9 @@ mwl_setrates(struct ieee80211vap *vap) /* while here calculate EAPOL fixed rate cookie */ mvp->mv_eapolformat = htole16(mwl_calcformat(rates.MgtRate, ni)); - return mwl_hal_settxrate(mvp->mv_hvap, RATE_AUTO, &rates); + return mwl_hal_settxrate(mvp->mv_hvap, + tp->ucastrate != IEEE80211_FIXED_RATE_NONE ? + RATE_FIXED : RATE_AUTO, &rates); } /* @@ -1136,12 +1139,16 @@ mwl_hal_reset(struct mwl_softc *sc) mwl_hal_setradio(mh, 1, WL_AUTO_PREAMBLE); mwl_hal_setwmm(sc->sc_mh, (ic->ic_flags & IEEE80211_F_WME) != 0); mwl_chan_set(sc, ic->ic_curchan); - mwl_hal_setrateadaptmode(mh, ic->ic_regdomain.location == 'O'); + /* NB: RF/RA performance tuned for indoor mode */ + mwl_hal_setrateadaptmode(mh, 0); mwl_hal_setoptimizationlevel(mh, (ic->ic_flags & IEEE80211_F_BURST) != 0); mwl_hal_setregioncode(mh, mwl_map2regioncode(&ic->ic_regdomain)); + mwl_hal_setaggampduratemode(mh, 1, 80); /* XXX */ + mwl_hal_setcfend(mh, 0); /* XXX */ + return 1; } @@ -1196,6 +1203,7 @@ mwl_init_locked(struct mwl_softc *sc) | MACREG_A2HRIC_BIT_QUEUE_EMPTY #endif | MACREG_A2HRIC_BIT_BA_WATCHDOG + | MACREQ_A2HRIC_BIT_TX_ACK ; ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -1297,6 +1305,7 @@ mwl_reset(struct ieee80211vap *vap, u_long cmd) struct mwl_softc *sc = ifp->if_softc; struct mwl_hal *mh = sc->sc_mh; + /* XXX handle DWDS sta vap change */ /* XXX do we need to disable interrupts? */ mwl_hal_intrset(mh, 0); /* disable interrupts */ error = mwl_reset_vap(vap, vap->iv_state); @@ -2884,11 +2893,7 @@ mwl_rx_proc(void *arg, int npending) mn->mn_ai.rsvd1 = rssi; #endif /* tag AMPDU aggregates for reorder processing */ -#if 0 - if ((ds->Rate & 0x80) && (ds->HtSig2 & 0x8)) -#else if (ni->ni_flags & IEEE80211_NODE_HT) -#endif m->m_flags |= M_AMPDU; (void) ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); @@ -3126,7 +3131,7 @@ mwl_calcformat(uint8_t rate, const struct ieee80211_node *ni) fmt = SM(3, EAGLE_TXD_ANTENNA) | (IEEE80211_IS_CHAN_HT40D(ni->ni_chan) ? EAGLE_TXD_EXTCHAN_LO : EAGLE_TXD_EXTCHAN_HI); - if (rate & 0x80) { /* HT MCS */ + if (rate & IEEE80211_RATE_MCS) { /* HT MCS */ fmt |= EAGLE_TXD_FORMAT_HT /* NB: 0x80 implicitly stripped from ucastrate */ | SM(rate, EAGLE_TXD_RATE); @@ -3317,6 +3322,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * /* NB: pPhysNext, DataRate, and SapPktInfo setup once, don't touch */ ds->Format = 0; ds->pad = 0; + ds->ack_wcb_addr = 0; mn = MWL_NODE(ni); /* @@ -3343,8 +3349,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * ds->Format = mvp->mv_eapolformat; ds->pad = htole16( EAGLE_TXD_FIXED_RATE | EAGLE_TXD_DONT_AGGR); - } else if (tp != NULL && /* XXX temp dwds WAR */ - tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { /* XXX pre-calculate per node */ ds->Format = htole16( mwl_calcformat(tp->ucastrate, ni)); @@ -3675,6 +3680,7 @@ mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout) { struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ieee80211vap *vap = ni->ni_vap; struct mwl_node *mn = MWL_NODE(ni); struct mwl_bastate *bas; @@ -3713,9 +3719,10 @@ mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, return 0; } /* NB: no held reference to ni */ - sp = mwl_hal_bastream_alloc(sc->sc_mh, - 1/* XXX immediate*/, ni->ni_macaddr, tap->txa_ac, - ni->ni_htparam, ni, tap); + sp = mwl_hal_bastream_alloc(MWL_VAP(vap)->mv_hvap, + (baparamset & IEEE80211_BAPS_POLICY_IMMEDIATE) != 0, + ni->ni_macaddr, WME_AC_TO_TID(tap->txa_ac), ni->ni_htparam, + ni, tap); if (sp == NULL) { /* * No available stream, return 0 so no @@ -3734,6 +3741,7 @@ mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, } /* fetch current seq# from the firmware; if available */ if (mwl_hal_bastream_get_seqno(sc->sc_mh, bas->bastream, + vap->iv_opmode == IEEE80211_M_STA ? vap->iv_myaddr : ni->ni_macaddr, &tap->txa_start) != 0) tap->txa_start = 0; return sc->sc_addba_request(ni, tap, dialogtoken, baparamset, batimeout); @@ -3756,6 +3764,7 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, return 0; } if (code == IEEE80211_STATUS_SUCCESS) { + struct ieee80211vap *vap = ni->ni_vap; int bufsiz, error; /* @@ -3766,8 +3775,8 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ); if (bufsiz == 0) bufsiz = IEEE80211_AGGR_BAWMAX; - error = mwl_hal_bastream_create(sc->sc_mh, bas->bastream, - bufsiz, bufsiz-1, tap->txa_start); + error = mwl_hal_bastream_create(MWL_VAP(vap)->mv_hvap, + bas->bastream, bufsiz, bufsiz, tap->txa_start); if (error != 0) { /* * Setup failed, return immediately so no a-mpdu @@ -4065,6 +4074,86 @@ mwl_setglobalkeys(struct ieee80211vap *vap) } /* + * Convert a legacy rate set to a firmware bitmask. + */ +static uint32_t +get_rate_bitmap(const struct ieee80211_rateset *rs) +{ + uint32_t rates; + int i; + + rates = 0; + for (i = 0; i < rs->rs_nrates; i++) + switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) { + case 2: rates |= 0x001; break; + case 4: rates |= 0x002; break; + case 11: rates |= 0x004; break; + case 22: rates |= 0x008; break; + case 44: rates |= 0x010; break; + case 12: rates |= 0x020; break; + case 18: rates |= 0x040; break; + case 24: rates |= 0x080; break; + case 36: rates |= 0x100; break; + case 48: rates |= 0x200; break; + case 72: rates |= 0x400; break; + case 96: rates |= 0x800; break; + case 108: rates |= 0x1000; break; + } + return rates; +} + +/* + * Construct an HT firmware bitmask from an HT rate set. + */ +static uint32_t +get_htrate_bitmap(const struct ieee80211_htrateset *rs) +{ + uint32_t rates; + int i; + + rates = 0; + for (i = 0; i < rs->rs_nrates; i++) { + if (rs->rs_rates[i] < 16) + rates |= 1<<rs->rs_rates[i]; + } + return rates; +} + +/* + * Craft station database entry for station. + * NB: use host byte order here, the hal handles byte swapping. + */ +static MWL_HAL_PEERINFO * +mkpeerinfo(MWL_HAL_PEERINFO *pi, const struct ieee80211_node *ni) +{ + const struct ieee80211vap *vap = ni->ni_vap; + + memset(pi, 0, sizeof(*pi)); + pi->LegacyRateBitMap = get_rate_bitmap(&ni->ni_rates); + pi->CapInfo = ni->ni_capinfo; + if (ni->ni_flags & IEEE80211_NODE_HT) { + /* HT capabilities, etc */ + pi->HTCapabilitiesInfo = ni->ni_htcap; + /* XXX pi.HTCapabilitiesInfo */ + pi->MacHTParamInfo = ni->ni_htparam; + pi->HTRateBitMap = get_htrate_bitmap(&ni->ni_htrates); + pi->AddHtInfo.ControlChan = ni->ni_htctlchan; + pi->AddHtInfo.AddChan = ni->ni_ht2ndchan; + pi->AddHtInfo.OpMode = ni->ni_htopmode; + pi->AddHtInfo.stbc = ni->ni_htstbc; + + /* constrain according to local configuration */ + if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0) + pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI40; + if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) + pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI20; + if (ni->ni_chw != 40) + pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_CHWIDTH40; + } + return pi; +} + +/* * Re-create the local sta db entry for a vap to ensure * up to date WME state is pushed to the firmware. Because * this resets crypto state this must be followed by a @@ -4076,13 +4165,16 @@ mwl_localstadb(struct ieee80211vap *vap) #define WME(ie) ((const struct ieee80211_wme_info *) ie) struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; struct ieee80211_node *bss; + MWL_HAL_PEERINFO pi; int error; switch (vap->iv_opmode) { case IEEE80211_M_STA: bss = vap->iv_bss; - error = mwl_hal_newstation(hvap, vap->iv_myaddr, - 0, 0, NULL, bss->ni_flags & IEEE80211_NODE_QOS, + error = mwl_hal_newstation(hvap, vap->iv_myaddr, 0, 0, + vap->iv_state == IEEE80211_S_RUN ? + mkpeerinfo(&pi, bss) : NULL, + (bss->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT)), bss->ni_ies.wme_ie != NULL ? WME(bss->ni_ies.wme_ie)->wme_info : 0); if (error == 0) @@ -4182,7 +4274,7 @@ mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ieee80211_chan2ieee(ic, ic->ic_curchan)); /* - * Recreate local sta db entry to update WME state. + * Recreate local sta db entry to update WME/HT state. */ mwl_localstadb(vap); switch (vap->iv_opmode) { @@ -4216,6 +4308,9 @@ mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) mwl_hal_setassocid(hvap, ni->ni_bssid, ni->ni_associd); mwl_setrates(vap); mwl_hal_setrtsthreshold(hvap, vap->iv_rtsthreshold); + if ((vap->iv_flags & IEEE80211_F_DWDS) && + sc->sc_ndwdsvaps++ == 0) + mwl_hal_setdwds(mh, 1); break; case IEEE80211_M_WDS: DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: bssid %s\n", @@ -4244,58 +4339,14 @@ mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) mwl_agestations, sc); } else if (nstate == IEEE80211_S_SLEEP) { /* XXX set chip in power save */ - } + } else if ((vap->iv_flags & IEEE80211_F_DWDS) && + --sc->sc_ndwdsvaps == 0) + mwl_hal_setdwds(mh, 0); bad: return error; } /* - * Convert a legacy rate set to a firmware bitmask. - */ -static uint32_t -get_rate_bitmap(const struct ieee80211_rateset *rs) -{ - uint32_t rates; - int i; - - rates = 0; - for (i = 0; i < rs->rs_nrates; i++) - switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) { - case 2: rates |= 0x001; break; - case 4: rates |= 0x002; break; - case 11: rates |= 0x004; break; - case 22: rates |= 0x008; break; - case 44: rates |= 0x010; break; - case 12: rates |= 0x020; break; - case 18: rates |= 0x040; break; - case 24: rates |= 0x080; break; - case 36: rates |= 0x100; break; - case 48: rates |= 0x200; break; - case 72: rates |= 0x400; break; - case 96: rates |= 0x800; break; - case 108: rates |= 0x1000; break; - } - return rates; -} - -/* - * Construct an HT firmware bitmask from an HT rate set. - */ -static uint32_t -get_htrate_bitmap(const struct ieee80211_htrateset *rs) -{ - uint32_t rates; - int i; - - rates = 0; - for (i = 0; i < rs->rs_nrates; i++) { - if (rs->rs_rates[i] < 16) - rates |= 1<<rs->rs_rates[i]; - } - return rates; -} - -/* * Manage station id's; these are separate from AID's * as AID's may have values out of the range of possible * station id's acceptable to the firmware. @@ -4347,33 +4398,7 @@ mwl_newassoc(struct ieee80211_node *ni, int isnew) } DPRINTF(sc, MWL_DEBUG_NODE, "%s: mac %s isnew %d aid %d staid %d\n", __func__, ether_sprintf(ni->ni_macaddr), isnew, aid, mn->mn_staid); - /* - * Craft station database entry for station. - * NB: use host byte order here, the hal handles byte swapping. - */ - memset(&pi, 0, sizeof(pi)); - pi.LegacyRateBitMap = get_rate_bitmap(&ni->ni_rates); - pi.CapInfo = ni->ni_capinfo; - if (ni->ni_flags & IEEE80211_NODE_HT) { - /* HT capabilities, etc */ - pi.HTCapabilitiesInfo = ni->ni_htcap; - /* XXX pi.HTCapabilitiesInfo */ - pi.MacHTParamInfo = ni->ni_htparam; - pi.HTRateBitMap = get_htrate_bitmap(&ni->ni_htrates); - pi.AddHtInfo.ControlChan = ni->ni_htctlchan; - pi.AddHtInfo.AddChan = ni->ni_ht2ndchan; - pi.AddHtInfo.OpMode = ni->ni_htopmode; - pi.AddHtInfo.stbc = ni->ni_htstbc; - - /* constrain according to local configuration */ - if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0) - pi.HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI40; - if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) - pi.HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI20; - if (ni->ni_chw != 40) - pi.HTCapabilitiesInfo &= ~IEEE80211_HTCAP_CHWIDTH40; - } - error = mwl_peerstadb(ni, aid, mn->mn_staid, &pi); + error = mwl_peerstadb(ni, aid, mn->mn_staid, mkpeerinfo(&pi, ni)); if (error != 0) { DPRINTF(sc, MWL_DEBUG_NODE, "%s: error %d creating sta db entry\n", @@ -4393,8 +4418,7 @@ mwl_agestations(void *arg) mwl_hal_setkeepalive(sc->sc_mh); if (sc->sc_ageinterval != 0) /* NB: catch dynamic changes */ - callout_reset(&sc->sc_timer, sc->sc_ageinterval*hz, - mwl_agestations, sc); + callout_schedule(&sc->sc_timer, sc->sc_ageinterval*hz); } static const struct mwl_hal_channel * diff --git a/sys/dev/mwl/if_mwlvar.h b/sys/dev/mwl/if_mwlvar.h index 6730ef6..182321a 100644 --- a/sys/dev/mwl/if_mwlvar.h +++ b/sys/dev/mwl/if_mwlvar.h @@ -45,6 +45,9 @@ #ifndef MWL_TXBUF #define MWL_TXBUF 256 /* number of TX descriptors/buffers */ #endif +#ifndef MWL_TXACKBUF +#define MWL_TXACKBUF (MWL_TXBUF/2) /* number of TX ACK desc's/buffers */ +#endif #ifndef MWL_RXDESC #define MWL_RXDESC 256 /* number of RX descriptors */ #endif @@ -274,6 +277,7 @@ struct mwl_softc { uint8_t sc_napvaps; /* # ap mode vaps */ uint8_t sc_nwdsvaps; /* # wds mode vaps */ uint8_t sc_nstavaps; /* # sta mode vaps */ + uint8_t sc_ndwdsvaps; /* # sta mode dwds vaps */ uint8_t sc_nbssid0; /* # vap's using base mac */ uint32_t sc_bssidmask; /* bssid mask */ diff --git a/sys/dev/mwl/mwlhal.c b/sys/dev/mwl/mwlhal.c index 0ffa0b1..3f953ac 100644 --- a/sys/dev/mwl/mwlhal.c +++ b/sys/dev/mwl/mwlhal.c @@ -115,7 +115,7 @@ struct mwl_hal_bastream { MWL_HAL_BASTREAM public; /* public state */ uint8_t stream; /* stream # */ uint8_t setup; /* f/w cmd sent */ - uint8_t ba_type; + uint8_t ba_policy; /* direct/delayed BA policy */ uint8_t tid; uint8_t paraminfo; uint8_t macaddr[IEEE80211_ADDR_LEN]; @@ -578,9 +578,9 @@ mwl_hal_gethwspecs(struct mwl_hal *mh0, struct mwl_hal_hwspec *hw) if (retval == 0) { IEEE80211_ADDR_COPY(hw->macAddr, pCmd->PermanentAddr); hw->wcbBase[0] = le32toh(pCmd->WcbBase0) & 0x0000ffff; - hw->wcbBase[1] = le32toh(pCmd->WcbBase1) & 0x0000ffff; - hw->wcbBase[2] = le32toh(pCmd->WcbBase2) & 0x0000ffff; - hw->wcbBase[3] = le32toh(pCmd->WcbBase3) & 0x0000ffff; + hw->wcbBase[1] = le32toh(pCmd->WcbBase1[0]) & 0x0000ffff; + hw->wcbBase[2] = le32toh(pCmd->WcbBase1[1]) & 0x0000ffff; + hw->wcbBase[3] = le32toh(pCmd->WcbBase1[2]) & 0x0000ffff; hw->rxDescRead = le32toh(pCmd->RxPdRdPtr)& 0x0000ffff; hw->rxDescWrite = le32toh(pCmd->RxPdWrPtr)& 0x0000ffff; hw->regionCode = le16toh(pCmd->RegionCode) & 0x00ff; @@ -1375,16 +1375,17 @@ mwl_hal_setchannel(struct mwl_hal *mh0, const MWL_HAL_CHANNEL *chan) } static int -bastream_check_available(struct mwl_hal_priv *mh, int qid, +bastream_check_available(struct mwl_hal_vap *vap, int qid, const uint8_t Macaddr[IEEE80211_ADDR_LEN], uint8_t Tid, uint8_t ParamInfo) { + struct mwl_hal_priv *mh = MWLVAP(vap); HostCmd_FW_BASTREAM *pCmd; int retval; MWL_HAL_LOCK_ASSERT(mh); - _CMD_SETUP(pCmd, HostCmd_FW_BASTREAM, HostCmd_CMD_BASTREAM); + _VCMD_SETUP(vap, pCmd, HostCmd_FW_BASTREAM, HostCmd_CMD_BASTREAM); pCmd->ActionType = htole32(BaCheckCreateStream); pCmd->BaInfo.CreateParams.BarThrs = htole32(63); pCmd->BaInfo.CreateParams.WindowSize = htole32(64); @@ -1395,7 +1396,7 @@ bastream_check_available(struct mwl_hal_priv *mh, int qid, pCmd->BaInfo.CreateParams.QueueId = qid; pCmd->BaInfo.CreateParams.ParamInfo = (uint8_t) ParamInfo; #if 0 - cvtBAFlags(&pCmd->BaInfo.CreateParams.Flags, sp->ba_type, 0); + cvtBAFlags(&pCmd->BaInfo.CreateParams.Flags, sp->ba_policy, 0); #else pCmd->BaInfo.CreateParams.Flags = htole32(BASTREAM_FLAG_IMMEDIATE_TYPE) @@ -1417,11 +1418,11 @@ bastream_check_available(struct mwl_hal_priv *mh, int qid, } const MWL_HAL_BASTREAM * -mwl_hal_bastream_alloc(struct mwl_hal *mh0, int ba_type, +mwl_hal_bastream_alloc(struct mwl_hal_vap *vap, int ba_policy, const uint8_t Macaddr[IEEE80211_ADDR_LEN], uint8_t Tid, uint8_t ParamInfo, void *a1, void *a2) { - struct mwl_hal_priv *mh = MWLPRIV(mh0); + struct mwl_hal_priv *mh = MWLVAP(vap); struct mwl_hal_bastream *sp; int s; @@ -1433,7 +1434,7 @@ mwl_hal_bastream_alloc(struct mwl_hal *mh0, int ba_type, } for (s = 0; (mh->mh_bastreams & (1<<s)) == 0; s++) ; - if (bastream_check_available(mh, s, Macaddr, Tid, ParamInfo)) { + if (bastream_check_available(vap, s, Macaddr, Tid, ParamInfo)) { MWL_HAL_UNLOCK(mh); return NULL; } @@ -1445,7 +1446,7 @@ mwl_hal_bastream_alloc(struct mwl_hal *mh0, int ba_type, sp->tid = Tid; sp->paraminfo = ParamInfo; sp->setup = 0; - sp->ba_type = ba_type; + sp->ba_policy = ba_policy; MWL_HAL_UNLOCK(mh); return sp != NULL ? &sp->public : NULL; } @@ -1467,22 +1468,24 @@ mwl_hal_bastream_lookup(struct mwl_hal *mh0, int s) #endif int -mwl_hal_bastream_create(struct mwl_hal *mh0, +mwl_hal_bastream_create(struct mwl_hal_vap *vap, const MWL_HAL_BASTREAM *s, int BarThrs, int WindowSize, uint16_t seqno) { - struct mwl_hal_priv *mh = MWLPRIV(mh0); + struct mwl_hal_priv *mh = MWLVAP(vap); struct mwl_hal_bastream *sp = __DECONST(struct mwl_hal_bastream *, s); HostCmd_FW_BASTREAM *pCmd; int retval; MWL_HAL_LOCK(mh); - _CMD_SETUP(pCmd, HostCmd_FW_BASTREAM, HostCmd_CMD_BASTREAM); + _VCMD_SETUP(vap, pCmd, HostCmd_FW_BASTREAM, HostCmd_CMD_BASTREAM); pCmd->ActionType = htole32(BaCreateStream); - pCmd->BaInfo.CreateParams.BarThrs = htole32(63);//BarThrs; - pCmd->BaInfo.CreateParams.WindowSize = htole32(64); /*WindowSize;*/ + pCmd->BaInfo.CreateParams.BarThrs = htole32(BarThrs); + pCmd->BaInfo.CreateParams.WindowSize = htole32(WindowSize); pCmd->BaInfo.CreateParams.IdleThrs = htole32(0x22000); IEEE80211_ADDR_COPY(&pCmd->BaInfo.CreateParams.PeerMacAddr[0], sp->macaddr); + /* XXX proxy STA */ + memset(&pCmd->BaInfo.CreateParams.StaSrcMacAddr, 0, IEEE80211_ADDR_LEN); #if 0 pCmd->BaInfo.CreateParams.DialogToken = DialogToken; #else @@ -1494,7 +1497,7 @@ mwl_hal_bastream_create(struct mwl_hal *mh0, /* NB: ResetSeqNo known to be zero */ pCmd->BaInfo.CreateParams.StartSeqNo = htole16(seqno); #if 0 - cvtBAFlags(&pCmd->BaInfo.CreateParams.Flags, sp->ba_type, 0); + cvtBAFlags(&pCmd->BaInfo.CreateParams.Flags, sp->ba_policy, 0); #else pCmd->BaInfo.CreateParams.Flags = htole32(BASTREAM_FLAG_IMMEDIATE_TYPE) @@ -1551,7 +1554,8 @@ mwl_hal_bastream_destroy(struct mwl_hal *mh0, const MWL_HAL_BASTREAM *s) int mwl_hal_bastream_get_seqno(struct mwl_hal *mh0, - const MWL_HAL_BASTREAM *s, uint16_t *pseqno) + const MWL_HAL_BASTREAM *s, const uint8_t Macaddr[IEEE80211_ADDR_LEN], + uint16_t *pseqno) { struct mwl_hal_priv *mh = MWLPRIV(mh0); struct mwl_hal_bastream *sp = __DECONST(struct mwl_hal_bastream *, s); @@ -1560,7 +1564,7 @@ mwl_hal_bastream_get_seqno(struct mwl_hal *mh0, MWL_HAL_LOCK(mh); _CMD_SETUP(pCmd, HostCmd_GET_SEQNO, HostCmd_CMD_GET_SEQNO); - IEEE80211_ADDR_COPY(pCmd->MacAddr, sp->macaddr); + IEEE80211_ADDR_COPY(pCmd->MacAddr, Macaddr); pCmd->TID = sp->tid; retval = mwlExecuteCmd(mh, HostCmd_CMD_GET_SEQNO); @@ -1592,6 +1596,82 @@ mwl_hal_getwatchdogbitmap(struct mwl_hal *mh0, uint8_t bitmap[1]) return retval; } +/* + * Configure aggressive Ampdu rate mode. + */ +int +mwl_hal_setaggampduratemode(struct mwl_hal *mh0, int mode, int threshold) +{ + struct mwl_hal_priv *mh = MWLPRIV(mh0); + HostCmd_FW_AMPDU_RETRY_RATEDROP_MODE *pCmd; + int retval; + + MWL_HAL_LOCK(mh); + _CMD_SETUP(pCmd, HostCmd_FW_AMPDU_RETRY_RATEDROP_MODE, + HostCmd_CMD_AMPDU_RETRY_RATEDROP_MODE); + pCmd->Action = htole16(1); + pCmd->Option = htole32(mode); + pCmd->Threshold = htole32(threshold); + + retval = mwlExecuteCmd(mh, HostCmd_CMD_AMPDU_RETRY_RATEDROP_MODE); + MWL_HAL_UNLOCK(mh); + return retval; +} + +int +mwl_hal_getaggampduratemode(struct mwl_hal *mh0, int *mode, int *threshold) +{ + struct mwl_hal_priv *mh = MWLPRIV(mh0); + HostCmd_FW_AMPDU_RETRY_RATEDROP_MODE *pCmd; + int retval; + + MWL_HAL_LOCK(mh); + _CMD_SETUP(pCmd, HostCmd_FW_AMPDU_RETRY_RATEDROP_MODE, + HostCmd_CMD_AMPDU_RETRY_RATEDROP_MODE); + pCmd->Action = htole16(0); + + retval = mwlExecuteCmd(mh, HostCmd_CMD_AMPDU_RETRY_RATEDROP_MODE); + MWL_HAL_UNLOCK(mh); + *mode = le32toh(pCmd->Option); + *threshold = le32toh(pCmd->Threshold); + return retval; +} + +/* + * Set CFEND status Enable/Disable + */ +int +mwl_hal_setcfend(struct mwl_hal *mh0, int ena) +{ + struct mwl_hal_priv *mh = MWLPRIV(mh0); + HostCmd_CFEND_ENABLE *pCmd; + int retval; + + MWL_HAL_LOCK(mh); + _CMD_SETUP(pCmd, HostCmd_CFEND_ENABLE, + HostCmd_CMD_CFEND_ENABLE); + pCmd->Enable = htole32(ena); + + retval = mwlExecuteCmd(mh, HostCmd_CMD_CFEND_ENABLE); + MWL_HAL_UNLOCK(mh); + return retval; +} + +int +mwl_hal_setdwds(struct mwl_hal *mh0, int ena) +{ + HostCmd_DWDS_ENABLE *pCmd; + struct mwl_hal_priv *mh = MWLPRIV(mh0); + int retval; + + MWL_HAL_LOCK(mh); + _CMD_SETUP(pCmd, HostCmd_DWDS_ENABLE, HostCmd_CMD_DWDS_ENABLE); + pCmd->Enable = htole32(ena); + retval = mwlExecuteCmd(mh, HostCmd_CMD_DWDS_ENABLE); + MWL_HAL_UNLOCK(mh); + return retval; +} + static void cvtPeerInfo(PeerInfo_t *to, const MWL_HAL_PEERINFO *from) { @@ -2659,6 +2739,9 @@ mwlcmdname(int cmd) CMD(SET_TIM); CMD(GET_TIM); CMD(GET_SEQNO); + CMD(DWDS_ENABLE); + CMD(AMPDU_RETRY_RATEDROP_MODE); + CMD(CFEND_ENABLE); } snprintf(buf, sizeof(buf), "0x%x", cmd); return buf; diff --git a/sys/dev/mwl/mwlhal.h b/sys/dev/mwl/mwlhal.h index c82b427..ab6b7d0 100644 --- a/sys/dev/mwl/mwlhal.h +++ b/sys/dev/mwl/mwlhal.h @@ -48,9 +48,10 @@ #define MWL_NUM_HCCA_QUEUES 0 #define MWL_NUM_BA_QUEUES 0 #define MWL_NUM_MGMT_QUEUES 0 +#define MWL_NUM_ACK_QUEUES 0 #define MWL_NUM_TX_QUEUES \ (MWL_NUM_EDCA_QUEUES + MWL_NUM_HCCA_QUEUES + MWL_NUM_BA_QUEUES + \ - MWL_NUM_MGMT_QUEUES) + MWL_NUM_MGMT_QUEUES + MWL_NUM_ACK_QUEUES) #define MWL_MAX_RXWCB_QUEUES 1 #define MWL_MAX_SUPPORTED_RATES 12 @@ -208,7 +209,7 @@ struct mwl_hal_hwspec { uint32_t rxDescRead; uint32_t rxDescWrite; uint32_t ulFwAwakeCookie; - uint32_t wcbBase[4]; + uint32_t wcbBase[MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES]; }; int mwl_hal_gethwspecs(struct mwl_hal *mh, struct mwl_hal_hwspec *); @@ -220,7 +221,7 @@ struct mwl_hal_txrxdma { uint32_t maxNumTxWcb; /* max # of tx descs per WCB */ uint32_t rxDescRead; uint32_t rxDescWrite; - uint32_t wcbBase[4]; + uint32_t wcbBase[MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES]; }; int mwl_hal_sethwdma(struct mwl_hal *mh, const struct mwl_hal_txrxdma *); @@ -507,21 +508,27 @@ typedef struct { int txq; } MWL_HAL_BASTREAM; -const MWL_HAL_BASTREAM *mwl_hal_bastream_alloc(struct mwl_hal *mh, - int ba_type, const uint8_t Macaddr[16], uint8_t Tid, +const MWL_HAL_BASTREAM *mwl_hal_bastream_alloc(struct mwl_hal_vap *, + int ba_type, const uint8_t Macaddr[6], uint8_t Tid, uint8_t ParamInfo, void *, void *); const MWL_HAL_BASTREAM *mwl_hal_bastream_lookup(struct mwl_hal *mh, int s); -int mwl_hal_bastream_create(struct mwl_hal *mh, const MWL_HAL_BASTREAM *, +int mwl_hal_bastream_create(struct mwl_hal_vap *, const MWL_HAL_BASTREAM *, int BarThrs, int WindowSize, uint16_t seqno); int mwl_hal_bastream_destroy(struct mwl_hal *mh, const MWL_HAL_BASTREAM *); -int mwl_hal_bastream_get_seqno(struct mwl_hal *mh, const MWL_HAL_BASTREAM *, - uint16_t *pseqno); int mwl_hal_getwatchdogbitmap(struct mwl_hal *mh, uint8_t bitmap[1]); +int mwl_hal_bastream_get_seqno(struct mwl_hal *mh, const MWL_HAL_BASTREAM *, + const uint8_t Macaddr[6], uint16_t *pseqno); /* for sysctl hookup for debugging */ void mwl_hal_setbastreams(struct mwl_hal *mh, int mask); int mwl_hal_getbastreams(struct mwl_hal *mh); /* + * Set/get A-MPDU aggregation parameters. + */ +int mwl_hal_setaggampduratemode(struct mwl_hal *, int mode, int thresh); +int mwl_hal_getaggampduratemode(struct mwl_hal *, int *mode, int *thresh); + +/* * Inform the firmware of a new association station. * The address is the MAC address of the peer station. * The AID is supplied sans the 0xc000 bits. The station @@ -579,6 +586,13 @@ int mwl_hal_stop(struct mwl_hal_vap *); int mwl_hal_start(struct mwl_hal_vap *); /* + * Add/Remove station from Power Save TIM handling. + * + * If set is non-zero the AID is enabled, if zero it is removed. + */ +int mwl_hal_updatetim(struct mwl_hal_vap *, uint16_t aid, int set); + +/* * Enable/disable 11g protection use. This call specifies * the ERP information element flags to use. */ @@ -651,6 +665,16 @@ int mwl_hal_setpromisc(struct mwl_hal *, int ena); int mwl_hal_getpromisc(struct mwl_hal *); /* + * Enable/disable CF-End use. + */ +int mwl_hal_setcfend(struct mwl_hal *, int ena); + +/* + * Enable/disable sta-mode DWDS use/operation. + */ +int mwl_hal_setdwds(struct mwl_hal *, int ena); + +/* * Diagnostic interface. This is an open-ended interface that * is opaque to applications. Diagnostic programs use this to * retrieve internal data structures, etc. There is no guarantee diff --git a/sys/dev/mwl/mwlreg.h b/sys/dev/mwl/mwlreg.h index 17ebd61..a8186b1 100644 --- a/sys/dev/mwl/mwlreg.h +++ b/sys/dev/mwl/mwlreg.h @@ -83,6 +83,7 @@ #define MACREG_A2HRIC_BIT_CHAN_SWITCH 0x00001000 #define MACREG_A2HRIC_BIT_TX_WATCHDOG 0x00002000 #define MACREG_A2HRIC_BIT_BA_WATCHDOG 0x00000400 +#define MACREQ_A2HRIC_BIT_TX_ACK 0x00008000 #define ISR_SRC_BITS ((MACREG_A2HRIC_BIT_RX_RDY) | \ (MACREG_A2HRIC_BIT_TX_DONE) | \ (MACREG_A2HRIC_BIT_OPC_DONE) | \ @@ -93,14 +94,15 @@ (MACREG_A2HRIC_BIT_CHAN_SWITCH)| \ (MACREG_A2HRIC_BIT_TX_WATCHDOG)| \ (MACREG_A2HRIC_BIT_QUEUE_EMPTY)| \ - (MACREG_A2HRIC_BIT_BA_WATCHDOG)) + (MACREG_A2HRIC_BIT_BA_WATCHDOG)| \ + (MACREQ_A2HRIC_BIT_TX_ACK)) #define MACREG_A2HRIC_BIT_MASK ISR_SRC_BITS // Bit definitio for MACREG_REG_H2A_INTERRUPT_CAUSE (H2ARIC) -#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001 // bit 0 -#define MACREG_H2ARIC_BIT_DOOR_BELL 0x00000002 // bit 1 +#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001 // bit 0 +#define MACREG_H2ARIC_BIT_DOOR_BELL 0x00000002 // bit 1 #define ISR_RESET (1<<15) // INT code register event definition @@ -120,9 +122,10 @@ #define NUM_HCCA_QUEUES 0 #define NUM_BA_QUEUES 0 #define NUM_MGMT_QUEUES 0 +#define NUM_ACK_EVENT_QUEUE 1 #define TOTAL_TX_QUEUES \ - (NUM_EDCA_QUEUES + NUM_HCCA_QUEUES + NUM_BA_QUEUES + NUM_MGMT_QUEUES) -#define MAX_TXWCB_QUEUES TOTAL_TX_QUEUES + (NUM_EDCA_QUEUES + NUM_HCCA_QUEUES + NUM_BA_QUEUES + NUM_MGMT_QUEUES + NUM_ACK_EVENT_QUEUE) +#define MAX_TXWCB_QUEUES TOTAL_TX_QUEUES - NUM_ACK_EVENT_QUEUE #define MAX_RXWCB_QUEUES 1 //============================================================================= @@ -201,6 +204,7 @@ struct mwl_txdesc { uint16_t pad; /* align to 4-byte boundary */ #define EAGLE_TXD_FIXED_RATE 0x0100 /* get tx rate from Format */ #define EAGLE_TXD_DONT_AGGR 0x0200 /* don't aggregate frame */ + uint32_t ack_wcb_addr; } __packed; struct mwl_ant_info { @@ -213,6 +217,7 @@ struct mwl_ant_info { uint8_t nf_c; /* Noise floor for antenna C */ uint8_t rsvd2; /* Reserved */ uint8_t nf; /* Noise floor */ + uint8_t rsvd3[3]; /* Reserved - To make word aligned */ } __packed; struct mwl_rxdesc { @@ -320,6 +325,9 @@ struct mwl_rxdesc { #define HostCmd_CMD_SET_TIM 0x1141 #define HostCmd_CMD_GET_TIM 0x1142 #define HostCmd_CMD_GET_SEQNO 0x1143 +#define HostCmd_CMD_DWDS_ENABLE 0x1144 +#define HostCmd_CMD_AMPDU_RETRY_RATEDROP_MODE 0x1145 +#define HostCmd_CMD_CFEND_ENABLE 0x1146 /* // Define general result code for each command @@ -467,9 +475,7 @@ typedef struct { u_int32_t RxPdWrPtr; u_int32_t RxPdRdPtr; u_int32_t ulFwAwakeCookie; - u_int32_t WcbBase1; - u_int32_t WcbBase2; - u_int32_t WcbBase3; + u_int32_t WcbBase1[TOTAL_TX_QUEUES-1]; } __packed HostCmd_DS_GET_HW_SPEC; typedef struct { @@ -894,6 +900,7 @@ typedef struct { PeerInfo_t PeerInfo; uint8_t Qosinfo; uint8_t isQosSta; + uint32_t FwStaPtr; } __packed HostCmd_FW_SET_NEW_STN; typedef struct { @@ -1218,6 +1225,9 @@ typedef struct { BASTREAM_CONTEXT FwBaContext; uint8_t ResetSeqNo; /** 0 or 1**/ uint16_t StartSeqNo; + + // proxy sta MAC Address + uint8_t StaSrcMacAddr[6]; }__packed BASTREAM_CREATE_STREAM; // new transmit sequence number information @@ -1349,4 +1359,21 @@ typedef struct { uint16_t SeqNo; uint8_t reserved; } __packed HostCmd_GET_SEQNO; + +typedef struct { + FWCmdHdr CmdHdr; + uint32_t Enable; //0 -- Disbale. or 1 -- Enable. +} __packed HostCmd_DWDS_ENABLE; + +typedef struct { + FWCmdHdr CmdHdr; + uint16_t Action; /* 0: Get. 1:Set */ + uint32_t Option; /* 0: default. 1:Aggressive */ + uint32_t Threshold; /* Range 0-200, default 8 */ +}__packed HostCmd_FW_AMPDU_RETRY_RATEDROP_MODE; + +typedef struct { + FWCmdHdr CmdHdr; + uint32_t Enable; /* 0 -- Disable. or 1 -- Enable */ +}__packed HostCmd_CFEND_ENABLE; #endif /* _MWL_HALREG_H_ */ |