aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c175
1 files changed, 77 insertions, 98 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1b087fff93e7..1a8591b77a13 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"
@@ -33,8 +34,6 @@
33#include "cfg.h" 34#include "cfg.h"
34#include "debugfs.h" 35#include "debugfs.h"
35 36
36static struct lock_class_key ieee80211_rx_skb_queue_class;
37
38void ieee80211_configure_filter(struct ieee80211_local *local) 37void ieee80211_configure_filter(struct ieee80211_local *local)
39{ 38{
40 u64 mc; 39 u64 mc;
@@ -207,76 +206,10 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
207 u32 changed) 206 u32 changed)
208{ 207{
209 struct ieee80211_local *local = sdata->local; 208 struct ieee80211_local *local = sdata->local;
210 static const u8 zero[ETH_ALEN] = { 0 };
211 209
212 if (!changed) 210 if (!changed)
213 return; 211 return;
214 212
215 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
216 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
217 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
218 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
219 else if (sdata->vif.type == NL80211_IFTYPE_AP)
220 sdata->vif.bss_conf.bssid = sdata->vif.addr;
221 else if (sdata->vif.type == NL80211_IFTYPE_WDS)
222 sdata->vif.bss_conf.bssid = NULL;
223 else if (ieee80211_vif_is_mesh(&sdata->vif)) {
224 sdata->vif.bss_conf.bssid = zero;
225 } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {
226 sdata->vif.bss_conf.bssid = sdata->vif.addr;
227 WARN_ONCE(changed & ~(BSS_CHANGED_IDLE),
228 "P2P Device BSS changed %#x", changed);
229 } else {
230 WARN_ON(1);
231 return;
232 }
233
234 switch (sdata->vif.type) {
235 case NL80211_IFTYPE_AP:
236 case NL80211_IFTYPE_ADHOC:
237 case NL80211_IFTYPE_WDS:
238 case NL80211_IFTYPE_MESH_POINT:
239 break;
240 default:
241 /* do not warn to simplify caller in scan.c */
242 changed &= ~BSS_CHANGED_BEACON_ENABLED;
243 if (WARN_ON(changed & BSS_CHANGED_BEACON))
244 return;
245 break;
246 }
247
248 if (changed & BSS_CHANGED_BEACON_ENABLED) {
249 if (local->quiescing || !ieee80211_sdata_running(sdata) ||
250 test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) {
251 sdata->vif.bss_conf.enable_beacon = false;
252 } else {
253 /*
254 * Beacon should be enabled, but AP mode must
255 * check whether there is a beacon configured.
256 */
257 switch (sdata->vif.type) {
258 case NL80211_IFTYPE_AP:
259 sdata->vif.bss_conf.enable_beacon =
260 !!sdata->u.ap.beacon;
261 break;
262 case NL80211_IFTYPE_ADHOC:
263 sdata->vif.bss_conf.enable_beacon =
264 !!sdata->u.ibss.presp;
265 break;
266#ifdef CONFIG_MAC80211_MESH
267 case NL80211_IFTYPE_MESH_POINT:
268 sdata->vif.bss_conf.enable_beacon =
269 !!sdata->u.mesh.mesh_id_len;
270 break;
271#endif
272 default:
273 /* not reached */
274 WARN_ON(1);
275 break;
276 }
277 }
278 }
279
280 drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); 213 drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
281} 214}
282 215
@@ -415,27 +348,19 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
415 348
416 /* Copy the addresses to the bss_conf list */ 349 /* Copy the addresses to the bss_conf list */
417 ifa = idev->ifa_list; 350 ifa = idev->ifa_list;
418 while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) { 351 while (ifa) {
419 bss_conf->arp_addr_list[c] = ifa->ifa_address; 352 if (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN)
353 bss_conf->arp_addr_list[c] = ifa->ifa_address;
420 ifa = ifa->ifa_next; 354 ifa = ifa->ifa_next;
421 c++; 355 c++;
422 } 356 }
423 357
424 /* If not all addresses fit the list, disable filtering */
425 if (ifa) {
426 sdata->arp_filter_state = false;
427 c = 0;
428 } else {
429 sdata->arp_filter_state = true;
430 }
431 bss_conf->arp_addr_cnt = c; 358 bss_conf->arp_addr_cnt = c;
432 359
433 /* Configure driver only if associated (which also implies it is up) */ 360 /* Configure driver only if associated (which also implies it is up) */
434 if (ifmgd->associated) { 361 if (ifmgd->associated)
435 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
436 ieee80211_bss_info_change_notify(sdata, 362 ieee80211_bss_info_change_notify(sdata,
437 BSS_CHANGED_ARP_FILTER); 363 BSS_CHANGED_ARP_FILTER);
438 }
439 364
440 mutex_unlock(&ifmgd->mtx); 365 mutex_unlock(&ifmgd->mtx);
441 366
@@ -443,6 +368,37 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
443} 368}
444#endif 369#endif
445 370
371#if IS_ENABLED(CONFIG_IPV6)
372static int ieee80211_ifa6_changed(struct notifier_block *nb,
373 unsigned long data, void *arg)
374{
375 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg;
376 struct inet6_dev *idev = ifa->idev;
377 struct net_device *ndev = ifa->idev->dev;
378 struct ieee80211_local *local =
379 container_of(nb, struct ieee80211_local, ifa6_notifier);
380 struct wireless_dev *wdev = ndev->ieee80211_ptr;
381 struct ieee80211_sub_if_data *sdata;
382
383 /* Make sure it's our interface that got changed */
384 if (!wdev || wdev->wiphy != local->hw.wiphy)
385 return NOTIFY_DONE;
386
387 sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
388
389 /*
390 * For now only support station mode. This is mostly because
391 * doing AP would have to handle AP_VLAN in some way ...
392 */
393 if (sdata->vif.type != NL80211_IFTYPE_STATION)
394 return NOTIFY_DONE;
395
396 drv_ipv6_addr_change(local, sdata, idev);
397
398 return NOTIFY_DONE;
399}
400#endif
401
446static int ieee80211_napi_poll(struct napi_struct *napi, int budget) 402static int ieee80211_napi_poll(struct napi_struct *napi, int budget)
447{ 403{
448 struct ieee80211_local *local = 404 struct ieee80211_local *local =
@@ -537,6 +493,7 @@ static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
537 493
538 .cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 494 .cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
539 IEEE80211_HT_CAP_MAX_AMSDU | 495 IEEE80211_HT_CAP_MAX_AMSDU |
496 IEEE80211_HT_CAP_SGI_20 |
540 IEEE80211_HT_CAP_SGI_40), 497 IEEE80211_HT_CAP_SGI_40),
541 .mcs = { 498 .mcs = {
542 .rx_mask = { 0xff, 0xff, 0xff, 0xff, 0xff, 499 .rx_mask = { 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -544,6 +501,11 @@ static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
544 }, 501 },
545}; 502};
546 503
504static const u8 extended_capabilities[] = {
505 0, 0, 0, 0, 0, 0, 0,
506 WLAN_EXT_CAPA8_OPMODE_NOTIF,
507};
508
547struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 509struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
548 const struct ieee80211_ops *ops) 510 const struct ieee80211_ops *ops)
549{ 511{
@@ -600,6 +562,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
600 WIPHY_FLAG_REPORTS_OBSS | 562 WIPHY_FLAG_REPORTS_OBSS |
601 WIPHY_FLAG_OFFCHAN_TX; 563 WIPHY_FLAG_OFFCHAN_TX;
602 564
565 wiphy->extended_capabilities = extended_capabilities;
566 wiphy->extended_capabilities_mask = extended_capabilities;
567 wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities);
568
603 if (ops->remain_on_channel) 569 if (ops->remain_on_channel)
604 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 570 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
605 571
@@ -653,25 +619,19 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
653 619
654 mutex_init(&local->key_mtx); 620 mutex_init(&local->key_mtx);
655 spin_lock_init(&local->filter_lock); 621 spin_lock_init(&local->filter_lock);
622 spin_lock_init(&local->rx_path_lock);
656 spin_lock_init(&local->queue_stop_reason_lock); 623 spin_lock_init(&local->queue_stop_reason_lock);
657 624
658 INIT_LIST_HEAD(&local->chanctx_list); 625 INIT_LIST_HEAD(&local->chanctx_list);
659 mutex_init(&local->chanctx_mtx); 626 mutex_init(&local->chanctx_mtx);
660 627
661 /*
662 * The rx_skb_queue is only accessed from tasklets,
663 * but other SKB queues are used from within IRQ
664 * context. Therefore, this one needs a different
665 * locking class so our direct, non-irq-safe use of
666 * the queue's lock doesn't throw lockdep warnings.
667 */
668 skb_queue_head_init_class(&local->rx_skb_queue,
669 &ieee80211_rx_skb_queue_class);
670
671 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 628 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
672 629
673 INIT_WORK(&local->restart_work, ieee80211_restart_work); 630 INIT_WORK(&local->restart_work, ieee80211_restart_work);
674 631
632 INIT_WORK(&local->radar_detected_work,
633 ieee80211_dfs_radar_detected_work);
634
675 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); 635 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
676 local->smps_mode = IEEE80211_SMPS_OFF; 636 local->smps_mode = IEEE80211_SMPS_OFF;
677 637
@@ -687,8 +647,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
687 647
688 spin_lock_init(&local->ack_status_lock); 648 spin_lock_init(&local->ack_status_lock);
689 idr_init(&local->ack_status_frames); 649 idr_init(&local->ack_status_frames);
690 /* preallocate at least one entry */
691 idr_pre_get(&local->ack_status_frames, GFP_KERNEL);
692 650
693 sta_info_init(local); 651 sta_info_init(local);
694 652
@@ -747,9 +705,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
747 return -EINVAL; 705 return -EINVAL;
748#endif 706#endif
749 707
750 if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
751 return -EINVAL;
752
753 if (!local->use_chanctx) { 708 if (!local->use_chanctx) {
754 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { 709 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
755 const struct ieee80211_iface_combination *comb; 710 const struct ieee80211_iface_combination *comb;
@@ -767,6 +722,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
767 */ 722 */
768 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) 723 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS))
769 return -EINVAL; 724 return -EINVAL;
725
726 /* DFS currently not supported with channel context drivers */
727 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
728 const struct ieee80211_iface_combination *comb;
729
730 comb = &local->hw.wiphy->iface_combinations[i];
731
732 if (comb->radar_detect_widths)
733 return -EINVAL;
734 }
770 } 735 }
771 736
772 /* Only HW csum features are currently compatible with mac80211 */ 737 /* Only HW csum features are currently compatible with mac80211 */
@@ -1049,12 +1014,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1049 goto fail_ifa; 1014 goto fail_ifa;
1050#endif 1015#endif
1051 1016
1017#if IS_ENABLED(CONFIG_IPV6)
1018 local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
1019 result = register_inet6addr_notifier(&local->ifa6_notifier);
1020 if (result)
1021 goto fail_ifa6;
1022#endif
1023
1052 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, 1024 netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll,
1053 local->hw.napi_weight); 1025 local->hw.napi_weight);
1054 1026
1055 return 0; 1027 return 0;
1056 1028
1029#if IS_ENABLED(CONFIG_IPV6)
1030 fail_ifa6:
1057#ifdef CONFIG_INET 1031#ifdef CONFIG_INET
1032 unregister_inetaddr_notifier(&local->ifa_notifier);
1033#endif
1034#endif
1035#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
1058 fail_ifa: 1036 fail_ifa:
1059 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, 1037 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
1060 &local->network_latency_notifier); 1038 &local->network_latency_notifier);
@@ -1090,6 +1068,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1090#ifdef CONFIG_INET 1068#ifdef CONFIG_INET
1091 unregister_inetaddr_notifier(&local->ifa_notifier); 1069 unregister_inetaddr_notifier(&local->ifa_notifier);
1092#endif 1070#endif
1071#if IS_ENABLED(CONFIG_IPV6)
1072 unregister_inet6addr_notifier(&local->ifa6_notifier);
1073#endif
1093 1074
1094 rtnl_lock(); 1075 rtnl_lock();
1095 1076
@@ -1113,7 +1094,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1113 wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); 1094 wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
1114 skb_queue_purge(&local->skb_queue); 1095 skb_queue_purge(&local->skb_queue);
1115 skb_queue_purge(&local->skb_queue_unreliable); 1096 skb_queue_purge(&local->skb_queue_unreliable);
1116 skb_queue_purge(&local->rx_skb_queue);
1117 1097
1118 destroy_workqueue(local->workqueue); 1098 destroy_workqueue(local->workqueue);
1119 wiphy_unregister(local->hw.wiphy); 1099 wiphy_unregister(local->hw.wiphy);
@@ -1191,8 +1171,7 @@ static void __exit ieee80211_exit(void)
1191 rc80211_minstrel_ht_exit(); 1171 rc80211_minstrel_ht_exit();
1192 rc80211_minstrel_exit(); 1172 rc80211_minstrel_exit();
1193 1173
1194 if (mesh_allocated) 1174 ieee80211s_stop();
1195 ieee80211s_stop();
1196 1175
1197 ieee80211_iface_exit(); 1176 ieee80211_iface_exit();
1198 1177