Date: Sat, 16 Apr 2011 12:42:54 +0000 (UTC) From: Bernhard Schmidt <bschmidt@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r220715 - head/sys/dev/iwn Message-ID: <201104161242.p3GCgsum005389@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bschmidt Date: Sat Apr 16 12:42:54 2011 New Revision: 220715 URL: http://svn.freebsd.org/changeset/base/220715 Log: Instead of hardcoding TX rates and using that to fill the retry table use the neogotiated ni_rates instead. Modified: head/sys/dev/iwn/if_iwn.c head/sys/dev/iwn/if_iwnreg.h Modified: head/sys/dev/iwn/if_iwn.c ============================================================================== --- head/sys/dev/iwn/if_iwn.c Sat Apr 16 12:41:22 2011 (r220714) +++ head/sys/dev/iwn/if_iwn.c Sat Apr 16 12:42:54 2011 (r220715) @@ -121,6 +121,7 @@ static void iwn_read_eeprom_channels(str static void iwn_read_eeprom_enhinfo(struct iwn_softc *); static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN]); +static void iwn_newassoc(struct ieee80211_node *, int); static int iwn_media_change(struct ifnet *); static int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwn_calib_timeout(void *); @@ -169,7 +170,8 @@ static int iwn4965_add_node(struct iwn_s int); static int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *, int); -static int iwn_set_link_quality(struct iwn_softc *, uint8_t, int); +static int iwn_set_link_quality(struct iwn_softc *, + struct ieee80211_node *); static int iwn_add_broadcast_node(struct iwn_softc *, int); static int iwn_wme_update(struct ieee80211com *); static void iwn_update_mcast(struct ifnet *); @@ -648,6 +650,7 @@ iwn_attach(device_t dev) ic->ic_vap_delete = iwn_vap_delete; ic->ic_raw_xmit = iwn_raw_xmit; ic->ic_node_alloc = iwn_node_alloc; + ic->ic_newassoc = iwn_newassoc; ic->ic_wme.wme_update = iwn_wme_update; ic->ic_update_mcast = iwn_update_mcast; ic->ic_scan_start = iwn_scan_start; @@ -1908,6 +1911,18 @@ iwn_node_alloc(struct ieee80211vap *vap, return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO); } +static void +iwn_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct iwn_node *wn = (void *)ni; + int ridx, i; + + for (i = 0; i < ni->ni_rates.rs_nrates; i++) { + ridx = iwn_plcp_signal(ni->ni_rates.rs_rates[i]); + wn->ridx[i] = ridx; + } +} + static int iwn_media_change(struct ifnet *ifp) { @@ -2891,7 +2906,7 @@ iwn_plcp_signal(int rate) { int i; for (i = 0; i < IWN_RIDX_MAX + 1; i++) { - if (rate == iwn_rates[i].rate) + if ((rate & IEEE80211_RATE_VAL) == iwn_rates[i].rate) return i; } @@ -3055,7 +3070,7 @@ iwn_tx_data(struct iwn_softc *sc, struct txant = IWN_LSB(sc->txchainmask); tx->rflags |= IWN_RFLAG_ANT(txant); } else { - tx->linkq = IWN_RIDX_OFDM54 - ridx; + tx->linkq = ni->ni_rates.rs_nrates - ridx - 1; flags |= IWN_TX_LINKQ; /* enable MRR */ } @@ -3599,98 +3614,39 @@ iwn5000_add_node(struct iwn_softc *sc, s return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async); } -#if 0 /* HT */ -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 */ -}; -#endif -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 link parameters for the specified - * node operating on the specified channel. - */ static int -iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async) +iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct iwn_node *wn = (void *)ni; + struct ieee80211_rateset *rs = &ni->ni_rates; struct iwn_cmd_link_quality linkq; const struct iwn_rate *rinfo; - int i; - uint8_t txant, ridx; + uint8_t txant; + int i, txrate; /* Use the first valid TX antenna. */ txant = IWN_LSB(sc->txchainmask); memset(&linkq, 0, sizeof linkq); - linkq.id = id; + linkq.id = wn->id; linkq.antmsk_1stream = txant; linkq.antmsk_2stream = IWN_ANT_AB; linkq.ampdu_max = 31; linkq.ampdu_threshold = 3; linkq.ampdu_limit = htole16(4000); /* 4ms */ -#if 0 /* HT */ - if (IEEE80211_IS_CHAN_HT(c)) - linkq.mimo = 1; -#endif - - if (id == IWN_ID_BSS) - ridx = IWN_RIDX_OFDM54; - else if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) - ridx = IWN_RIDX_OFDM6; - else - ridx = IWN_RIDX_CCK1; - + /* Start at highest available bit-rate. */ + txrate = rs->rs_nrates - 1; for (i = 0; i < IWN_MAX_TX_RETRIES; i++) { - rinfo = &iwn_rates[ridx]; -#if 0 /* HT */ - if (IEEE80211_IS_CHAN_HT40(c)) { - linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx] - | IWN_RIDX_MCS; - linkq.retry[i].rflags = IWN_RFLAG_HT - | IWN_RFLAG_HT40; - /* XXX shortGI */ - } else if (IEEE80211_IS_CHAN_HT(c)) { - linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx] - | IWN_RIDX_MCS; - linkq.retry[i].rflags = IWN_RFLAG_HT; - /* XXX shortGI */ - } else -#endif - { - linkq.retry[i].plcp = rinfo->plcp; - linkq.retry[i].rflags = rinfo->flags; - } + rinfo = &iwn_rates[wn->ridx[txrate]]; + linkq.retry[i].plcp = rinfo->plcp; + linkq.retry[i].rflags = rinfo->flags; linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant); - ridx = iwn_prev_ridx[ridx]; + /* Next retry at immediate lower bit-rate. */ + if (txrate > 0) + txrate--; } -#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, linkq.mimo, linkq.antmsk_1stream); - printf("%s:", __func__); - for (i = 0; i < IWN_MAX_TX_RETRIES; i++) - printf(" %d:%x", linkq.retry[i].plcp, - linkq.retry[i].rflags); - printf("\n"); - } -#endif - return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async); + return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1); } /* @@ -3701,8 +3657,12 @@ iwn_add_broadcast_node(struct iwn_softc { const struct iwn_hal *hal = sc->sc_hal; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct iwn_node_info node; - int error; + struct iwn_cmd_link_quality linkq; + const struct iwn_rate *rinfo; + uint8_t txant; + int i, error; memset(&node, 0, sizeof node); IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr); @@ -3712,8 +3672,31 @@ iwn_add_broadcast_node(struct iwn_softc if (error != 0) return error; - error = iwn_set_link_quality(sc, hal->broadcast_id, async); - return error; + /* Use the first valid TX antenna. */ + txant = IWN_LSB(sc->txchainmask); + + memset(&linkq, 0, sizeof linkq); + linkq.id = sc->sc_hal->broadcast_id; + linkq.antmsk_1stream = txant; + linkq.antmsk_2stream = IWN_ANT_AB; + linkq.ampdu_max = 64; + linkq.ampdu_threshold = 3; + linkq.ampdu_limit = htole16(4000); /* 4ms */ + + /* Use lowest mandatory bit-rate. */ + if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) + rinfo = &iwn_rates[IWN_RIDX_OFDM6]; + else + rinfo = &iwn_rates[IWN_RIDX_CCK1]; + linkq.retry[0].plcp = rinfo->plcp; + linkq.retry[0].rflags = rinfo->flags; + linkq.retry[0].rflags |= IWN_RFLAG_ANT(txant); + /* Use same bit-rate for all TX retries. */ + for (i = 1; i < IWN_MAX_TX_RETRIES; i++) { + linkq.retry[i].plcp = linkq.retry[0].plcp; + linkq.retry[i].rflags = linkq.retry[0].rflags; + } + return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async); } static int @@ -5010,6 +4993,10 @@ iwn_run(struct iwn_softc *sc, struct iee return error; } + /* Fake a join to initialize the TX rate. */ + ((struct iwn_node *)ni)->id = IWN_ID_BSS; + iwn_newassoc(ni, 1); + /* Add BSS node. */ memset(&node, 0, sizeof node); IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr); @@ -5027,7 +5014,7 @@ iwn_run(struct iwn_softc *sc, struct iee } DPRINTF(sc, IWN_DEBUG_STATE, "setting link quality for node %d\n", node.id); - error = iwn_set_link_quality(sc, node.id, 1); + error = iwn_set_link_quality(sc, ni); if (error != 0) { device_printf(sc->sc_dev, "%s: could not setup MRR for node %d, error %d\n", Modified: head/sys/dev/iwn/if_iwnreg.h ============================================================================== --- head/sys/dev/iwn/if_iwnreg.h Sat Apr 16 12:41:22 2011 (r220714) +++ head/sys/dev/iwn/if_iwnreg.h Sat Apr 16 12:42:54 2011 (r220715) @@ -1433,10 +1433,8 @@ static const struct iwn_chan_band { #define IWN6050_OTP_NBLOCKS 7 /* HW rate indices. */ -#define IWN_RIDX_CCK1 0 -#define IWN_RIDX_CCK11 3 -#define IWN_RIDX_OFDM6 4 -#define IWN_RIDX_OFDM54 11 +#define IWN_RIDX_CCK1 0 +#define IWN_RIDX_OFDM6 4 static const struct iwn_rate { uint8_t rate;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104161242.p3GCgsum005389>