From owner-svn-src-head@FreeBSD.ORG Wed Apr 23 22:44:50 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1B266804; Wed, 23 Apr 2014 22:44:50 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E26AA11E9; Wed, 23 Apr 2014 22:44:49 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3NMin9Z081450; Wed, 23 Apr 2014 22:44:49 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3NMinZU081449; Wed, 23 Apr 2014 22:44:49 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201404232244.s3NMinZU081449@svn.freebsd.org> From: Adrian Chadd Date: Wed, 23 Apr 2014 22:44:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264844 - head/sys/net80211 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Apr 2014 22:44:50 -0000 Author: adrian Date: Wed Apr 23 22:44:49 2014 New Revision: 264844 URL: http://svnweb.freebsd.org/changeset/base/264844 Log: Allow frames to be transmitted in either RUN or SLEEP state Frames transmitted during SLEEP state should be queued in the power save queue before waking the unit up. Otherwise DHCP requests and such will be dropped if the NIC is asleep - the NIC will wake up but not transmit the frame. Modified: head/sys/net80211/ieee80211_output.c Modified: head/sys/net80211/ieee80211_output.c ============================================================================== --- head/sys/net80211/ieee80211_output.c Wed Apr 23 22:43:39 2014 (r264843) +++ head/sys/net80211/ieee80211_output.c Wed Apr 23 22:44:49 2014 (r264844) @@ -390,6 +390,19 @@ ieee80211_start_pkt(struct ieee80211vap /* * We've resolved the sender, so attempt to transmit it. */ + + if (vap->iv_state == IEEE80211_S_SLEEP) { + /* + * In power save; queue frame and then wakeup device + * for transmit. + */ + ic->ic_lastdata = ticks; + (void) ieee80211_pwrsave(ni, m); + ieee80211_free_node(ni); + ieee80211_new_state(vap, IEEE80211_S_RUN, 0); + return (0); + } + if (ieee80211_vap_pkt_send_dest(vap, m, ni) != 0) return (ENOBUFS); return (0); @@ -420,24 +433,19 @@ ieee80211_vap_transmit(struct ifnet *ifp m_freem(m); return (EINVAL); } - if (vap->iv_state == IEEE80211_S_SLEEP) { - /* - * In power save, wakeup device for transmit. - */ - ieee80211_new_state(vap, IEEE80211_S_RUN, 0); - m_freem(m); - return (0); - } + /* * No data frames go out unless we're running. * Note in particular this covers CAC and CSA * states (though maybe we should check muting * for CSA). */ - if (vap->iv_state != IEEE80211_S_RUN) { + if (vap->iv_state != IEEE80211_S_RUN && + vap->iv_state != IEEE80211_S_SLEEP) { IEEE80211_LOCK(ic); /* re-check under the com lock to avoid races */ - if (vap->iv_state != IEEE80211_S_RUN) { + if (vap->iv_state != IEEE80211_S_RUN && + vap->iv_state != IEEE80211_S_SLEEP) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, "%s: ignore queue, in %s state\n", __func__, ieee80211_state_name[vap->iv_state]); @@ -477,6 +485,13 @@ ieee80211_vap_qflush(struct ifnet *ifp) /* * 802.11 raw output routine. + * + * XXX TODO: this (and other send routines) should correctly + * XXX keep the pwr mgmt bit set if it decides to call into the + * XXX driver to send a frame whilst the state is SLEEP. + * + * Otherwise the peer may decide that we're awake and flood us + * with traffic we are still too asleep to receive! */ int ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,