Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 May 2011 11:58:23 +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: r221650 - head/sys/dev/iwn
Message-ID:  <201105081158.p48BwNdC044852@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Sun May  8 11:58:23 2011
New Revision: 221650
URL: http://svn.freebsd.org/changeset/base/221650

Log:
  Add support for RX packet aggregation.

Modified:
  head/sys/dev/iwn/if_iwn.c
  head/sys/dev/iwn/if_iwnvar.h

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c	Sun May  8 11:54:38 2011	(r221649)
+++ head/sys/dev/iwn/if_iwn.c	Sun May  8 11:58:23 2011	(r221650)
@@ -251,11 +251,11 @@ static uint8_t	*ieee80211_add_ssid(uint8
 static int	iwn_scan(struct iwn_softc *);
 static int	iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
 static int	iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
+static int	iwn_ampdu_rx_start(struct ieee80211_node *,
+		    struct ieee80211_rx_ampdu *, int, int, int);
+static void	iwn_ampdu_rx_stop(struct ieee80211_node *,
+		    struct ieee80211_rx_ampdu *);
 #if 0	/* HT */
-static int	iwn_ampdu_rx_start(struct ieee80211com *,
-		    struct ieee80211_node *, uint8_t);
-static void	iwn_ampdu_rx_stop(struct ieee80211com *,
-		    struct ieee80211_node *, uint8_t);
 static int	iwn_ampdu_tx_start(struct ieee80211com *,
 		    struct ieee80211_node *, uint8_t);
 static void	iwn_ampdu_tx_stop(struct ieee80211com *,
@@ -653,9 +653,11 @@ 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;
-#if 0	/* HT */
+	sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
 	ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
+	sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
 	ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
+#if 0	/* HT */
 	ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
 	ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
 #endif
@@ -2434,6 +2436,8 @@ iwn_rx_done(struct iwn_softc *sc, struct
 
 	/* Send the frame to the 802.11 layer. */
 	if (ni != NULL) {
+		if (ni->ni_flags & IEEE80211_NODE_HT)
+			m->m_flags |= M_AMPDU;
 		(void)ieee80211_input(ni, m, rssi - nf, nf);
 		/* Node is no longer needed. */
 		ieee80211_free_node(ni);
@@ -3765,7 +3769,8 @@ iwn_cmd(struct iwn_softc *sc, int code, 
 	bus_addr_t paddr;
 	int totlen, error;
 
-	IWN_LOCK_ASSERT(sc);
+	if (async == 0)
+		IWN_LOCK_ASSERT(sc);
 
 	desc = &ring->desc[ring->cur];
 	data = &ring->data[ring->cur];
@@ -5321,30 +5326,39 @@ iwn_run(struct iwn_softc *sc, struct iee
 #undef MS
 }
 
-#if 0	/* HT */
 /*
  * This function is called by upper layer when an ADDBA request is received
  * from another STA and before the ADDBA response is sent.
  */
 static int
-iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
-    uint8_t tid)
+iwn_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
+    int baparamset, int batimeout, int baseqctl)
 {
-	struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
-	struct iwn_softc *sc = ic->ic_softc;
+#define MS(_v, _f)	(((_v) & _f) >> _f##_S)
+	struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
 	struct iwn_ops *ops = &sc->ops;
 	struct iwn_node *wn = (void *)ni;
 	struct iwn_node_info node;
+	uint16_t ssn;
+	uint8_t tid;
+	int error;
+
+	tid = MS(le16toh(baparamset), IEEE80211_BAPS_TID);
+	ssn = MS(le16toh(baseqctl), IEEE80211_BASEQ_START);
 
 	memset(&node, 0, sizeof node);
 	node.id = wn->id;
 	node.control = IWN_NODE_UPDATE;
 	node.flags = IWN_FLAG_SET_ADDBA;
 	node.addba_tid = tid;
-	node.addba_ssn = htole16(ba->ba_winstart);
+	node.addba_ssn = htole16(ssn);
 	DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
-	    wn->id, tid, ba->ba_winstart);
-	return ops->add_node(sc, &node, 1);
+	    wn->id, tid, ssn);
+	error = ops->add_node(sc, &node, 1);
+	if (error != 0)
+		return error;
+	return sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
+#undef MS
 }
 
 /*
@@ -5352,13 +5366,20 @@ iwn_ampdu_rx_start(struct ieee80211com *
  * Block Ack agreement (eg. uppon receipt of a DELBA frame).
  */
 static void
-iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
-    uint8_t tid)
+iwn_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
 {
-	struct iwn_softc *sc = ic->ic_softc;
+	struct ieee80211com *ic = ni->ni_ic;
+	struct iwn_softc *sc = ic->ic_ifp->if_softc;
 	struct iwn_ops *ops = &sc->ops;
 	struct iwn_node *wn = (void *)ni;
 	struct iwn_node_info node;
+	uint8_t tid;
+
+	/* XXX: tid as an argument */
+	for (tid = 0; tid < WME_NUM_TID; tid++) {
+		if (&ni->ni_rx_ampdu[tid] == rap)
+			break;
+	}
 
 	memset(&node, 0, sizeof node);
 	node.id = wn->id;
@@ -5367,8 +5388,10 @@ iwn_ampdu_rx_stop(struct ieee80211com *i
 	node.delba_tid = tid;
 	DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
 	(void)ops->add_node(sc, &node, 1);
+	sc->sc_ampdu_rx_stop(ni, rap);
 }
 
+#if 0 /* HT */
 /*
  * This function is called by upper layer when an ADDBA response is received
  * from another STA.

Modified: head/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- head/sys/dev/iwn/if_iwnvar.h	Sun May  8 11:54:38 2011	(r221649)
+++ head/sys/dev/iwn/if_iwnvar.h	Sun May  8 11:58:23 2011	(r221650)
@@ -306,6 +306,11 @@ struct iwn_softc {
 
 	int			sc_tx_timer;
 
+	int			(*sc_ampdu_rx_start)(struct ieee80211_node *,
+				    struct ieee80211_rx_ampdu *, int, int, int);
+	void			(*sc_ampdu_rx_stop)(struct ieee80211_node *,
+				    struct ieee80211_rx_ampdu *);
+
 	struct iwn_rx_radiotap_header sc_rxtap;
 	struct iwn_tx_radiotap_header sc_txtap;
 };



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