aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-07-09 08:40:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:30:06 -0400
commit3e122be089e6fb8d3f322416da4cdbb80ce12927 (patch)
tree087db56fcbe05e9a8e2caa874262c81267c27573 /net/mac80211/sta_info.c
parent500c11973233437cbfd298b9d41ba942550aec76 (diff)
mac80211: make master netdev handling sane
Currently, almost every interface type has a 'bss' pointer pointing to BSS information. This BSS information, however, is for a _local_ BSS, not for the BSS we joined, so having it on a STA mode interface makes little sense, but now they have it pointing to the master device, which is an AP mode virtual interface. However, except for some bitrate control data, this pointer is only used in AP/VLAN modes (for power saving stations.) Overall, it is not necessary to even have the master netdev be a valid virtual interface, and it doesn't have to be on the list of interfaces either. This patch changes the master netdev to be special, it now - no longer is on the list of virtual interfaces, which lets me remove a lot of tests for that - no longer has sub_if_data attached, since that isn't used Additionally, this patch changes some vlan/ap mode handling that is related to these 'bss' pointers described above (but in the VLAN case they actually make sense because there they point to the AP they belong to); it also adds some debugging code to IEEE80211_DEV_TO_SUB_IF to validate it is not called on the master netdev any more. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 47d2c1bbfcaa..f2ba653b9d69 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -320,7 +320,9 @@ int sta_info_insert(struct sta_info *sta)
320 /* notify driver */ 320 /* notify driver */
321 if (local->ops->sta_notify) { 321 if (local->ops->sta_notify) {
322 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 322 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
323 sdata = sdata->u.vlan.ap; 323 sdata = container_of(sdata->bss,
324 struct ieee80211_sub_if_data,
325 u.ap);
324 326
325 local->ops->sta_notify(local_to_hw(local), &sdata->vif, 327 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
326 STA_NOTIFY_ADD, sta->addr); 328 STA_NOTIFY_ADD, sta->addr);
@@ -375,8 +377,10 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid)
375static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 377static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
376 struct sta_info *sta) 378 struct sta_info *sta)
377{ 379{
378 if (bss) 380 BUG_ON(!bss);
379 __bss_tim_set(bss, sta->aid); 381
382 __bss_tim_set(bss, sta->aid);
383
380 if (sta->local->ops->set_tim) { 384 if (sta->local->ops->set_tim) {
381 sta->local->tim_in_locked_section = true; 385 sta->local->tim_in_locked_section = true;
382 sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 386 sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1);
@@ -388,6 +392,8 @@ void sta_info_set_tim_bit(struct sta_info *sta)
388{ 392{
389 unsigned long flags; 393 unsigned long flags;
390 394
395 BUG_ON(!sta->sdata->bss);
396
391 spin_lock_irqsave(&sta->local->sta_lock, flags); 397 spin_lock_irqsave(&sta->local->sta_lock, flags);
392 __sta_info_set_tim_bit(sta->sdata->bss, sta); 398 __sta_info_set_tim_bit(sta->sdata->bss, sta);
393 spin_unlock_irqrestore(&sta->local->sta_lock, flags); 399 spin_unlock_irqrestore(&sta->local->sta_lock, flags);
@@ -396,8 +402,10 @@ void sta_info_set_tim_bit(struct sta_info *sta)
396static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 402static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
397 struct sta_info *sta) 403 struct sta_info *sta)
398{ 404{
399 if (bss) 405 BUG_ON(!bss);
400 __bss_tim_clear(bss, sta->aid); 406
407 __bss_tim_clear(bss, sta->aid);
408
401 if (sta->local->ops->set_tim) { 409 if (sta->local->ops->set_tim) {
402 sta->local->tim_in_locked_section = true; 410 sta->local->tim_in_locked_section = true;
403 sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 411 sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0);
@@ -409,6 +417,8 @@ void sta_info_clear_tim_bit(struct sta_info *sta)
409{ 417{
410 unsigned long flags; 418 unsigned long flags;
411 419
420 BUG_ON(!sta->sdata->bss);
421
412 spin_lock_irqsave(&sta->local->sta_lock, flags); 422 spin_lock_irqsave(&sta->local->sta_lock, flags);
413 __sta_info_clear_tim_bit(sta->sdata->bss, sta); 423 __sta_info_clear_tim_bit(sta->sdata->bss, sta);
414 spin_unlock_irqrestore(&sta->local->sta_lock, flags); 424 spin_unlock_irqrestore(&sta->local->sta_lock, flags);
@@ -437,8 +447,9 @@ void __sta_info_unlink(struct sta_info **sta)
437 list_del(&(*sta)->list); 447 list_del(&(*sta)->list);
438 448
439 if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { 449 if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) {
440 if (sdata->bss) 450 BUG_ON(!sdata->bss);
441 atomic_dec(&sdata->bss->num_sta_ps); 451
452 atomic_dec(&sdata->bss->num_sta_ps);
442 __sta_info_clear_tim_bit(sdata->bss, *sta); 453 __sta_info_clear_tim_bit(sdata->bss, *sta);
443 } 454 }
444 455
@@ -446,7 +457,9 @@ void __sta_info_unlink(struct sta_info **sta)
446 457
447 if (local->ops->sta_notify) { 458 if (local->ops->sta_notify) {
448 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 459 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
449 sdata = sdata->u.vlan.ap; 460 sdata = container_of(sdata->bss,
461 struct ieee80211_sub_if_data,
462 u.ap);
450 463
451 local->ops->sta_notify(local_to_hw(local), &sdata->vif, 464 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
452 STA_NOTIFY_REMOVE, (*sta)->addr); 465 STA_NOTIFY_REMOVE, (*sta)->addr);