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>