Commit 84efbb84 authored by Johannes Berg's avatar Johannes Berg

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 71bbc994
...@@ -1487,14 +1487,14 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, ...@@ -1487,14 +1487,14 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
return 0; return 0;
} }
static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
char *name, char *name,
enum nl80211_iftype type, enum nl80211_iftype type,
u32 *flags, u32 *flags,
struct vif_params *params) struct vif_params *params)
{ {
struct ath6kl *ar = wiphy_priv(wiphy); struct ath6kl *ar = wiphy_priv(wiphy);
struct net_device *ndev; struct wireless_dev *wdev;
u8 if_idx, nw_type; u8 if_idx, nw_type;
if (ar->num_vif == ar->vif_max) { if (ar->num_vif == ar->vif_max) {
...@@ -1507,20 +1507,20 @@ static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, ...@@ -1507,20 +1507,20 @@ static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type); wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
if (!ndev) if (!wdev)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ar->num_vif++; ar->num_vif++;
return ndev; return wdev;
} }
static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
struct net_device *ndev) struct wireless_dev *wdev)
{ {
struct ath6kl *ar = wiphy_priv(wiphy); struct ath6kl *ar = wiphy_priv(wiphy);
struct ath6kl_vif *vif = netdev_priv(ndev); struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
spin_lock_bh(&ar->list_lock); spin_lock_bh(&ar->list_lock);
list_del(&vif->list); list_del(&vif->list);
...@@ -3477,9 +3477,9 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) ...@@ -3477,9 +3477,9 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
ar->num_vif--; ar->num_vif--;
} }
struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name,
enum nl80211_iftype type, u8 fw_vif_idx, enum nl80211_iftype type,
u8 nw_type) u8 fw_vif_idx, u8 nw_type)
{ {
struct net_device *ndev; struct net_device *ndev;
struct ath6kl_vif *vif; struct ath6kl_vif *vif;
...@@ -3533,7 +3533,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, ...@@ -3533,7 +3533,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
list_add_tail(&vif->list, &ar->vif_list); list_add_tail(&vif->list, &ar->vif_list);
spin_unlock_bh(&ar->list_lock); spin_unlock_bh(&ar->list_lock);
return ndev; return &vif->wdev;
err: err:
aggr_module_destroy(vif->aggr_cntxt); aggr_module_destroy(vif->aggr_cntxt);
......
...@@ -25,9 +25,9 @@ enum ath6kl_cfg_suspend_mode { ...@@ -25,9 +25,9 @@ enum ath6kl_cfg_suspend_mode {
ATH6KL_CFG_SUSPEND_SCHED_SCAN, ATH6KL_CFG_SUSPEND_SCHED_SCAN,
}; };
struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name,
enum nl80211_iftype type, enum nl80211_iftype type,
u8 fw_vif_idx, u8 nw_type); u8 fw_vif_idx, u8 nw_type);
void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
enum wmi_phy_mode mode); enum wmi_phy_mode mode);
void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
......
...@@ -56,7 +56,7 @@ EXPORT_SYMBOL(ath6kl_core_rx_complete); ...@@ -56,7 +56,7 @@ EXPORT_SYMBOL(ath6kl_core_rx_complete);
int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
{ {
struct ath6kl_bmi_target_info targ_info; struct ath6kl_bmi_target_info targ_info;
struct net_device *ndev; struct wireless_dev *wdev;
int ret = 0, i; int ret = 0, i;
switch (htc_type) { switch (htc_type) {
...@@ -187,12 +187,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ...@@ -187,12 +187,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
rtnl_lock(); rtnl_lock();
/* Add an initial station interface */ /* Add an initial station interface */
ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, wdev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
INFRA_NETWORK); INFRA_NETWORK);
rtnl_unlock(); rtnl_unlock();
if (!ndev) { if (!wdev) {
ath6kl_err("Failed to instantiate a network device\n"); ath6kl_err("Failed to instantiate a network device\n");
ret = -ENOMEM; ret = -ENOMEM;
wiphy_unregister(ar->wiphy); wiphy_unregister(ar->wiphy);
...@@ -200,7 +200,7 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ...@@ -200,7 +200,7 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
} }
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
__func__, ndev->name, ndev, ar); __func__, wdev->netdev->name, wdev->netdev, ar);
return ret; return ret;
......
...@@ -1512,11 +1512,11 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, ...@@ -1512,11 +1512,11 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
/* /*
* create a new virtual interface with the given name * create a new virtual interface with the given name
*/ */
struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
char *name, char *name,
enum nl80211_iftype type, enum nl80211_iftype type,
u32 *flags, u32 *flags,
struct vif_params *params) struct vif_params *params)
{ {
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
struct mwifiex_private *priv; struct mwifiex_private *priv;
...@@ -1634,7 +1634,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, ...@@ -1634,7 +1634,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
mwifiex_dev_debugfs_init(priv); mwifiex_dev_debugfs_init(priv);
#endif #endif
return dev; return wdev;
error: error:
if (dev && (dev->reg_state == NETREG_UNREGISTERED)) if (dev && (dev->reg_state == NETREG_UNREGISTERED))
free_netdev(dev); free_netdev(dev);
...@@ -1647,9 +1647,9 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); ...@@ -1647,9 +1647,9 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
/* /*
* del_virtual_intf: remove the virtual interface determined by dev * del_virtual_intf: remove the virtual interface determined by dev
*/ */
int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
mwifiex_dev_debugfs_remove(priv); mwifiex_dev_debugfs_remove(priv);
...@@ -1661,11 +1661,11 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) ...@@ -1661,11 +1661,11 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
if (netif_carrier_ok(priv->netdev)) if (netif_carrier_ok(priv->netdev))
netif_carrier_off(priv->netdev); netif_carrier_off(priv->netdev);
if (dev->reg_state == NETREG_REGISTERED) if (wdev->netdev->reg_state == NETREG_REGISTERED)
unregister_netdevice(dev); unregister_netdevice(wdev->netdev);
if (dev->reg_state == NETREG_UNREGISTERED) if (wdev->netdev->reg_state == NETREG_UNREGISTERED)
free_netdev(dev); free_netdev(wdev->netdev);
/* Clear the priv in adapter */ /* Clear the priv in adapter */
priv->netdev = NULL; priv->netdev = NULL;
......
...@@ -377,7 +377,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) ...@@ -377,7 +377,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
goto done; goto done;
err_add_intf: err_add_intf:
mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
rtnl_unlock(); rtnl_unlock();
err_init_fw: err_init_fw:
pr_debug("info: %s: unregister device\n", __func__); pr_debug("info: %s: unregister device\n", __func__);
...@@ -844,7 +844,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) ...@@ -844,7 +844,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
rtnl_lock(); rtnl_lock();
if (priv->wdev && priv->netdev) if (priv->wdev && priv->netdev)
mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
rtnl_unlock(); rtnl_unlock();
} }
......
...@@ -1005,10 +1005,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1005,10 +1005,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
int mwifiex_check_network_compatibility(struct mwifiex_private *priv, int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
struct mwifiex_bssdescriptor *bss_desc); struct mwifiex_bssdescriptor *bss_desc);
struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
char *name, enum nl80211_iftype type, char *name,
u32 *flags, struct vif_params *params); enum nl80211_iftype type,
int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); u32 *flags,
struct vif_params *params);
int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config);
......
...@@ -1435,10 +1435,10 @@ struct cfg80211_gtk_rekey_data { ...@@ -1435,10 +1435,10 @@ struct cfg80211_gtk_rekey_data {
* *
* @add_virtual_intf: create a new virtual interface with the given name, * @add_virtual_intf: create a new virtual interface with the given name,
* must set the struct wireless_dev's iftype. Beware: You must create * must set the struct wireless_dev's iftype. Beware: You must create
* the new netdev in the wiphy's network namespace! Returns the netdev, * the new netdev in the wiphy's network namespace! Returns the struct
* or an ERR_PTR. * wireless_dev, or an ERR_PTR.
* *
* @del_virtual_intf: remove the virtual interface determined by ifindex. * @del_virtual_intf: remove the virtual interface
* *
* @change_virtual_intf: change type/configuration of virtual interface, * @change_virtual_intf: change type/configuration of virtual interface,
* keep the struct wireless_dev's iftype updated. * keep the struct wireless_dev's iftype updated.
...@@ -1617,12 +1617,13 @@ struct cfg80211_ops { ...@@ -1617,12 +1617,13 @@ struct cfg80211_ops {
int (*resume)(struct wiphy *wiphy); int (*resume)(struct wiphy *wiphy);
void (*set_wakeup)(struct wiphy *wiphy, bool enabled); void (*set_wakeup)(struct wiphy *wiphy, bool enabled);
struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy,
char *name, char *name,
enum nl80211_iftype type, enum nl80211_iftype type,
u32 *flags, u32 *flags,
struct vif_params *params); struct vif_params *params);
int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev); int (*del_virtual_intf)(struct wiphy *wiphy,
struct wireless_dev *wdev);
int (*change_virtual_intf)(struct wiphy *wiphy, int (*change_virtual_intf)(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
enum nl80211_iftype type, u32 *flags, enum nl80211_iftype type, u32 *flags,
......
...@@ -20,31 +20,31 @@ ...@@ -20,31 +20,31 @@
#include "rate.h" #include "rate.h"
#include "mesh.h" #include "mesh.h"
static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, char *name,
enum nl80211_iftype type, enum nl80211_iftype type,
u32 *flags, u32 *flags,
struct vif_params *params) struct vif_params *params)
{ {
struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_local *local = wiphy_priv(wiphy);
struct net_device *dev; struct wireless_dev *wdev;
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
int err; int err;
err = ieee80211_if_add(local, name, &dev, type, params); err = ieee80211_if_add(local, name, &wdev, type, params);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
if (type == NL80211_IFTYPE_MONITOR && flags) { if (type == NL80211_IFTYPE_MONITOR && flags) {
sdata = IEEE80211_DEV_TO_SUB_IF(dev); sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
sdata->u.mntr_flags = *flags; sdata->u.mntr_flags = *flags;
} }
return dev; return wdev;
} }
static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
{ {
ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev)); ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev));
return 0; return 0;
} }
......
...@@ -1284,7 +1284,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); ...@@ -1284,7 +1284,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
int ieee80211_iface_init(void); int ieee80211_iface_init(void);
void ieee80211_iface_exit(void); void ieee80211_iface_exit(void);
int ieee80211_if_add(struct ieee80211_local *local, const char *name, int ieee80211_if_add(struct ieee80211_local *local, const char *name,
struct net_device **new_dev, enum nl80211_iftype type, struct wireless_dev **new_wdev, enum nl80211_iftype type,
struct vif_params *params); struct vif_params *params);
int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type); enum nl80211_iftype type);
......
...@@ -1373,7 +1373,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, ...@@ -1373,7 +1373,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
} }
int ieee80211_if_add(struct ieee80211_local *local, const char *name, int ieee80211_if_add(struct ieee80211_local *local, const char *name,
struct net_device **new_dev, enum nl80211_iftype type, struct wireless_dev **new_wdev, enum nl80211_iftype type,
struct vif_params *params) struct vif_params *params)
{ {
struct net_device *ndev; struct net_device *ndev;
...@@ -1463,8 +1463,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ...@@ -1463,8 +1463,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
list_add_tail_rcu(&sdata->list, &local->interfaces); list_add_tail_rcu(&sdata->list, &local->interfaces);
mutex_unlock(&local->iflist_mtx); mutex_unlock(&local->iflist_mtx);
if (new_dev) if (new_wdev)
*new_dev = ndev; *new_wdev = &sdata->wdev;
return 0; return 0;
......
...@@ -1971,7 +1971,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) ...@@ -1971,7 +1971,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
{ {
struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct vif_params params; struct vif_params params;
struct net_device *dev; struct wireless_dev *wdev;
int err; int err;
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
u32 flags; u32 flags;
...@@ -2001,16 +2001,14 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) ...@@ -2001,16 +2001,14 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
&flags); &flags);
dev = rdev->ops->add_virtual_intf(&rdev->wiphy, wdev = rdev->ops->add_virtual_intf(&rdev->wiphy,
nla_data(info->attrs[NL80211_ATTR_IFNAME]), nla_data(info->attrs[NL80211_ATTR_IFNAME]),
type, err ? NULL : &flags, &params); type, err ? NULL : &flags, &params);
if (IS_ERR(dev)) if (IS_ERR(wdev))
return PTR_ERR(dev); return PTR_ERR(wdev);
if (type == NL80211_IFTYPE_MESH_POINT && if (type == NL80211_IFTYPE_MESH_POINT &&
info->attrs[NL80211_ATTR_MESH_ID]) { info->attrs[NL80211_ATTR_MESH_ID]) {
struct wireless_dev *wdev = dev->ieee80211_ptr;
wdev_lock(wdev); wdev_lock(wdev);
BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
IEEE80211_MAX_MESH_ID_LEN); IEEE80211_MAX_MESH_ID_LEN);
...@@ -2027,12 +2025,22 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) ...@@ -2027,12 +2025,22 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
{ {
struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = info->user_ptr[1];
if (!rdev->ops->del_virtual_intf) if (!rdev->ops->del_virtual_intf)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return rdev->ops->del_virtual_intf(&rdev->wiphy, dev); /*
* If we remove a wireless device without a netdev then clear
* user_ptr[1] so that nl80211_post_doit won't dereference it
* to check if it needs to do dev_put(). Otherwise it crashes
* since the wdev has been freed, unlike with a netdev where
* we need the dev_put() for the netdev to really be freed.
*/
if (!wdev->netdev)
info->user_ptr[1] = NULL;
return rdev->ops->del_virtual_intf(&rdev->wiphy, wdev);
} }
static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) 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,7 +6882,7 @@ static struct genl_ops nl80211_ops[] = {
.doit = nl80211_del_interface, .doit = nl80211_del_interface,
.policy = nl80211_policy, .policy = nl80211_policy,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_NETDEV | .internal_flags = NL80211_FLAG_NEED_WDEV |
NL80211_FLAG_NEED_RTNL, NL80211_FLAG_NEED_RTNL,
}, },
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment