diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-06-15 18:00:26 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-12 06:08:10 -0400 |
commit | 84efbb84cf76238faf26facf481c8675859bfaeb (patch) | |
tree | 3cc01b479a4c2db70b1b9ed59e1451d93acb5769 | |
parent | 71bbc9943883cffaf5d7a7728a4e4c50b3ac44d3 (diff) |
cfg80211: use wireless_dev for interface management
In order to be able to create P2P Device wdevs, move
the virtual interface management over to wireless_dev
structures.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 10 | ||||
-rw-r--r-- | include/net/cfg80211.h | 19 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 20 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 26 |
11 files changed, 83 insertions, 72 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5f0c66bb6bdf..88bed02f7521 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -1487,14 +1487,14 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
1487 | return 0; | 1487 | return 0; |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | 1490 | static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, |
1491 | char *name, | 1491 | char *name, |
1492 | enum nl80211_iftype type, | 1492 | enum nl80211_iftype type, |
1493 | u32 *flags, | 1493 | u32 *flags, |
1494 | struct vif_params *params) | 1494 | struct vif_params *params) |
1495 | { | 1495 | { |
1496 | struct ath6kl *ar = wiphy_priv(wiphy); | 1496 | struct ath6kl *ar = wiphy_priv(wiphy); |
1497 | struct net_device *ndev; | 1497 | struct wireless_dev *wdev; |
1498 | u8 if_idx, nw_type; | 1498 | u8 if_idx, nw_type; |
1499 | 1499 | ||
1500 | if (ar->num_vif == ar->vif_max) { | 1500 | if (ar->num_vif == ar->vif_max) { |
@@ -1507,20 +1507,20 @@ static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | |||
1507 | return ERR_PTR(-EINVAL); | 1507 | return ERR_PTR(-EINVAL); |
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type); | 1510 | wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type); |
1511 | if (!ndev) | 1511 | if (!wdev) |
1512 | return ERR_PTR(-ENOMEM); | 1512 | return ERR_PTR(-ENOMEM); |
1513 | 1513 | ||
1514 | ar->num_vif++; | 1514 | ar->num_vif++; |
1515 | 1515 | ||
1516 | return ndev; | 1516 | return wdev; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, | 1519 | static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, |
1520 | struct net_device *ndev) | 1520 | struct wireless_dev *wdev) |
1521 | { | 1521 | { |
1522 | struct ath6kl *ar = wiphy_priv(wiphy); | 1522 | struct ath6kl *ar = wiphy_priv(wiphy); |
1523 | struct ath6kl_vif *vif = netdev_priv(ndev); | 1523 | struct ath6kl_vif *vif = netdev_priv(wdev->netdev); |
1524 | 1524 | ||
1525 | spin_lock_bh(&ar->list_lock); | 1525 | spin_lock_bh(&ar->list_lock); |
1526 | list_del(&vif->list); | 1526 | list_del(&vif->list); |
@@ -3477,9 +3477,9 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) | |||
3477 | ar->num_vif--; | 3477 | ar->num_vif--; |
3478 | } | 3478 | } |
3479 | 3479 | ||
3480 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | 3480 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name, |
3481 | enum nl80211_iftype type, u8 fw_vif_idx, | 3481 | enum nl80211_iftype type, |
3482 | u8 nw_type) | 3482 | u8 fw_vif_idx, u8 nw_type) |
3483 | { | 3483 | { |
3484 | struct net_device *ndev; | 3484 | struct net_device *ndev; |
3485 | struct ath6kl_vif *vif; | 3485 | struct ath6kl_vif *vif; |
@@ -3533,7 +3533,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | |||
3533 | list_add_tail(&vif->list, &ar->vif_list); | 3533 | list_add_tail(&vif->list, &ar->vif_list); |
3534 | spin_unlock_bh(&ar->list_lock); | 3534 | spin_unlock_bh(&ar->list_lock); |
3535 | 3535 | ||
3536 | return ndev; | 3536 | return &vif->wdev; |
3537 | 3537 | ||
3538 | err: | 3538 | err: |
3539 | aggr_module_destroy(vif->aggr_cntxt); | 3539 | aggr_module_destroy(vif->aggr_cntxt); |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index b992046a1b0e..56b1ebe79812 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -25,9 +25,9 @@ enum ath6kl_cfg_suspend_mode { | |||
25 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, | 25 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | 28 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name, |
29 | enum nl80211_iftype type, | 29 | enum nl80211_iftype type, |
30 | u8 fw_vif_idx, u8 nw_type); | 30 | u8 fw_vif_idx, u8 nw_type); |
31 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | 31 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, |
32 | enum wmi_phy_mode mode); | 32 | enum wmi_phy_mode mode); |
33 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); | 33 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); |
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index fdb3b1decc76..82c4dd2a960e 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c | |||
@@ -56,7 +56,7 @@ EXPORT_SYMBOL(ath6kl_core_rx_complete); | |||
56 | int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | 56 | int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) |
57 | { | 57 | { |
58 | struct ath6kl_bmi_target_info targ_info; | 58 | struct ath6kl_bmi_target_info targ_info; |
59 | struct net_device *ndev; | 59 | struct wireless_dev *wdev; |
60 | int ret = 0, i; | 60 | int ret = 0, i; |
61 | 61 | ||
62 | switch (htc_type) { | 62 | switch (htc_type) { |
@@ -187,12 +187,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | |||
187 | rtnl_lock(); | 187 | rtnl_lock(); |
188 | 188 | ||
189 | /* Add an initial station interface */ | 189 | /* Add an initial station interface */ |
190 | ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, | 190 | wdev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, |
191 | INFRA_NETWORK); | 191 | INFRA_NETWORK); |
192 | 192 | ||
193 | rtnl_unlock(); | 193 | rtnl_unlock(); |
194 | 194 | ||
195 | if (!ndev) { | 195 | if (!wdev) { |
196 | ath6kl_err("Failed to instantiate a network device\n"); | 196 | ath6kl_err("Failed to instantiate a network device\n"); |
197 | ret = -ENOMEM; | 197 | ret = -ENOMEM; |
198 | wiphy_unregister(ar->wiphy); | 198 | wiphy_unregister(ar->wiphy); |
@@ -200,7 +200,7 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", | 202 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", |
203 | __func__, ndev->name, ndev, ar); | 203 | __func__, wdev->netdev->name, wdev->netdev, ar); |
204 | 204 | ||
205 | return ret; | 205 | return ret; |
206 | 206 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 9c2e08e4b093..1e8024ea6910 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1512,11 +1512,11 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1512 | /* | 1512 | /* |
1513 | * create a new virtual interface with the given name | 1513 | * create a new virtual interface with the given name |
1514 | */ | 1514 | */ |
1515 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1515 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1516 | char *name, | 1516 | char *name, |
1517 | enum nl80211_iftype type, | 1517 | enum nl80211_iftype type, |
1518 | u32 *flags, | 1518 | u32 *flags, |
1519 | struct vif_params *params) | 1519 | struct vif_params *params) |
1520 | { | 1520 | { |
1521 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); | 1521 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
1522 | struct mwifiex_private *priv; | 1522 | struct mwifiex_private *priv; |
@@ -1634,7 +1634,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1634 | #ifdef CONFIG_DEBUG_FS | 1634 | #ifdef CONFIG_DEBUG_FS |
1635 | mwifiex_dev_debugfs_init(priv); | 1635 | mwifiex_dev_debugfs_init(priv); |
1636 | #endif | 1636 | #endif |
1637 | return dev; | 1637 | return wdev; |
1638 | error: | 1638 | error: |
1639 | if (dev && (dev->reg_state == NETREG_UNREGISTERED)) | 1639 | if (dev && (dev->reg_state == NETREG_UNREGISTERED)) |
1640 | free_netdev(dev); | 1640 | free_netdev(dev); |
@@ -1647,9 +1647,9 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); | |||
1647 | /* | 1647 | /* |
1648 | * del_virtual_intf: remove the virtual interface determined by dev | 1648 | * del_virtual_intf: remove the virtual interface determined by dev |
1649 | */ | 1649 | */ |
1650 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) | 1650 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) |
1651 | { | 1651 | { |
1652 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 1652 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); |
1653 | 1653 | ||
1654 | #ifdef CONFIG_DEBUG_FS | 1654 | #ifdef CONFIG_DEBUG_FS |
1655 | mwifiex_dev_debugfs_remove(priv); | 1655 | mwifiex_dev_debugfs_remove(priv); |
@@ -1661,11 +1661,11 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) | |||
1661 | if (netif_carrier_ok(priv->netdev)) | 1661 | if (netif_carrier_ok(priv->netdev)) |
1662 | netif_carrier_off(priv->netdev); | 1662 | netif_carrier_off(priv->netdev); |
1663 | 1663 | ||
1664 | if (dev->reg_state == NETREG_REGISTERED) | 1664 | if (wdev->netdev->reg_state == NETREG_REGISTERED) |
1665 | unregister_netdevice(dev); | 1665 | unregister_netdevice(wdev->netdev); |
1666 | 1666 | ||
1667 | if (dev->reg_state == NETREG_UNREGISTERED) | 1667 | if (wdev->netdev->reg_state == NETREG_UNREGISTERED) |
1668 | free_netdev(dev); | 1668 | free_netdev(wdev->netdev); |
1669 | 1669 | ||
1670 | /* Clear the priv in adapter */ | 1670 | /* Clear the priv in adapter */ |
1671 | priv->netdev = NULL; | 1671 | priv->netdev = NULL; |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index f0219efc8953..46803621d015 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -377,7 +377,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) | |||
377 | goto done; | 377 | goto done; |
378 | 378 | ||
379 | err_add_intf: | 379 | err_add_intf: |
380 | mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); | 380 | mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); |
381 | rtnl_unlock(); | 381 | rtnl_unlock(); |
382 | err_init_fw: | 382 | err_init_fw: |
383 | pr_debug("info: %s: unregister device\n", __func__); | 383 | pr_debug("info: %s: unregister device\n", __func__); |
@@ -844,7 +844,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
844 | 844 | ||
845 | rtnl_lock(); | 845 | rtnl_lock(); |
846 | if (priv->wdev && priv->netdev) | 846 | if (priv->wdev && priv->netdev) |
847 | mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); | 847 | mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); |
848 | rtnl_unlock(); | 848 | rtnl_unlock(); |
849 | } | 849 | } |
850 | 850 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 0b3b5aa9830d..434a90e46934 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -1005,10 +1005,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1005 | int mwifiex_check_network_compatibility(struct mwifiex_private *priv, | 1005 | int mwifiex_check_network_compatibility(struct mwifiex_private *priv, |
1006 | struct mwifiex_bssdescriptor *bss_desc); | 1006 | struct mwifiex_bssdescriptor *bss_desc); |
1007 | 1007 | ||
1008 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1008 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1009 | char *name, enum nl80211_iftype type, | 1009 | char *name, |
1010 | u32 *flags, struct vif_params *params); | 1010 | enum nl80211_iftype type, |
1011 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); | 1011 | u32 *flags, |
1012 | struct vif_params *params); | ||
1013 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev); | ||
1012 | 1014 | ||
1013 | void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); | 1015 | void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); |
1014 | 1016 | ||
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7eaaee7bb07d..aaaa3a255ed5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1435,10 +1435,10 @@ struct cfg80211_gtk_rekey_data { | |||
1435 | * | 1435 | * |
1436 | * @add_virtual_intf: create a new virtual interface with the given name, | 1436 | * @add_virtual_intf: create a new virtual interface with the given name, |
1437 | * must set the struct wireless_dev's iftype. Beware: You must create | 1437 | * must set the struct wireless_dev's iftype. Beware: You must create |
1438 | * the new netdev in the wiphy's network namespace! Returns the netdev, | 1438 | * the new netdev in the wiphy's network namespace! Returns the struct |
1439 | * or an ERR_PTR. | 1439 | * wireless_dev, or an ERR_PTR. |
1440 | * | 1440 | * |
1441 | * @del_virtual_intf: remove the virtual interface determined by ifindex. | 1441 | * @del_virtual_intf: remove the virtual interface |
1442 | * | 1442 | * |
1443 | * @change_virtual_intf: change type/configuration of virtual interface, | 1443 | * @change_virtual_intf: change type/configuration of virtual interface, |
1444 | * keep the struct wireless_dev's iftype updated. | 1444 | * keep the struct wireless_dev's iftype updated. |
@@ -1617,12 +1617,13 @@ struct cfg80211_ops { | |||
1617 | int (*resume)(struct wiphy *wiphy); | 1617 | int (*resume)(struct wiphy *wiphy); |
1618 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); | 1618 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); |
1619 | 1619 | ||
1620 | struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, | 1620 | struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy, |
1621 | char *name, | 1621 | char *name, |
1622 | enum nl80211_iftype type, | 1622 | enum nl80211_iftype type, |
1623 | u32 *flags, | 1623 | u32 *flags, |
1624 | struct vif_params *params); | 1624 | struct vif_params *params); |
1625 | int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev); | 1625 | int (*del_virtual_intf)(struct wiphy *wiphy, |
1626 | struct wireless_dev *wdev); | ||
1626 | int (*change_virtual_intf)(struct wiphy *wiphy, | 1627 | int (*change_virtual_intf)(struct wiphy *wiphy, |
1627 | struct net_device *dev, | 1628 | struct net_device *dev, |
1628 | enum nl80211_iftype type, u32 *flags, | 1629 | enum nl80211_iftype type, u32 *flags, |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7d9abea37b17..a752c7341d62 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -20,31 +20,31 @@ | |||
20 | #include "rate.h" | 20 | #include "rate.h" |
21 | #include "mesh.h" | 21 | #include "mesh.h" |
22 | 22 | ||
23 | static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, | 23 | static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, char *name, |
24 | enum nl80211_iftype type, | 24 | enum nl80211_iftype type, |
25 | u32 *flags, | 25 | u32 *flags, |
26 | struct vif_params *params) | 26 | struct vif_params *params) |
27 | { | 27 | { |
28 | struct ieee80211_local *local = wiphy_priv(wiphy); | 28 | struct ieee80211_local *local = wiphy_priv(wiphy); |
29 | struct net_device *dev; | 29 | struct wireless_dev *wdev; |
30 | struct ieee80211_sub_if_data *sdata; | 30 | struct ieee80211_sub_if_data *sdata; |
31 | int err; | 31 | int err; |
32 | 32 | ||
33 | err = ieee80211_if_add(local, name, &dev, type, params); | 33 | err = ieee80211_if_add(local, name, &wdev, type, params); |
34 | if (err) | 34 | if (err) |
35 | return ERR_PTR(err); | 35 | return ERR_PTR(err); |
36 | 36 | ||
37 | if (type == NL80211_IFTYPE_MONITOR && flags) { | 37 | if (type == NL80211_IFTYPE_MONITOR && flags) { |
38 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 38 | sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
39 | sdata->u.mntr_flags = *flags; | 39 | sdata->u.mntr_flags = *flags; |
40 | } | 40 | } |
41 | 41 | ||
42 | return dev; | 42 | return wdev; |
43 | } | 43 | } |
44 | 44 | ||
45 | static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) | 45 | static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) |
46 | { | 46 | { |
47 | ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev)); | 47 | ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev)); |
48 | 48 | ||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8f8535ee5995..c3241c3ec6d1 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1284,7 +1284,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); | |||
1284 | int ieee80211_iface_init(void); | 1284 | int ieee80211_iface_init(void); |
1285 | void ieee80211_iface_exit(void); | 1285 | void ieee80211_iface_exit(void); |
1286 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1286 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1287 | struct net_device **new_dev, enum nl80211_iftype type, | 1287 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1288 | struct vif_params *params); | 1288 | struct vif_params *params); |
1289 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 1289 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
1290 | enum nl80211_iftype type); | 1290 | enum nl80211_iftype type); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index fbef7a1ada7a..b1edf60fbba7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1373,7 +1373,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1375 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1376 | struct net_device **new_dev, enum nl80211_iftype type, | 1376 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1377 | struct vif_params *params) | 1377 | struct vif_params *params) |
1378 | { | 1378 | { |
1379 | struct net_device *ndev; | 1379 | struct net_device *ndev; |
@@ -1463,8 +1463,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1463 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 1463 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
1464 | mutex_unlock(&local->iflist_mtx); | 1464 | mutex_unlock(&local->iflist_mtx); |
1465 | 1465 | ||
1466 | if (new_dev) | 1466 | if (new_wdev) |
1467 | *new_dev = ndev; | 1467 | *new_wdev = &sdata->wdev; |
1468 | 1468 | ||
1469 | return 0; | 1469 | return 0; |
1470 | 1470 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0dc3356eea40..789d0c7b287e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1971,7 +1971,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1971 | { | 1971 | { |
1972 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 1972 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1973 | struct vif_params params; | 1973 | struct vif_params params; |
1974 | struct net_device *dev; | 1974 | struct wireless_dev *wdev; |
1975 | int err; | 1975 | int err; |
1976 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 1976 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
1977 | u32 flags; | 1977 | u32 flags; |
@@ -2001,16 +2001,14 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2001 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2001 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
2002 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2002 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2003 | &flags); | 2003 | &flags); |
2004 | dev = rdev->ops->add_virtual_intf(&rdev->wiphy, | 2004 | wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, |
2005 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2005 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2006 | type, err ? NULL : &flags, ¶ms); | 2006 | type, err ? NULL : &flags, ¶ms); |
2007 | if (IS_ERR(dev)) | 2007 | if (IS_ERR(wdev)) |
2008 | return PTR_ERR(dev); | 2008 | return PTR_ERR(wdev); |
2009 | 2009 | ||
2010 | if (type == NL80211_IFTYPE_MESH_POINT && | 2010 | if (type == NL80211_IFTYPE_MESH_POINT && |
2011 | info->attrs[NL80211_ATTR_MESH_ID]) { | 2011 | info->attrs[NL80211_ATTR_MESH_ID]) { |
2012 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
2013 | |||
2014 | wdev_lock(wdev); | 2012 | wdev_lock(wdev); |
2015 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != | 2013 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != |
2016 | IEEE80211_MAX_MESH_ID_LEN); | 2014 | IEEE80211_MAX_MESH_ID_LEN); |
@@ -2027,12 +2025,22 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2027 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | 2025 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) |
2028 | { | 2026 | { |
2029 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2027 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2030 | struct net_device *dev = info->user_ptr[1]; | 2028 | struct wireless_dev *wdev = info->user_ptr[1]; |
2031 | 2029 | ||
2032 | if (!rdev->ops->del_virtual_intf) | 2030 | if (!rdev->ops->del_virtual_intf) |
2033 | return -EOPNOTSUPP; | 2031 | return -EOPNOTSUPP; |
2034 | 2032 | ||
2035 | return rdev->ops->del_virtual_intf(&rdev->wiphy, dev); | 2033 | /* |
2034 | * If we remove a wireless device without a netdev then clear | ||
2035 | * user_ptr[1] so that nl80211_post_doit won't dereference it | ||
2036 | * to check if it needs to do dev_put(). Otherwise it crashes | ||
2037 | * since the wdev has been freed, unlike with a netdev where | ||
2038 | * we need the dev_put() for the netdev to really be freed. | ||
2039 | */ | ||
2040 | if (!wdev->netdev) | ||
2041 | info->user_ptr[1] = NULL; | ||
2042 | |||
2043 | return rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); | ||
2036 | } | 2044 | } |
2037 | 2045 | ||
2038 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) | 2046 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) |
@@ -6874,7 +6882,7 @@ static struct genl_ops nl80211_ops[] = { | |||
6874 | .doit = nl80211_del_interface, | 6882 | .doit = nl80211_del_interface, |
6875 | .policy = nl80211_policy, | 6883 | .policy = nl80211_policy, |
6876 | .flags = GENL_ADMIN_PERM, | 6884 | .flags = GENL_ADMIN_PERM, |
6877 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 6885 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
6878 | NL80211_FLAG_NEED_RTNL, | 6886 | NL80211_FLAG_NEED_RTNL, |
6879 | }, | 6887 | }, |
6880 | { | 6888 | { |