Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Oct 2015 22:35:38 +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: r288642 - head/sys/dev/usb/wlan
Message-ID:  <201510032235.t93MZcB8051503@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sat Oct  3 22:35:37 2015
New Revision: 288642
URL: https://svnweb.freebsd.org/changeset/base/288642

Log:
  rum(4): add WME support.
  
  Tested:
  
  * WUSB54GC, HOSTAP and STA modes.
  * Me: rum0: MAC/BBP RT2573 (rev 0x2573a), RF RT2528
  
  Submitted by:	<s3erios@gmail.com>
  Differential Revision:	https://reviews.freebsd.org/D3700

Modified:
  head/sys/dev/usb/wlan/if_rum.c
  head/sys/dev/usb/wlan/if_rumreg.h
  head/sys/dev/usb/wlan/if_rumvar.h

Modified: head/sys/dev/usb/wlan/if_rum.c
==============================================================================
--- head/sys/dev/usb/wlan/if_rum.c	Sat Oct  3 22:33:45 2015	(r288641)
+++ head/sys/dev/usb/wlan/if_rum.c	Sat Oct  3 22:35:37 2015	(r288642)
@@ -169,7 +169,7 @@ static int		rum_newstate(struct ieee8021
 static uint8_t		rum_crypto_mode(struct rum_softc *, u_int, int);
 static void		rum_setup_tx_desc(struct rum_softc *,
 			    struct rum_tx_desc *, struct ieee80211_key *,
-			    uint32_t, uint8_t, int, int, int);
+			    uint32_t, uint8_t, uint8_t, int, int, int);
 static uint32_t		rum_tx_crypto_flags(struct rum_softc *,
 			    struct ieee80211_node *,
 			    const struct ieee80211_key *);
