From owner-p4-projects@FreeBSD.ORG Tue Apr 1 23:30:25 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B79211065670; Tue, 1 Apr 2008 23:30:25 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 76AA4106564A for ; Tue, 1 Apr 2008 23:30:25 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 674628FC15 for ; Tue, 1 Apr 2008 23:30:25 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m31NUPVZ020202 for ; Tue, 1 Apr 2008 23:30:25 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m31NUPxR020200 for perforce@freebsd.org; Tue, 1 Apr 2008 23:30:25 GMT (envelope-from sam@freebsd.org) Date: Tue, 1 Apr 2008 23:30:25 GMT Message-Id: <200804012330.m31NUPxR020200@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 139171 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Apr 2008 23:30:26 -0000 http://perforce.freebsd.org/chv.cgi?CH=139171 Change 139171 by sam@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;