diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d2eb64e12353..f3e502502fee 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 | ||
@@ -137,7 +142,7 @@ static void free_sta_work(struct work_struct *wk) | |||
137 | * drivers have to handle aggregation stop being requested, followed | 142 | * drivers have to handle aggregation stop being requested, followed |
138 | * directly by station destruction. | 143 | * directly by station destruction. |
139 | */ | 144 | */ |
140 | for (i = 0; i < STA_TID_NUM; i++) { | 145 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
141 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); | 146 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); |
142 | if (!tid_tx) | 147 | if (!tid_tx) |
143 | continue; | 148 | continue; |
@@ -325,7 +330,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
325 | return NULL; | 330 | return NULL; |
326 | } | 331 | } |
327 | 332 | ||
328 | for (i = 0; i < STA_TID_NUM; i++) { | 333 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
329 | /* | 334 | /* |
330 | * timer_to_tid must be initialized with identity mapping | 335 | * timer_to_tid must be initialized with identity mapping |
331 | * to enable session_timer's data differentiation. See | 336 | * to enable session_timer's data differentiation. See |
@@ -338,7 +343,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
338 | skb_queue_head_init(&sta->tx_filtered[i]); | 343 | skb_queue_head_init(&sta->tx_filtered[i]); |
339 | } | 344 | } |
340 | 345 | ||
341 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 346 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) |
342 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 347 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); |
343 | 348 | ||
344 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); | 349 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); |
@@ -502,22 +507,22 @@ int sta_info_insert(struct sta_info *sta) | |||
502 | return err; | 507 | return err; |
503 | } | 508 | } |
504 | 509 | ||
505 | static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) | 510 | static 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 | ||
514 | static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | 519 | static 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 | ||
523 | static unsigned long ieee80211_tids_for_ac(int ac) | 528 | static unsigned long ieee80211_tids_for_ac(int ac) |
@@ -541,14 +546,23 @@ static unsigned long ieee80211_tids_for_ac(int ac) | |||
541 | void sta_info_recalc_tim(struct sta_info *sta) | 546 | void 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; |
@@ -893,8 +907,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
893 | continue; | 907 | continue; |
894 | 908 | ||
895 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 909 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
896 | ibss_dbg(sdata, "expiring inactive STA %pM\n", | 910 | sta_dbg(sta->sdata, "expiring inactive STA %pM\n", |
897 | sta->sta.addr); | 911 | sta->sta.addr); |
898 | WARN_ON(__sta_info_destroy(sta)); | 912 | WARN_ON(__sta_info_destroy(sta)); |
899 | } | 913 | } |
900 | } | 914 | } |
@@ -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 */ |
@@ -965,7 +986,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
965 | 986 | ||
966 | clear_sta_flag(sta, WLAN_STA_SP); | 987 | clear_sta_flag(sta, WLAN_STA_SP); |
967 | 988 | ||
968 | BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1); | 989 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); |
969 | sta->driver_buffered_tids = 0; | 990 | sta->driver_buffered_tids = 0; |
970 | 991 | ||
971 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 992 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
@@ -1013,6 +1034,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1013 | __le16 fc; | 1034 | __le16 fc; |
1014 | bool qos = test_sta_flag(sta, WLAN_STA_WME); | 1035 | bool qos = test_sta_flag(sta, WLAN_STA_WME); |
1015 | struct ieee80211_tx_info *info; | 1036 | struct ieee80211_tx_info *info; |
1037 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
1016 | 1038 | ||
1017 | if (qos) { | 1039 | if (qos) { |
1018 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | 1040 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | |
@@ -1062,7 +1084,16 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1062 | 1084 | ||
1063 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); | 1085 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); |
1064 | 1086 | ||
1065 | ieee80211_xmit(sdata, skb); | 1087 | rcu_read_lock(); |
1088 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
1089 | if (WARN_ON(!chanctx_conf)) { | ||
1090 | rcu_read_unlock(); | ||
1091 | kfree_skb(skb); | ||
1092 | return; | ||
1093 | } | ||
1094 | |||
1095 | ieee80211_xmit(sdata, skb, chanctx_conf->def.chan->band); | ||
1096 | rcu_read_unlock(); | ||
1066 | } | 1097 | } |
1067 | 1098 | ||
1068 | static void | 1099 | static void |
@@ -1343,7 +1374,7 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | |||
1343 | { | 1374 | { |
1344 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 1375 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
1345 | 1376 | ||
1346 | if (WARN_ON(tid >= STA_TID_NUM)) | 1377 | if (WARN_ON(tid >= IEEE80211_NUM_TIDS)) |
1347 | return; | 1378 | return; |
1348 | 1379 | ||
1349 | if (buffered) | 1380 | if (buffered) |