Date: Fri, 29 May 2020 15:56:44 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r361626 - head/sys/dev/usb/wlan Message-ID: <202005291556.04TFuisS067773@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Fri May 29 15:56:44 2020 New Revision: 361626 URL: https://svnweb.freebsd.org/changeset/base/361626 Log: [run] Add initial 802.11n support. * Enable self-generated 11n frames * add MCS rates for 1-stream and 2-stream rates; will do 3-stream once the rest of this tests out OK with other people. * Hard-code 1 stream for now * Add A-MPDU RX mbuf tagging * RTS/CTS if doing RTSCTS in HT protmode as well as legacy; they're separate configuration flags * Update the amrr rate index stuff - walk the rates array like others to find the right one - this now works for MCS and CCK/OFDM rates * Add support for atheros fast frames/AMSDU support as we can generate those in net80211. TODO: * HT40 isn't enabled yet * No A-MPDU support just yet; that requires some more firmware research and maybe porting some ath(4) A-MPDU support/tracking into net80211 * Short preamble flags aren't set yet for MCS; need to check the linux driver and see what's going on there * Add 3x3 rates and set tx/rx stream configuration appropriately * More 5GHz testing; I have a 3x3 dual band USB NIC coming soon that'll let me test this. * Figure out why the RX path isn't performing as fast as it could - there's only a single buffer loaded at a time for the receive path in the USB bulk handler and this may not be super useful. Tested: * RT5390 usb, 1x1, RF5370 (2GHz radio), STA mode - A-MSDU TX, A-MPDU RX Submitted by: Ashish Gupta <ashishgu@andrew.cmu.edu> Differential Revision: https://reviews.freebsd.org/D22840 Modified: head/sys/dev/usb/wlan/if_run.c head/sys/dev/usb/wlan/if_runreg.h head/sys/dev/usb/wlan/if_runvar.h Modified: head/sys/dev/usb/wlan/if_run.c ============================================================================== --- head/sys/dev/usb/wlan/if_run.c Fri May 29 13:07:52 2020 (r361625) +++ head/sys/dev/usb/wlan/if_run.c Fri May 29 15:56:44 2020 (r361626) @@ -64,6 +64,9 @@ __FBSDID("$FreeBSD$"); #include <net80211/ieee80211_regdomain.h> #include <net80211/ieee80211_radiotap.h> #include <net80211/ieee80211_ratectl.h> +#ifdef IEEE80211_SUPPORT_SUPERG +#include <net80211/ieee80211_superg.h> +#endif #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> @@ -495,6 +498,9 @@ static void run_adjust_freq_offset(struct run_softc *) static void run_init_locked(struct run_softc *); static void run_stop(void *); static void run_delay(struct run_softc *, u_int); +static void run_update_chw(struct ieee80211com *ic); +static int run_ampdu_enable(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap); static eventhandler_tag run_etag; @@ -506,10 +512,13 @@ static const struct rt2860_rate { uint16_t sp_ack_dur; uint16_t lp_ack_dur; } rt2860_rates[] = { + /* CCK rates (11b) */ { 2, 0, IEEE80211_T_DS, 0, 314, 314 }, { 4, 1, IEEE80211_T_DS, 1, 258, 162 }, { 11, 2, IEEE80211_T_DS, 2, 223, 127 }, { 22, 3, IEEE80211_T_DS, 3, 213, 117 }, + + /* OFDM rates (11a / 11g) */ { 12, 0, IEEE80211_T_OFDM, 4, 60, 60 }, { 18, 1, IEEE80211_T_OFDM, 4, 52, 52 }, { 24, 2, IEEE80211_T_OFDM, 6, 48, 48 }, @@ -517,9 +526,35 @@ static const struct rt2860_rate { { 48, 4, IEEE80211_T_OFDM, 8, 44, 44 }, { 72, 5, IEEE80211_T_OFDM, 8, 40, 40 }, { 96, 6, IEEE80211_T_OFDM, 8, 40, 40 }, - { 108, 7, IEEE80211_T_OFDM, 8, 40, 40 } + { 108, 7, IEEE80211_T_OFDM, 8, 40, 40 }, + + /* MCS - single stream */ + { 0x80, 0, IEEE80211_T_HT, 4, 60, 60 }, + { 0x81, 1, IEEE80211_T_HT, 4, 60, 60 }, + { 0x82, 2, IEEE80211_T_HT, 4, 60, 60 }, + { 0x83, 3, IEEE80211_T_HT, 4, 60, 60 }, + { 0x84, 4, IEEE80211_T_HT, 4, 60, 60 }, + { 0x85, 5, IEEE80211_T_HT, 4, 60, 60 }, + { 0x86, 6, IEEE80211_T_HT, 4, 60, 60 }, + { 0x87, 7, IEEE80211_T_HT, 4, 60, 60 }, + /* MCS - 2 streams */ + { 0x88, 8, IEEE80211_T_HT, 4, 60, 60 }, + { 0x89, 9, IEEE80211_T_HT, 4, 60, 60 }, + { 0x8a, 10, IEEE80211_T_HT, 4, 60, 60 }, + { 0x8b, 11, IEEE80211_T_HT, 4, 60, 60 }, + { 0x8c, 12, IEEE80211_T_HT, 4, 60, 60 }, + { 0x8d, 13, IEEE80211_T_HT, 4, 60, 60 }, + { 0x8e, 14, IEEE80211_T_HT, 4, 60, 60 }, + { 0x8f, 15, IEEE80211_T_HT, 4, 60, 60 }, }; +/* These are indexes into the above rt2860_rates[] array */ +#define RT2860_RIDX_CCK1 0 +#define RT2860_RIDX_CCK11 3 +#define RT2860_RIDX_OFDM6 4 +#define RT2860_RIDX_MCS0 12 +#define RT2860_RIDX_MAX 28 + static const struct { uint16_t reg; uint32_t val; @@ -807,9 +842,25 @@ run_attach(device_t self) IEEE80211_C_MBSS | IEEE80211_C_SHPREAMBLE | /* short preamble supported */ IEEE80211_C_SHSLOT | /* short slot time supported */ + IEEE80211_C_SWAMSDUTX | /* Do software A-MSDU TX */ + IEEE80211_C_FF | /* Atheros fast-frames */ IEEE80211_C_WME | /* WME */ IEEE80211_C_WPA; /* WPA1|WPA2(RSN) */ + ic->ic_htcaps = + IEEE80211_HTC_HT | + IEEE80211_HTC_AMPDU | + IEEE80211_HTC_AMSDU | + IEEE80211_HTCAP_MAXAMSDU_3839 | + IEEE80211_HTCAP_SMPS_OFF; + + /* + * For now, just do 1 stream. Later on we'll figure out + * how many tx/rx streams a particular NIC supports. + */ + ic->ic_rxstream = 1; + ic->ic_txstream = 1; + ic->ic_cryptocaps = IEEE80211_CRYPTO_WEP | IEEE80211_CRYPTO_AES_CCM | @@ -839,6 +890,8 @@ run_attach(device_t self) ic->ic_vap_delete = run_vap_delete; ic->ic_transmit = run_transmit; ic->ic_parent = run_parent; + ic->ic_update_chw = run_update_chw; + ic->ic_ampdu_enable = run_ampdu_enable; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -974,6 +1027,10 @@ run_vap_create(struct ieee80211com *ic, const char nam vap->iv_update_beacon = run_update_beacon; vap->iv_max_aid = RT2870_WCID_MAX; + + vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K; + vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_2; + /* * To delete the right key from h/w, we need wcid. * Luckily, there is unused space in ieee80211_key{}, wk_pad, @@ -2059,11 +2116,13 @@ run_media_change(struct ifnet *ifp) struct ieee80211_node *ni; struct run_node *rn; + /* XXX TODO: methodize with MCS rates */ rate = ic->ic_sup_rates[ic->ic_curmode]. rs_rates[tp->ucastrate] & IEEE80211_RATE_VAL; for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) if (rt2860_rates[ridx].rate == rate) break; + ni = ieee80211_ref_node(vap->iv_bss); rn = RUN_NODE(ni); rn->fix_ridx = ridx; @@ -2605,7 +2664,7 @@ run_iter_func(void *arg, struct ieee80211_node *ni) struct run_node *rn = RUN_NODE(ni); union run_stats sta[2]; uint16_t (*wstat)[3]; - int error; + int error, ridx; RUN_LOCK(sc); @@ -2656,12 +2715,17 @@ run_iter_func(void *arg, struct ieee80211_node *ni) } ieee80211_ratectl_tx_update(vap, txs); - rn->amrr_ridx = ieee80211_ratectl_rate(ni, NULL, 0); + ieee80211_ratectl_rate(ni, NULL, 0); + /* XXX TODO: methodize with MCS rates */ + for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) + if (rt2860_rates[ridx].rate == ni->ni_txrate) + break; + rn->amrr_ridx = ridx; fail: RUN_UNLOCK(sc); - RUN_DPRINTF(sc, RUN_DEBUG_RATE, "ridx=%d\n", rn->amrr_ridx); + RUN_DPRINTF(sc, RUN_DEBUG_RATE, "rate=%d, ridx=%d\n", ni->ni_txrate, rn->amrr_ridx); } static void @@ -2684,14 +2748,12 @@ static void run_newassoc(struct ieee80211_node *ni, int isnew) { struct run_node *rn = RUN_NODE(ni); - struct ieee80211_rateset *rs = &ni->ni_rates; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = vap->iv_ic; struct run_softc *sc = ic->ic_softc; uint8_t rate; uint8_t ridx; uint8_t wcid; - int i, j; wcid = (vap->iv_opmode == IEEE80211_M_STA) ? 1 : RUN_AID2WCID(ni->ni_associd); @@ -2721,31 +2783,8 @@ run_newassoc(struct ieee80211_node *ni, int isnew) "new assoc isnew=%d associd=%x addr=%s\n", isnew, ni->ni_associd, ether_sprintf(ni->ni_macaddr)); - for (i = 0; i < rs->rs_nrates; i++) { - rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; - /* convert 802.11 rate to hardware rate index */ - for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) - if (rt2860_rates[ridx].rate == rate) - break; - rn->ridx[i] = ridx; - /* determine rate of control response frames */ - for (j = i; j >= 0; j--) { - if ((rs->rs_rates[j] & IEEE80211_RATE_BASIC) && - rt2860_rates[rn->ridx[i]].phy == - rt2860_rates[rn->ridx[j]].phy) - break; - } - if (j >= 0) { - rn->ctl_ridx[i] = rn->ridx[j]; - } else { - /* no basic rate found, use mandatory one */ - rn->ctl_ridx[i] = rt2860_rates[ridx].ctl_ridx; - } - RUN_DPRINTF(sc, RUN_DEBUG_STATE | RUN_DEBUG_RATE, - "rate=0x%02x ridx=%d ctl_ridx=%d\n", - rs->rs_rates[i], rn->ridx[i], rn->ctl_ridx[i]); - } rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate; + /* XXX TODO: methodize with MCS rates */ for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) if (rt2860_rates[ridx].rate == rate) break; @@ -2876,6 +2915,10 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uin } else ni = NULL; + if(ni && ni->ni_flags & IEEE80211_NODE_HT) { + m->m_flags |= M_AMPDU; + } + if (__predict_false(flags & RT2860_RX_MICERR)) { /* report MIC failures to net80211 for TKIP */ if (ni != NULL) @@ -3089,6 +3132,9 @@ tr_setup: /* make sure we free the source buffer, if any */ m_freem(m); +#ifdef IEEE80211_SUPPORT_SUPERG + ieee80211_ff_age_all(ic, 100); +#endif RUN_LOCK(sc); } @@ -3234,6 +3280,15 @@ tr_setup: } break; } +#ifdef IEEE80211_SUPPORT_SUPERG + /* XXX TODO: make this deferred rather than unlock/relock */ + /* XXX TODO: should only do the QoS AC this belongs to */ + if (pq->tx_nfree >= RUN_TX_RING_COUNT) { + RUN_UNLOCK(sc); + ieee80211_ff_flush_all(ic); + RUN_LOCK(sc); + } +#endif } static void @@ -3318,15 +3373,21 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_da if (ridx != RT2860_RIDX_CCK1 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) mcs |= RT2860_PHY_SHPRE; - } else + } else if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM) { mcs |= RT2860_PHY_OFDM; + } else if (rt2860_rates[ridx].phy == IEEE80211_T_HT) { + /* XXX TODO: [adrian] set short preamble for MCS? */ + mcs |= RT2860_PHY_HT; /* Mixed, not greenfield */ + } txwi->phy = htole16(mcs); /* check if RTS/CTS or CTS-to-self protection is required */ if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold || + ((m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) || ((ic->ic_flags & IEEE80211_F_USEPROT) && - rt2860_rates[ridx].phy == IEEE80211_T_OFDM))) + rt2860_rates[ridx].phy == IEEE80211_T_OFDM) || + ((ic->ic_htprotmode == IEEE80211_PROT_RTSCTS) && + rt2860_rates[ridx].phy == IEEE80211_T_HT))) txwi->txop |= RT2860_TX_TXOP_HT; else txwi->txop |= RT2860_TX_TXOP_BACKOFF; @@ -3390,7 +3451,8 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ie /* pickup a rate index */ if (IEEE80211_IS_MULTICAST(wh->i_addr1) || type != IEEE80211_FC0_TYPE_DATA || m->m_flags & M_EAPOL) { - ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? + /* XXX TODO: methodize for 11n; use MCS0 for 11NA/11NG */ + ridx = (ic->ic_curmode == IEEE80211_MODE_11A || ic->ic_curmode == IEEE80211_MODE_11NA) ? RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1; ctl_ridx = rt2860_rates[ridx].ctl_ridx; } else { @@ -3609,6 +3671,7 @@ run_sendprot(struct run_softc *sc, data->m = mprot; data->ni = ieee80211_ref_node(ni); + /* XXX TODO: methodize with MCS rates */ for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) if (rt2860_rates[ridx].rate == protrate) break; @@ -3684,6 +3747,7 @@ run_tx_param(struct run_softc *sc, struct mbuf *m, str data->m = m; data->ni = ni; + /* XXX TODO: methodize with MCS rates */ for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++) if (rt2860_rates[ridx].rate == rate) break; @@ -4856,12 +4920,17 @@ run_getradiocaps(struct ieee80211com *ic, memset(bands, 0, sizeof(bands)); setbit(bands, IEEE80211_MODE_11B); setbit(bands, IEEE80211_MODE_11G); + setbit(bands, IEEE80211_MODE_11NG); + + /* Note: for now, only support HT20 channels */ ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, bands, 0); if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850 || sc->rf_rev == RT3070_RF_3052 || sc->rf_rev == RT3593_RF_3053 || sc->rf_rev == RT5592_RF_5592) { setbit(bands, IEEE80211_MODE_11A); + setbit(bands, IEEE80211_MODE_11NA); + /* Note: for now, only support HT20 channels */ ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, run_chan_5ghz, nitems(run_chan_5ghz), bands, 0); } @@ -6205,6 +6274,10 @@ run_init_locked(struct run_softc *sc) /* turn radio LED on */ run_set_leds(sc, RT2860_LED_RADIO); + /* Set up AUTO_RSP_CFG register for auto response */ + run_write(sc, RT2860_AUTO_RSP_CFG, RT2860_AUTO_RSP_EN | + RT2860_BAC_ACKPOLICY_EN | RT2860_CTS_40M_MODE_EN); + sc->sc_flags |= RUN_RUNNING; sc->cmdq_run = RUN_CMDQ_GO; @@ -6309,6 +6382,22 @@ run_delay(struct run_softc *sc, u_int ms) { usb_pause_mtx(mtx_owned(&sc->sc_mtx) ? &sc->sc_mtx : NULL, USB_MS_TO_TICKS(ms)); +} + + +static void +run_update_chw(struct ieee80211com *ic) +{ + + printf("%s: TODO\n", __func__); +} + +static int +run_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) +{ + + /* For now, no A-MPDU TX support in the driver */ + return (0); } static device_method_t run_methods[] = { Modified: head/sys/dev/usb/wlan/if_runreg.h ============================================================================== --- head/sys/dev/usb/wlan/if_runreg.h Fri May 29 13:07:52 2020 (r361625) +++ head/sys/dev/usb/wlan/if_runreg.h Fri May 29 15:56:44 2020 (r361626) @@ -955,11 +955,6 @@ struct rt2860_rxwi { #define RT5390_EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5GHZ 0x14e #define RT5390_EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5GHZ 0x14f -#define RT2860_RIDX_CCK1 0 -#define RT2860_RIDX_CCK11 3 -#define RT2860_RIDX_OFDM6 4 -#define RT2860_RIDX_MAX 12 - /* * EEPROM access macro. */ Modified: head/sys/dev/usb/wlan/if_runvar.h ============================================================================== --- head/sys/dev/usb/wlan/if_runvar.h Fri May 29 13:07:52 2020 (r361625) +++ head/sys/dev/usb/wlan/if_runvar.h Fri May 29 15:56:44 2020 (r361626) @@ -97,8 +97,6 @@ STAILQ_HEAD(run_tx_data_head, run_tx_data); struct run_node { struct ieee80211_node ni; - uint8_t ridx[IEEE80211_RATE_MAXSIZE]; - uint8_t ctl_ridx[IEEE80211_RATE_MAXSIZE]; uint8_t amrr_ridx; uint8_t mgt_ridx; uint8_t fix_ridx;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005291556.04TFuisS067773>