diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b8295cbd7e8f..80c16f6e2af6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -184,10 +184,12 @@ static int ieee80211_open(struct net_device *dev) | |||
184 | * No need to check netif_running since we do not allow | 184 | * No need to check netif_running since we do not allow |
185 | * it to start up with this invalid address. | 185 | * it to start up with this invalid address. |
186 | */ | 186 | */ |
187 | if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) | 187 | if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { |
188 | memcpy(ndev->dev_addr, | 188 | memcpy(ndev->dev_addr, |
189 | local->hw.wiphy->perm_addr, | 189 | local->hw.wiphy->perm_addr, |
190 | ETH_ALEN); | 190 | ETH_ALEN); |
191 | memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); | ||
192 | } | ||
191 | } | 193 | } |
192 | 194 | ||
193 | /* | 195 | /* |
@@ -212,8 +214,8 @@ static int ieee80211_open(struct net_device *dev) | |||
212 | /* must be before the call to ieee80211_configure_filter */ | 214 | /* must be before the call to ieee80211_configure_filter */ |
213 | local->monitors++; | 215 | local->monitors++; |
214 | if (local->monitors == 1) { | 216 | if (local->monitors == 1) { |
215 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | 217 | local->hw.conf.flags |= IEEE80211_CONF_MONITOR; |
216 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | 218 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
217 | } | 219 | } |
218 | 220 | ||
219 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 221 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
@@ -312,7 +314,7 @@ static int ieee80211_open(struct net_device *dev) | |||
312 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 314 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
313 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); | 315 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
314 | 316 | ||
315 | netif_tx_start_all_queues(dev); | 317 | netif_start_queue(dev); |
316 | 318 | ||
317 | return 0; | 319 | return 0; |
318 | err_del_interface: | 320 | err_del_interface: |
@@ -341,7 +343,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
341 | /* | 343 | /* |
342 | * Stop TX on this interface first. | 344 | * Stop TX on this interface first. |
343 | */ | 345 | */ |
344 | netif_tx_stop_all_queues(dev); | 346 | netif_stop_queue(dev); |
345 | 347 | ||
346 | /* | 348 | /* |
347 | * Now delete all active aggregation sessions. | 349 | * Now delete all active aggregation sessions. |
@@ -433,8 +435,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
433 | 435 | ||
434 | local->monitors--; | 436 | local->monitors--; |
435 | if (local->monitors == 0) { | 437 | if (local->monitors == 0) { |
436 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | 438 | local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; |
437 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | 439 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
438 | } | 440 | } |
439 | 441 | ||
440 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 442 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
@@ -750,14 +752,12 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
750 | ieee80211_mandatory_rates(sdata->local, | 752 | ieee80211_mandatory_rates(sdata->local, |
751 | sdata->local->hw.conf.channel->band); | 753 | sdata->local->hw.conf.channel->band); |
752 | sdata->drop_unencrypted = 0; | 754 | sdata->drop_unencrypted = 0; |
755 | if (type == NL80211_IFTYPE_STATION) | ||
756 | sdata->u.mgd.use_4addr = false; | ||
753 | 757 | ||
754 | return 0; | 758 | return 0; |
755 | } | 759 | } |
756 | 760 | ||
757 | static struct device_type wiphy_type = { | ||
758 | .name = "wlan", | ||
759 | }; | ||
760 | |||
761 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 761 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
762 | struct net_device **new_dev, enum nl80211_iftype type, | 762 | struct net_device **new_dev, enum nl80211_iftype type, |
763 | struct vif_params *params) | 763 | struct vif_params *params) |
@@ -788,8 +788,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
788 | goto fail; | 788 | goto fail; |
789 | 789 | ||
790 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 790 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
791 | memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); | ||
791 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 792 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
792 | SET_NETDEV_DEVTYPE(ndev, &wiphy_type); | ||
793 | 793 | ||
794 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ | 794 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
795 | sdata = netdev_priv(ndev); | 795 | sdata = netdev_priv(ndev); |
@@ -811,6 +811,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
811 | /* setup type-dependent data */ | 811 | /* setup type-dependent data */ |
812 | ieee80211_setup_sdata(sdata, type); | 812 | ieee80211_setup_sdata(sdata, type); |
813 | 813 | ||
814 | if (params) { | ||
815 | ndev->ieee80211_ptr->use_4addr = params->use_4addr; | ||
816 | if (type == NL80211_IFTYPE_STATION) | ||
817 | sdata->u.mgd.use_4addr = params->use_4addr; | ||
818 | } | ||
819 | |||
814 | ret = register_netdevice(ndev); | 820 | ret = register_netdevice(ndev); |
815 | if (ret) | 821 | if (ret) |
816 | goto fail; | 822 | goto fail; |
@@ -854,22 +860,18 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) | |||
854 | void ieee80211_remove_interfaces(struct ieee80211_local *local) | 860 | void ieee80211_remove_interfaces(struct ieee80211_local *local) |
855 | { | 861 | { |
856 | struct ieee80211_sub_if_data *sdata, *tmp; | 862 | struct ieee80211_sub_if_data *sdata, *tmp; |
863 | LIST_HEAD(unreg_list); | ||
857 | 864 | ||
858 | ASSERT_RTNL(); | 865 | ASSERT_RTNL(); |
859 | 866 | ||
867 | mutex_lock(&local->iflist_mtx); | ||
860 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | 868 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |
861 | /* | ||
862 | * we cannot hold the iflist_mtx across unregister_netdevice, | ||
863 | * but we only need to hold it for list modifications to lock | ||
864 | * out readers since we're under the RTNL here as all other | ||
865 | * writers. | ||
866 | */ | ||
867 | mutex_lock(&local->iflist_mtx); | ||
868 | list_del(&sdata->list); | 869 | list_del(&sdata->list); |
869 | mutex_unlock(&local->iflist_mtx); | ||
870 | 870 | ||
871 | unregister_netdevice(sdata->dev); | 871 | unregister_netdevice_queue(sdata->dev, &unreg_list); |
872 | } | 872 | } |
873 | mutex_unlock(&local->iflist_mtx); | ||
874 | unregister_netdevice_many(&unreg_list); | ||
873 | } | 875 | } |
874 | 876 | ||
875 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | 877 | static u32 ieee80211_idle_off(struct ieee80211_local *local, |