From bc5627d91f8cce793deecb3472b8fa27e9b335cd Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 6 Jul 2005 01:55:17 +0000 Subject: [PATCH] Fix handling of data frames queued for a station in power save mode: don't mark the MORE_DATA bit when taking it off the ps queue, there's no 802.11 header then; we must wait to do this at encap time so mark the mbuf instead. Reviewed by: avatar Approved by: re (scottl) Obtained from: Atheros --- sys/net80211/ieee80211_freebsd.h | 1 + sys/net80211/ieee80211_input.c | 10 ++++------ sys/net80211/ieee80211_output.c | 2 ++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index 94b5296bf93..17483b67f00 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -148,6 +148,7 @@ int ieee80211_node_dectestref(struct ieee80211_node *ni); struct mbuf *ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen); #define M_LINK0 M_PROTO1 /* WEP requested */ #define M_PWR_SAV M_PROTO4 /* bypass PS handling */ +#define M_MORE_DATA M_PROTO5 /* more data frames to follow */ /* * Encode WME access control bits in the PROTO flags. * This is safe since it's passed directly in to the diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index c0ead1624f0..106615bcf6c 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -2609,13 +2609,11 @@ ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) /* * If this is the last packet, turn off the TIM bit. * If there are more packets, set the more packets bit - * in the packet dispatched to the station. + * in the mbuf so ieee80211_encap will mark the 802.11 + * head to indicate more data frames will follow. */ - if (qlen != 0) { - struct ieee80211_frame_min *wh = - mtod(m, struct ieee80211_frame_min *); - wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; - } + if (qlen != 0) + m->m_flags |= M_MORE_DATA; /* XXX need different driver interface */ /* XXX bypasses q max */ IF_ENQUEUE(&ic->ic_ifp->if_snd, m); diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 0319a39baf9..657a10a2517 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -534,6 +534,8 @@ ieee80211_encap(struct ieee80211com *ic, struct mbuf *m, case IEEE80211_M_MONITOR: goto bad; } + if (m->m_flags & M_MORE_DATA) + wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; if (addqos) { struct ieee80211_qosframe *qwh = (struct ieee80211_qosframe *) wh;