mirror of https://gitee.com/openkylin/linux.git
cfg80211/mac80211: move more combination checks to mac80211
Get rid of the cfg80211_can_add_interface() and cfg80211_can_change_interface() functions by moving that functionality to mac80211. With this patch all interface combination checks are now out of cfg80211 (except for the channel switch case which will be addressed in a future commit). Additionally, modify the ieee80211_check_combinations() function so that an undefined chandef can be passed, in order to use it before a channel is defined. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
71965c1d04
commit
b6a550156b
|
@ -109,6 +109,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
||||||
static int ieee80211_start_p2p_device(struct wiphy *wiphy,
|
static int ieee80211_start_p2p_device(struct wiphy *wiphy,
|
||||||
struct wireless_dev *wdev)
|
struct wireless_dev *wdev)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&sdata->local->chanctx_mtx);
|
||||||
|
ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
|
||||||
|
mutex_unlock(&sdata->local->chanctx_mtx);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return ieee80211_do_open(wdev, true);
|
return ieee80211_do_open(wdev, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct ieee80211_sub_if_data *nsdata;
|
struct ieee80211_sub_if_data *nsdata;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
|
@ -300,7 +301,10 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
mutex_lock(&local->chanctx_mtx);
|
||||||
|
ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
|
||||||
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
|
static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
|
@ -2808,7 +2808,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
|
||||||
enum nl80211_iftype iftype = sdata->wdev.iftype;
|
enum nl80211_iftype iftype = sdata->wdev.iftype;
|
||||||
int num[NUM_NL80211_IFTYPES];
|
int num[NUM_NL80211_IFTYPES];
|
||||||
struct ieee80211_chanctx *ctx;
|
struct ieee80211_chanctx *ctx;
|
||||||
int num_different_channels = 1;
|
int num_different_channels = 0;
|
||||||
int total = 1;
|
int total = 1;
|
||||||
|
|
||||||
lockdep_assert_held(&local->chanctx_mtx);
|
lockdep_assert_held(&local->chanctx_mtx);
|
||||||
|
@ -2816,9 +2816,13 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
|
||||||
if (WARN_ON(hweight32(radar_detect) > 1))
|
if (WARN_ON(hweight32(radar_detect) > 1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (WARN_ON(chanmode == IEEE80211_CHANCTX_SHARED && !chandef->chan))
|
if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
|
||||||
|
!chandef->chan))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (chandef)
|
||||||
|
num_different_channels = 1;
|
||||||
|
|
||||||
if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
|
if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -2841,7 +2845,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
|
||||||
num_different_channels++;
|
num_different_channels++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((chanmode == IEEE80211_CHANCTX_SHARED) &&
|
if (chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
|
||||||
cfg80211_chandef_compatible(chandef,
|
cfg80211_chandef_compatible(chandef,
|
||||||
&ctx->conf.def))
|
&ctx->conf.def))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -439,10 +439,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
|
||||||
for (j = 0; j < c->n_limits; j++) {
|
for (j = 0; j < c->n_limits; j++) {
|
||||||
u16 types = c->limits[j].types;
|
u16 types = c->limits[j].types;
|
||||||
|
|
||||||
/*
|
/* interface types shouldn't overlap */
|
||||||
* interface types shouldn't overlap, this is
|
|
||||||
* used in cfg80211_can_change_interface()
|
|
||||||
*/
|
|
||||||
if (WARN_ON(types & all_iftypes))
|
if (WARN_ON(types & all_iftypes))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
all_iftypes |= types;
|
all_iftypes |= types;
|
||||||
|
@ -840,7 +837,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
||||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
struct cfg80211_registered_device *rdev;
|
struct cfg80211_registered_device *rdev;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!wdev)
|
if (!wdev)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
@ -1003,9 +999,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
||||||
case NETDEV_PRE_UP:
|
case NETDEV_PRE_UP:
|
||||||
if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
|
if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
|
||||||
return notifier_from_errno(-EOPNOTSUPP);
|
return notifier_from_errno(-EOPNOTSUPP);
|
||||||
ret = cfg80211_can_add_interface(rdev, wdev->iftype);
|
if (rfkill_blocked(rdev->rfkill))
|
||||||
if (ret)
|
return notifier_from_errno(-ERFKILL);
|
||||||
return notifier_from_errno(ret);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -412,28 +412,6 @@ unsigned int
|
||||||
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
|
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
|
||||||
const struct cfg80211_chan_def *chandef);
|
const struct cfg80211_chan_def *chandef);
|
||||||
|
|
||||||
static inline int
|
|
||||||
cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
|
|
||||||
struct wireless_dev *wdev,
|
|
||||||
enum nl80211_iftype iftype)
|
|
||||||
{
|
|
||||||
/* TODO: For this function, we'll probably need to keep some
|
|
||||||
* kind of interface combination check in cfg80211...
|
|
||||||
*/
|
|
||||||
return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL,
|
|
||||||
CHAN_MODE_UNDEFINED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
|
|
||||||
enum nl80211_iftype iftype)
|
|
||||||
{
|
|
||||||
if (rfkill_blocked(rdev->rfkill))
|
|
||||||
return -ERFKILL;
|
|
||||||
|
|
||||||
return cfg80211_can_change_interface(rdev, NULL, iftype);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
|
static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
|
||||||
{
|
{
|
||||||
unsigned long end = jiffies;
|
unsigned long end = jiffies;
|
||||||
|
|
|
@ -8969,9 +8969,8 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (wdev->p2p_started)
|
if (wdev->p2p_started)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err = cfg80211_can_add_interface(rdev, wdev->iftype);
|
if (rfkill_blocked(rdev->rfkill))
|
||||||
if (err)
|
return -ERFKILL;
|
||||||
return err;
|
|
||||||
|
|
||||||
err = rdev_start_p2p_device(rdev, wdev);
|
err = rdev_start_p2p_device(rdev, wdev);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -888,11 +888,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (ntype != otype && netif_running(dev)) {
|
if (ntype != otype && netif_running(dev)) {
|
||||||
err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
|
|
||||||
ntype);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
dev->ieee80211_ptr->use_4addr = false;
|
dev->ieee80211_ptr->use_4addr = false;
|
||||||
dev->ieee80211_ptr->mesh_id_up_len = 0;
|
dev->ieee80211_ptr->mesh_id_up_len = 0;
|
||||||
wdev_lock(dev->ieee80211_ptr);
|
wdev_lock(dev->ieee80211_ptr);
|
||||||
|
|
Loading…
Reference in New Issue