aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-01-30 14:22:19 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-01-30 14:22:19 -0500
commit20fb9e50338199d9e88512703af4c560ab53bad4 (patch)
tree2d0913749141e9e8e0df774426a658b52fddabbf /net/mac80211
parent0f496df2d9ba48faa808b5fa330de0da1a2d29d7 (diff)
parent3b4797bce0050570e84bedd10e1b14e9320a3551 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-rx.c14
-rw-r--r--net/mac80211/agg-tx.c61
-rw-r--r--net/mac80211/driver-ops.h36
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/key.c5
-rw-r--r--net/mac80211/main.c64
-rw-r--r--net/mac80211/mesh_plink.c168
-rw-r--r--net/mac80211/mlme.c42
-rw-r--r--net/mac80211/sta_info.c5
-rw-r--r--net/mac80211/trace.h53
-rw-r--r--net/mac80211/tx.c8
12 files changed, 304 insertions, 158 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 808338a1bce5..31bf2586fb84 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -83,8 +83,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
83 if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, 83 if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
84 &sta->sta, tid, NULL, 0)) 84 &sta->sta, tid, NULL, 0))
85 sdata_info(sta->sdata, 85 sdata_info(sta->sdata,
86 "HW problem - can not stop rx aggregation for tid %d\n", 86 "HW problem - can not stop rx aggregation for %pM tid %d\n",
87 tid); 87 sta->sta.addr, tid);
88 88
89 /* check if this is a self generated aggregation halt */ 89 /* check if this is a self generated aggregation halt */
90 if (initiator == WLAN_BACK_RECIPIENT && tx) 90 if (initiator == WLAN_BACK_RECIPIENT && tx)
@@ -159,7 +159,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
159 } 159 }
160 rcu_read_unlock(); 160 rcu_read_unlock();
161 161
162 ht_dbg(sta->sdata, "rx session timer expired on tid %d\n", (u16)*ptid); 162 ht_dbg(sta->sdata, "RX session timer expired on %pM tid %d\n",
163 sta->sta.addr, (u16)*ptid);
163 164
164 set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); 165 set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
165 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); 166 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
@@ -247,7 +248,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
247 status = WLAN_STATUS_REQUEST_DECLINED; 248 status = WLAN_STATUS_REQUEST_DECLINED;
248 249
249 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { 250 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
250 ht_dbg(sta->sdata, "Suspend in progress - Denying ADDBA request\n"); 251 ht_dbg(sta->sdata,
252 "Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
253 sta->sta.addr, tid);
251 goto end_no_lock; 254 goto end_no_lock;
252 } 255 }
253 256
@@ -317,7 +320,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
317 320
318 ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, 321 ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
319 &sta->sta, tid, &start_seq_num, 0); 322 &sta->sta, tid, &start_seq_num, 0);
320 ht_dbg(sta->sdata, "Rx A-MPDU request on tid %d result %d\n", tid, ret); 323 ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
324 sta->sta.addr, tid, ret);
321 if (ret) { 325 if (ret) {
322 kfree(tid_agg_rx->reorder_buf); 326 kfree(tid_agg_rx->reorder_buf);
323 kfree(tid_agg_rx->reorder_time); 327 kfree(tid_agg_rx->reorder_time);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 2f0ccbc5f13e..13b7683de5a4 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -296,7 +296,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
296 IEEE80211_AMPDU_TX_STOP_FLUSH_CONT, 296 IEEE80211_AMPDU_TX_STOP_FLUSH_CONT,
297 &sta->sta, tid, NULL, 0); 297 &sta->sta, tid, NULL, 0);
298 WARN_ON_ONCE(ret); 298 WARN_ON_ONCE(ret);
299 goto remove_tid_tx; 299 return 0;
300 } 300 }
301 301
302 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { 302 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
@@ -354,12 +354,15 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
354 */ 354 */
355 } 355 }
356 356
357 if (reason == AGG_STOP_DESTROY_STA) { 357 /*
358 remove_tid_tx: 358 * In the case of AGG_STOP_DESTROY_STA, the driver won't
359 spin_lock_bh(&sta->lock); 359 * necessarily call ieee80211_stop_tx_ba_cb(), so this may
360 ieee80211_remove_tid_tx(sta, tid); 360 * seem like we can leave the tid_tx data pending forever.
361 spin_unlock_bh(&sta->lock); 361 * This is true, in a way, but "forever" is only until the
362 } 362 * station struct is actually destroyed. In the meantime,
363 * leaving it around ensures that we don't transmit packets
364 * to the driver on this TID which might confuse it.
365 */
363 366
364 return 0; 367 return 0;
365} 368}
@@ -387,12 +390,13 @@ static void sta_addba_resp_timer_expired(unsigned long data)
387 test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { 390 test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) {
388 rcu_read_unlock(); 391 rcu_read_unlock();
389 ht_dbg(sta->sdata, 392 ht_dbg(sta->sdata,
390 "timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", 393 "timer expired on %pM tid %d but we are not (or no longer) expecting addBA response there\n",
391 tid); 394 sta->sta.addr, tid);
392 return; 395 return;
393 } 396 }
394 397
395 ht_dbg(sta->sdata, "addBA response timer expired on tid %d\n", tid); 398 ht_dbg(sta->sdata, "addBA response timer expired on %pM tid %d\n",
399 sta->sta.addr, tid);
396 400
397 ieee80211_stop_tx_ba_session(&sta->sta, tid); 401 ieee80211_stop_tx_ba_session(&sta->sta, tid);
398 rcu_read_unlock(); 402 rcu_read_unlock();
@@ -429,7 +433,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
429 &sta->sta, tid, &start_seq_num, 0); 433 &sta->sta, tid, &start_seq_num, 0);
430 if (ret) { 434 if (ret) {
431 ht_dbg(sdata, 435 ht_dbg(sdata,
432 "BA request denied - HW unavailable for tid %d\n", tid); 436 "BA request denied - HW unavailable for %pM tid %d\n",
437 sta->sta.addr, tid);
433 spin_lock_bh(&sta->lock); 438 spin_lock_bh(&sta->lock);
434 ieee80211_agg_splice_packets(sdata, tid_tx, tid); 439 ieee80211_agg_splice_packets(sdata, tid_tx, tid);
435 ieee80211_assign_tid_tx(sta, tid, NULL); 440 ieee80211_assign_tid_tx(sta, tid, NULL);
@@ -442,7 +447,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
442 447
443 /* activate the timer for the recipient's addBA response */ 448 /* activate the timer for the recipient's addBA response */
444 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); 449 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
445 ht_dbg(sdata, "activated addBA response timer on tid %d\n", tid); 450 ht_dbg(sdata, "activated addBA response timer on %pM tid %d\n",
451 sta->sta.addr, tid);
446 452
447 spin_lock_bh(&sta->lock); 453 spin_lock_bh(&sta->lock);
448 sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; 454 sta->ampdu_mlme.last_addba_req_time[tid] = jiffies;
@@ -489,7 +495,8 @@ static void sta_tx_agg_session_timer_expired(unsigned long data)
489 495
490 rcu_read_unlock(); 496 rcu_read_unlock();
491 497
492 ht_dbg(sta->sdata, "tx session timer expired on tid %d\n", (u16)*ptid); 498 ht_dbg(sta->sdata, "tx session timer expired on %pM tid %d\n",
499 sta->sta.addr, (u16)*ptid);
493 500
494 ieee80211_stop_tx_ba_session(&sta->sta, *ptid); 501 ieee80211_stop_tx_ba_session(&sta->sta, *ptid);
495} 502}
@@ -525,7 +532,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
525 532
526 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { 533 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
527 ht_dbg(sdata, 534 ht_dbg(sdata,
528 "BA sessions blocked - Denying BA session request\n"); 535 "BA sessions blocked - Denying BA session request %pM tid %d\n",
536 sta->sta.addr, tid);
529 return -EINVAL; 537 return -EINVAL;
530 } 538 }
531 539
@@ -566,8 +574,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
566 time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + 574 time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] +
567 HT_AGG_RETRIES_PERIOD)) { 575 HT_AGG_RETRIES_PERIOD)) {
568 ht_dbg(sdata, 576 ht_dbg(sdata,
569 "BA request denied - waiting a grace period after %d failed requests on tid %u\n", 577 "BA request denied - waiting a grace period after %d failed requests on %pM tid %u\n",
570 sta->ampdu_mlme.addba_req_num[tid], tid); 578 sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid);
571 ret = -EBUSY; 579 ret = -EBUSY;
572 goto err_unlock_sta; 580 goto err_unlock_sta;
573 } 581 }
@@ -576,8 +584,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
576 /* check if the TID is not in aggregation flow already */ 584 /* check if the TID is not in aggregation flow already */
577 if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { 585 if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) {
578 ht_dbg(sdata, 586 ht_dbg(sdata,
579 "BA request denied - session is not idle on tid %u\n", 587 "BA request denied - session is not idle on %pM tid %u\n",
580 tid); 588 sta->sta.addr, tid);
581 ret = -EAGAIN; 589 ret = -EAGAIN;
582 goto err_unlock_sta; 590 goto err_unlock_sta;
583 } 591 }
@@ -632,7 +640,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
632 640
633 tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 641 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
634 642
635 ht_dbg(sta->sdata, "Aggregation is on for tid %d\n", tid); 643 ht_dbg(sta->sdata, "Aggregation is on for %pM tid %d\n",
644 sta->sta.addr, tid);
636 645
637 drv_ampdu_action(local, sta->sdata, 646 drv_ampdu_action(local, sta->sdata,
638 IEEE80211_AMPDU_TX_OPERATIONAL, 647 IEEE80211_AMPDU_TX_OPERATIONAL,
@@ -802,7 +811,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
802 tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 811 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
803 812
804 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { 813 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
805 ht_dbg(sdata, "unexpected callback to A-MPDU stop\n"); 814 ht_dbg(sdata,
815 "unexpected callback to A-MPDU stop for %pM tid %d\n",
816 sta->sta.addr, tid);
806 goto unlock_sta; 817 goto unlock_sta;
807 } 818 }
808 819
@@ -861,13 +872,15 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
861 goto out; 872 goto out;
862 873
863 if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { 874 if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) {
864 ht_dbg(sta->sdata, "wrong addBA response token, tid %d\n", tid); 875 ht_dbg(sta->sdata, "wrong addBA response token, %pM tid %d\n",
876 sta->sta.addr, tid);
865 goto out; 877 goto out;
866 } 878 }
867 879
868 del_timer_sync(&tid_tx->addba_resp_timer); 880 del_timer_sync(&tid_tx->addba_resp_timer);
869 881
870 ht_dbg(sta->sdata, "switched off addBA timer for tid %d\n", tid); 882 ht_dbg(sta->sdata, "switched off addBA timer for %pM tid %d\n",
883 sta->sta.addr, tid);
871 884
872 /* 885 /*
873 * addba_resp_timer may have fired before we got here, and 886 * addba_resp_timer may have fired before we got here, and
@@ -877,8 +890,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
877 if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || 890 if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) ||
878 test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { 891 test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
879 ht_dbg(sta->sdata, 892 ht_dbg(sta->sdata,
880 "got addBA resp for tid %d but we already gave up\n", 893 "got addBA resp for %pM tid %d but we already gave up\n",
881 tid); 894 sta->sta.addr, tid);
882 goto out; 895 goto out;
883 } 896 }
884 897
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 0c07f94c5378..434b3c4f31b5 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -569,7 +569,8 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local,
569 check_sdata_in_driver(sdata); 569 check_sdata_in_driver(sdata);
570 570
571 WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && 571 WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
572 sdata->vif.type != NL80211_IFTYPE_ADHOC); 572 (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
573 sdata->vif.type != NL80211_IFTYPE_MESH_POINT));
573 574
574 trace_drv_sta_rc_update(local, sdata, sta, changed); 575 trace_drv_sta_rc_update(local, sdata, sta, changed);
575 if (local->ops->sta_rc_update) 576 if (local->ops->sta_rc_update)
@@ -845,11 +846,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
845} 846}
846 847
847static inline void drv_rssi_callback(struct ieee80211_local *local, 848static inline void drv_rssi_callback(struct ieee80211_local *local,
849 struct ieee80211_sub_if_data *sdata,
848 const enum ieee80211_rssi_event event) 850 const enum ieee80211_rssi_event event)
849{ 851{
850 trace_drv_rssi_callback(local, event); 852 trace_drv_rssi_callback(local, sdata, event);
851 if (local->ops->rssi_callback) 853 if (local->ops->rssi_callback)
852 local->ops->rssi_callback(&local->hw, event); 854 local->ops->rssi_callback(&local->hw, &sdata->vif, event);
853 trace_drv_return_void(local); 855 trace_drv_return_void(local);
854} 856}
855 857
@@ -1020,4 +1022,32 @@ static inline void drv_restart_complete(struct ieee80211_local *local)
1020 trace_drv_return_void(local); 1022 trace_drv_return_void(local);
1021} 1023}
1022 1024
1025static inline void
1026drv_set_default_unicast_key(struct ieee80211_local *local,
1027 struct ieee80211_sub_if_data *sdata,
1028 int key_idx)
1029{
1030 check_sdata_in_driver(sdata);
1031
1032 WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
1033
1034 trace_drv_set_default_unicast_key(local, sdata, key_idx);
1035 if (local->ops->set_default_unicast_key)
1036 local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
1037 key_idx);
1038 trace_drv_return_void(local);
1039}
1040
1041#if IS_ENABLED(CONFIG_IPV6)
1042static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
1043 struct ieee80211_sub_if_data *sdata,
1044 struct inet6_dev *idev)
1045{
1046 trace_drv_ipv6_addr_change(local, sdata);
1047 if (local->ops->ipv6_addr_change)
1048 local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1049 trace_drv_return_void(local);
1050}
1051#endif
1052
1023#endif /* __MAC80211_DRIVER_OPS */ 1053#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 63f0430c131e..5fba867d9e2e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -747,8 +747,6 @@ struct ieee80211_sub_if_data {
747 struct work_struct work; 747 struct work_struct work;
748 struct sk_buff_head skb_queue; 748 struct sk_buff_head skb_queue;
749 749
750 bool arp_filter_state;
751
752 u8 needed_rx_chains; 750 u8 needed_rx_chains;
753 enum ieee80211_smps_mode smps_mode; 751 enum ieee80211_smps_mode smps_mode;
754 752
@@ -1129,6 +1127,7 @@ struct ieee80211_local {
1129 struct timer_list dynamic_ps_timer; 1127 struct timer_list dynamic_ps_timer;
1130 struct notifier_block network_latency_notifier; 1128 struct notifier_block network_latency_notifier;
1131 struct notifier_block ifa_notifier; 1129 struct notifier_block ifa_notifier;
1130 struct notifier_block ifa6_notifier;
1132 1131
1133 /* 1132 /*
1134 * The dynamic ps timeout configured from user space via WEXT - 1133 * The dynamic ps timeout configured from user space via WEXT -
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 06fac2991d40..0a36dc6346bb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1574,9 +1574,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1574 /* initialise type-independent data */ 1574 /* initialise type-independent data */
1575 sdata->wdev.wiphy = local->hw.wiphy; 1575 sdata->wdev.wiphy = local->hw.wiphy;
1576 sdata->local = local; 1576 sdata->local = local;
1577#ifdef CONFIG_INET
1578 sdata->arp_filter_state = true;
1579#endif
1580 1577
1581 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 1578 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
1582 skb_queue_head_init(&sdata->fragments[i].skb_list); 1579 skb_queue_head_init(&sdata->fragments[i].skb_list);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 619c5d697999..ef252eb58c36 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -204,8 +204,11 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
204 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 204 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
205 key = key_mtx_dereference(sdata->local, sdata->keys[idx]); 205 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
206 206
207 if (uni) 207 if (uni) {
208 rcu_assign_pointer(sdata->default_unicast_key, key); 208 rcu_assign_pointer(sdata->default_unicast_key, key);
209 drv_set_default_unicast_key(sdata->local, sdata, idx);
210 }
211
209 if (multi) 212 if (multi)
210 rcu_assign_pointer(sdata->default_multicast_key, key); 213 rcu_assign_pointer(sdata->default_multicast_key, key);
211 214
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 39cfe8f10ad2..2bdd454e8bcf 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -23,6 +23,7 @@
23#include <linux/inetdevice.h> 23#include <linux/inetdevice.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/cfg80211.h> 25#include <net/cfg80211.h>
26#include <net/addrconf.h>
26 27
27#include "ieee80211_i.h" 28#include "ieee80211_i.h"
28#include "driver-ops.h" 29#include "driver-ops.h"
@@ -349,27 +350,19 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
349 350
350 /* Copy the addresses to the bss_conf list */ 351 /* Copy the addresses to the bss_conf list */
351 ifa = idev->ifa_list; 352 ifa = idev->ifa_list;
352 while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) { 353 while (ifa) {
353 bss_conf->arp_addr_list[c] = ifa->ifa_address; 354 if (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN)
355 bss_conf->arp_addr_list[c] = ifa->ifa_address;
354 ifa = ifa->ifa_next; 356 ifa = ifa->ifa_next;
355 c++; 357 c++;
356 } 358 }
357 359
358 /* If not all addresses fit the list, disable filtering */
359 if (ifa) {
360 sdata->arp_filter_state = false;
361 c = 0;
362 } else {
363 sdata->arp_filter_state = true;
364 }
365 bss_conf->arp_addr_cnt = c; 360 bss_conf->arp_addr_cnt = c;
366 361
367 /* Configure driver only if associated (which also implies it is up) */ 362 /* Configure driver only if associated (which also implies it is up) */
368 if (ifmgd->associated) { 363 if (ifmgd->associated)
369 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
370 ieee80211_bss_info_change_notify(sdata, 364 ieee80211_bss_info_change_notify(sdata,
371 BSS_CHANGED_ARP_FILTER); 365 BSS_CHANGED_ARP_FILTER);
372 }
373 366
374 mutex_unlock(&ifmgd->mtx); 367 mutex_unlock(&ifmgd->mtx);
375 368
@@ -377,6 +370,37 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
377} 370}
378#endif 371#endif
379 372
373#if IS_ENABLED(CONFIG_IPV6)
374static int ieee80211_ifa6_changed(struct notifier_block *nb,
375 unsigned long data, void *arg)
376{
377 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
378 struct inet6_dev *idev = ifa->idev;
379 struct net_device *ndev = ifa->idev->dev;
380 struct ieee80211_local *local =
381 container_of(nb, struct ieee80211_local, ifa6_notifier);
382 struct wireless_dev *wdev = ndev->ieee80211_ptr;
383 struct ieee80211_sub_if_data *sdata;
384
385 /* Make sure it's our interface that got changed */
386 if (!wdev || wdev->wiphy != local->hw.wiphy)
387 return NOTIFY_DONE;
388
389 sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
390
391 /*
392 * For now only support station mode. This is mostly because
393 * doing AP would have to handle AP_VLAN in some way ...
394 */
395 if (sdata->vif.type != NL80211_IFTYPE_STATION)
396 return NOTIFY_DONE;
397
398 drv_ipv6_addr_change(local, sdata, idev);
399
400 return NOTIFY_DONE;
401}
402#endif
403
380static int ieee80211_napi_poll(struct napi_struct *napi, int budget) 404static int ieee80211_napi_poll(struct napi_struct *napi, int budget)
381{ 405{
382 struct ieee80211_local *local = 406 struct ieee80211_local *local =
@@ -985,12 +1009,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
985 goto fail_ifa; 1009 goto fail_ifa;
986#endif 1010#endif
987 1011
1012#if IS_ENABLED(CONFIG_IPV6)
1013 local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
1014 result = register_inet6addr_notifier(&local->ifa6_notifier);
1015 if (result)
1016 goto fail_ifa6;
1017#endif
1018
988 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, 1019 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll,
989 local->hw.napi_weight); 1020 local->hw.napi_weight);
990 1021
991 return 0; 1022 return 0;
992 1023
1024#if IS_ENABLED(CONFIG_IPV6)
1025 fail_ifa6:
993#ifdef CONFIG_INET 1026#ifdef CONFIG_INET
1027 unregister_inetaddr_notifier(&local->ifa_notifier);
1028#endif
1029#endif
1030#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
994 fail_ifa: 1031 fail_ifa:
995 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, 1032 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
996 &local->network_latency_notifier); 1033 &local->network_latency_notifier);
@@ -1026,6 +1063,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1026#ifdef CONFIG_INET 1063#ifdef CONFIG_INET
1027 unregister_inetaddr_notifier(&local->ifa_notifier); 1064 unregister_inetaddr_notifier(&local->ifa_notifier);
1028#endif 1065#endif
1066#if IS_ENABLED(CONFIG_IPV6)
1067 unregister_inet6addr_notifier(&local->ifa6_notifier);
1068#endif
1029 1069
1030 rtnl_lock(); 1070 rtnl_lock();
1031 1071
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 9e0416696a83..81e612682bc3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -55,30 +55,6 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
55 sta->plink_retries = 0; 55 sta->plink_retries = 0;
56} 56}
57 57
58/*
59 * Allocate mesh sta entry and insert into station table
60 */
61static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
62 u8 *hw_addr)
63{
64 struct sta_info *sta;
65
66 if (sdata->local->num_sta >= MESH_MAX_PLINKS)
67 return NULL;
68
69 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
70 if (!sta)
71 return NULL;
72
73 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
74 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
75 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
76
77 set_sta_flag(sta, WLAN_STA_WME);
78
79 return sta;
80}
81
82/** 58/**
83 * mesh_set_ht_prot_mode - set correct HT protection mode 59 * mesh_set_ht_prot_mode - set correct HT protection mode
84 * 60 *
@@ -309,53 +285,27 @@ free:
309 return err; 285 return err;
310} 286}
311 287
312/** 288static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
313 * mesh_peer_init - initialize new mesh peer and return resulting sta_info 289 struct sta_info *sta,
314 * 290 struct ieee802_11_elems *elems, bool insert)
315 * @sdata: local meshif
316 * @addr: peer's address
317 * @elems: IEs from beacon or mesh peering frame
318 *
319 * call under RCU
320 */
321static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
322 u8 *addr,
323 struct ieee802_11_elems *elems)
324{ 291{
325 struct ieee80211_local *local = sdata->local; 292 struct ieee80211_local *local = sdata->local;
326 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 293 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
327 struct ieee80211_supported_band *sband; 294 struct ieee80211_supported_band *sband;
328 u32 rates, basic_rates = 0; 295 u32 rates, basic_rates = 0, changed = 0;
329 struct sta_info *sta;
330 bool insert = false;
331 296
332 sband = local->hw.wiphy->bands[band]; 297 sband = local->hw.wiphy->bands[band];
333 rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates); 298 rates = ieee80211_sta_get_rates(local, elems, band, &basic_rates);
334 299
335 sta = sta_info_get(sdata, addr);
336 if (!sta) {
337 /* Userspace handles peer allocation when security is enabled */
338 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
339 cfg80211_notify_new_peer_candidate(sdata->dev, addr,
340 elems->ie_start,
341 elems->total_len,
342 GFP_ATOMIC);
343 return NULL;
344 }
345
346 sta = mesh_plink_alloc(sdata, addr);
347 if (!sta)
348 return NULL;
349 insert = true;
350 }
351
352 spin_lock_bh(&sta->lock); 300 spin_lock_bh(&sta->lock);
353 sta->last_rx = jiffies; 301 sta->last_rx = jiffies;
354 if (sta->plink_state == NL80211_PLINK_ESTAB) {
355 spin_unlock_bh(&sta->lock);
356 return sta;
357 }
358 302
303 /* rates and capabilities don't change during peering */
304 if (sta->plink_state == NL80211_PLINK_ESTAB)
305 goto out;
306
307 if (sta->sta.supp_rates[band] != rates)
308 changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
359 sta->sta.supp_rates[band] = rates; 309 sta->sta.supp_rates[band] = rates;
360 if (elems->ht_cap_elem && 310 if (elems->ht_cap_elem &&
361 sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) 311 sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
@@ -374,27 +324,115 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
374 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 324 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
375 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan, 325 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
376 elems->ht_operation, &chandef); 326 elems->ht_operation, &chandef);
327 if (sta->ch_width != chandef.width)
328 changed |= IEEE80211_RC_BW_CHANGED;
377 sta->ch_width = chandef.width; 329 sta->ch_width = chandef.width;
378 } 330 }
379 331
380 if (insert) 332 if (insert)
381 rate_control_rate_init(sta); 333 rate_control_rate_init(sta);
334 else
335 rate_control_rate_update(local, sband, sta, changed);
336out:
382 spin_unlock_bh(&sta->lock); 337 spin_unlock_bh(&sta->lock);
338}
339
340static struct sta_info *
341__mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
342{
343 struct sta_info *sta;
383 344
384 if (insert && sta_info_insert(sta)) 345 if (sdata->local->num_sta >= MESH_MAX_PLINKS)
385 return NULL; 346 return NULL;
386 347
348 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
349 if (!sta)
350 return NULL;
351
352 sta->plink_state = NL80211_PLINK_LISTEN;
353 init_timer(&sta->plink_timer);
354
355 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
356 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
357 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
358
359 set_sta_flag(sta, WLAN_STA_WME);
360
361 return sta;
362}
363
364static struct sta_info *
365mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
366 struct ieee802_11_elems *elems)
367{
368 struct sta_info *sta = NULL;
369
370 /* Userspace handles peer allocation when security is enabled */
371 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
372 cfg80211_notify_new_peer_candidate(sdata->dev, addr,
373 elems->ie_start,
374 elems->total_len,
375 GFP_KERNEL);
376 else
377 sta = __mesh_sta_info_alloc(sdata, addr);
378
379 return sta;
380}
381
382/*
383 * mesh_sta_info_get - return mesh sta info entry for @addr.
384 *
385 * @sdata: local meshif
386 * @addr: peer's address
387 * @elems: IEs from beacon or mesh peering frame.
388 *
389 * Return existing or newly allocated sta_info under RCU read lock.
390 * (re)initialize with given IEs.
391 */
392static struct sta_info *
393mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
394 u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU)
395{
396 struct sta_info *sta = NULL;
397
398 rcu_read_lock();
399 sta = sta_info_get(sdata, addr);
400 if (sta) {
401 mesh_sta_info_init(sdata, sta, elems, false);
402 } else {
403 rcu_read_unlock();
404 /* can't run atomic */
405 sta = mesh_sta_info_alloc(sdata, addr, elems);
406 if (!sta) {
407 rcu_read_lock();
408 return NULL;
409 }
410
411 mesh_sta_info_init(sdata, sta, elems, true);
412
413 if (sta_info_insert_rcu(sta))
414 return NULL;
415 }
416
387 return sta; 417 return sta;
388} 418}
389 419
420/*
421 * mesh_neighbour_update - update or initialize new mesh neighbor.
422 *
423 * @sdata: local meshif
424 * @addr: peer's address
425 * @elems: IEs from beacon or mesh peering frame
426 *
427 * Initiates peering if appropriate.
428 */
390void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 429void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
391 u8 *hw_addr, 430 u8 *hw_addr,
392 struct ieee802_11_elems *elems) 431 struct ieee802_11_elems *elems)
393{ 432{
394 struct sta_info *sta; 433 struct sta_info *sta;
395 434
396 rcu_read_lock(); 435 sta = mesh_sta_info_get(sdata, hw_addr, elems);
397 sta = mesh_peer_init(sdata, hw_addr, elems);
398 if (!sta) 436 if (!sta)
399 goto out; 437 goto out;
400 438
@@ -632,6 +670,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
632 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) 670 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
633 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2); 671 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
634 672
673 /* WARNING: Only for sta pointer, is dropped & re-acquired */
635 rcu_read_lock(); 674 rcu_read_lock();
636 675
637 sta = sta_info_get(sdata, mgmt->sa); 676 sta = sta_info_get(sdata, mgmt->sa);
@@ -735,8 +774,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
735 } 774 }
736 775
737 if (event == OPN_ACPT) { 776 if (event == OPN_ACPT) {
777 rcu_read_unlock();
738 /* allocate sta entry if necessary and update info */ 778 /* allocate sta entry if necessary and update info */
739 sta = mesh_peer_init(sdata, mgmt->sa, &elems); 779 sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
740 if (!sta) { 780 if (!sta) {
741 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); 781 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
742 rcu_read_unlock(); 782 rcu_read_unlock();
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e930175771ff..5913fb924b12 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1465,10 +1465,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1465 bss_info_changed |= BSS_CHANGED_CQM; 1465 bss_info_changed |= BSS_CHANGED_CQM;
1466 1466
1467 /* Enable ARP filtering */ 1467 /* Enable ARP filtering */
1468 if (bss_conf->arp_filter_enabled != sdata->arp_filter_state) { 1468 if (bss_conf->arp_addr_cnt)
1469 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
1470 bss_info_changed |= BSS_CHANGED_ARP_FILTER; 1469 bss_info_changed |= BSS_CHANGED_ARP_FILTER;
1471 }
1472 1470
1473 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 1471 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
1474 1472
@@ -1489,7 +1487,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1489{ 1487{
1490 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1488 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1491 struct ieee80211_local *local = sdata->local; 1489 struct ieee80211_local *local = sdata->local;
1492 struct sta_info *sta;
1493 u32 changed = 0; 1490 u32 changed = 0;
1494 1491
1495 ASSERT_MGD_MTX(ifmgd); 1492 ASSERT_MGD_MTX(ifmgd);
@@ -1521,14 +1518,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1521 netif_tx_stop_all_queues(sdata->dev); 1518 netif_tx_stop_all_queues(sdata->dev);
1522 netif_carrier_off(sdata->dev); 1519 netif_carrier_off(sdata->dev);
1523 1520
1524 mutex_lock(&local->sta_mtx);
1525 sta = sta_info_get(sdata, ifmgd->bssid);
1526 if (sta) {
1527 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
1528 ieee80211_sta_tear_down_BA_sessions(sta, AGG_STOP_DESTROY_STA);
1529 }
1530 mutex_unlock(&local->sta_mtx);
1531
1532 /* 1521 /*
1533 * if we want to get out of ps before disassoc (why?) we have 1522 * if we want to get out of ps before disassoc (why?) we have
1534 * to do it before sending disassoc, as otherwise the null-packet 1523 * to do it before sending disassoc, as otherwise the null-packet
@@ -1582,10 +1571,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1582 cancel_work_sync(&local->dynamic_ps_enable_work); 1571 cancel_work_sync(&local->dynamic_ps_enable_work);
1583 1572
1584 /* Disable ARP filtering */ 1573 /* Disable ARP filtering */
1585 if (sdata->vif.bss_conf.arp_filter_enabled) { 1574 if (sdata->vif.bss_conf.arp_addr_cnt)
1586 sdata->vif.bss_conf.arp_filter_enabled = false;
1587 changed |= BSS_CHANGED_ARP_FILTER; 1575 changed |= BSS_CHANGED_ARP_FILTER;
1588 }
1589 1576
1590 sdata->vif.bss_conf.qos = false; 1577 sdata->vif.bss_conf.qos = false;
1591 changed |= BSS_CHANGED_QOS; 1578 changed |= BSS_CHANGED_QOS;
@@ -2608,12 +2595,12 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2608 if (sig > ifmgd->rssi_max_thold && 2595 if (sig > ifmgd->rssi_max_thold &&
2609 (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) { 2596 (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
2610 ifmgd->last_ave_beacon_signal = sig; 2597 ifmgd->last_ave_beacon_signal = sig;
2611 drv_rssi_callback(local, RSSI_EVENT_HIGH); 2598 drv_rssi_callback(local, sdata, RSSI_EVENT_HIGH);
2612 } else if (sig < ifmgd->rssi_min_thold && 2599 } else if (sig < ifmgd->rssi_min_thold &&
2613 (last_sig >= ifmgd->rssi_max_thold || 2600 (last_sig >= ifmgd->rssi_max_thold ||
2614 last_sig == 0)) { 2601 last_sig == 0)) {
2615 ifmgd->last_ave_beacon_signal = sig; 2602 ifmgd->last_ave_beacon_signal = sig;
2616 drv_rssi_callback(local, RSSI_EVENT_LOW); 2603 drv_rssi_callback(local, sdata, RSSI_EVENT_LOW);
2617 } 2604 }
2618 } 2605 }
2619 2606
@@ -3169,23 +3156,22 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3169{ 3156{
3170 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3157 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3171 3158
3172 if (!ifmgd->associated) 3159 mutex_lock(&ifmgd->mtx);
3160 if (!ifmgd->associated) {
3161 mutex_unlock(&ifmgd->mtx);
3173 return; 3162 return;
3163 }
3174 3164
3175 if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) { 3165 if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
3176 sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; 3166 sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
3177 mutex_lock(&ifmgd->mtx); 3167 mlme_dbg(sdata, "driver requested disconnect after resume\n");
3178 if (ifmgd->associated) { 3168 ieee80211_sta_connection_lost(sdata,
3179 mlme_dbg(sdata, 3169 ifmgd->associated->bssid,
3180 "driver requested disconnect after resume\n"); 3170 WLAN_REASON_UNSPECIFIED);
3181 ieee80211_sta_connection_lost(sdata,
3182 ifmgd->associated->bssid,
3183 WLAN_REASON_UNSPECIFIED);
3184 mutex_unlock(&ifmgd->mtx);
3185 return;
3186 }
3187 mutex_unlock(&ifmgd->mtx); 3171 mutex_unlock(&ifmgd->mtx);
3172 return;
3188 } 3173 }
3174 mutex_unlock(&ifmgd->mtx);
3189 3175
3190 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) 3176 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
3191 add_timer(&ifmgd->timer); 3177 add_timer(&ifmgd->timer);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 9d864ed5f3da..227233c3ff7f 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -380,11 +380,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
380 380
381 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); 381 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
382 382
383#ifdef CONFIG_MAC80211_MESH
384 sta->plink_state = NL80211_PLINK_LISTEN;
385 init_timer(&sta->plink_timer);
386#endif
387
388 return sta; 383 return sta;
389} 384}
390 385
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 41861b91daa3..6ca53d64cb28 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -347,8 +347,11 @@ TRACE_EVENT(drv_bss_info_changed,
347 __field(s32, cqm_rssi_hyst); 347 __field(s32, cqm_rssi_hyst);
348 __field(u32, channel_width); 348 __field(u32, channel_width);
349 __field(u32, channel_cfreq1); 349 __field(u32, channel_cfreq1);
350 __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt); 350 __dynamic_array(u32, arp_addr_list,
351 __field(bool, arp_filter_enabled); 351 info->arp_addr_cnt > IEEE80211_BSS_ARP_ADDR_LIST_LEN ?
352 IEEE80211_BSS_ARP_ADDR_LIST_LEN :
353 info->arp_addr_cnt);
354 __field(int, arp_addr_cnt);
352 __field(bool, qos); 355 __field(bool, qos);
353 __field(bool, idle); 356 __field(bool, idle);
354 __field(bool, ps); 357 __field(bool, ps);
@@ -384,9 +387,11 @@ TRACE_EVENT(drv_bss_info_changed,
384 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst; 387 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst;
385 __entry->channel_width = info->chandef.width; 388 __entry->channel_width = info->chandef.width;
386 __entry->channel_cfreq1 = info->chandef.center_freq1; 389 __entry->channel_cfreq1 = info->chandef.center_freq1;
390 __entry->arp_addr_cnt = info->arp_addr_cnt;
387 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list, 391 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list,
388 sizeof(u32) * info->arp_addr_cnt); 392 sizeof(u32) * (info->arp_addr_cnt > IEEE80211_BSS_ARP_ADDR_LIST_LEN ?
389 __entry->arp_filter_enabled = info->arp_filter_enabled; 393 IEEE80211_BSS_ARP_ADDR_LIST_LEN :
394 info->arp_addr_cnt));
390 __entry->qos = info->qos; 395 __entry->qos = info->qos;
391 __entry->idle = info->idle; 396 __entry->idle = info->idle;
392 __entry->ps = info->ps; 397 __entry->ps = info->ps;
@@ -1184,23 +1189,26 @@ TRACE_EVENT(drv_set_rekey_data,
1184 1189
1185TRACE_EVENT(drv_rssi_callback, 1190TRACE_EVENT(drv_rssi_callback,
1186 TP_PROTO(struct ieee80211_local *local, 1191 TP_PROTO(struct ieee80211_local *local,
1192 struct ieee80211_sub_if_data *sdata,
1187 enum ieee80211_rssi_event rssi_event), 1193 enum ieee80211_rssi_event rssi_event),
1188 1194
1189 TP_ARGS(local, rssi_event), 1195 TP_ARGS(local, sdata, rssi_event),
1190 1196
1191 TP_STRUCT__entry( 1197 TP_STRUCT__entry(
1192 LOCAL_ENTRY 1198 LOCAL_ENTRY
1199 VIF_ENTRY
1193 __field(u32, rssi_event) 1200 __field(u32, rssi_event)
1194 ), 1201 ),
1195 1202
1196 TP_fast_assign( 1203 TP_fast_assign(
1197 LOCAL_ASSIGN; 1204 LOCAL_ASSIGN;
1205 VIF_ASSIGN;
1198 __entry->rssi_event = rssi_event; 1206 __entry->rssi_event = rssi_event;
1199 ), 1207 ),
1200 1208
1201 TP_printk( 1209 TP_printk(
1202 LOCAL_PR_FMT " rssi_event:%d", 1210 LOCAL_PR_FMT VIF_PR_FMT " rssi_event:%d",
1203 LOCAL_PR_ARG, __entry->rssi_event 1211 LOCAL_PR_ARG, VIF_PR_ARG, __entry->rssi_event
1204 ) 1212 )
1205); 1213);
1206 1214
@@ -1432,6 +1440,14 @@ DEFINE_EVENT(local_only_evt, drv_restart_complete,
1432 TP_ARGS(local) 1440 TP_ARGS(local)
1433); 1441);
1434 1442
1443#if IS_ENABLED(CONFIG_IPV6)
1444DEFINE_EVENT(local_sdata_evt, drv_ipv6_addr_change,
1445 TP_PROTO(struct ieee80211_local *local,
1446 struct ieee80211_sub_if_data *sdata),
1447 TP_ARGS(local, sdata)
1448);
1449#endif
1450
1435/* 1451/*
1436 * Tracing for API calls that drivers call. 1452 * Tracing for API calls that drivers call.
1437 */ 1453 */
@@ -1821,6 +1837,29 @@ TRACE_EVENT(stop_queue,
1821 ) 1837 )
1822); 1838);
1823 1839
1840TRACE_EVENT(drv_set_default_unicast_key,
1841 TP_PROTO(struct ieee80211_local *local,
1842 struct ieee80211_sub_if_data *sdata,
1843 int key_idx),
1844
1845 TP_ARGS(local, sdata, key_idx),
1846
1847 TP_STRUCT__entry(
1848 LOCAL_ENTRY
1849 VIF_ENTRY
1850 __field(int, key_idx)
1851 ),
1852
1853 TP_fast_assign(
1854 LOCAL_ASSIGN;
1855 VIF_ASSIGN;
1856 __entry->key_idx = key_idx;
1857 ),
1858
1859 TP_printk(LOCAL_PR_FMT VIF_PR_FMT " key_idx:%d",
1860 LOCAL_PR_ARG, VIF_PR_ARG, __entry->key_idx)
1861);
1862
1824#ifdef CONFIG_MAC80211_MESSAGE_TRACING 1863#ifdef CONFIG_MAC80211_MESSAGE_TRACING
1825#undef TRACE_SYSTEM 1864#undef TRACE_SYSTEM
1826#define TRACE_SYSTEM mac80211_msg 1865#define TRACE_SYSTEM mac80211_msg
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index f32d68186dbc..a2cb6a302cc7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1787,16 +1787,16 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1787 break; 1787 break;
1788 /* fall through */ 1788 /* fall through */
1789 case NL80211_IFTYPE_AP: 1789 case NL80211_IFTYPE_AP:
1790 if (sdata->vif.type == NL80211_IFTYPE_AP)
1791 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1792 if (!chanctx_conf)
1793 goto fail_rcu;
1790 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 1794 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
1791 /* DA BSSID SA */ 1795 /* DA BSSID SA */
1792 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1796 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1793 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); 1797 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
1794 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); 1798 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
1795 hdrlen = 24; 1799 hdrlen = 24;
1796 if (sdata->vif.type == NL80211_IFTYPE_AP)
1797 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1798 if (!chanctx_conf)
1799 goto fail_rcu;
1800 band = chanctx_conf->def.chan->band; 1800 band = chanctx_conf->def.chan->band;
1801 break; 1801 break;
1802 case NL80211_IFTYPE_WDS: 1802 case NL80211_IFTYPE_WDS: