Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Oct 2012 17:45:19 +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: r241138 - head/sys/net80211
Message-ID:  <201210021745.q92HjKlK078184@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Oct  2 17:45:19 2012
New Revision: 241138
URL: http://svn.freebsd.org/changeset/base/241138

Log:
  Migrate the power-save functions to be overridable VAP methods.
  
  This turns ieee80211_node_pwrsave(), ieee80211_sta_pwrsave() and
  ieee80211_recv_pspoll() into methods.
  
  The intent is to let drivers override these and tie into the power save
  management pathway.
  
  For ath(4), this is the beginning of forcing a node software queue to
  stop and start as needed, as well as supporting "leaking" single frames
  from the software queue to the hardware.
  
  Right now, ieee80211_recv_pspoll() will attempt to transmit a single frame
  to the hardware (whether it be a data frame on the power-save queue or
  a NULL data frame) but the driver may have hardware/software queued frames
  queued up.  This initial work is an attempt at providing the hooks required
  to implement correct behaviour.
  
  Allowing ieee80211_node_pwrsave() to be overridden allows the ath(4)
  driver to pause and unpause the entire software queue for a given node.
  It doesn't make sense to transmit anything whilst the node is asleep.
  
  Please note that there are other corner cases to correctly handle -
  specifically, setting the MORE data bit correctly on frames to a station,
  as well as keeping the TIM updated.  Those particular issues can be
  addressed later.

Modified:
  head/sys/net80211/ieee80211_adhoc.c
  head/sys/net80211/ieee80211_hostap.c
  head/sys/net80211/ieee80211_hostap.h
  head/sys/net80211/ieee80211_power.c
  head/sys/net80211/ieee80211_power.h
  head/sys/net80211/ieee80211_scan.c
  head/sys/net80211/ieee80211_sta.c
  head/sys/net80211/ieee80211_var.h

Modified: head/sys/net80211/ieee80211_adhoc.c
==============================================================================
--- head/sys/net80211/ieee80211_adhoc.c	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_adhoc.c	Tue Oct  2 17:45:19 2012	(r241138)
@@ -242,7 +242,7 @@ adhoc_newstate(struct ieee80211vap *vap,
 			ic->ic_newassoc(ni, ostate != IEEE80211_S_RUN);
 		break;
 	case IEEE80211_S_SLEEP:
-		ieee80211_sta_pwrsave(vap, 0);
+		vap->iv_sta_ps(vap, 0);
 		break;
 	default:
 	invalid:

Modified: head/sys/net80211/ieee80211_hostap.c
==============================================================================
--- head/sys/net80211/ieee80211_hostap.c	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_hostap.c	Tue Oct  2 17:45:19 2012	(r241138)
@@ -73,7 +73,6 @@ static void hostap_deliver_data(struct i
 static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
 	    int subtype, int rssi, int nf);
 static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
-static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *);
 
 void
 ieee80211_hostap_attach(struct ieee80211com *ic)
@@ -100,6 +99,7 @@ hostap_vattach(struct ieee80211vap *vap)
 	vap->iv_recv_ctl = hostap_recv_ctl;
 	vap->iv_opdetach = hostap_vdetach;
 	vap->iv_deliver_data = hostap_deliver_data;
+	vap->iv_recv_pspoll = ieee80211_recv_pspoll;
 }
 
 static void
@@ -645,7 +645,7 @@ hostap_input(struct ieee80211_node *ni, 
 		 */
 		if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^
 		    (ni->ni_flags & IEEE80211_NODE_PWR_MGT)))
-			ieee80211_node_pwrsave(ni,
+			vap->iv_node_ps(ni,
 				wh->i_fc[1] & IEEE80211_FC1_PWR_MGT);
 		/*
 		 * For 4-address packets handle WDS discovery
@@ -2240,7 +2240,7 @@ hostap_recv_ctl(struct ieee80211_node *n
 {
 	switch (subtype) {
 	case IEEE80211_FC0_SUBTYPE_PS_POLL:
-		hostap_recv_pspoll(ni, m);
+		ni->ni_vap->iv_recv_pspoll(ni, m);
 		break;
 	case IEEE80211_FC0_SUBTYPE_BAR:
 		ieee80211_recv_bar(ni, m);
@@ -2251,8 +2251,8 @@ hostap_recv_ctl(struct ieee80211_node *n
 /*
  * Process a received ps-poll frame.
  */
-static void
-hostap_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
+void
+ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211_frame_min *wh;

Modified: head/sys/net80211/ieee80211_hostap.h
==============================================================================
--- head/sys/net80211/ieee80211_hostap.h	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_hostap.h	Tue Oct  2 17:45:19 2012	(r241138)
@@ -32,4 +32,10 @@
  */
 void	ieee80211_hostap_attach(struct ieee80211com *);
 void	ieee80211_hostap_detach(struct ieee80211com *);
+
+/*
+ * This method can be overridden
+ */
+void ieee80211_recv_pspoll(struct ieee80211_node *, struct mbuf *);
+
 #endif /* !_NET80211_IEEE80211_HOSTAP_H_ */

Modified: head/sys/net80211/ieee80211_power.c
==============================================================================
--- head/sys/net80211/ieee80211_power.c	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_power.c	Tue Oct  2 17:45:19 2012	(r241138)
@@ -69,6 +69,8 @@ ieee80211_power_vattach(struct ieee80211
 		vap->iv_update_ps = ieee80211_update_ps;
 		vap->iv_set_tim = ieee80211_set_tim;
 	}
+	vap->iv_node_ps = ieee80211_node_pwrsave;
+	vap->iv_sta_ps = ieee80211_sta_pwrsave;
 }
 
 void

Modified: head/sys/net80211/ieee80211_power.h
==============================================================================
--- head/sys/net80211/ieee80211_power.h	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_power.h	Tue Oct  2 17:45:19 2012	(r241138)
@@ -71,6 +71,11 @@ void	ieee80211_power_latevattach(struct 
 struct mbuf *ieee80211_node_psq_dequeue(struct ieee80211_node *ni, int *qlen);
 int	ieee80211_node_psq_drain(struct ieee80211_node *);
 int	ieee80211_node_psq_age(struct ieee80211_node *);
+
+/*
+ * Don't call these directly from the stack; they are vap methods
+ * that should be overridden.
+ */
 int	ieee80211_pwrsave(struct ieee80211_node *, struct mbuf *);
 void	ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
 void	ieee80211_sta_pwrsave(struct ieee80211vap *, int enable);

Modified: head/sys/net80211/ieee80211_scan.c
==============================================================================
--- head/sys/net80211/ieee80211_scan.c	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_scan.c	Tue Oct  2 17:45:19 2012	(r241138)
@@ -866,7 +866,7 @@ scan_task(void *arg, int pending)
 	    vap->iv_state == IEEE80211_S_RUN) {
 		if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) {
 			/* Enable station power save mode */
-			ieee80211_sta_pwrsave(vap, 1);
+			vap->iv_sta_ps(vap, 1);
 			/*
 			 * Use an 1ms delay so the null data frame has a chance
 			 * to go out.
@@ -1047,7 +1047,7 @@ done:
 	 * waiting for us.
 	 */
 	if (scandone) {
-		ieee80211_sta_pwrsave(vap, 0);
+		vap->iv_sta_ps(vap, 0);
 		if (ss->ss_next >= ss->ss_last) {
 			ieee80211_notify_scan_done(vap);
 			ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;

Modified: head/sys/net80211/ieee80211_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_sta.c	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_sta.c	Tue Oct  2 17:45:19 2012	(r241138)
@@ -402,7 +402,7 @@ sta_newstate(struct ieee80211vap *vap, e
 			    arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
 			break;
 		case IEEE80211_S_SLEEP:
-			ieee80211_sta_pwrsave(vap, 0);
+			vap->iv_sta_ps(vap, 0);
 			break;
 		default:
 			goto invalid;
@@ -438,7 +438,7 @@ sta_newstate(struct ieee80211vap *vap, e
 			goto invalid;
 		break;
 	case IEEE80211_S_SLEEP:
-		ieee80211_sta_pwrsave(vap, 1);
+		vap->iv_sta_ps(vap, 1);
 		break;
 	default:
 	invalid:
@@ -1396,7 +1396,7 @@ sta_recv_mgmt(struct ieee80211_node *ni,
 					 * we are expecting data.
 					 */
 					ic->ic_lastdata = ticks;
-					ieee80211_sta_pwrsave(vap, 0);
+					vap->iv_sta_ps(vap, 0);
 				}
 #endif
 				ni->ni_dtim_count = tim->tim_count;

Modified: head/sys/net80211/ieee80211_var.h
==============================================================================
--- head/sys/net80211/ieee80211_var.h	Tue Oct  2 17:44:08 2012	(r241137)
+++ head/sys/net80211/ieee80211_var.h	Tue Oct  2 17:45:19 2012	(r241138)
@@ -486,6 +486,11 @@ struct ieee80211vap {
 	/* power save handling */
 	void			(*iv_update_ps)(struct ieee80211vap *, int);
 	int			(*iv_set_tim)(struct ieee80211_node *, int);
+	void			(*iv_node_ps)(struct ieee80211_node *, int);
+	void			(*iv_sta_ps)(struct ieee80211vap *, int);
+	void			(*iv_recv_pspoll)(struct ieee80211_node *,
+				    struct mbuf *);
+
 	/* state machine processing */
 	int			(*iv_newstate)(struct ieee80211vap *,
 				    enum ieee80211_state, int);



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