[svn-upgrade] new version madwifi (0.9.4+r4136.20110203)
[debian/madwifi.git] / net80211 / ieee80211_power.c
1 /*-
2  * Copyright (c) 2001 Atsushi Onoe
3  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
16  *
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.
20  *
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.
31  *
32  * $Id: ieee80211_power.c 4136 2011-02-02 21:22:31Z proski $
33  */
34 #ifndef EXPORT_SYMTAB
35 #define EXPORT_SYMTAB
36 #endif
37
38 /*
39  * IEEE 802.11 power save support.
40  */
41 #if !defined(AUTOCONF_INCLUDED) && !defined(CONFIG_LOCALVERSION)
42 #include <linux/config.h>
43 #endif
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>
49
50 #include "if_media.h"
51
52 #include <net80211/ieee80211_var.h>
53 #include <net80211/ieee80211_proto.h>
54
55 static void ieee80211_set_tim(struct ieee80211_node *ni, int set);
56
57 void
58 ieee80211_power_attach(struct ieee80211com *ic)
59 {
60 }
61
62 void
63 ieee80211_power_detach(struct ieee80211com *ic)
64 {
65 }
66
67 void
68 ieee80211_power_vattach(struct ieee80211vap *vap)
69 {
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;
74         }
75 }
76
77 void
78 ieee80211_power_latevattach(struct ieee80211vap *vap)
79 {
80         /*
81          * Allocate these only if needed.  Beware that we
82          * know adhoc mode doesn't support ATIM yet...
83          */
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                         printf("%s: no memory for TIM bitmap!\n", __func__);
90                         /* XXX good enough to keep from crashing? */
91                         vap->iv_tim_len = 0;
92                 }
93         }
94 }
95
96 void
97 ieee80211_power_vdetach(struct ieee80211vap *vap)
98 {
99         if (vap->iv_tim_bitmap != NULL) {
100                 FREE(vap->iv_tim_bitmap, M_DEVBUF);
101                 vap->iv_tim_bitmap = NULL;
102         }
103 }
104
105 /*
106  * Clear any frames queued on a node's power save queue.
107  * The number of frames that were present is returned.
108  */
109 int
110 ieee80211_node_saveq_drain(struct ieee80211_node *ni)
111 {
112         struct sk_buff *skb;
113         int qlen;
114
115         IEEE80211_NODE_SAVEQ_LOCK(ni);
116         qlen = skb_queue_len(&ni->ni_savedq);
117         while ((skb = __skb_dequeue(&ni->ni_savedq)) != NULL) {
118                 ieee80211_free_node(ni);
119                 dev_kfree_skb_any(skb);
120         }
121         IEEE80211_NODE_SAVEQ_UNLOCK(ni);
122
123         return qlen;
124 }
125
126 /*
127  * Age frames on the power save queue. The aging interval is
128  * 4 times the listen interval specified by the station.  This
129  * number is factored into the age calculations when the frame
130  * is placed on the queue.  We store ages as time differences
131  * so we can check and/or adjust only the head of the list.
132  * If a frame's age exceeds the threshold then discard it.
133  * The number of frames discarded is returned so the caller
134  * can check if it needs to adjust the tim.
135  */
136 int
137 ieee80211_node_saveq_age(struct ieee80211_node *ni)
138 {
139         int discard = 0;
140
141         /* XXX racey but good 'nuf? */
142         if (IEEE80211_NODE_SAVEQ_QLEN(ni) != 0) {
143 #ifdef IEEE80211_DEBUG
144                 struct ieee80211vap *vap = ni->ni_vap;
145 #endif
146                 struct sk_buff *skb;
147
148                 IEEE80211_NODE_SAVEQ_LOCK(ni);
149                 while ((skb = skb_peek(&ni->ni_savedq)) != NULL &&
150                      M_AGE_GET(skb) < IEEE80211_INACT_WAIT) {
151                         IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
152                                 "discard frame, age %u", M_AGE_GET(skb));
153
154                         skb = __skb_dequeue(&ni->ni_savedq);
155                         dev_kfree_skb_any(skb);
156                         discard++;
157                 }
158                 if (skb != NULL)
159                         M_AGE_SUB(skb, IEEE80211_INACT_WAIT);
160                 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
161
162                 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
163                         "discard %u frames for age", discard);
164                 IEEE80211_NODE_STAT_ADD(ni, ps_discard, discard);
165         }
166         return discard;
167 }
168
169 /*
170  * Indicate whether there are frames queued for a station in power-save mode.
171  */
172 static void
173 ieee80211_set_tim(struct ieee80211_node *ni, int set)
174 {
175         struct ieee80211vap *vap = ni->ni_vap;
176         u_int16_t aid;
177
178         KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP ||
179                 vap->iv_opmode == IEEE80211_M_IBSS,
180                 ("operating mode %u", vap->iv_opmode));
181
182         aid = IEEE80211_AID(ni->ni_associd);
183         KASSERT(aid < vap->iv_max_aid,
184                 ("bogus aid %u, max %u", aid, vap->iv_max_aid));
185
186         IEEE80211_LOCK(ni->ni_ic);
187         if (set != (isset(vap->iv_tim_bitmap, aid) != 0)) {
188                 if (set) {
189                         setbit(vap->iv_tim_bitmap, aid);
190                         vap->iv_ps_pending++;
191                 } else {
192                         clrbit(vap->iv_tim_bitmap, aid);
193                         vap->iv_ps_pending--;
194                 }
195                 vap->iv_flags |= IEEE80211_F_TIMUPDATE;
196         }
197         IEEE80211_UNLOCK(ni->ni_ic);
198 }
199
200 /*
201  * Save an outbound packet for a node in power-save sleep state.
202  * The new packet is placed on the node's saved queue, and the TIM
203  * is changed, if necessary.
204  */
205 void
206 ieee80211_pwrsave(struct ieee80211_node *ni, struct sk_buff *skb)
207 {
208         struct ieee80211vap *vap = ni->ni_vap;
209         struct ieee80211com *ic = ni->ni_ic;
210         unsigned long flags;
211         struct sk_buff *tail;
212         int qlen, age;
213
214         spin_lock_irqsave(&ni->ni_savedq.lock, flags);
215         if (skb_queue_len(&ni->ni_savedq) >= IEEE80211_PS_MAX_QUEUE) {
216                 IEEE80211_NODE_STAT(ni, psq_drops);
217                 spin_unlock_irqrestore(&ni->ni_savedq.lock, flags);
218                 IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni,
219                         "pwr save q overflow, drops %d (size %d)",
220                         ni->ni_stats.ns_psq_drops, IEEE80211_PS_MAX_QUEUE);
221 #ifdef IEEE80211_DEBUG
222                 if (ieee80211_msg_dumppkts(vap))
223                         ieee80211_dump_pkt(ni->ni_ic, skb->data, skb->len, -1, -1);
224 #endif
225                 dev_kfree_skb(skb);
226                 return;
227         }
228         /*
229          * Tag the frame with it's expiry time and insert
230          * it in the queue.  The aging interval is 4 times
231          * the listen interval specified by the station.
232          * Frames that sit around too long are reclaimed
233          * using this information.
234          */
235         /* XXX handle overflow? */
236         age = ((ni->ni_intval * ic->ic_lintval) << 2) / 1024; /* TU -> secs */
237         tail = skb_peek_tail(&ni->ni_savedq);
238         if (tail != NULL) {
239                 age -= M_AGE_GET(tail);
240                 __skb_queue_after(&ni->ni_savedq, tail, skb);
241         } else
242                 __skb_queue_head(&ni->ni_savedq, skb);
243         M_AGE_SET(skb, age);
244         qlen = skb_queue_len(&ni->ni_savedq);
245         spin_unlock_irqrestore(&ni->ni_savedq.lock, flags);
246
247         IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
248                 "save frame, %u now queued", qlen);
249
250         if (qlen == 1 && vap->iv_set_tim != NULL)
251                 vap->iv_set_tim(ni, 1);
252 }
253
254 /*
255  * Handle power-save state change in ap/ibss mode.
256  */
257 void
258 ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable)
259 {
260         struct ieee80211vap *vap = ni->ni_vap;
261
262         KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP ||
263                 vap->iv_opmode == IEEE80211_M_IBSS,
264                 ("unexpected operating mode %u", vap->iv_opmode));
265
266         if (enable) {
267                 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
268                         vap->iv_ps_sta++;
269                 ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
270                 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
271                         "power save mode on, %u sta's in ps mode",
272                         vap->iv_ps_sta);
273                 return;
274         }
275
276         if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT))
277                 vap->iv_ps_sta--;
278         ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
279         IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
280                 "power save mode off, %u sta's in ps mode", vap->iv_ps_sta);
281         /* XXX if no stations in ps mode, flush mc frames */
282
283         /*
284          * Flush queued unicast frames.
285          */
286         if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) {
287                 if (vap->iv_set_tim != NULL)
288                         vap->iv_set_tim(ni, 0);         /* just in case */
289                 return;
290         }
291         IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
292                 "flush ps queue, %u packets queued",
293                 IEEE80211_NODE_SAVEQ_QLEN(ni));
294         for (;;) {
295                 struct sk_buff *skb;
296                 int qlen;
297
298                 IEEE80211_NODE_SAVEQ_LOCK(ni);
299                 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, skb, qlen);
300                 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
301                 if (skb == NULL)
302                         break;
303                 /* 
304                  * If this is the last packet, turn off the TIM bit.
305                  *
306                  * Set the M_PWR_SAV bit on skb to allow encap to test for
307                  * adding MORE_DATA bit to wh.
308                  *
309                  * The 802.11 MAC Spec says we should only set MORE_DATA for 
310                  * unicast packets when the STA is in PS mode (7.1.3.1.8);
311                  * which it isn't.
312                  */
313                 // M_PWR_SAV_SET(skb);
314
315 #ifdef ATH_SUPERG_XR
316                 /*
317                  * if it is a XR vap, send the data to associated normal net
318                  * device. XR vap has a net device which is not registered with
319                  * OS. 
320                  */
321                 if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
322                         skb->dev = vap->iv_xrvap->iv_dev;
323                 else
324                         skb->dev = vap->iv_dev;         /* XXX? unnecessary */
325 #endif
326                 
327                 ieee80211_parent_queue_xmit(skb);
328         }
329         vap->iv_set_tim(ni, 0);
330 }
331
332 /*
333  * Handle power-save state change in station mode.
334  */
335 void
336 ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable)
337 {
338         struct ieee80211_node *ni = vap->iv_bss;
339         int qlen;
340
341         if (!!enable == !!IEEE80211_VAP_IS_SLEEPING(vap)) /* Bool. normalise */
342                 return;
343
344         IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
345                 "sta power save mode %s", enable ? "on" : "off");
346         if (!enable) {
347                 IEEE80211_VAP_WAKEUP(vap);
348                 ieee80211_send_nulldata(ieee80211_ref_node(ni));
349                 /*
350                  * Flush any queued frames; we can do this immediately
351                  * because we know they'll be queued behind the null
352                  * data frame we send the ap.
353                  * XXX can we use a data frame to take us out of ps?
354                  */
355                 qlen = IEEE80211_NODE_SAVEQ_QLEN(ni);
356                 if (qlen != 0) {
357                         IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
358                                 "flush ps queue, %u packets queued", qlen);
359                         for (;;) {
360                                 struct sk_buff *skb;
361
362                                 IEEE80211_NODE_SAVEQ_LOCK(ni);
363                                 skb = __skb_dequeue(&ni->ni_savedq);
364                                 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
365                                 if (skb == NULL)
366                                         break;
367                                 ieee80211_parent_queue_xmit(skb);
368                         }
369                 }
370         } else {
371                 IEEE80211_VAP_GOTOSLEEP(vap);
372                 ieee80211_send_nulldata(ieee80211_ref_node(ni));
373         }
374 }