PERFORCE change 139171 for review
Sam Leffler
sam at FreeBSD.org
Tue Apr 1 16:30:26 PDT 2008
http://perforce.freebsd.org/chv.cgi?CH=139171
Change 139171 by sam at sam_ebb on 2008/04/01 23:30:11
checkpoint work I've been holding on to; includes tracking
of various api changes
Affected files ...
.. //depot/projects/vap/sys/dev/iwn/if_iwn.c#6 edit
.. //depot/projects/vap/sys/dev/iwn/if_iwnreg.h#4 edit
.. //depot/projects/vap/sys/dev/iwn/if_iwnvar.h#3 edit
Differences ...
==== //depot/projects/vap/sys/dev/iwn/if_iwn.c#6 (text+kox) ====
@@ -124,9 +124,6 @@
void iwn_unload_firmware(struct iwn_softc *);
static void iwn_timer_timeout(void *);
static void iwn_calib_reset(struct iwn_softc *);
-static void iwn_amrr_reset(struct ieee80211vap *);
-static void iwn_amrr_iter_func(void *, struct ieee80211_node *);
-static void iwn_amrr_timeout(void *);
void iwn_ampdu_rx_start(struct iwn_softc *, struct iwn_rx_desc *);
void iwn_rx_intr(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
@@ -147,7 +144,8 @@
static void iwn_watchdog(struct iwn_softc *);
int iwn_ioctl(struct ifnet *, u_long, caddr_t);
int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
-int iwn_setup_node_mrr(struct iwn_softc *, uint8_t, int);
+int iwn_set_link_quality(struct iwn_softc *, uint8_t,
+ const struct ieee80211_channel *, int);
int iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
const struct ieee80211_key *);
int iwn_wme_update(struct ieee80211com *);
@@ -201,6 +199,7 @@
IWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
IWN_DEBUG_NODE = 0x00000400, /* node management */
IWN_DEBUG_LED = 0x00000800, /* led management */
+ IWN_DEBUG_CMD = 0x00001000, /* cmd submission */
IWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
IWN_DEBUG_ANY = 0xffffffff
};
@@ -375,8 +374,7 @@
/* set device capabilities */
ic->ic_caps =
- IEEE80211_C_WEP /* s/w WEP */
- | IEEE80211_C_MONITOR /* monitor mode supported */
+ IEEE80211_C_MONITOR /* monitor mode supported */
| IEEE80211_C_TXPMGT /* tx power management */
| IEEE80211_C_SHSLOT /* short slot time supported */
| IEEE80211_C_WPA
@@ -514,10 +512,10 @@
ivp->iv_newstate = vap->iv_newstate;
vap->iv_newstate = iwn_newstate;
- callout_init(&ivp->iv_amrr_to, CALLOUT_MPSAFE);
ieee80211_amrr_init(&ivp->iv_amrr, vap,
IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD);
+ IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
+ 500 /*ms*/);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
@@ -530,7 +528,7 @@
{
struct iwn_vap *ivp = IWN_VAP(vap);
- callout_drain(&ivp->iv_amrr_to);
+ ieee80211_amrr_cleanup(&ivp->iv_amrr);
ieee80211_vap_detach(vap);
free(ivp, M_80211_VAP);
}
@@ -948,15 +946,9 @@
iwn_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211vap *vap = ni->ni_vap;
- int i;
- ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr, &IWN_NODE(ni)->amn);
-
- /* set rate to some reasonable initial value */
- for (i = ni->ni_rates.rs_nrates - 1;
- i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
- i--);
- ni->ni_txrate = i;
+ ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
+ &IWN_NODE(ni)->amn, ni);
}
int
@@ -973,13 +965,13 @@
struct iwn_vap *ivp = IWN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
struct iwn_softc *sc = ic->ic_ifp->if_softc;
+ int error;
DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate]);
callout_stop(&sc->sc_timer_to);
- callout_stop(&ivp->iv_amrr_to);
/*
* Some state transitions require issuing a configure request
@@ -989,7 +981,8 @@
*/
if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
/* !AUTH -> AUTH requires adapter config */
- return iwn_queue_cmd(sc, IWN_AUTH, arg, IWN_QUEUE_NORMAL);
+ error = iwn_queue_cmd(sc, IWN_AUTH, arg, IWN_QUEUE_NORMAL);
+ return (error != 0 ? error : EINPROGRESS);
}
if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
/*
@@ -997,18 +990,14 @@
* which is done with a firmware cmd. We also defer
* starting the timers until that work is done.
*/
- return iwn_queue_cmd(sc, IWN_RUN, arg, IWN_QUEUE_NORMAL);
+ error = iwn_queue_cmd(sc, IWN_RUN, arg, IWN_QUEUE_NORMAL);
+ return (error != 0 ? error : EINPROGRESS);
}
if (nstate == IEEE80211_S_RUN) {
- const struct ieee80211_txparam *tp;
/*
* RUN -> RUN transition; just restart the timers.
*/
iwn_calib_reset(sc);
- tp = &vap->iv_txparms[
- ieee80211_chan2mode(vap->iv_bss->ni_chan)];
- if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- iwn_amrr_reset(vap);
}
return ivp->iv_newstate(vap, nstate, arg);
}
@@ -1348,34 +1337,6 @@
sc->calib_cnt = 60; /* do calibration every 60s */
}
-static void
-iwn_amrr_reset(struct ieee80211vap *vap)
-{
- /* rate control updated every 500ms */
- callout_reset(&IWN_VAP(vap)->iv_amrr_to, hz / 2, iwn_amrr_timeout, vap);
-}
-
-static void
-iwn_amrr_iter_func(void *arg, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_amrr_choose(&IWN_VAP(vap)->iv_amrr, ni, &IWN_NODE(ni)->amn);
-}
-
-static void
-iwn_amrr_timeout(void *arg)
-{
- struct ieee80211vap *vap = arg;
-
- if (vap->iv_opmode != IEEE80211_M_STA) {
- struct ieee80211com *ic = vap->iv_ic;
- ieee80211_iterate_nodes(&ic->ic_sta, iwn_amrr_iter_func, vap);
- } else
- iwn_amrr_iter_func(vap, vap->iv_bss);
- iwn_amrr_reset(vap);
-}
-
void
iwn_ampdu_rx_start(struct iwn_softc *sc, struct iwn_rx_desc *desc)
{
@@ -1598,11 +1559,13 @@
struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
struct iwn_tx_data *data = &ring->data[desc->idx];
struct iwn_tx_stat *stat = (struct iwn_tx_stat *)(desc + 1);
- struct iwn_node *wn = (struct iwn_node *)data->ni;
+ struct iwn_node *wn = IWN_NODE(data->ni);
struct mbuf *m;
struct ieee80211_node *ni;
uint32_t status;
+ KASSERT(data->ni != NULL, ("no node"));
+
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
"qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
__func__, desc->qid, desc->idx, stat->ntries,
@@ -1612,19 +1575,18 @@
/*
* Update rate control statistics for the node.
*/
- wn->amn.amn_txcnt++;
- if (stat->ntries > 0) {
- DPRINTF(sc, IWN_DEBUG_XMIT, "%s: ntries %d\n",
- __func__, stat->ntries);
- wn->amn.amn_retrycnt++;
- }
-
status = le32toh(stat->status) & 0xff;
if (status & 0x80) {
DPRINTF(sc, IWN_DEBUG_ANY, "%s: status 0x%x\n",
__func__, le32toh(stat->status));
ifp->if_oerrors++;
+ ieee80211_amrr_tx_complete(&wn->amn,
+ IEEE80211_AMRR_FAILURE, stat->ntries);
+ } else {
+ ieee80211_amrr_tx_complete(&wn->amn,
+ IEEE80211_AMRR_SUCCESS, stat->ntries);
}
+
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ring->data_dmat, data->map);
@@ -1933,9 +1895,10 @@
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
- else
- rate = ni->ni_rates.rs_rates[ni->ni_txrate];
- rate &= IEEE80211_RATE_VAL;
+ else {
+ (void) ieee80211_amrr_choose(ni, &IWN_NODE(ni)->amn);
+ rate = ni->ni_txrate;
+ }
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
k = ieee80211_crypto_encap(ni, m0);
@@ -2701,6 +2664,9 @@
htole16(8);
}
+ DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
+ __func__, iwn_intr_str(cmd->code), cmd->code,
+ cmd->flags, cmd->qid, cmd->idx);
/* kick cmd ring */
ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
@@ -2709,45 +2675,87 @@
return async ? 0 : msleep(cmd, &sc->sc_mtx, PCATCH, "iwncmd", hz);
}
+static const uint8_t iwn_ridx_to_plcp[] = {
+ 10, 20, 55, 110, /* CCK */
+ 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
+};
+static const uint8_t iwn_siso_mcs_to_plcp[] = {
+ 0, 0, 0, 0, /* CCK */
+ 0, 0, 1, 2, 3, 4, 5, 6, 7 /* HT */
+};
+static const uint8_t iwn_mimo_mcs_to_plcp[] = {
+ 0, 0, 0, 0, /* CCK */
+ 8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
+};
+static const uint8_t iwn_prev_ridx[] = {
+ /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
+ 0, 0, 1, 5, /* CCK */
+ 2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
+};
+
/*
- * Configure hardware multi-rate retries for one node.
+ * Configure hardware link parameters for the specified
+ * node operating on the specified channel.
*/
int
-iwn_setup_node_mrr(struct iwn_softc *sc, uint8_t id, int async)
+iwn_set_link_quality(struct iwn_softc *sc, uint8_t id,
+ const struct ieee80211_channel *c, int async)
{
- struct ieee80211com *ic = &sc->sc_ic;
- struct iwn_cmd_mrr mrr;
+ struct iwn_cmd_link_quality lq;
int i, ridx;
- memset(&mrr, 0, sizeof mrr);
- mrr.id = id;
- if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
- IEEE80211_IS_CHAN_HT(ic->ic_bsschan)) {
- mrr.mimo = 1;
- mrr.ssmask = 1;
+ memset(&lq, 0, sizeof(lq));
+ lq.id = id;
+ if (IEEE80211_IS_CHAN_HT(c)) {
+ lq.mimo = 1;
+ lq.ssmask = 0x1;
} else
- mrr.ssmask = 2;
- mrr.dsmask = 3;
- mrr.ampdu_disable = 3;
- mrr.ampdu_limit = htole16(4000);
+ lq.ssmask = 0x2;
if (id == IWN_ID_BSS)
- ridx = IWN_OFDM54;
- else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
- ridx = IWN_OFDM6;
+ ridx = IWN_RATE_OFDM54;
+ else if (IEEE80211_IS_CHAN_A(c))
+ ridx = IWN_RATE_OFDM6;
else
- ridx = IWN_CCK1;
+ ridx = IWN_RATE_CCK1;
for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
- mrr.table[i].rate = iwn_ridx_to_plcp[ridx];
- mrr.table[i].rflags = IWN_RFLAG_ANT_B;
- if (ridx <= IWN_CCK11)
- mrr.table[i].rflags |= IWN_RFLAG_CCK;
+ /* XXX toggle antenna for retry patterns */
+ if (IEEE80211_IS_CHAN_HT40(c)) {
+ lq.table[i].rate = iwn_mimo_mcs_to_plcp[ridx]
+ | IWN_RATE_MCS;
+ lq.table[i].rflags = IWN_RFLAG_HT
+ | IWN_RFLAG_HT40
+ | IWN_RFLAG_ANT_A;
+ /* XXX shortGI */
+ } else if (IEEE80211_IS_CHAN_HT(c)) {
+ lq.table[i].rate = iwn_siso_mcs_to_plcp[ridx]
+ | IWN_RATE_MCS;
+ lq.table[i].rflags = IWN_RFLAG_HT
+ | IWN_RFLAG_ANT_A;
+ /* XXX shortGI */
+ } else {
+ lq.table[i].rate = iwn_ridx_to_plcp[ridx];
+ if (ridx <= IWN_RATE_CCK11)
+ lq.table[i].rflags = IWN_RFLAG_CCK;
+ lq.table[i].rflags |= IWN_RFLAG_ANT_B;
+ }
ridx = iwn_prev_ridx[ridx];
}
- DPRINTF(sc, IWN_DEBUG_STATE,
- "%s: set MRR for node %d, mimo %d ssmask %d\n",
- __func__, id, mrr.mimo, mrr.ssmask);
- return iwn_cmd(sc, IWN_CMD_NODE_MRR_SETUP, &mrr, sizeof mrr, async);
+
+ lq.dsmask = 0x3;
+ lq.ampdu_disable = 3;
+ lq.ampdu_limit = htole16(4000);
+#ifdef IWN_DEBUG
+ if (sc->sc_debug & IWN_DEBUG_STATE) {
+ printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
+ __func__, id, lq.mimo, lq.ssmask);
+ printf("%s:", __func__);
+ for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
+ printf(" %d:%x", lq.table[i].rate, lq.table[i].rflags);
+ printf("\n");
+ }
+#endif
+ return iwn_cmd(sc, IWN_CMD_TX_LINK_QUALITY, &lq, sizeof(lq), async);
}
#if 0
@@ -3463,6 +3471,7 @@
"%s: could not configure, error %d\n", __func__, error);
return error;
}
+ sc->sc_curchan = ic->ic_curchan;
/* configuration has changed, set Tx power accordingly */
error = iwn_set_txpower(sc, ni->ni_chan, 1);
@@ -3487,7 +3496,7 @@
__func__, error);
return error;
}
- error = iwn_setup_node_mrr(sc, node.id, 1);
+ error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 1);
if (error != 0) {
device_printf(sc->sc_dev,
"%s: could not setup MRR for broadcast node, error %d\n",
@@ -3508,7 +3517,6 @@
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); /*XXX*/
struct ieee80211_node *ni = vap->iv_bss;
- const struct ieee80211_txparam *tp;
struct iwn_node_info node;
int error, maxrxampdu, ampdudensity;
@@ -3538,6 +3546,12 @@
sc->config.flags |= htole32(IWN_CONFIG_HT40D);
else
sc->config.flags |= htole32(IWN_CONFIG_HT20);
+ sc->config.rxchain = htole16(
+ (3 << IWN_RXCHAIN_VALID_S)
+ | (3 << IWN_RXCHAIN_MIMO_CNT_S)
+ | (1 << IWN_RXCHAIN_CNT_S)
+ | IWN_RXCHAIN_MIMO_FORCE);
+
maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
} else
@@ -3563,6 +3577,7 @@
__func__, error);
return error;
}
+ sc->sc_curchan = ni->ni_chan;
/* configuration has changed, set Tx power accordingly */
error = iwn_set_txpower(sc, ni->ni_chan, 1);
@@ -3577,8 +3592,8 @@
IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
node.id = IWN_ID_BSS;
node.htflags = htole32(
- (maxrxampdu << IWN_MAXRXAMPDU_SHIFT) |
- (ampdudensity << IWN_MPDUDENSITY_SHIFT));
+ (maxrxampdu << IWN_MAXRXAMPDU_S) |
+ (ampdudensity << IWN_MPDUDENSITY_S));
DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
__func__, node.id, le32toh(node.htflags));
error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
@@ -3586,7 +3601,7 @@
device_printf(sc->sc_dev,"could not add BSS node\n");
return error;
}
- error = iwn_setup_node_mrr(sc, node.id, 1);
+ error = iwn_set_link_quality(sc, node.id, ni->ni_chan, 1);
if (error != 0) {
device_printf(sc->sc_dev,
"%s: could not setup MRR for node %d, error %d\n",
@@ -3614,11 +3629,6 @@
/* link LED always on while associated */
iwn_set_led(sc, IWN_LED_LINK, 0, 1);
- /* start rate control timer is not fixed rate */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- iwn_amrr_reset(vap);
-
return 0;
#undef MS
}
@@ -3679,7 +3689,7 @@
hdr->plcp_threshold = htole16(1); /* min # of packets */
/* select Ant B and Ant C for scanning */
- hdr->rxchain = htole16(0x3e1 | 7 << IWN_RXCHAIN_ANTMSK_SHIFT);
+ hdr->rxchain = htole16(0x3e1 | (7 << IWN_RXCHAIN_VALID_S));
tx = (struct iwn_cmd_data *)(hdr + 1);
memset(tx, 0, sizeof (struct iwn_cmd_data));
@@ -3691,11 +3701,11 @@
if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
hdr->crc_threshold = htole16(1);
/* send probe requests at 6Mbps */
- tx->rate = iwn_ridx_to_plcp[IWN_OFDM6];
+ tx->rate = iwn_ridx_to_plcp[IWN_RATE_OFDM6];
} else {
hdr->flags = htole32(IWN_CONFIG_24GHZ | IWN_CONFIG_AUTO);
/* send probe requests at 1Mbps */
- tx->rate = iwn_ridx_to_plcp[IWN_CCK1];
+ tx->rate = iwn_ridx_to_plcp[IWN_RATE_CCK1];
tx->rflags |= IWN_RFLAG_CCK;
}
@@ -3883,7 +3893,7 @@
sc->config.ofdm_mask = 0xff; /* not yet negotiated */
sc->config.ht_single_mask = 0xff;
sc->config.ht_dual_mask = 0xff;
- sc->config.rxchain = htole16(0x2800 | 7 << IWN_RXCHAIN_ANTMSK_SHIFT);
+ sc->config.rxchain = htole16(0x2800 | (7 << IWN_RXCHAIN_VALID_S));
DPRINTF(sc, IWN_DEBUG_STATE,
"%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
@@ -3904,6 +3914,7 @@
__func__, error);
return error;
}
+ sc->sc_curchan = ic->ic_curchan;
/* configuration has changed, set Tx power accordingly */
error = iwn_set_txpower(sc, ic->ic_curchan, 0);
@@ -3926,7 +3937,7 @@
__func__, error);
return error;
}
- error = iwn_setup_node_mrr(sc, node.id, 0);
+ error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 0);
if (error != 0) {
device_printf(sc->sc_dev,
"%s: could not setup MRR for node %d, error %d\n",
@@ -4285,11 +4296,13 @@
struct iwn_softc *sc = ifp->if_softc;
const struct ieee80211_channel *c = ic->ic_curchan;
- sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
- sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
- sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
- sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
- iwn_queue_cmd(sc, IWN_SET_CHAN, 0, IWN_QUEUE_NORMAL);
+ if (c != sc->sc_curchan) {
+ sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
+ sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
+ sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
+ sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
+ iwn_queue_cmd(sc, IWN_SET_CHAN, 0, IWN_QUEUE_NORMAL);
+ }
}
/*
@@ -4325,6 +4338,7 @@
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap;
int cmd, arg, error;
+ enum ieee80211_state nstate;
for (;;) {
IWN_CMD_LOCK(sc);
@@ -4344,7 +4358,7 @@
sc->sc_cmd_cur = (sc->sc_cmd_cur + 1) % IWN_CMD_MAXOPS;
IWN_CMD_UNLOCK(sc);
- DPRINTF(sc, IWN_DEBUG_OPS, "%s: %s (cmd %d)\n",
+ DPRINTF(sc, IWN_DEBUG_OPS, "%s: %s (cmd 0x%x)\n",
__func__, iwn_ops_str(cmd), cmd);
vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
@@ -4380,31 +4394,28 @@
}
break;
case IWN_AUTH:
+ case IWN_RUN:
IWN_LOCK(sc);
- error = iwn_auth(sc);
- IWN_UNLOCK(sc);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "%s: could not move to auth state, error %d\n",
- __func__, error);
- return;
+ if (cmd == IWN_AUTH) {
+ error = iwn_auth(sc);
+ nstate = IEEE80211_S_AUTH;
+ } else {
+ error = iwn_run(sc);
+ nstate = IEEE80211_S_RUN;
}
- IWN_VAP(vap)->iv_newstate(vap, IEEE80211_S_AUTH, arg);
- break;
- case IWN_RUN:
- IWN_LOCK(sc);
- error = iwn_run(sc);
IWN_UNLOCK(sc);
- if (error != 0) {
+ if (error == 0) {
+ IEEE80211_LOCK(ic);
+ IWN_VAP(vap)->iv_newstate(vap, nstate, arg);
+ if (vap->iv_newstate_cb != NULL)
+ vap->iv_newstate_cb(vap, nstate, arg);
+ IEEE80211_UNLOCK(ic);
+ } else {
device_printf(sc->sc_dev,
- "%s: could not move to run state, error %d\n",
- __func__, error);
- return;
+ "%s: %s state change failed, error %d\n",
+ __func__, ieee80211_state_name[nstate],
+ error);
}
- IWN_VAP(vap)->iv_newstate(vap, IEEE80211_S_RUN, arg);
- /* XXX compensate for deferred handling of newstate */
- vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- if_start(vap->iv_ifp);
break;
case IWN_REINIT:
//XXX DEBUG
@@ -4528,7 +4539,7 @@
case IWN_CMD_ASSOCIATE: return "IWN_CMD_ASSOCIATE";
case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS";
case IWN_CMD_TSF: return "IWN_CMD_TSF";
- case IWN_CMD_NODE_MRR_SETUP: return "IWN_CMD_NODE_MRR_SETUP";
+ case IWN_CMD_TX_LINK_QUALITY: return "IWN_CMD_TX_LINK_QUALITY";
case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED";
case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE";
case IWN_CMD_SCAN: return "IWN_CMD_SCAN";
==== //depot/projects/vap/sys/dev/iwn/if_iwnreg.h#4 (text+kox) ====
@@ -251,30 +251,29 @@
struct iwn_tx_cmd {
uint8_t code;
-#define IWN_CMD_CONFIGURE 16
-#define IWN_CMD_ASSOCIATE 17
-#define IWN_CMD_EDCA_PARAMS 19
-#define IWN_CMD_TSF 20
-#define IWN_CMD_ADD_NODE 24
-#define IWN_CMD_TX_DATA 28
-#define IWN_CMD_NODE_MRR_SETUP 78
-#define IWN_CMD_SET_LED 72
-#define IWN_CMD_SET_POWER_MODE 119
-#define IWN_CMD_SCAN 128
-#define IWN_CMD_TXPOWER 151
-#define IWN_CMD_BLUETOOTH 155
-#define IWN_CMD_GET_STATISTICS 156
-#define IWN_CMD_SET_CRITICAL_TEMP 164
-#define IWN_SENSITIVITY 168
-#define IWN_PHY_CALIB 176
-
+#define IWN_CMD_CONFIGURE 0x10 /* REPLY_RXON */
+#define IWN_CMD_ASSOCIATE 0x11 /* REPLY_RXON_ASSOC */
+#define IWN_CMD_EDCA_PARAMS 0x13 /* REPLY_QOS_PARAM */
+#define IWN_CMD_TSF 0x14 /* REPLY_RXON_TIMING */
+#define IWN_CMD_ADD_NODE 0x18 /* REPLY_ADD_STA */
+#define IWN_CMD_TX_DATA 0x1c /* REPLY_TX */
+#define IWN_CMD_TX_LINK_QUALITY 0x4e /* REPLY_TX_LINK_QUALITY_CMD */
+#define IWN_CMD_SET_LED 0x48 /* REPLY_LEDS_CMD */
+#define IWN_CMD_SET_POWER_MODE 0x77 /* POWER_TABLE_CMD */
+#define IWN_CMD_SCAN 0x80 /* REPLY_SCAN_CMD */
+#define IWN_CMD_TXPOWER 0x97 /* REPLY_TX_PWR_TABLE_CMD */
+#define IWN_CMD_BLUETOOTH 0x9b /* REPLY_BT_CONFIG */
+#define IWN_CMD_GET_STATISTICS 0x9c /* REPLY_STATISTICS_CMD */
+#define IWN_CMD_SET_CRITICAL_TEMP 0xa4 /* REPLY_CT_KILL_CONFIG_CMD */
+#define IWN_SENSITIVITY 0xa8 /* SENSITIVITY_CMD */
+#define IWN_PHY_CALIB 0xb0 /* REPLY_PHY_CALIBRATION_CMD */
uint8_t flags;
uint8_t idx;
uint8_t qid;
uint8_t data[136];
} __packed;
-/* structure for command IWN_CMD_CONFIGURE (NB: RXON) */
+/* structure for command IWN_CMD_CONFIGURE (aka RXON) */
struct iwn_config {
uint8_t myaddr[IEEE80211_ADDR_LEN];
uint16_t reserved1;
@@ -289,8 +288,18 @@
#define IWN_MODE_MONITOR 6
uint8_t unused4; /* air propagation */
uint16_t rxchain;
-#define IWN_RXCHAIN_ANTMSK_SHIFT 1
-#define IWN_RXCHAIN_FORCE_MIMO (1 << 14)
+#define IWN_RXCHAIN_VALID 0x000e /* which antennae are valid */
+#define IWN_RXCHAIN_VALID_S 1
+#define IWN_RXCHAIN_FORCE 0x0070
+#define IWN_RXCHAIN_FORCE_S 4
+#define IWN_RXCHAIN_FORCE_MIMO 0x0380
+#define IWN_RXCHAIN_FORCE_MIMO_S 7
+#define IWN_RXCHAIN_CNT 0x0c00
+#define IWN_RXCHAIN_CNT_S 10
+#define IWN_RXCHAIN_MIMO_CNT 0x3000
+#define IWN_RXCHAIN_MIMO_CNT_S 12
+#define IWN_RXCHAIN_MIMO_FORCE 0x4000
+#define IWN_RXCHAIN_MIMO_FORCE_S 14
uint8_t ofdm_mask; /* basic rates */
uint8_t cck_mask; /* basic rates */
uint16_t associd;
@@ -362,17 +371,14 @@
struct iwn_node_info {
uint8_t control;
#define IWN_NODE_UPDATE (1 << 0)
-
uint8_t reserved1[3];
uint8_t macaddr[IEEE80211_ADDR_LEN];
uint16_t reserved2;
uint8_t id;
#define IWN_ID_BSS 0
#define IWN_ID_BROADCAST 31
-
uint8_t flags;
#define IWN_FLAG_SET_KEY (1 << 0)
-
uint16_t reserved3;
uint16_t security;
uint8_t tsc2; /* TKIP TSC2 */
@@ -381,17 +387,19 @@
uint16_t reserved5;
uint8_t key[IEEE80211_KEYBUF_SIZE];
uint32_t htflags;
-#define IWN_MAXRXAMPDU_SHIFT 19
-#define IWN_MPDUDENSITY_SHIFT 23
-
+#define IWN_MAXRXAMPDU_S 19
+#define IWN_MPDUDENSITY_S 23
uint32_t mask;
uint16_t tid;
- uint8_t rate;
+ uint8_t rate; /* legacy rate/MCS */
+#define IWN_RATE_MCS 0x08 /* or'd to indicate MCS */
uint8_t rflags;
-#define IWN_RFLAG_CCK (1 << 1)
-#define IWN_RFLAG_ANT_A (1 << 6)
-#define IWN_RFLAG_ANT_B (1 << 7)
-
+#define IWN_RFLAG_HT (1 << 0) /* use HT modulation */
+#define IWN_RFLAG_CCK (1 << 1) /* use CCK modulation */
+#define IWN_RFLAG_HT40 (1 << 3) /* use dual-stream */
+#define IWN_RFLAG_SGI (1 << 5) /* use short GI */
+#define IWN_RFLAG_ANT_A (1 << 6) /* start on antenna port A */
+#define IWN_RFLAG_ANT_B (1 << 7) /* start on antenna port B */
uint8_t add_imm;
uint8_t del_imm;
uint16_t add_imm_start;
@@ -443,9 +451,9 @@
uint16_t txop;
} __packed;
-/* structure for command IWN_CMD_MRR_NODE_SETUP */
+/* structure for command IWN_CMD_TX_LINK_QUALITY */
#define IWN_MAX_TX_RETRIES 16
-struct iwn_cmd_mrr {
+struct iwn_cmd_link_quality {
uint8_t id;
uint8_t reserved1;
uint16_t ctl;
@@ -460,10 +468,10 @@
uint32_t reserved2;
struct {
uint8_t rate;
-#define IWN_CCK1 0
-#define IWN_CCK11 3
-#define IWN_OFDM6 4
-#define IWN_OFDM54 11
+#define IWN_RATE_CCK1 0
+#define IWN_RATE_CCK11 3
+#define IWN_RATE_OFDM6 4
+#define IWN_RATE_OFDM54 11
uint8_t rflags;
uint16_t xrflags;
} table[IWN_MAX_TX_RETRIES];
@@ -888,17 +896,6 @@
struct iwn_eeprom_chan_samples chans[2];
} __packed;
-static const uint8_t iwn_ridx_to_plcp[] = {
- 10, 20, 55, 110, /* CCK */
- 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
-};
-
-/* allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
-static const uint8_t iwn_prev_ridx[] = {
- 0, 0, 1, 5, /* CCK */
- 2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
-};
-
#define IWN_MAX_PWR_INDEX 107
/*
==== //depot/projects/vap/sys/dev/iwn/if_iwnvar.h#3 (text+kox) ====
@@ -141,6 +141,7 @@
int sc_debug;
struct callout sc_timer_to; /* calib+watchdog timer */
int sc_tx_timer; /* tx watchdog timer/counter */
+ const struct ieee80211_channel *sc_curchan;
struct iwn_rx_radiotap_header sc_rxtap;
int sc_rxtap_len;
More information about the p4-projects
mailing list