2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * $Id: ieee80211_power.c 3713 2008-06-08 01:43:53Z mentor $
39 * IEEE 802.11 power save support.
41 #ifndef AUTOCONF_INCLUDED
42 #include <linux/config.h>
44 #include <linux/version.h>
45 #include <linux/module.h>
46 #include <linux/skbuff.h>
47 #include <linux/netdevice.h>
48 #include <linux/etherdevice.h>
52 #include <net80211/ieee80211_var.h>
53 #include <net80211/ieee80211_proto.h>
55 static void ieee80211_set_tim(struct ieee80211_node
*ni
, int set
);
58 ieee80211_power_attach(struct ieee80211com
*ic
)
63 ieee80211_power_detach(struct ieee80211com
*ic
)
68 ieee80211_power_vattach(struct ieee80211vap
*vap
)
70 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
||
71 vap
->iv_opmode
== IEEE80211_M_IBSS
) {
72 /* NB: driver should override */
73 vap
->iv_set_tim
= ieee80211_set_tim
;
78 ieee80211_power_latevattach(struct ieee80211vap
*vap
)
81 * Allocate these only if needed. Beware that we
82 * know adhoc mode doesn't support ATIM yet...
84 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
) {
85 vap
->iv_tim_len
= howmany(vap
->iv_max_aid
, 8) * sizeof(u_int8_t
);
86 MALLOC(vap
->iv_tim_bitmap
, u_int8_t
*, vap
->iv_tim_len
,
87 M_DEVBUF
, M_NOWAIT
| M_ZERO
);
88 if (vap
->iv_tim_bitmap
== NULL
) {
89 printk(KERN_ERR
"%s: no memory for TIM bitmap!\n", __func__
);
90 /* XXX good enough to keep from crashing? */
97 ieee80211_power_vdetach(struct ieee80211vap
*vap
)
99 if (vap
->iv_tim_bitmap
!= NULL
) {
100 FREE(vap
->iv_tim_bitmap
, M_DEVBUF
);
101 vap
->iv_tim_bitmap
= NULL
;
106 * Clear any frames queued on a node's power save queue.
107 * The number of frames that were present is returned.
110 ieee80211_node_saveq_drain(struct ieee80211_node
*ni
)
115 IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni
);
116 qlen
= IEEE80211_NODE_SAVEQ_QLEN(ni
);
117 while ((skb
= __skb_dequeue(&ni
->ni_savedq
)) != NULL
) {
118 if (SKB_NI(skb
) != NULL
)
119 ieee80211_unref_node(&SKB_NI(skb
));
120 ieee80211_dev_kfree_skb(&skb
);
122 IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni
);
128 * Age frames on the power save queue. The aging interval is
129 * 4 times the listen interval specified by the station. This
130 * number is factored into the age calculations when the frame
131 * is placed on the queue. We store ages as time differences
132 * so we can check and/or adjust only the head of the list.
133 * If a frame's age exceeds the threshold then discard it.
134 * The number of frames discarded is returned so the caller
135 * can check if it needs to adjust the tim.
138 ieee80211_node_saveq_age(struct ieee80211_node
*ni
)
142 /* XXX racey but good 'nuf? */
143 if (IEEE80211_NODE_SAVEQ_QLEN(ni
) != 0) {
144 #ifdef IEEE80211_DEBUG
145 struct ieee80211vap
*vap
= ni
->ni_vap
;
149 IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni
);
150 while ((skb
= skb_peek(&ni
->ni_savedq
)) != NULL
&&
151 M_AGE_GET(skb
) < IEEE80211_INACT_WAIT
) {
152 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
153 "discard frame, age %u", M_AGE_GET(skb
));
155 skb
= __skb_dequeue(&ni
->ni_savedq
);
156 if (SKB_NI(skb
) != NULL
)
157 ieee80211_unref_node(&SKB_NI(skb
));
158 ieee80211_dev_kfree_skb(&skb
);
162 M_AGE_SUB(skb
, IEEE80211_INACT_WAIT
);
163 IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni
);
165 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
166 "discard %u frames for age", discard
);
167 IEEE80211_NODE_STAT_ADD(ni
, ps_discard
, discard
);
173 * Indicate whether there are frames queued for a station in power-save mode.
176 ieee80211_set_tim(struct ieee80211_node
*ni
, int set
)
178 struct ieee80211vap
*vap
= ni
->ni_vap
;
181 KASSERT(vap
->iv_opmode
== IEEE80211_M_HOSTAP
||
182 vap
->iv_opmode
== IEEE80211_M_IBSS
,
183 ("operating mode %u", vap
->iv_opmode
));
185 aid
= IEEE80211_AID(ni
->ni_associd
);
186 KASSERT(aid
< vap
->iv_max_aid
,
187 ("bogus aid %u, max %u", aid
, vap
->iv_max_aid
));
189 IEEE80211_LOCK_IRQ(ni
->ni_ic
);
190 if (set
!= (isset(vap
->iv_tim_bitmap
, aid
) != 0)) {
192 setbit(vap
->iv_tim_bitmap
, aid
);
193 vap
->iv_ps_pending
++;
195 clrbit(vap
->iv_tim_bitmap
, aid
);
196 vap
->iv_ps_pending
--;
198 vap
->iv_flags
|= IEEE80211_F_TIMUPDATE
;
200 IEEE80211_UNLOCK_IRQ(ni
->ni_ic
);
204 * Save an outbound packet for a node in power-save sleep state.
205 * The new packet is placed on the node's saved queue, and the TIM
206 * is changed, if necessary.
207 * It must return either NETDEV_TX_OK or NETDEV_TX_BUSY
210 ieee80211_pwrsave(struct sk_buff
*skb
)
212 struct ieee80211_node
*ni
= SKB_NI(skb
);
213 struct ieee80211vap
*vap
= ni
->ni_vap
;
214 struct ieee80211com
*ic
= ni
->ni_ic
;
215 struct sk_buff
*tail
;
218 IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni
);
219 if (IEEE80211_NODE_SAVEQ_QLEN(ni
) >= IEEE80211_PS_MAX_QUEUE
) {
220 IEEE80211_NODE_STAT(ni
, psq_drops
);
221 IEEE80211_NODE_SAVEQ_UNLOCK_IRQ_EARLY(ni
);
222 IEEE80211_NOTE(vap
, IEEE80211_MSG_ANY
, ni
,
223 "pwr save q overflow, drops %d (size %d)",
224 ni
->ni_stats
.ns_psq_drops
, IEEE80211_PS_MAX_QUEUE
);
225 #ifdef IEEE80211_DEBUG
226 if (ieee80211_msg_dumppkts(vap
))
227 ieee80211_dump_pkt(ni
->ni_ic
, skb
->data
,
228 skb
->len
, -1, -1, 1);
230 if (SKB_NI(skb
) != NULL
)
231 ieee80211_unref_node(&SKB_NI(skb
));
232 ieee80211_dev_kfree_skb(&skb
);
237 * Tag the frame with its expiry time and insert
238 * it in the queue. The aging interval is 4 times
239 * the listen interval specified by the station.
240 * Frames that sit around too long are reclaimed
241 * using this information.
243 /* XXX handle overflow? */
244 age
= ((ni
->ni_intval
* ic
->ic_lintval
) << 2) / 1024; /* TU -> secs */
245 tail
= skb_peek_tail(&ni
->ni_savedq
);
247 age
-= M_AGE_GET(tail
);
248 __skb_queue_after(&ni
->ni_savedq
, tail
, skb
);
250 __skb_queue_head(&ni
->ni_savedq
, skb
);
252 qlen
= IEEE80211_NODE_SAVEQ_QLEN(ni
);
253 IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni
);
255 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
256 "save frame, %u now queued", qlen
);
258 if (qlen
== 1 && vap
->iv_set_tim
!= NULL
)
259 vap
->iv_set_tim(ni
, 1);
265 * Handle power-save state change in ap/ibss mode.
268 ieee80211_node_pwrsave(struct ieee80211_node
*ni
, int enable
)
270 struct ieee80211vap
*vap
= ni
->ni_vap
;
272 KASSERT(vap
->iv_opmode
== IEEE80211_M_HOSTAP
||
273 vap
->iv_opmode
== IEEE80211_M_IBSS
,
274 ("unexpected operating mode %u", vap
->iv_opmode
));
277 if ((ni
->ni_flags
& IEEE80211_NODE_PWR_MGT
) == 0)
279 ni
->ni_flags
|= IEEE80211_NODE_PWR_MGT
;
280 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
281 "power save mode on, %u STAs in PS mode",
284 if ((ni
->ni_flags
& IEEE80211_NODE_PWR_MGT
))
286 ni
->ni_flags
&= ~IEEE80211_NODE_PWR_MGT
;
287 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
288 "power save mode off, %u STAs in PS mode",
290 /* XXX if no stations in ps mode, flush mc frames */
293 * Flush queued unicast frames.
295 if (IEEE80211_NODE_SAVEQ_QLEN(ni
) == 0) {
296 if (vap
->iv_set_tim
!= NULL
)
297 vap
->iv_set_tim(ni
, 0); /* just in case */
301 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
302 "flush ps queue, %u packets queued",
303 IEEE80211_NODE_SAVEQ_QLEN(ni
));
309 IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni
);
310 IEEE80211_NODE_SAVEQ_DEQUEUE(ni
, skb
, qlen
);
311 IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni
);
315 * If this is the last packet, turn off the TIM bit.
317 * Set the M_PWR_SAV bit on skb to allow encap to test for
318 * adding MORE_DATA bit to wh.
320 * The 802.11 MAC Spec says we should only set MORE_DATA for
321 * unicast packets when the STA is in PS mode (7.1.3.1.8);
330 * if it is a XR vap, send the data to associated normal net
331 * device. XR vap has a net device which is not registered with
334 if (vap
->iv_xrvap
&& vap
->iv_flags
& IEEE80211_F_XR
)
335 skb
->dev
= vap
->iv_xrvap
->iv_dev
;
337 skb
->dev
= vap
->iv_dev
; /* XXX? unnecessary */
340 ieee80211_parent_queue_xmit(skb
);
342 vap
->iv_set_tim(ni
, 0);
347 * Handle power-save state change in station mode.
350 ieee80211_sta_pwrsave(struct ieee80211vap
*vap
, int enable
)
352 struct ieee80211_node
*ni
= vap
->iv_bss
;
355 if (vap
->iv_opmode
!= IEEE80211_M_STA
)
358 if (!!enable
== !!IEEE80211_VAP_IS_SLEEPING(vap
)) /* Bool. normalise */
361 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
362 "STA power save mode %s", enable
? "on" : "off");
364 IEEE80211_VAP_WAKEUP(vap
);
365 ieee80211_send_nulldata(ieee80211_ref_node(ni
));
367 * Flush any queued frames; we can do this immediately
368 * because we know they'll be queued behind the null
369 * data frame we send the ap.
370 * XXX: Can we use a data frame to take us out of PS mode?
372 qlen
= IEEE80211_NODE_SAVEQ_QLEN(ni
);
374 IEEE80211_NOTE(vap
, IEEE80211_MSG_POWER
, ni
,
375 "flush PS queue, %u packets queued", qlen
);
379 IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni
);
380 skb
= __skb_dequeue(&ni
->ni_savedq
);
381 IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni
);
384 ieee80211_parent_queue_xmit(skb
);
388 IEEE80211_VAP_GOTOSLEEP(vap
);
389 ieee80211_send_nulldata(ieee80211_ref_node(ni
));