@@ -216,6 +216,9 @@ static void		rum_get_tsf(struct rum_soft
 static void		rum_update_slot_cb(struct rum_softc *,
 			    union sec_param *, uint8_t);
 static void		rum_update_slot(struct ieee80211com *);
+static void		rum_wme_update_cb(struct rum_softc *,
+			    union sec_param *, uint8_t);
+static int		rum_wme_update(struct ieee80211com *);
 static void		rum_set_bssid(struct rum_softc *, const uint8_t *);
 static void		rum_set_macaddr(struct rum_softc *, const uint8_t *);
 static void		rum_update_mcast(struct ieee80211com *);
@@ -526,6 +529,7 @@ rum_attach(device_t self)
 	    | IEEE80211_C_SHSLOT	/* short slot time supported */
 	    | IEEE80211_C_BGSCAN	/* bg scanning supported */
 	    | IEEE80211_C_WPA		/* 802.11i */
+	    | IEEE80211_C_WME		/* 802.11e */
 	    ;
 
 	ic->ic_cryptocaps =
@@ -552,6 +556,7 @@ rum_attach(device_t self)
 	ic->ic_vap_create = rum_vap_create;
 	ic->ic_vap_delete = rum_vap_delete;
 	ic->ic_updateslot = rum_update_slot;
+	ic->ic_wme.wme_update = rum_wme_update;
 	ic->ic_update_mcast = rum_update_mcast;
 
 	ieee80211_radiotap_attach(ic,
@@ -1139,10 +1144,11 @@ rum_crypto_mode(struct rum_softc *sc, u_
 
 static void
 rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
-    struct ieee80211_key *k, uint32_t flags, uint8_t xflags, int hdrlen,
-    int len, int rate)
+    struct ieee80211_key *k, uint32_t flags, uint8_t xflags, uint8_t qid,
+    int hdrlen, int len, int rate)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
+	struct wmeParams *wmep = &sc->wme_params[qid];
 	uint16_t plcp_length;
 	int remainder;
 
@@ -1189,8 +1195,10 @@ rum_setup_tx_desc(struct rum_softc *sc, 
 	desc->hdrlen = hdrlen;
 	desc->xflags = xflags;
 
-	desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
-	    RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
+	desc->wme = htole16(RT2573_QID(qid) |
+	    RT2573_AIFSN(wmep->wmep_aifsn) |
+	    RT2573_LOGCWMIN(wmep->wmep_logcwmin) |
+	    RT2573_LOGCWMAX(wmep->wmep_logcwmax));
 }
 
 static int
@@ -1236,7 +1244,7 @@ rum_sendprot(struct rum_softc *sc,
 	data->m = mprot;
 	data->ni = ieee80211_ref_node(ni);
 	data->rate = protrate;
-	rum_setup_tx_desc(sc, &data->desc, NULL, flags, 0, 0,
+	rum_setup_tx_desc(sc, &data->desc, NULL, flags, 0, 0, 0,
 	    mprot->m_pkthdr.len, protrate);
 
 	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
@@ -1290,7 +1298,7 @@ rum_tx_mgt(struct rum_softc *sc, struct 
 	struct ieee80211_key *k = NULL;
 	uint32_t flags = 0;
 	uint16_t dur;
-	uint8_t type, xflags = 0;
+	uint8_t ac, type, xflags = 0;
 	int hdrlen;
 
 	RUM_LOCK_ASSERT(sc);
@@ -1302,6 +1310,7 @@ rum_tx_mgt(struct rum_softc *sc, struct 
 	wh = mtod(m0, struct ieee80211_frame *);
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 	hdrlen = ieee80211_anyhdrsize(wh);
+	ac = M_WME_GETAC(m0);
 
 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
 		k = ieee80211_crypto_get_txkey(ni, m0);
@@ -1341,7 +1350,7 @@ rum_tx_mgt(struct rum_softc *sc, struct 
 	data->ni = ni;
 	data->rate = tp->mgmtrate;
 
-	rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, hdrlen,
+	rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, ac, hdrlen,
 	    m0->m_pkthdr.len, tp->mgmtrate);
 
 	DPRINTFN(10, "sending mgt frame len=%d rate=%d\n",
@@ -1361,7 +1370,7 @@ rum_tx_raw(struct rum_softc *sc, struct 
 	struct ieee80211_frame *wh;
 	struct rum_tx_data *data;
 	uint32_t flags;
-	uint8_t type, xflags = 0;
+	uint8_t ac, type, xflags = 0;
 	int rate, error;
 
 	RUM_LOCK_ASSERT(sc);
@@ -1369,6 +1378,8 @@ rum_tx_raw(struct rum_softc *sc, struct 
 	wh = mtod(m0, struct ieee80211_frame *);
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 
+	ac = params->ibp_pri & 3;
+
 	rate = params->ibp_rate0;
 	if (!ieee80211_isratevalid(ic->ic_rt, rate))
 		return (EINVAL);
@@ -1399,7 +1410,7 @@ rum_tx_raw(struct rum_softc *sc, struct 
 	data->rate = rate;
 
 	/* XXX need to setup descriptor ourself */
-	rum_setup_tx_desc(sc, &data->desc, NULL, flags, xflags, 0,
+	rum_setup_tx_desc(sc, &data->desc, NULL, flags, xflags, ac, 0,
 	    m0->m_pkthdr.len, rate);
 
 	DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
@@ -1422,7 +1433,7 @@ rum_tx_data(struct rum_softc *sc, struct
 	struct ieee80211_key *k = NULL;
 	uint32_t flags = 0;
 	uint16_t dur;
-	uint8_t type, xflags = 0;
+	uint8_t ac, type, qos, xflags = 0;
 	int error, hdrlen, rate;
 
 	RUM_LOCK_ASSERT(sc);
@@ -1431,6 +1442,12 @@ rum_tx_data(struct rum_softc *sc, struct
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 	hdrlen = ieee80211_anyhdrsize(wh);
 
+	if (IEEE80211_QOS_HAS_SEQ(wh))
+		qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
+	else
+		qos = 0;
+	ac = M_WME_GETAC(m0);
+
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
 		rate = tp->mcastrate;
@@ -1487,14 +1504,17 @@ rum_tx_data(struct rum_softc *sc, struct
 	data->rate = rate;
 
 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-		flags |= RT2573_TX_NEED_ACK;
+		/* Unicast frame, check if an ACK is expected. */
+		if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) !=
+		    IEEE80211_QOS_ACKPOLICY_NOACK)
+			flags |= RT2573_TX_NEED_ACK;
 
-		dur = ieee80211_ack_duration(ic->ic_rt, rate, 
+		dur = ieee80211_ack_duration(ic->ic_rt, rate,
 		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
 		USETW(wh->i_dur, dur);
 	}
 
-	rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, hdrlen,
+	rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, ac, hdrlen,
 	    m0->m_pkthdr.len, rate);
 
 	DPRINTFN(10, "sending frame len=%d rate=%d\n",
@@ -2064,6 +2084,65 @@ rum_update_slot(struct ieee80211com *ic)
 }
 
 static void
+rum_wme_update_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id)
+{
+	const struct wmeParams (*chanp)[WME_NUM_AC] = &data->wme_params;
+	int error = 0;
+
+	error = rum_write(sc, RT2573_AIFSN_CSR,
+	    chanp[WME_AC_VO]->wmep_aifsn  << 12 |
+	    chanp[WME_AC_VI]->wmep_aifsn  <<  8 |
+	    chanp[WME_AC_BK]->wmep_aifsn  <<  4 |
+	    chanp[WME_AC_BE]->wmep_aifsn);
+	if (error)
+		goto print_err;
+	error = rum_write(sc, RT2573_CWMIN_CSR,
+	    chanp[WME_AC_VO]->wmep_logcwmin << 12 |
+	    chanp[WME_AC_VI]->wmep_logcwmin <<  8 |
+	    chanp[WME_AC_BK]->wmep_logcwmin <<  4 |
+	    chanp[WME_AC_BE]->wmep_logcwmin);
+	if (error)
+		goto print_err;
+	error = rum_write(sc, RT2573_CWMAX_CSR,
+	    chanp[WME_AC_VO]->wmep_logcwmax << 12 |
+	    chanp[WME_AC_VI]->wmep_logcwmax <<  8 |
+	    chanp[WME_AC_BK]->wmep_logcwmax <<  4 |
+	    chanp[WME_AC_BE]->wmep_logcwmax);
+	if (error)
+		goto print_err;
+	error = rum_write(sc, RT2573_TXOP01_CSR,
+	    chanp[WME_AC_BK]->wmep_txopLimit << 16 |
+	    chanp[WME_AC_BE]->wmep_txopLimit);
+	if (error)
+		goto print_err;
+	error = rum_write(sc, RT2573_TXOP23_CSR,
+	    chanp[WME_AC_VO]->wmep_txopLimit << 16 |
+	    chanp[WME_AC_VI]->wmep_txopLimit);
+	if (error)
+		goto print_err;
+
+	memcpy(sc->wme_params, chanp, sizeof(*chanp) * WME_NUM_AC);
+
+	return;
+
+print_err:
+	device_printf(sc->sc_dev, "%s: WME update failed, error %d\n",
+	    __func__, error);
+}
+
+static int
+rum_wme_update(struct ieee80211com *ic)
+{
+	struct rum_softc *sc = ic->ic_softc;
+	const struct wmeParams (*chanp)[WME_NUM_AC] =
+	   &ic->ic_wme.wme_chanParams.cap_wmeParams;
+
+	rum_cmd_sleepable(sc, chanp, sizeof (*chanp), 0, rum_wme_update_cb);
+
+	return (0);
+}
+
+static void
 rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
 {
 
@@ -2288,6 +2367,11 @@ rum_init(struct rum_softc *sc)
 	for (i = 0; i < nitems(rum_def_mac); i++)
 		rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
 
+	/* reset some WME parameters to default values */
+	sc->wme_params[0].wmep_aifsn = 2;
+	sc->wme_params[0].wmep_logcwmin = 4;
+	sc->wme_params[0].wmep_logcwmax = 10;
+
 	/* set host ready */
 	rum_write(sc, RT2573_MAC_CSR1, RT2573_RESET_ASIC | RT2573_RESET_BBP);
 	rum_write(sc, RT2573_MAC_CSR1, 0);
@@ -2431,7 +2515,7 @@ rum_set_beacon(struct rum_softc *sc, str
 
 	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
 	rum_setup_tx_desc(sc, &desc, NULL, RT2573_TX_TIMESTAMP,
-	    RT2573_TX_HWSEQ, 0, m->m_pkthdr.len, tp->mgmtrate);
+	    RT2573_TX_HWSEQ, 0, 0, m->m_pkthdr.len, tp->mgmtrate);
 
 	/* copy the Tx descriptor into NIC memory */
 	if (rum_write_multi(sc, RT2573_HW_BCN_BASE(0), (uint8_t *)&desc,

Modified: head/sys/dev/usb/wlan/if_rumreg.h
==============================================================================
--- head/sys/dev/usb/wlan/if_rumreg.h	Sat Oct  3 22:33:45 2015	(r288641)
+++ head/sys/dev/usb/wlan/if_rumreg.h	Sat Oct  3 22:35:37 2015	(r288642)
@@ -39,6 +39,8 @@
 #define RT2573_AIFSN_CSR	0x0400
 #define RT2573_CWMIN_CSR	0x0404
 #define RT2573_CWMAX_CSR	0x0408
+#define RT2573_TXOP01_CSR	0x040C
+#define RT2573_TXOP23_CSR	0x0410
 #define RT2573_MCU_CODE_BASE	0x0800
 
 /*

Modified: head/sys/dev/usb/wlan/if_rumvar.h
==============================================================================
--- head/sys/dev/usb/wlan/if_rumvar.h	Sat Oct  3 22:33:45 2015	(r288641)
+++ head/sys/dev/usb/wlan/if_rumvar.h	Sat Oct  3 22:35:37 2015	(r288642)
@@ -73,6 +73,7 @@ typedef STAILQ_HEAD(, rum_tx_data) rum_t
 
 union sec_param {
 	struct ieee80211_key		key;
+	struct wmeParams		wme_params[WME_NUM_AC];
 	uint8_t				macaddr[IEEE80211_ADDR_LEN];
 	struct ieee80211vap		*vap;
 };
@@ -138,6 +139,7 @@ struct rum_softc {
 					sc_clr_shkeys:1;
 
 	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
+	struct wmeParams		wme_params[WME_NUM_AC];
 
 	uint8_t				vap_key_count[1];
 	uint64_t			keys_bmap;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510032235.t93MZcB8051503>