summaryrefslogtreecommitdiffstats
path: root/sys/dev/mwl
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-06-29 18:42:54 +0000
committersam <sam@FreeBSD.org>2009-06-29 18:42:54 +0000
commit49f1934625b5e0ef669dd50385840fa4a71a85f3 (patch)
tree1b2eadb8b21a84c4711cffb083bbed9554b26d05 /sys/dev/mwl
parenta0406a12532b60a577e09907c61942649ac1c59f (diff)
downloadFreeBSD-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.c214
-rw-r--r--sys/dev/mwl/if_mwlvar.h4
-rw-r--r--sys/dev/mwl/mwlhal.c121
-rw-r--r--sys/dev/mwl/mwlhal.h40
-rw-r--r--sys/dev/mwl/mwlreg.h43
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_ */
OpenPOWER on IntegriCloud