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)
This commit is contained in:
Sam Leffler 2009-06-29 18:42:54 +00:00
parent 562a924de0
commit 7850fa71f5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195171
6 changed files with 2390 additions and 2251 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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
@ -4064,6 +4073,86 @@ mwl_setglobalkeys(struct ieee80211vap *vap)
(void) mwl_key_set(vap, wk, vap->iv_myaddr);
}
/*
* 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
@ -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,57 +4339,13 @@ 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
@ -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 *

View File

@ -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 */

View File

@ -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;

View File

@ -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,20 +508,26 @@ 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.
@ -578,6 +585,13 @@ int mwl_hal_setapmode(struct mwl_hal_vap *, MWL_HAL_APMODE);
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.
@ -650,6 +664,16 @@ int mwl_hal_SetRifs(struct mwl_hal *mh, uint8_t QNum);
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

View File

@ -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_ */