svn commit: r292014 - head/sys/dev/usb/wlan

Andriy Voskoboinyk avos at FreeBSD.org
Wed Dec 9 09:29:40 UTC 2015


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


More information about the svn-src-head mailing list