diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 316 |
1 files changed, 196 insertions, 120 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index bfb57dcc1538..6f8a73c64fb3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -100,6 +100,10 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
100 | sdata->vif.bss_conf.idle = true; | 100 | sdata->vif.bss_conf.idle = true; |
101 | continue; | 101 | continue; |
102 | } | 102 | } |
103 | |||
104 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
105 | continue; | ||
106 | |||
103 | /* count everything else */ | 107 | /* count everything else */ |
104 | sdata->vif.bss_conf.idle = false; | 108 | sdata->vif.bss_conf.idle = false; |
105 | count++; | 109 | count++; |
@@ -121,7 +125,8 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
121 | 125 | ||
122 | list_for_each_entry(sdata, &local->interfaces, list) { | 126 | list_for_each_entry(sdata, &local->interfaces, list) { |
123 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | 127 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
124 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 128 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
129 | sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
125 | continue; | 130 | continue; |
126 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | 131 | if (sdata->old_idle == sdata->vif.bss_conf.idle) |
127 | continue; | 132 | continue; |
@@ -204,6 +209,8 @@ static inline int identical_mac_addr_allowed(int type1, int type2) | |||
204 | { | 209 | { |
205 | return type1 == NL80211_IFTYPE_MONITOR || | 210 | return type1 == NL80211_IFTYPE_MONITOR || |
206 | type2 == NL80211_IFTYPE_MONITOR || | 211 | type2 == NL80211_IFTYPE_MONITOR || |
212 | type1 == NL80211_IFTYPE_P2P_DEVICE || | ||
213 | type2 == NL80211_IFTYPE_P2P_DEVICE || | ||
207 | (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) || | 214 | (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) || |
208 | (type1 == NL80211_IFTYPE_WDS && | 215 | (type1 == NL80211_IFTYPE_WDS && |
209 | (type2 == NL80211_IFTYPE_WDS || | 216 | (type2 == NL80211_IFTYPE_WDS || |
@@ -271,13 +278,15 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata) | |||
271 | int n_queues = sdata->local->hw.queues; | 278 | int n_queues = sdata->local->hw.queues; |
272 | int i; | 279 | int i; |
273 | 280 | ||
274 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 281 | if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) { |
275 | if (WARN_ON_ONCE(sdata->vif.hw_queue[i] == | 282 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
276 | IEEE80211_INVAL_HW_QUEUE)) | 283 | if (WARN_ON_ONCE(sdata->vif.hw_queue[i] == |
277 | return -EINVAL; | 284 | IEEE80211_INVAL_HW_QUEUE)) |
278 | if (WARN_ON_ONCE(sdata->vif.hw_queue[i] >= | 285 | return -EINVAL; |
279 | n_queues)) | 286 | if (WARN_ON_ONCE(sdata->vif.hw_queue[i] >= |
280 | return -EINVAL; | 287 | n_queues)) |
288 | return -EINVAL; | ||
289 | } | ||
281 | } | 290 | } |
282 | 291 | ||
283 | if ((sdata->vif.type != NL80211_IFTYPE_AP) || | 292 | if ((sdata->vif.type != NL80211_IFTYPE_AP) || |
@@ -406,9 +415,10 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
406 | * an error on interface type changes that have been pre-checked, so most | 415 | * an error on interface type changes that have been pre-checked, so most |
407 | * checks should be in ieee80211_check_concurrent_iface. | 416 | * checks should be in ieee80211_check_concurrent_iface. |
408 | */ | 417 | */ |
409 | static int ieee80211_do_open(struct net_device *dev, bool coming_up) | 418 | int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) |
410 | { | 419 | { |
411 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 420 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
421 | struct net_device *dev = wdev->netdev; | ||
412 | struct ieee80211_local *local = sdata->local; | 422 | struct ieee80211_local *local = sdata->local; |
413 | struct sta_info *sta; | 423 | struct sta_info *sta; |
414 | u32 changed = 0; | 424 | u32 changed = 0; |
@@ -443,6 +453,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
443 | case NL80211_IFTYPE_STATION: | 453 | case NL80211_IFTYPE_STATION: |
444 | case NL80211_IFTYPE_MONITOR: | 454 | case NL80211_IFTYPE_MONITOR: |
445 | case NL80211_IFTYPE_ADHOC: | 455 | case NL80211_IFTYPE_ADHOC: |
456 | case NL80211_IFTYPE_P2P_DEVICE: | ||
446 | /* no special treatment */ | 457 | /* no special treatment */ |
447 | break; | 458 | break; |
448 | case NL80211_IFTYPE_UNSPECIFIED: | 459 | case NL80211_IFTYPE_UNSPECIFIED: |
@@ -471,7 +482,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
471 | * Copy the hopefully now-present MAC address to | 482 | * Copy the hopefully now-present MAC address to |
472 | * this interface, if it has the special null one. | 483 | * this interface, if it has the special null one. |
473 | */ | 484 | */ |
474 | if (is_zero_ether_addr(dev->dev_addr)) { | 485 | if (dev && is_zero_ether_addr(dev->dev_addr)) { |
475 | memcpy(dev->dev_addr, | 486 | memcpy(dev->dev_addr, |
476 | local->hw.wiphy->perm_addr, | 487 | local->hw.wiphy->perm_addr, |
477 | ETH_ALEN); | 488 | ETH_ALEN); |
@@ -536,15 +547,23 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
536 | local->fif_probe_req++; | 547 | local->fif_probe_req++; |
537 | } | 548 | } |
538 | 549 | ||
539 | changed |= ieee80211_reset_erp_info(sdata); | 550 | if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) |
551 | changed |= ieee80211_reset_erp_info(sdata); | ||
540 | ieee80211_bss_info_change_notify(sdata, changed); | 552 | ieee80211_bss_info_change_notify(sdata, changed); |
541 | 553 | ||
542 | if (sdata->vif.type == NL80211_IFTYPE_STATION || | 554 | switch (sdata->vif.type) { |
543 | sdata->vif.type == NL80211_IFTYPE_ADHOC || | 555 | case NL80211_IFTYPE_STATION: |
544 | sdata->vif.type == NL80211_IFTYPE_AP) | 556 | case NL80211_IFTYPE_ADHOC: |
557 | case NL80211_IFTYPE_AP: | ||
558 | case NL80211_IFTYPE_MESH_POINT: | ||
545 | netif_carrier_off(dev); | 559 | netif_carrier_off(dev); |
546 | else | 560 | break; |
561 | case NL80211_IFTYPE_WDS: | ||
562 | case NL80211_IFTYPE_P2P_DEVICE: | ||
563 | break; | ||
564 | default: | ||
547 | netif_carrier_on(dev); | 565 | netif_carrier_on(dev); |
566 | } | ||
548 | 567 | ||
549 | /* | 568 | /* |
550 | * set default queue parameters so drivers don't | 569 | * set default queue parameters so drivers don't |
@@ -576,6 +595,9 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
576 | } | 595 | } |
577 | 596 | ||
578 | rate_control_rate_init(sta); | 597 | rate_control_rate_init(sta); |
598 | netif_carrier_on(dev); | ||
599 | } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { | ||
600 | rcu_assign_pointer(local->p2p_sdata, sdata); | ||
579 | } | 601 | } |
580 | 602 | ||
581 | /* | 603 | /* |
@@ -601,7 +623,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
601 | 623 | ||
602 | ieee80211_recalc_ps(local, -1); | 624 | ieee80211_recalc_ps(local, -1); |
603 | 625 | ||
604 | netif_tx_start_all_queues(dev); | 626 | if (dev) |
627 | netif_tx_start_all_queues(dev); | ||
605 | 628 | ||
606 | return 0; | 629 | return 0; |
607 | err_del_interface: | 630 | err_del_interface: |
@@ -631,7 +654,7 @@ static int ieee80211_open(struct net_device *dev) | |||
631 | if (err) | 654 | if (err) |
632 | return err; | 655 | return err; |
633 | 656 | ||
634 | return ieee80211_do_open(dev, true); | 657 | return ieee80211_do_open(&sdata->wdev, true); |
635 | } | 658 | } |
636 | 659 | ||
637 | static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | 660 | static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, |
@@ -652,7 +675,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
652 | /* | 675 | /* |
653 | * Stop TX on this interface first. | 676 | * Stop TX on this interface first. |
654 | */ | 677 | */ |
655 | netif_tx_stop_all_queues(sdata->dev); | 678 | if (sdata->dev) |
679 | netif_tx_stop_all_queues(sdata->dev); | ||
656 | 680 | ||
657 | ieee80211_roc_purge(sdata); | 681 | ieee80211_roc_purge(sdata); |
658 | 682 | ||
@@ -691,14 +715,16 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
691 | local->fif_probe_req--; | 715 | local->fif_probe_req--; |
692 | } | 716 | } |
693 | 717 | ||
694 | netif_addr_lock_bh(sdata->dev); | 718 | if (sdata->dev) { |
695 | spin_lock_bh(&local->filter_lock); | 719 | netif_addr_lock_bh(sdata->dev); |
696 | __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, | 720 | spin_lock_bh(&local->filter_lock); |
697 | sdata->dev->addr_len); | 721 | __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, |
698 | spin_unlock_bh(&local->filter_lock); | 722 | sdata->dev->addr_len); |
699 | netif_addr_unlock_bh(sdata->dev); | 723 | spin_unlock_bh(&local->filter_lock); |
724 | netif_addr_unlock_bh(sdata->dev); | ||
700 | 725 | ||
701 | ieee80211_configure_filter(local); | 726 | ieee80211_configure_filter(local); |
727 | } | ||
702 | 728 | ||
703 | del_timer_sync(&local->dynamic_ps_timer); | 729 | del_timer_sync(&local->dynamic_ps_timer); |
704 | cancel_work_sync(&local->dynamic_ps_enable_work); | 730 | cancel_work_sync(&local->dynamic_ps_enable_work); |
@@ -708,7 +734,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
708 | struct ieee80211_sub_if_data *vlan, *tmpsdata; | 734 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
709 | struct beacon_data *old_beacon = | 735 | struct beacon_data *old_beacon = |
710 | rtnl_dereference(sdata->u.ap.beacon); | 736 | rtnl_dereference(sdata->u.ap.beacon); |
711 | struct sk_buff *old_probe_resp = | 737 | struct probe_resp *old_probe_resp = |
712 | rtnl_dereference(sdata->u.ap.probe_resp); | 738 | rtnl_dereference(sdata->u.ap.probe_resp); |
713 | 739 | ||
714 | /* sdata_running will return false, so this will disable */ | 740 | /* sdata_running will return false, so this will disable */ |
@@ -720,7 +746,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
720 | RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); | 746 | RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); |
721 | synchronize_rcu(); | 747 | synchronize_rcu(); |
722 | kfree(old_beacon); | 748 | kfree(old_beacon); |
723 | kfree_skb(old_probe_resp); | 749 | kfree(old_probe_resp); |
724 | 750 | ||
725 | /* down all dependent devices, that is VLANs */ | 751 | /* down all dependent devices, that is VLANs */ |
726 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, | 752 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, |
@@ -759,24 +785,29 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
759 | ieee80211_adjust_monitor_flags(sdata, -1); | 785 | ieee80211_adjust_monitor_flags(sdata, -1); |
760 | ieee80211_configure_filter(local); | 786 | ieee80211_configure_filter(local); |
761 | break; | 787 | break; |
788 | case NL80211_IFTYPE_P2P_DEVICE: | ||
789 | /* relies on synchronize_rcu() below */ | ||
790 | rcu_assign_pointer(local->p2p_sdata, NULL); | ||
791 | /* fall through */ | ||
762 | default: | 792 | default: |
763 | flush_work(&sdata->work); | 793 | flush_work(&sdata->work); |
764 | /* | 794 | /* |
765 | * When we get here, the interface is marked down. | 795 | * When we get here, the interface is marked down. |
766 | * Call synchronize_rcu() to wait for the RX path | 796 | * Call rcu_barrier() to wait both for the RX path |
767 | * should it be using the interface and enqueuing | 797 | * should it be using the interface and enqueuing |
768 | * frames at this very time on another CPU. | 798 | * frames at this very time on another CPU, and |
799 | * for the sta free call_rcu callbacks. | ||
769 | */ | 800 | */ |
770 | synchronize_rcu(); | 801 | rcu_barrier(); |
771 | skb_queue_purge(&sdata->skb_queue); | ||
772 | 802 | ||
773 | /* | 803 | /* |
774 | * Disable beaconing here for mesh only, AP and IBSS | 804 | * free_sta_rcu() enqueues a work for the actual |
775 | * are already taken care of. | 805 | * sta cleanup, so we need to flush it while |
806 | * sdata is still valid. | ||
776 | */ | 807 | */ |
777 | if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | 808 | flush_workqueue(local->workqueue); |
778 | ieee80211_bss_info_change_notify(sdata, | 809 | |
779 | BSS_CHANGED_BEACON_ENABLED); | 810 | skb_queue_purge(&sdata->skb_queue); |
780 | 811 | ||
781 | /* | 812 | /* |
782 | * Free all remaining keys, there shouldn't be any, | 813 | * Free all remaining keys, there shouldn't be any, |
@@ -877,9 +908,8 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
877 | * Called when the netdev is removed or, by the code below, before | 908 | * Called when the netdev is removed or, by the code below, before |
878 | * the interface type changes. | 909 | * the interface type changes. |
879 | */ | 910 | */ |
880 | static void ieee80211_teardown_sdata(struct net_device *dev) | 911 | static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) |
881 | { | 912 | { |
882 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
883 | struct ieee80211_local *local = sdata->local; | 913 | struct ieee80211_local *local = sdata->local; |
884 | int flushed; | 914 | int flushed; |
885 | int i; | 915 | int i; |
@@ -900,6 +930,11 @@ static void ieee80211_teardown_sdata(struct net_device *dev) | |||
900 | WARN_ON(flushed); | 930 | WARN_ON(flushed); |
901 | } | 931 | } |
902 | 932 | ||
933 | static void ieee80211_uninit(struct net_device *dev) | ||
934 | { | ||
935 | ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); | ||
936 | } | ||
937 | |||
903 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, | 938 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, |
904 | struct sk_buff *skb) | 939 | struct sk_buff *skb) |
905 | { | 940 | { |
@@ -909,7 +944,7 @@ static u16 ieee80211_netdev_select_queue(struct net_device *dev, | |||
909 | static const struct net_device_ops ieee80211_dataif_ops = { | 944 | static const struct net_device_ops ieee80211_dataif_ops = { |
910 | .ndo_open = ieee80211_open, | 945 | .ndo_open = ieee80211_open, |
911 | .ndo_stop = ieee80211_stop, | 946 | .ndo_stop = ieee80211_stop, |
912 | .ndo_uninit = ieee80211_teardown_sdata, | 947 | .ndo_uninit = ieee80211_uninit, |
913 | .ndo_start_xmit = ieee80211_subif_start_xmit, | 948 | .ndo_start_xmit = ieee80211_subif_start_xmit, |
914 | .ndo_set_rx_mode = ieee80211_set_multicast_list, | 949 | .ndo_set_rx_mode = ieee80211_set_multicast_list, |
915 | .ndo_change_mtu = ieee80211_change_mtu, | 950 | .ndo_change_mtu = ieee80211_change_mtu, |
@@ -940,7 +975,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev, | |||
940 | static const struct net_device_ops ieee80211_monitorif_ops = { | 975 | static const struct net_device_ops ieee80211_monitorif_ops = { |
941 | .ndo_open = ieee80211_open, | 976 | .ndo_open = ieee80211_open, |
942 | .ndo_stop = ieee80211_stop, | 977 | .ndo_stop = ieee80211_stop, |
943 | .ndo_uninit = ieee80211_teardown_sdata, | 978 | .ndo_uninit = ieee80211_uninit, |
944 | .ndo_start_xmit = ieee80211_monitor_start_xmit, | 979 | .ndo_start_xmit = ieee80211_monitor_start_xmit, |
945 | .ndo_set_rx_mode = ieee80211_set_multicast_list, | 980 | .ndo_set_rx_mode = ieee80211_set_multicast_list, |
946 | .ndo_change_mtu = ieee80211_change_mtu, | 981 | .ndo_change_mtu = ieee80211_change_mtu, |
@@ -1099,7 +1134,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1099 | /* and set some type-dependent values */ | 1134 | /* and set some type-dependent values */ |
1100 | sdata->vif.type = type; | 1135 | sdata->vif.type = type; |
1101 | sdata->vif.p2p = false; | 1136 | sdata->vif.p2p = false; |
1102 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; | ||
1103 | sdata->wdev.iftype = type; | 1137 | sdata->wdev.iftype = type; |
1104 | 1138 | ||
1105 | sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); | 1139 | sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); |
@@ -1107,8 +1141,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1107 | 1141 | ||
1108 | sdata->noack_map = 0; | 1142 | sdata->noack_map = 0; |
1109 | 1143 | ||
1110 | /* only monitor differs */ | 1144 | /* only monitor/p2p-device differ */ |
1111 | sdata->dev->type = ARPHRD_ETHER; | 1145 | if (sdata->dev) { |
1146 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; | ||
1147 | sdata->dev->type = ARPHRD_ETHER; | ||
1148 | } | ||
1112 | 1149 | ||
1113 | skb_queue_head_init(&sdata->skb_queue); | 1150 | skb_queue_head_init(&sdata->skb_queue); |
1114 | INIT_WORK(&sdata->work, ieee80211_iface_work); | 1151 | INIT_WORK(&sdata->work, ieee80211_iface_work); |
@@ -1146,6 +1183,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1146 | break; | 1183 | break; |
1147 | case NL80211_IFTYPE_WDS: | 1184 | case NL80211_IFTYPE_WDS: |
1148 | case NL80211_IFTYPE_AP_VLAN: | 1185 | case NL80211_IFTYPE_AP_VLAN: |
1186 | case NL80211_IFTYPE_P2P_DEVICE: | ||
1149 | break; | 1187 | break; |
1150 | case NL80211_IFTYPE_UNSPECIFIED: | 1188 | case NL80211_IFTYPE_UNSPECIFIED: |
1151 | case NUM_NL80211_IFTYPES: | 1189 | case NUM_NL80211_IFTYPES: |
@@ -1156,18 +1194,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1156 | ieee80211_debugfs_add_netdev(sdata); | 1194 | ieee80211_debugfs_add_netdev(sdata); |
1157 | } | 1195 | } |
1158 | 1196 | ||
1159 | static void ieee80211_clean_sdata(struct ieee80211_sub_if_data *sdata) | ||
1160 | { | ||
1161 | switch (sdata->vif.type) { | ||
1162 | case NL80211_IFTYPE_MESH_POINT: | ||
1163 | mesh_path_flush_by_iface(sdata); | ||
1164 | break; | ||
1165 | |||
1166 | default: | ||
1167 | break; | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | 1197 | static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, |
1172 | enum nl80211_iftype type) | 1198 | enum nl80211_iftype type) |
1173 | { | 1199 | { |
@@ -1225,7 +1251,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | |||
1225 | 1251 | ||
1226 | ieee80211_do_stop(sdata, false); | 1252 | ieee80211_do_stop(sdata, false); |
1227 | 1253 | ||
1228 | ieee80211_teardown_sdata(sdata->dev); | 1254 | ieee80211_teardown_sdata(sdata); |
1229 | 1255 | ||
1230 | ret = drv_change_interface(local, sdata, internal_type, p2p); | 1256 | ret = drv_change_interface(local, sdata, internal_type, p2p); |
1231 | if (ret) | 1257 | if (ret) |
@@ -1240,7 +1266,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | |||
1240 | 1266 | ||
1241 | ieee80211_setup_sdata(sdata, type); | 1267 | ieee80211_setup_sdata(sdata, type); |
1242 | 1268 | ||
1243 | err = ieee80211_do_open(sdata->dev, false); | 1269 | err = ieee80211_do_open(&sdata->wdev, false); |
1244 | WARN(err, "type change: do_open returned %d", err); | 1270 | WARN(err, "type change: do_open returned %d", err); |
1245 | 1271 | ||
1246 | return ret; | 1272 | return ret; |
@@ -1267,14 +1293,14 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1267 | return ret; | 1293 | return ret; |
1268 | } else { | 1294 | } else { |
1269 | /* Purge and reset type-dependent state. */ | 1295 | /* Purge and reset type-dependent state. */ |
1270 | ieee80211_teardown_sdata(sdata->dev); | 1296 | ieee80211_teardown_sdata(sdata); |
1271 | ieee80211_setup_sdata(sdata, type); | 1297 | ieee80211_setup_sdata(sdata, type); |
1272 | } | 1298 | } |
1273 | 1299 | ||
1274 | /* reset some values that shouldn't be kept across type changes */ | 1300 | /* reset some values that shouldn't be kept across type changes */ |
1275 | sdata->vif.bss_conf.basic_rates = | 1301 | sdata->vif.bss_conf.basic_rates = |
1276 | ieee80211_mandatory_rates(sdata->local, | 1302 | ieee80211_mandatory_rates(sdata->local, |
1277 | sdata->local->hw.conf.channel->band); | 1303 | sdata->local->oper_channel->band); |
1278 | sdata->drop_unencrypted = 0; | 1304 | sdata->drop_unencrypted = 0; |
1279 | if (type == NL80211_IFTYPE_STATION) | 1305 | if (type == NL80211_IFTYPE_STATION) |
1280 | sdata->u.mgd.use_4addr = false; | 1306 | sdata->u.mgd.use_4addr = false; |
@@ -1283,8 +1309,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1283 | } | 1309 | } |
1284 | 1310 | ||
1285 | static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | 1311 | static void ieee80211_assign_perm_addr(struct ieee80211_local *local, |
1286 | struct net_device *dev, | 1312 | u8 *perm_addr, enum nl80211_iftype type) |
1287 | enum nl80211_iftype type) | ||
1288 | { | 1313 | { |
1289 | struct ieee80211_sub_if_data *sdata; | 1314 | struct ieee80211_sub_if_data *sdata; |
1290 | u64 mask, start, addr, val, inc; | 1315 | u64 mask, start, addr, val, inc; |
@@ -1293,13 +1318,12 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1293 | int i; | 1318 | int i; |
1294 | 1319 | ||
1295 | /* default ... something at least */ | 1320 | /* default ... something at least */ |
1296 | memcpy(dev->perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 1321 | memcpy(perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
1297 | 1322 | ||
1298 | if (is_zero_ether_addr(local->hw.wiphy->addr_mask) && | 1323 | if (is_zero_ether_addr(local->hw.wiphy->addr_mask) && |
1299 | local->hw.wiphy->n_addresses <= 1) | 1324 | local->hw.wiphy->n_addresses <= 1) |
1300 | return; | 1325 | return; |
1301 | 1326 | ||
1302 | |||
1303 | mutex_lock(&local->iflist_mtx); | 1327 | mutex_lock(&local->iflist_mtx); |
1304 | 1328 | ||
1305 | switch (type) { | 1329 | switch (type) { |
@@ -1312,11 +1336,24 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1312 | list_for_each_entry(sdata, &local->interfaces, list) { | 1336 | list_for_each_entry(sdata, &local->interfaces, list) { |
1313 | if (sdata->vif.type != NL80211_IFTYPE_AP) | 1337 | if (sdata->vif.type != NL80211_IFTYPE_AP) |
1314 | continue; | 1338 | continue; |
1315 | memcpy(dev->perm_addr, sdata->vif.addr, ETH_ALEN); | 1339 | memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); |
1316 | break; | 1340 | break; |
1317 | } | 1341 | } |
1318 | /* keep default if no AP interface present */ | 1342 | /* keep default if no AP interface present */ |
1319 | break; | 1343 | break; |
1344 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1345 | case NL80211_IFTYPE_P2P_GO: | ||
1346 | if (local->hw.flags & IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF) { | ||
1347 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1348 | if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) | ||
1349 | continue; | ||
1350 | if (!ieee80211_sdata_running(sdata)) | ||
1351 | continue; | ||
1352 | memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); | ||
1353 | goto out_unlock; | ||
1354 | } | ||
1355 | } | ||
1356 | /* otherwise fall through */ | ||
1320 | default: | 1357 | default: |
1321 | /* assign a new address if possible -- try n_addresses first */ | 1358 | /* assign a new address if possible -- try n_addresses first */ |
1322 | for (i = 0; i < local->hw.wiphy->n_addresses; i++) { | 1359 | for (i = 0; i < local->hw.wiphy->n_addresses; i++) { |
@@ -1331,7 +1368,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1331 | } | 1368 | } |
1332 | 1369 | ||
1333 | if (!used) { | 1370 | if (!used) { |
1334 | memcpy(dev->perm_addr, | 1371 | memcpy(perm_addr, |
1335 | local->hw.wiphy->addresses[i].addr, | 1372 | local->hw.wiphy->addresses[i].addr, |
1336 | ETH_ALEN); | 1373 | ETH_ALEN); |
1337 | break; | 1374 | break; |
@@ -1382,7 +1419,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1382 | } | 1419 | } |
1383 | 1420 | ||
1384 | if (!used) { | 1421 | if (!used) { |
1385 | memcpy(dev->perm_addr, tmp_addr, ETH_ALEN); | 1422 | memcpy(perm_addr, tmp_addr, ETH_ALEN); |
1386 | break; | 1423 | break; |
1387 | } | 1424 | } |
1388 | addr = (start & ~mask) | (val & mask); | 1425 | addr = (start & ~mask) | (val & mask); |
@@ -1391,6 +1428,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1391 | break; | 1428 | break; |
1392 | } | 1429 | } |
1393 | 1430 | ||
1431 | out_unlock: | ||
1394 | mutex_unlock(&local->iflist_mtx); | 1432 | mutex_unlock(&local->iflist_mtx); |
1395 | } | 1433 | } |
1396 | 1434 | ||
@@ -1398,49 +1436,68 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1398 | struct wireless_dev **new_wdev, enum nl80211_iftype type, | 1436 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1399 | struct vif_params *params) | 1437 | struct vif_params *params) |
1400 | { | 1438 | { |
1401 | struct net_device *ndev; | 1439 | struct net_device *ndev = NULL; |
1402 | struct ieee80211_sub_if_data *sdata = NULL; | 1440 | struct ieee80211_sub_if_data *sdata = NULL; |
1403 | int ret, i; | 1441 | int ret, i; |
1404 | int txqs = 1; | 1442 | int txqs = 1; |
1405 | 1443 | ||
1406 | ASSERT_RTNL(); | 1444 | ASSERT_RTNL(); |
1407 | 1445 | ||
1408 | if (local->hw.queues >= IEEE80211_NUM_ACS) | 1446 | if (type == NL80211_IFTYPE_P2P_DEVICE) { |
1409 | txqs = IEEE80211_NUM_ACS; | 1447 | struct wireless_dev *wdev; |
1410 | 1448 | ||
1411 | ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, | 1449 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, |
1412 | name, ieee80211_if_setup, txqs, 1); | 1450 | GFP_KERNEL); |
1413 | if (!ndev) | 1451 | if (!sdata) |
1414 | return -ENOMEM; | 1452 | return -ENOMEM; |
1415 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | 1453 | wdev = &sdata->wdev; |
1416 | 1454 | ||
1417 | ndev->needed_headroom = local->tx_headroom + | 1455 | sdata->dev = NULL; |
1418 | 4*6 /* four MAC addresses */ | 1456 | strlcpy(sdata->name, name, IFNAMSIZ); |
1419 | + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ | 1457 | ieee80211_assign_perm_addr(local, wdev->address, type); |
1420 | + 6 /* mesh */ | 1458 | memcpy(sdata->vif.addr, wdev->address, ETH_ALEN); |
1421 | + 8 /* rfc1042/bridge tunnel */ | 1459 | } else { |
1422 | - ETH_HLEN /* ethernet hard_header_len */ | 1460 | if (local->hw.queues >= IEEE80211_NUM_ACS) |
1423 | + IEEE80211_ENCRYPT_HEADROOM; | 1461 | txqs = IEEE80211_NUM_ACS; |
1424 | ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; | 1462 | |
1425 | 1463 | ndev = alloc_netdev_mqs(sizeof(*sdata) + | |
1426 | ret = dev_alloc_name(ndev, ndev->name); | 1464 | local->hw.vif_data_size, |
1427 | if (ret < 0) | 1465 | name, ieee80211_if_setup, txqs, 1); |
1428 | goto fail; | 1466 | if (!ndev) |
1429 | 1467 | return -ENOMEM; | |
1430 | ieee80211_assign_perm_addr(local, ndev, type); | 1468 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); |
1431 | memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); | 1469 | |
1432 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 1470 | ndev->needed_headroom = local->tx_headroom + |
1433 | 1471 | 4*6 /* four MAC addresses */ | |
1434 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ | 1472 | + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ |
1435 | sdata = netdev_priv(ndev); | 1473 | + 6 /* mesh */ |
1436 | ndev->ieee80211_ptr = &sdata->wdev; | 1474 | + 8 /* rfc1042/bridge tunnel */ |
1437 | memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); | 1475 | - ETH_HLEN /* ethernet hard_header_len */ |
1438 | memcpy(sdata->name, ndev->name, IFNAMSIZ); | 1476 | + IEEE80211_ENCRYPT_HEADROOM; |
1477 | ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; | ||
1478 | |||
1479 | ret = dev_alloc_name(ndev, ndev->name); | ||
1480 | if (ret < 0) { | ||
1481 | free_netdev(ndev); | ||
1482 | return ret; | ||
1483 | } | ||
1484 | |||
1485 | ieee80211_assign_perm_addr(local, ndev->perm_addr, type); | ||
1486 | memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); | ||
1487 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | ||
1488 | |||
1489 | /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ | ||
1490 | sdata = netdev_priv(ndev); | ||
1491 | ndev->ieee80211_ptr = &sdata->wdev; | ||
1492 | memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); | ||
1493 | memcpy(sdata->name, ndev->name, IFNAMSIZ); | ||
1494 | |||
1495 | sdata->dev = ndev; | ||
1496 | } | ||
1439 | 1497 | ||
1440 | /* initialise type-independent data */ | 1498 | /* initialise type-independent data */ |
1441 | sdata->wdev.wiphy = local->hw.wiphy; | 1499 | sdata->wdev.wiphy = local->hw.wiphy; |
1442 | sdata->local = local; | 1500 | sdata->local = local; |
1443 | sdata->dev = ndev; | ||
1444 | #ifdef CONFIG_INET | 1501 | #ifdef CONFIG_INET |
1445 | sdata->arp_filter_state = true; | 1502 | sdata->arp_filter_state = true; |
1446 | #endif | 1503 | #endif |
@@ -1469,17 +1526,21 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1469 | /* setup type-dependent data */ | 1526 | /* setup type-dependent data */ |
1470 | ieee80211_setup_sdata(sdata, type); | 1527 | ieee80211_setup_sdata(sdata, type); |
1471 | 1528 | ||
1472 | if (params) { | 1529 | if (ndev) { |
1473 | ndev->ieee80211_ptr->use_4addr = params->use_4addr; | 1530 | if (params) { |
1474 | if (type == NL80211_IFTYPE_STATION) | 1531 | ndev->ieee80211_ptr->use_4addr = params->use_4addr; |
1475 | sdata->u.mgd.use_4addr = params->use_4addr; | 1532 | if (type == NL80211_IFTYPE_STATION) |
1476 | } | 1533 | sdata->u.mgd.use_4addr = params->use_4addr; |
1534 | } | ||
1477 | 1535 | ||
1478 | ndev->features |= local->hw.netdev_features; | 1536 | ndev->features |= local->hw.netdev_features; |
1479 | 1537 | ||
1480 | ret = register_netdevice(ndev); | 1538 | ret = register_netdevice(ndev); |
1481 | if (ret) | 1539 | if (ret) { |
1482 | goto fail; | 1540 | free_netdev(ndev); |
1541 | return ret; | ||
1542 | } | ||
1543 | } | ||
1483 | 1544 | ||
1484 | mutex_lock(&local->iflist_mtx); | 1545 | mutex_lock(&local->iflist_mtx); |
1485 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 1546 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
@@ -1489,10 +1550,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1489 | *new_wdev = &sdata->wdev; | 1550 | *new_wdev = &sdata->wdev; |
1490 | 1551 | ||
1491 | return 0; | 1552 | return 0; |
1492 | |||
1493 | fail: | ||
1494 | free_netdev(ndev); | ||
1495 | return ret; | ||
1496 | } | 1553 | } |
1497 | 1554 | ||
1498 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) | 1555 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) |
@@ -1503,11 +1560,22 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) | |||
1503 | list_del_rcu(&sdata->list); | 1560 | list_del_rcu(&sdata->list); |
1504 | mutex_unlock(&sdata->local->iflist_mtx); | 1561 | mutex_unlock(&sdata->local->iflist_mtx); |
1505 | 1562 | ||
1506 | /* clean up type-dependent data */ | ||
1507 | ieee80211_clean_sdata(sdata); | ||
1508 | |||
1509 | synchronize_rcu(); | 1563 | synchronize_rcu(); |
1510 | unregister_netdevice(sdata->dev); | 1564 | |
1565 | if (sdata->dev) { | ||
1566 | unregister_netdevice(sdata->dev); | ||
1567 | } else { | ||
1568 | cfg80211_unregister_wdev(&sdata->wdev); | ||
1569 | kfree(sdata); | ||
1570 | } | ||
1571 | } | ||
1572 | |||
1573 | void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata) | ||
1574 | { | ||
1575 | if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) | ||
1576 | return; | ||
1577 | ieee80211_do_stop(sdata, true); | ||
1578 | ieee80211_teardown_sdata(sdata); | ||
1511 | } | 1579 | } |
1512 | 1580 | ||
1513 | /* | 1581 | /* |
@@ -1518,6 +1586,7 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
1518 | { | 1586 | { |
1519 | struct ieee80211_sub_if_data *sdata, *tmp; | 1587 | struct ieee80211_sub_if_data *sdata, *tmp; |
1520 | LIST_HEAD(unreg_list); | 1588 | LIST_HEAD(unreg_list); |
1589 | LIST_HEAD(wdev_list); | ||
1521 | 1590 | ||
1522 | ASSERT_RTNL(); | 1591 | ASSERT_RTNL(); |
1523 | 1592 | ||
@@ -1525,13 +1594,20 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
1525 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | 1594 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |
1526 | list_del(&sdata->list); | 1595 | list_del(&sdata->list); |
1527 | 1596 | ||
1528 | ieee80211_clean_sdata(sdata); | 1597 | if (sdata->dev) |
1529 | 1598 | unregister_netdevice_queue(sdata->dev, &unreg_list); | |
1530 | unregister_netdevice_queue(sdata->dev, &unreg_list); | 1599 | else |
1600 | list_add(&sdata->list, &wdev_list); | ||
1531 | } | 1601 | } |
1532 | mutex_unlock(&local->iflist_mtx); | 1602 | mutex_unlock(&local->iflist_mtx); |
1533 | unregister_netdevice_many(&unreg_list); | 1603 | unregister_netdevice_many(&unreg_list); |
1534 | list_del(&unreg_list); | 1604 | list_del(&unreg_list); |
1605 | |||
1606 | list_for_each_entry_safe(sdata, tmp, &wdev_list, list) { | ||
1607 | list_del(&sdata->list); | ||
1608 | cfg80211_unregister_wdev(&sdata->wdev); | ||
1609 | kfree(sdata); | ||
1610 | } | ||
1535 | } | 1611 | } |
1536 | 1612 | ||
1537 | static int netdev_notify(struct notifier_block *nb, | 1613 | static int netdev_notify(struct notifier_block *nb, |