svn commit: r247529 - user/adrian/net80211_tx/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Fri Mar 1 04:51:45 UTC 2013


Author: adrian
Date: Fri Mar  1 04:51:44 2013
New Revision: 247529
URL: http://svnweb.freebsd.org/changeset/base/247529

Log:
  Defer the main frame TX through a per-vap task.
  
  The task runs in the ieee80211com task, so vaps are still serialised with
  each other as well as the rest of the ic state.
  
  This doesn't serialise the raw xmit path or any of the raw xmit state setup.
  It also doesn't touch the other paths (fast frames deferred handling/flush;
  ageq and power save handling; mesh TX handling.)  These will come next.
  
  Tested:
  
  * AR5416, STA mode
  * AR9280, STA mode

Modified:
  user/adrian/net80211_tx/sys/net80211/ieee80211.c
  user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c
  user/adrian/net80211_tx/sys/net80211/ieee80211_output.c
  user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c
  user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h
  user/adrian/net80211_tx/sys/net80211/ieee80211_var.h

Modified: user/adrian/net80211_tx/sys/net80211/ieee80211.c
==============================================================================
--- user/adrian/net80211_tx/sys/net80211/ieee80211.c	Fri Mar  1 04:21:22 2013	(r247528)
+++ user/adrian/net80211_tx/sys/net80211/ieee80211.c	Fri Mar  1 04:51:44 2013	(r247529)
@@ -427,7 +427,8 @@ ieee80211_vap_setup(struct ieee80211com 
 	if_initname(ifp, name, unit);
 	ifp->if_softc = vap;			/* back pointer */
 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
-	ifp->if_start = ieee80211_start;
+	ifp->if_transmit = ieee80211_vap_transmit;
+	ifp->if_qflush = ieee80211_vap_qflush;
 	ifp->if_ioctl = ieee80211_ioctl;
 	ifp->if_init = ieee80211_init;
 	/* NB: input+output filled in by ether_ifattach */
@@ -622,6 +623,7 @@ ieee80211_vap_detach(struct ieee80211vap
 	 */
 	ieee80211_draintask(ic, &vap->iv_nstate_task);
 	ieee80211_draintask(ic, &vap->iv_swbmiss_task);
+	ieee80211_draintask(ic, &vap->iv_tx_task);
 
 	/* XXX band-aid until ifnet handles this for us */
 	taskqueue_drain(taskqueue_swi, &ifp->if_linktask);

Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c
==============================================================================
--- user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c	Fri Mar  1 04:21:22 2013	(r247528)
+++ user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c	Fri Mar  1 04:51:44 2013	(r247529)
@@ -761,7 +761,7 @@ static void
 bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
 {
 	/* NB: identify vap's by if_start */
-	if (dlt == DLT_IEEE802_11_RADIO && ifp->if_start == ieee80211_start) {
+	if (dlt == DLT_IEEE802_11_RADIO && ifp->if_transmit == ieee80211_vap_transmit) {
 		struct ieee80211vap *vap = ifp->if_softc;
 		/*
 		 * Track bpf radiotap listener state.  We mark the vap

Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_output.c
==============================================================================
--- user/adrian/net80211_tx/sys/net80211/ieee80211_output.c	Fri Mar  1 04:21:22 2013	(r247528)
+++ user/adrian/net80211_tx/sys/net80211/ieee80211_output.c	Fri Mar  1 04:51:44 2013	(r247529)
@@ -133,16 +133,6 @@ ieee80211_start_pkt(struct ieee80211vap 
 	int error;
 
 	/*
-	 * Sanitize mbuf flags for net80211 use.  We cannot
-	 * clear M_PWR_SAV or M_MORE_DATA because these may
-	 * be set for frames that are re-submitted from the
-	 * power save queue.
-	 *
-	 * NB: This must be done before ieee80211_classify as
-	 *     it marks EAPOL in frames with M_EAPOL.
-	 */
-	m->m_flags &= ~(M_80211_TX - M_PWR_SAV - M_MORE_DATA);
-	/*
 	 * Cancel any background scan.
 	 */
 	if (ic->ic_flags & IEEE80211_F_SCAN)
@@ -370,14 +360,81 @@ ieee80211_start_pkt(struct ieee80211vap 
 }
 
 /*
+ * Entry point for transmission for all VAPs.
+ *
+ * This sanitises the mbuf flags and queues it into the transmit
+ * queue.
+ */
+int
+ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m)
+{
+	struct ieee80211vap *vap = ifp->if_softc;
+	struct ieee80211com *ic = vap->iv_ic;
+	struct ifnet *parent = ic->ic_ifp;
+
+	/* NB: parent must be up and running */
+	if (!IFNET_IS_UP_RUNNING(parent)) {
+		IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
+		    "%s: ignore queue, parent %s not up+running\n",
+		    __func__, parent->if_xname);
+		/* XXX stat */
+		m_free(m);
+		return (EINVAL);/* XXX errno? */
+	}
+
+	IF_LOCK(&ifp->if_snd);
+
+	/* Enforce queue limits */
+	if (_IF_QFULL(&ifp->if_snd)) {
+		IF_UNLOCK(&ifp->if_snd);
+		m_free(m);
+		return (ENOBUFS);	/* XXX errno? */
+	}
+
+	/*
+	 * Sanitize mbuf flags for net80211 use.  We cannot
+	 * clear M_PWR_SAV or M_MORE_DATA because these may
+	 * be set for frames that are re-submitted from the
+	 * power save queue.
+	 *
+	 * NB: This must be done before ieee80211_classify as
+	 *     it marks EAPOL in frames with M_EAPOL.
+	 *
+	 * XXX TODO: for VAP frames coming in from the stack
+	 * itself, we should just inject them directly into
+	 * the vap rather than via ieee80211_vap_transmit().
+	 * Yes, they still need to go into the ifnet queue
+	 * and be dequeued, but we can skip this particular
+	 * check as they're already "in" the net80211 layer.
+	 */
+	m->m_flags &= ~(M_80211_TX - M_PWR_SAV - M_MORE_DATA);
+	_IF_ENQUEUE(&ifp->if_snd, m);
+	IF_UNLOCK(&ifp->if_snd);
+
+	/* Schedule the deferred TX task */
+	ieee80211_runtask(ic, &vap->iv_tx_task);
+
+	return (0);
+}
+
+void
+ieee80211_vap_qflush(struct ifnet *ifp)
+{
+
+	/* XXX TODO */
+}
+
+
+/*
  * Start method for vap's.  All packets from the stack come
  * through here.  We handle common processing of the packets
  * before dispatching them to the underlying device.
  */
 void
-ieee80211_start(struct ifnet *ifp)
+ieee80211_vap_tx_task(void *arg, int npending)
 {
-	struct ieee80211vap *vap = ifp->if_softc;
+	struct ieee80211vap *vap = (struct ieee80211vap *) arg;
+	struct ifnet *ifp = vap->iv_ifp;
 	struct ieee80211com *ic = vap->iv_ic;
 	struct ifnet *parent = ic->ic_ifp;
 	struct mbuf *m;

Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c
==============================================================================
--- user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c	Fri Mar  1 04:21:22 2013	(r247528)
+++ user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c	Fri Mar  1 04:51:44 2013	(r247529)
@@ -199,6 +199,7 @@ ieee80211_proto_vattach(struct ieee80211
 	callout_init(&vap->iv_mgtsend, CALLOUT_MPSAFE);
 	TASK_INIT(&vap->iv_nstate_task, 0, ieee80211_newstate_cb, vap);
 	TASK_INIT(&vap->iv_swbmiss_task, 0, beacon_swmiss, vap);
+	TASK_INIT(&vap->iv_tx_task, 0, ieee80211_vap_tx_task, vap);
 	/*
 	 * Install default tx rate handling: no fixed rate, lowest
 	 * supported rate for mgmt and multicast frames.  Default
@@ -1792,7 +1793,7 @@ ieee80211_newstate_cb(void *xvap, int np
 		 * XXX Kick-start a VAP queue - this should be a method,
 		 * not if_start()!
 		 */
-		if_start(vap->iv_ifp);
+		ieee80211_runtask(ic, &vap->iv_tx_task);
 
 		/* bring up any vaps waiting on us */
 		wakeupwaiting(vap);

Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h
==============================================================================
--- user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h	Fri Mar  1 04:21:22 2013	(r247528)
+++ user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h	Fri Mar  1 04:51:44 2013	(r247529)
@@ -103,7 +103,9 @@ int	ieee80211_raw_output(struct ieee8021
 void	ieee80211_send_setup(struct ieee80211_node *, struct mbuf *, int, int,
         const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
         const uint8_t [IEEE80211_ADDR_LEN]);
-void	ieee80211_start(struct ifnet *);
+int	ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m);
+void	ieee80211_vap_qflush(struct ifnet *ifp);
+void	ieee80211_vap_tx_task(void *, int);
 int	ieee80211_send_nulldata(struct ieee80211_node *);
 int	ieee80211_classify(struct ieee80211_node *, struct mbuf *m);
 struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int,

Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_var.h
==============================================================================
--- user/adrian/net80211_tx/sys/net80211/ieee80211_var.h	Fri Mar  1 04:21:22 2013	(r247528)
+++ user/adrian/net80211_tx/sys/net80211/ieee80211_var.h	Fri Mar  1 04:51:44 2013	(r247529)
@@ -362,6 +362,7 @@ struct ieee80211vap {
 	int			iv_nstate_arg;	/* pending state arg */
 	struct task		iv_nstate_task;	/* deferred state processing */
 	struct task		iv_swbmiss_task;/* deferred iv_bmiss call */
+	struct task		iv_tx_task;	/* VAP deferred TX task */
 	struct callout		iv_mgtsend;	/* mgmt frame response timer */
 						/* inactivity timer settings */
 	int			iv_inact_init;	/* setting for new station */


More information about the svn-src-user mailing list