aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarco Porsch <marco.porsch@etit.tu-chemnitz.de>2012-10-10 15:39:50 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-19 09:43:51 -0400
commitd012a605108a482392be80710ea35f1db27c4aa9 (patch)
treed39be4edcc102a07a7bb764bef154ccd1b46b399 /net
parent5c95b940bd97e744267249e3b0780e6ef04b029c (diff)
mac80211: make client powersave independent of interface type
This patch prepares mac80211 for a later implementation of mesh or ad-hoc powersave clients. The structures related to powersave (buffer, TIM map, counters) are moved from the AP-specific interface structure to a generic structure that can be embedded into any interface type. The functions related to powersave are prepared to allow easy extension with different interface types. For example with: + } else if (sta->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { + ps = &sdata->u.mesh.ps; Some references to the AP's beacon structure are removed where they were obviously not used. The patch compiles without warning and has been briefly tested as AP interface with one client in PS mode. Signed-off-by: Marco Porsch <marco.porsch@etit.tu-chemnitz.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/debugfs_netdev.c6
-rw-r--r--net/mac80211/ieee80211_i.h20
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/rx.c21
-rw-r--r--net/mac80211/sta_info.c43
-rw-r--r--net/mac80211/tx.c100
6 files changed, 122 insertions, 74 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 8802b8d7be13..3393ad5b8ab1 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -395,14 +395,14 @@ __IEEE80211_IF_FILE_W(uapsd_max_sp_len);
395 395
396/* AP attributes */ 396/* AP attributes */
397IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); 397IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC);
398IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 398IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC);
399IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); 399IEEE80211_IF_FILE(dtim_count, u.ap.ps.dtim_count, DEC);
400 400
401static ssize_t ieee80211_if_fmt_num_buffered_multicast( 401static ssize_t ieee80211_if_fmt_num_buffered_multicast(
402 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) 402 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
403{ 403{
404 return scnprintf(buf, buflen, "%u\n", 404 return scnprintf(buf, buflen, "%u\n",
405 skb_queue_len(&sdata->u.ap.ps_bc_buf)); 405 skb_queue_len(&sdata->u.ap.ps.bc_buf));
406} 406}
407__IEEE80211_IF_FILE(num_buffered_multicast, NULL); 407__IEEE80211_IF_FILE(num_buffered_multicast, NULL);
408 408
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ebc1b5dc4127..3026519b236a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -280,23 +280,27 @@ struct probe_resp {
280 u8 data[0]; 280 u8 data[0];
281}; 281};
282 282
283struct ieee80211_if_ap { 283struct ps_data {
284 struct beacon_data __rcu *beacon;
285 struct probe_resp __rcu *probe_resp;
286
287 struct list_head vlans;
288
289 /* yes, this looks ugly, but guarantees that we can later use 284 /* yes, this looks ugly, but guarantees that we can later use
290 * bitmap_empty :) 285 * bitmap_empty :)
291 * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ 286 * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */
292 u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; 287 u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
293 struct sk_buff_head ps_bc_buf; 288 struct sk_buff_head bc_buf;
294 atomic_t num_sta_ps; /* number of stations in PS mode */ 289 atomic_t num_sta_ps; /* number of stations in PS mode */
295 atomic_t num_mcast_sta; /* number of stations receiving multicast */
296 int dtim_count; 290 int dtim_count;
297 bool dtim_bc_mc; 291 bool dtim_bc_mc;
298}; 292};
299 293
294struct ieee80211_if_ap {
295 struct beacon_data __rcu *beacon;
296 struct probe_resp __rcu *probe_resp;
297
298 struct list_head vlans;
299
300 struct ps_data ps;
301 atomic_t num_mcast_sta; /* number of stations receiving multicast */
302};
303
300struct ieee80211_if_wds { 304struct ieee80211_if_wds {
301 struct sta_info *sta; 305 struct sta_info *sta;
302 u8 remote_addr[ETH_ALEN]; 306 u8 remote_addr[ETH_ALEN];
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 99f2b19c8f0d..c50cf6b9e28d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -767,8 +767,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
767 WARN_ON(!list_empty(&sdata->u.ap.vlans)); 767 WARN_ON(!list_empty(&sdata->u.ap.vlans));
768 768
769 /* free all potentially still buffered bcast frames */ 769 /* free all potentially still buffered bcast frames */
770 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf); 770 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
771 skb_queue_purge(&sdata->u.ap.ps_bc_buf); 771 skb_queue_purge(&sdata->u.ap.ps.bc_buf);
772 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { 772 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
773 ieee80211_mgd_stop(sdata); 773 ieee80211_mgd_stop(sdata);
774 } 774 }
@@ -1171,7 +1171,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1171 sdata->vif.p2p = true; 1171 sdata->vif.p2p = true;
1172 /* fall through */ 1172 /* fall through */
1173 case NL80211_IFTYPE_AP: 1173 case NL80211_IFTYPE_AP:
1174 skb_queue_head_init(&sdata->u.ap.ps_bc_buf); 1174 skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
1175 INIT_LIST_HEAD(&sdata->u.ap.vlans); 1175 INIT_LIST_HEAD(&sdata->u.ap.vlans);
1176 break; 1176 break;
1177 case NL80211_IFTYPE_P2P_CLIENT: 1177 case NL80211_IFTYPE_P2P_CLIENT:
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9f64fc4ecd29..d07216ab5f72 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1141,12 +1141,19 @@ ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx)
1141 return RX_CONTINUE; 1141 return RX_CONTINUE;
1142} 1142}
1143 1143
1144static void ap_sta_ps_start(struct sta_info *sta) 1144static void sta_ps_start(struct sta_info *sta)
1145{ 1145{
1146 struct ieee80211_sub_if_data *sdata = sta->sdata; 1146 struct ieee80211_sub_if_data *sdata = sta->sdata;
1147 struct ieee80211_local *local = sdata->local; 1147 struct ieee80211_local *local = sdata->local;
1148 struct ps_data *ps;
1148 1149
1149 atomic_inc(&sdata->bss->num_sta_ps); 1150 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
1151 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1152 ps = &sdata->bss->ps;
1153 else
1154 return;
1155
1156 atomic_inc(&ps->num_sta_ps);
1150 set_sta_flag(sta, WLAN_STA_PS_STA); 1157 set_sta_flag(sta, WLAN_STA_PS_STA);
1151 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) 1158 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
1152 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); 1159 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
@@ -1154,7 +1161,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
1154 sta->sta.addr, sta->sta.aid); 1161 sta->sta.addr, sta->sta.aid);
1155} 1162}
1156 1163
1157static void ap_sta_ps_end(struct sta_info *sta) 1164static void sta_ps_end(struct sta_info *sta)
1158{ 1165{
1159 ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", 1166 ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n",
1160 sta->sta.addr, sta->sta.aid); 1167 sta->sta.addr, sta->sta.aid);
@@ -1181,9 +1188,9 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
1181 return -EINVAL; 1188 return -EINVAL;
1182 1189
1183 if (start) 1190 if (start)
1184 ap_sta_ps_start(sta_inf); 1191 sta_ps_start(sta_inf);
1185 else 1192 else
1186 ap_sta_ps_end(sta_inf); 1193 sta_ps_end(sta_inf);
1187 1194
1188 return 0; 1195 return 0;
1189} 1196}
@@ -1335,10 +1342,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1335 */ 1342 */
1336 if (ieee80211_is_data(hdr->frame_control) && 1343 if (ieee80211_is_data(hdr->frame_control) &&
1337 !ieee80211_has_pm(hdr->frame_control)) 1344 !ieee80211_has_pm(hdr->frame_control))
1338 ap_sta_ps_end(sta); 1345 sta_ps_end(sta);
1339 } else { 1346 } else {
1340 if (ieee80211_has_pm(hdr->frame_control)) 1347 if (ieee80211_has_pm(hdr->frame_control))
1341 ap_sta_ps_start(sta); 1348 sta_ps_start(sta);
1342 } 1349 }
1343 } 1350 }
1344 1351
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d5a5d62b6b0c..daf55e1e0fd3 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -98,6 +98,7 @@ static void free_sta_work(struct work_struct *wk)
98 struct tid_ampdu_tx *tid_tx; 98 struct tid_ampdu_tx *tid_tx;
99 struct ieee80211_sub_if_data *sdata = sta->sdata; 99 struct ieee80211_sub_if_data *sdata = sta->sdata;
100 struct ieee80211_local *local = sdata->local; 100 struct ieee80211_local *local = sdata->local;
101 struct ps_data *ps;
101 102
102 /* 103 /*
103 * At this point, when being called as call_rcu callback, 104 * At this point, when being called as call_rcu callback,
@@ -107,11 +108,15 @@ static void free_sta_work(struct work_struct *wk)
107 */ 108 */
108 109
109 if (test_sta_flag(sta, WLAN_STA_PS_STA)) { 110 if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
110 BUG_ON(!sdata->bss); 111 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
112 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
113 ps = &sdata->bss->ps;
114 else
115 return;
111 116
112 clear_sta_flag(sta, WLAN_STA_PS_STA); 117 clear_sta_flag(sta, WLAN_STA_PS_STA);
113 118
114 atomic_dec(&sdata->bss->num_sta_ps); 119 atomic_dec(&ps->num_sta_ps);
115 sta_info_recalc_tim(sta); 120 sta_info_recalc_tim(sta);
116 } 121 }
117 122
@@ -502,22 +507,22 @@ int sta_info_insert(struct sta_info *sta)
502 return err; 507 return err;
503} 508}
504 509
505static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 510static inline void __bss_tim_set(u8 *tim, u16 id)
506{ 511{
507 /* 512 /*
508 * This format has been mandated by the IEEE specifications, 513 * This format has been mandated by the IEEE specifications,
509 * so this line may not be changed to use the __set_bit() format. 514 * so this line may not be changed to use the __set_bit() format.
510 */ 515 */
511 bss->tim[aid / 8] |= (1 << (aid % 8)); 516 tim[id / 8] |= (1 << (id % 8));
512} 517}
513 518
514static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) 519static inline void __bss_tim_clear(u8 *tim, u16 id)
515{ 520{
516 /* 521 /*
517 * This format has been mandated by the IEEE specifications, 522 * This format has been mandated by the IEEE specifications,
518 * so this line may not be changed to use the __clear_bit() format. 523 * so this line may not be changed to use the __clear_bit() format.
519 */ 524 */
520 bss->tim[aid / 8] &= ~(1 << (aid % 8)); 525 tim[id / 8] &= ~(1 << (id % 8));
521} 526}
522 527
523static unsigned long ieee80211_tids_for_ac(int ac) 528static unsigned long ieee80211_tids_for_ac(int ac)
@@ -541,14 +546,23 @@ static unsigned long ieee80211_tids_for_ac(int ac)
541void sta_info_recalc_tim(struct sta_info *sta) 546void sta_info_recalc_tim(struct sta_info *sta)
542{ 547{
543 struct ieee80211_local *local = sta->local; 548 struct ieee80211_local *local = sta->local;
544 struct ieee80211_if_ap *bss = sta->sdata->bss; 549 struct ps_data *ps;
545 unsigned long flags; 550 unsigned long flags;
546 bool indicate_tim = false; 551 bool indicate_tim = false;
547 u8 ignore_for_tim = sta->sta.uapsd_queues; 552 u8 ignore_for_tim = sta->sta.uapsd_queues;
548 int ac; 553 int ac;
554 u16 id;
555
556 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
557 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
558 if (WARN_ON_ONCE(!sta->sdata->bss))
559 return;
549 560
550 if (WARN_ON_ONCE(!sta->sdata->bss)) 561 ps = &sta->sdata->bss->ps;
562 id = sta->sta.aid;
563 } else {
551 return; 564 return;
565 }
552 566
553 /* No need to do anything if the driver does all */ 567 /* No need to do anything if the driver does all */
554 if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) 568 if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
@@ -587,9 +601,9 @@ void sta_info_recalc_tim(struct sta_info *sta)
587 spin_lock_irqsave(&local->tim_lock, flags); 601 spin_lock_irqsave(&local->tim_lock, flags);
588 602
589 if (indicate_tim) 603 if (indicate_tim)
590 __bss_tim_set(bss, sta->sta.aid); 604 __bss_tim_set(ps->tim, id);
591 else 605 else
592 __bss_tim_clear(bss, sta->sta.aid); 606 __bss_tim_clear(ps->tim, id);
593 607
594 if (local->ops->set_tim) { 608 if (local->ops->set_tim) {
595 local->tim_in_locked_section = true; 609 local->tim_in_locked_section = true;
@@ -948,10 +962,17 @@ static void clear_sta_ps_flags(void *_sta)
948{ 962{
949 struct sta_info *sta = _sta; 963 struct sta_info *sta = _sta;
950 struct ieee80211_sub_if_data *sdata = sta->sdata; 964 struct ieee80211_sub_if_data *sdata = sta->sdata;
965 struct ps_data *ps;
966
967 if (sdata->vif.type == NL80211_IFTYPE_AP ||
968 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
969 ps = &sdata->bss->ps;
970 else
971 return;
951 972
952 clear_sta_flag(sta, WLAN_STA_PS_DRIVER); 973 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
953 if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) 974 if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
954 atomic_dec(&sdata->bss->num_sta_ps); 975 atomic_dec(&ps->num_sta_ps);
955} 976}
956 977
957/* powersave support code */ 978/* powersave support code */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index bbe1d86beea1..065f81cb5618 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -325,16 +325,19 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
325 struct sta_info *sta; 325 struct sta_info *sta;
326 326
327 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 327 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
328 struct ieee80211_if_ap *ap; 328 struct ps_data *ps;
329 if (sdata->vif.type != NL80211_IFTYPE_AP) 329
330 if (sdata->vif.type == NL80211_IFTYPE_AP)
331 ps = &sdata->u.ap.ps;
332 else
330 continue; 333 continue;
331 ap = &sdata->u.ap; 334
332 skb = skb_dequeue(&ap->ps_bc_buf); 335 skb = skb_dequeue(&ps->bc_buf);
333 if (skb) { 336 if (skb) {
334 purged++; 337 purged++;
335 dev_kfree_skb(skb); 338 dev_kfree_skb(skb);
336 } 339 }
337 total += skb_queue_len(&ap->ps_bc_buf); 340 total += skb_queue_len(&ps->bc_buf);
338 } 341 }
339 342
340 /* 343 /*
@@ -364,6 +367,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
364{ 367{
365 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 368 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
366 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 369 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
370 struct ps_data *ps;
367 371
368 /* 372 /*
369 * broadcast/multicast frame 373 * broadcast/multicast frame
@@ -373,16 +377,24 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
373 * This is done either by the hardware or us. 377 * This is done either by the hardware or us.
374 */ 378 */
375 379
376 /* powersaving STAs only in AP/VLAN mode */ 380 /* powersaving STAs currently only in AP/VLAN mode */
377 if (!tx->sdata->bss) 381 if (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
382 tx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
383 if (!tx->sdata->bss)
384 return TX_CONTINUE;
385
386 ps = &tx->sdata->bss->ps;
387 } else {
378 return TX_CONTINUE; 388 return TX_CONTINUE;
389 }
390
379 391
380 /* no buffering for ordered frames */ 392 /* no buffering for ordered frames */
381 if (ieee80211_has_order(hdr->frame_control)) 393 if (ieee80211_has_order(hdr->frame_control))
382 return TX_CONTINUE; 394 return TX_CONTINUE;
383 395
384 /* no stations in PS mode */ 396 /* no stations in PS mode */
385 if (!atomic_read(&tx->sdata->bss->num_sta_ps)) 397 if (!atomic_read(&ps->num_sta_ps))
386 return TX_CONTINUE; 398 return TX_CONTINUE;
387 399
388 info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; 400 info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
@@ -397,14 +409,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
397 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) 409 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
398 purge_old_ps_buffers(tx->local); 410 purge_old_ps_buffers(tx->local);
399 411
400 if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { 412 if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) {
401 ps_dbg(tx->sdata, 413 ps_dbg(tx->sdata,
402 "BC TX buffer full - dropping the oldest frame\n"); 414 "BC TX buffer full - dropping the oldest frame\n");
403 dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); 415 dev_kfree_skb(skb_dequeue(&ps->bc_buf));
404 } else 416 } else
405 tx->local->total_ps_buffered++; 417 tx->local->total_ps_buffered++;
406 418
407 skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb); 419 skb_queue_tail(&ps->bc_buf, tx->skb);
408 420
409 return TX_QUEUED; 421 return TX_QUEUED;
410} 422}
@@ -2246,9 +2258,8 @@ void ieee80211_tx_pending(unsigned long data)
2246/* functions for drivers to get certain frames */ 2258/* functions for drivers to get certain frames */
2247 2259
2248static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, 2260static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
2249 struct ieee80211_if_ap *bss, 2261 struct ps_data *ps,
2250 struct sk_buff *skb, 2262 struct sk_buff *skb)
2251 struct beacon_data *beacon)
2252{ 2263{
2253 u8 *pos, *tim; 2264 u8 *pos, *tim;
2254 int aid0 = 0; 2265 int aid0 = 0;
@@ -2256,27 +2267,27 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
2256 2267
2257 /* Generate bitmap for TIM only if there are any STAs in power save 2268 /* Generate bitmap for TIM only if there are any STAs in power save
2258 * mode. */ 2269 * mode. */
2259 if (atomic_read(&bss->num_sta_ps) > 0) 2270 if (atomic_read(&ps->num_sta_ps) > 0)
2260 /* in the hope that this is faster than 2271 /* in the hope that this is faster than
2261 * checking byte-for-byte */ 2272 * checking byte-for-byte */
2262 have_bits = !bitmap_empty((unsigned long*)bss->tim, 2273 have_bits = !bitmap_empty((unsigned long*)ps->tim,
2263 IEEE80211_MAX_AID+1); 2274 IEEE80211_MAX_AID+1);
2264 2275
2265 if (bss->dtim_count == 0) 2276 if (ps->dtim_count == 0)
2266 bss->dtim_count = sdata->vif.bss_conf.dtim_period - 1; 2277 ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1;
2267 else 2278 else
2268 bss->dtim_count--; 2279 ps->dtim_count--;
2269 2280
2270 tim = pos = (u8 *) skb_put(skb, 6); 2281 tim = pos = (u8 *) skb_put(skb, 6);
2271 *pos++ = WLAN_EID_TIM; 2282 *pos++ = WLAN_EID_TIM;
2272 *pos++ = 4; 2283 *pos++ = 4;
2273 *pos++ = bss->dtim_count; 2284 *pos++ = ps->dtim_count;
2274 *pos++ = sdata->vif.bss_conf.dtim_period; 2285 *pos++ = sdata->vif.bss_conf.dtim_period;
2275 2286
2276 if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) 2287 if (ps->dtim_count == 0 && !skb_queue_empty(&ps->bc_buf))
2277 aid0 = 1; 2288 aid0 = 1;
2278 2289
2279 bss->dtim_bc_mc = aid0 == 1; 2290 ps->dtim_bc_mc = aid0 == 1;
2280 2291
2281 if (have_bits) { 2292 if (have_bits) {
2282 /* Find largest even number N1 so that bits numbered 1 through 2293 /* Find largest even number N1 so that bits numbered 1 through
@@ -2284,14 +2295,14 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
2284 * (N2 + 1) x 8 through 2007 are 0. */ 2295 * (N2 + 1) x 8 through 2007 are 0. */
2285 n1 = 0; 2296 n1 = 0;
2286 for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) { 2297 for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) {
2287 if (bss->tim[i]) { 2298 if (ps->tim[i]) {
2288 n1 = i & 0xfe; 2299 n1 = i & 0xfe;
2289 break; 2300 break;
2290 } 2301 }
2291 } 2302 }
2292 n2 = n1; 2303 n2 = n1;
2293 for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) { 2304 for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) {
2294 if (bss->tim[i]) { 2305 if (ps->tim[i]) {
2295 n2 = i; 2306 n2 = i;
2296 break; 2307 break;
2297 } 2308 }
@@ -2301,7 +2312,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
2301 *pos++ = n1 | aid0; 2312 *pos++ = n1 | aid0;
2302 /* Part Virt Bitmap */ 2313 /* Part Virt Bitmap */
2303 skb_put(skb, n2 - n1); 2314 skb_put(skb, n2 - n1);
2304 memcpy(pos, bss->tim + n1, n2 - n1 + 1); 2315 memcpy(pos, ps->tim + n1, n2 - n1 + 1);
2305 2316
2306 tim[1] = n2 - n1 + 4; 2317 tim[1] = n2 - n1 + 4;
2307 } else { 2318 } else {
@@ -2318,8 +2329,6 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2318 struct sk_buff *skb = NULL; 2329 struct sk_buff *skb = NULL;
2319 struct ieee80211_tx_info *info; 2330 struct ieee80211_tx_info *info;
2320 struct ieee80211_sub_if_data *sdata = NULL; 2331 struct ieee80211_sub_if_data *sdata = NULL;
2321 struct ieee80211_if_ap *ap = NULL;
2322 struct beacon_data *beacon;
2323 enum ieee80211_band band; 2332 enum ieee80211_band band;
2324 struct ieee80211_tx_rate_control txrc; 2333 struct ieee80211_tx_rate_control txrc;
2325 struct ieee80211_chanctx_conf *chanctx_conf; 2334 struct ieee80211_chanctx_conf *chanctx_conf;
@@ -2338,8 +2347,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2338 *tim_length = 0; 2347 *tim_length = 0;
2339 2348
2340 if (sdata->vif.type == NL80211_IFTYPE_AP) { 2349 if (sdata->vif.type == NL80211_IFTYPE_AP) {
2341 ap = &sdata->u.ap; 2350 struct ieee80211_if_ap *ap = &sdata->u.ap;
2342 beacon = rcu_dereference(ap->beacon); 2351 struct beacon_data *beacon = rcu_dereference(ap->beacon);
2352
2343 if (beacon) { 2353 if (beacon) {
2344 /* 2354 /*
2345 * headroom, head length, 2355 * headroom, head length,
@@ -2363,14 +2373,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2363 * of the tim bitmap in mac80211 and the driver. 2373 * of the tim bitmap in mac80211 and the driver.
2364 */ 2374 */
2365 if (local->tim_in_locked_section) { 2375 if (local->tim_in_locked_section) {
2366 ieee80211_beacon_add_tim(sdata, ap, skb, 2376 ieee80211_beacon_add_tim(sdata, &ap->ps, skb);
2367 beacon);
2368 } else { 2377 } else {
2369 unsigned long flags; 2378 unsigned long flags;
2370 2379
2371 spin_lock_irqsave(&local->tim_lock, flags); 2380 spin_lock_irqsave(&local->tim_lock, flags);
2372 ieee80211_beacon_add_tim(sdata, ap, skb, 2381 ieee80211_beacon_add_tim(sdata, &ap->ps, skb);
2373 beacon);
2374 spin_unlock_irqrestore(&local->tim_lock, flags); 2382 spin_unlock_irqrestore(&local->tim_lock, flags);
2375 } 2383 }
2376 2384
@@ -2694,32 +2702,40 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2694 struct sk_buff *skb = NULL; 2702 struct sk_buff *skb = NULL;
2695 struct ieee80211_tx_data tx; 2703 struct ieee80211_tx_data tx;
2696 struct ieee80211_sub_if_data *sdata; 2704 struct ieee80211_sub_if_data *sdata;
2697 struct ieee80211_if_ap *bss = NULL; 2705 struct ps_data *ps;
2698 struct beacon_data *beacon;
2699 struct ieee80211_tx_info *info; 2706 struct ieee80211_tx_info *info;
2700 struct ieee80211_chanctx_conf *chanctx_conf; 2707 struct ieee80211_chanctx_conf *chanctx_conf;
2701 2708
2702 sdata = vif_to_sdata(vif); 2709 sdata = vif_to_sdata(vif);
2703 bss = &sdata->u.ap;
2704 2710
2705 rcu_read_lock(); 2711 rcu_read_lock();
2706 beacon = rcu_dereference(bss->beacon);
2707 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2712 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2708 2713
2709 if (sdata->vif.type != NL80211_IFTYPE_AP || !beacon || !beacon->head || 2714 if (!chanctx_conf)
2710 !chanctx_conf) 2715 goto out;
2716
2717 if (sdata->vif.type == NL80211_IFTYPE_AP) {
2718 struct beacon_data *beacon =
2719 rcu_dereference(sdata->u.ap.beacon);
2720
2721 if (!beacon || !beacon->head)
2722 goto out;
2723
2724 ps = &sdata->u.ap.ps;
2725 } else {
2711 goto out; 2726 goto out;
2727 }
2712 2728
2713 if (bss->dtim_count != 0 || !bss->dtim_bc_mc) 2729 if (ps->dtim_count != 0 || !ps->dtim_bc_mc)
2714 goto out; /* send buffered bc/mc only after DTIM beacon */ 2730 goto out; /* send buffered bc/mc only after DTIM beacon */
2715 2731
2716 while (1) { 2732 while (1) {
2717 skb = skb_dequeue(&bss->ps_bc_buf); 2733 skb = skb_dequeue(&ps->bc_buf);
2718 if (!skb) 2734 if (!skb)
2719 goto out; 2735 goto out;
2720 local->total_ps_buffered--; 2736 local->total_ps_buffered--;
2721 2737
2722 if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { 2738 if (!skb_queue_empty(&ps->bc_buf) && skb->len >= 2) {
2723 struct ieee80211_hdr *hdr = 2739 struct ieee80211_hdr *hdr =
2724 (struct ieee80211_hdr *) skb->data; 2740 (struct ieee80211_hdr *) skb->data;
2725 /* more buffered multicast/broadcast frames ==> set 2741 /* more buffered multicast/broadcast frames ==> set