Date: Wed, 9 Dec 2015 09:29:38 +0000 (UTC) From: Andriy Voskoboinyk <avos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r292014 - head/sys/dev/usb/wlan Message-ID: <201512090929.tB99Tc0E010380@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avos Date: Wed Dec 9 09:29:38 2015 New Revision: 292014 URL: https://svnweb.freebsd.org/changeset/base/292014 Log: urtwn: add WME support Tested with: - RTL8188CUS, HOSTAP mode. - RTL8188EU, STA mode. Reviewed by: kevlo Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D4020 Modified: head/sys/dev/usb/wlan/if_urtwn.c head/sys/dev/usb/wlan/if_urtwnreg.h head/sys/dev/usb/wlan/if_urtwnvar.h Modified: head/sys/dev/usb/wlan/if_urtwn.c ============================================================================== --- head/sys/dev/usb/wlan/if_urtwn.c Wed Dec 9 09:14:57 2015 (r292013) +++ head/sys/dev/usb/wlan/if_urtwn.c Wed Dec 9 09:29:38 2015 (r292014) @@ -291,6 +291,7 @@ static void urtwn_set_gain(struct urtwn static void urtwn_scan_start(struct ieee80211com *); static void urtwn_scan_end(struct ieee80211com *); static void urtwn_set_channel(struct ieee80211com *); +static int urtwn_wme_update(struct ieee80211com *); static void urtwn_set_promisc(struct urtwn_softc *); static void urtwn_update_promisc(struct ieee80211com *); static void urtwn_update_mcast(struct ieee80211com *); @@ -376,6 +377,16 @@ static const struct usb_config urtwn_con }, }; +static const struct wme_to_queue { + uint16_t reg; + uint8_t qid; +} wme2queue[WME_NUM_AC] = { + { R92C_EDCA_BE_PARAM, URTWN_BULK_TX_BE}, + { R92C_EDCA_BK_PARAM, URTWN_BULK_TX_BK}, + { R92C_EDCA_VI_PARAM, URTWN_BULK_TX_VI}, + { R92C_EDCA_VO_PARAM, URTWN_BULK_TX_VO} +}; + static int urtwn_match(device_t self) { @@ -473,6 +484,7 @@ urtwn_attach(device_t self) | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_BGSCAN /* capable of bg scanning */ | IEEE80211_C_WPA /* 802.11i */ + | IEEE80211_C_WME /* 802.11e */ ; bands = 0; @@ -489,6 +501,7 @@ urtwn_attach(device_t self) ic->ic_parent = urtwn_parent; ic->ic_vap_create = urtwn_vap_create; ic->ic_vap_delete = urtwn_vap_delete; + ic->ic_wme.wme_update = urtwn_wme_update; ic->ic_update_promisc = urtwn_update_promisc; ic->ic_update_mcast = urtwn_update_mcast; @@ -2158,8 +2171,8 @@ urtwn_tx_data(struct urtwn_softc *sc, st struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct r92c_tx_desc *txd; - uint8_t macid, raid, ridx, subtype, type, qsel; - int ismcast; + uint8_t macid, raid, ridx, subtype, type, tid, qsel; + int hasqos, ismcast; URTWN_ASSERT_LOCKED(sc); @@ -2169,8 +2182,16 @@ urtwn_tx_data(struct urtwn_softc *sc, st wh = mtod(m, struct ieee80211_frame *); type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; + hasqos = IEEE80211_QOS_HAS_SEQ(wh); ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); + /* Select TX ring for this frame. */ + if (hasqos) { + tid = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; + tid &= IEEE80211_QOS_TID; + } else + tid = 0; + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m); if (k == NULL) { @@ -2199,7 +2220,7 @@ urtwn_tx_data(struct urtwn_softc *sc, st macid = URTWN_MACID_BSS; if (type == IEEE80211_FC0_TYPE_DATA) { - qsel = R92C_TXDW1_QSEL_BE; + qsel = tid % URTWN_MAX_TID; if (!(m->m_flags & M_EAPOL)) { if (ic->ic_curmode != IEEE80211_MODE_11B) { @@ -2255,7 +2276,7 @@ urtwn_tx_data(struct urtwn_softc *sc, st (m->m_flags & M_EAPOL)) txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE); - if (!IEEE80211_QOS_HAS_SEQ(wh)) { + if (!hasqos) { /* Use HW sequence numbering for non-QoS frames. */ if (sc->chip & URTWN_CHIP_88E) txd->txdseq = htole16(R88E_TXDSEQ_HWSEQ_EN); @@ -2292,12 +2313,6 @@ urtwn_tx_start(struct urtwn_softc *sc, s struct r92c_tx_desc *txd; uint16_t ac, sum; int i, xferlen; - struct usb_xfer *urtwn_pipes[WME_NUM_AC] = { - sc->sc_xfer[URTWN_BULK_TX_BE], - sc->sc_xfer[URTWN_BULK_TX_BK], - sc->sc_xfer[URTWN_BULK_TX_VI], - sc->sc_xfer[URTWN_BULK_TX_VO] - }; URTWN_ASSERT_LOCKED(sc); @@ -2309,7 +2324,7 @@ urtwn_tx_start(struct urtwn_softc *sc, s xfer = sc->sc_xfer[URTWN_BULK_TX_VO]; break; default: - xfer = urtwn_pipes[ac]; + xfer = sc->sc_xfer[wme2queue[ac].qid]; break; } @@ -3598,6 +3613,43 @@ urtwn_set_channel(struct ieee80211com *i URTWN_UNLOCK(sc); } +static int +urtwn_wme_update(struct ieee80211com *ic) +{ + const struct wmeParams *wmep = + ic->ic_wme.wme_chanParams.cap_wmeParams; + struct urtwn_softc *sc = ic->ic_softc; + uint8_t aifs, acm, slottime; + int ac; + + acm = 0; + slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? + IEEE80211_DUR_SHSLOT : IEEE80211_DUR_SLOT; + + URTWN_LOCK(sc); + for (ac = WME_AC_BE; ac < WME_NUM_AC; ac++) { + /* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */ + aifs = wmep[ac].wmep_aifsn * slottime + IEEE80211_DUR_SIFS; + urtwn_write_4(sc, wme2queue[ac].reg, + SM(R92C_EDCA_PARAM_TXOP, wmep[ac].wmep_txopLimit) | + SM(R92C_EDCA_PARAM_ECWMIN, wmep[ac].wmep_logcwmin) | + SM(R92C_EDCA_PARAM_ECWMAX, wmep[ac].wmep_logcwmax) | + SM(R92C_EDCA_PARAM_AIFS, aifs)); + if (ac != WME_AC_BE) + acm |= wmep[ac].wmep_acm << ac; + } + + if (acm != 0) + acm |= R92C_ACMHWCTRL_EN; + urtwn_write_1(sc, R92C_ACMHWCTRL, + (urtwn_read_1(sc, R92C_ACMHWCTRL) & ~R92C_ACMHWCTRL_ACM_MASK) | + acm); + + URTWN_UNLOCK(sc); + + return 0; +} + static void urtwn_set_promisc(struct urtwn_softc *sc) { Modified: head/sys/dev/usb/wlan/if_urtwnreg.h ============================================================================== --- head/sys/dev/usb/wlan/if_urtwnreg.h Wed Dec 9 09:14:57 2015 (r292013) +++ head/sys/dev/usb/wlan/if_urtwnreg.h Wed Dec 9 09:29:38 2015 (r292014) @@ -503,6 +503,13 @@ #define R92C_DUAL_TSF_RST0 0x01 #define R92C_DUAL_TSF_RST1 0x02 +/* Bits for R92C_ACMHWCTRL. */ +#define R92C_ACMHWCTRL_EN 0x01 +#define R92C_ACMHWCTRL_BE 0x02 +#define R92C_ACMHWCTRL_VI 0x04 +#define R92C_ACMHWCTRL_VO 0x08 +#define R92C_ACMHWCTRL_ACM_MASK 0x0f + /* Bits for R92C_APSD_CTRL. */ #define R92C_APSD_CTRL_OFF 0x40 #define R92C_APSD_CTRL_OFF_STATUS 0x80 Modified: head/sys/dev/usb/wlan/if_urtwnvar.h ============================================================================== --- head/sys/dev/usb/wlan/if_urtwnvar.h Wed Dec 9 09:14:57 2015 (r292013) +++ head/sys/dev/usb/wlan/if_urtwnvar.h Wed Dec 9 09:29:38 2015 (r292014) @@ -140,7 +140,6 @@ struct urtwn_softc { struct usb_device *sc_udev; uint8_t sc_iface_index; - int ac2idx[WME_NUM_AC]; u_int sc_flags; #define URTWN_FLAG_CCK_HIPWR 0x01 #define URTWN_DETACHED 0x02
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512090929.tB99Tc0E010380>