aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c30
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h6
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c8
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c24
-rw-r--r--drivers/net/wireless/mwifiex/main.c4
-rw-r--r--drivers/net/wireless/mwifiex/main.h10
-rw-r--r--include/net/cfg80211.h19
-rw-r--r--net/mac80211/cfg.c20
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/wireless/nl80211.c26
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
1490static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, 1490static 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
1519static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, 1519static 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
3480struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, 3480struct 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
3538err: 3538err:
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
28struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, 28struct 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);
31void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, 31void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
32 enum wmi_phy_mode mode); 32 enum wmi_phy_mode mode);
33void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); 33void 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);
56int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) 56int 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 */
1515struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, 1515struct 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;
1638error: 1638error:
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 */
1650int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) 1650int 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
379err_add_intf: 379err_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();
382err_init_fw: 382err_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,
1005int mwifiex_check_network_compatibility(struct mwifiex_private *priv, 1005int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1006 struct mwifiex_bssdescriptor *bss_desc); 1006 struct mwifiex_bssdescriptor *bss_desc);
1007 1007
1008struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, 1008struct 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,
1011int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); 1011 u32 *flags,
1012 struct vif_params *params);
1013int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
1012 1014
1013void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); 1015void 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
23static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, 23static 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
45static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) 45static 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);
1284int ieee80211_iface_init(void); 1284int ieee80211_iface_init(void);
1285void ieee80211_iface_exit(void); 1285void ieee80211_iface_exit(void);
1286int ieee80211_if_add(struct ieee80211_local *local, const char *name, 1286int 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);
1289int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 1289int 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
1375int ieee80211_if_add(struct ieee80211_local *local, const char *name, 1375int 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, &params); 2006 type, err ? NULL : &flags, &params);
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)
2027static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 2025static 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
2038static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) 2046static 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 {