Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
@@ -564,12 +564,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
|
||||
if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
|
||||
goto nla_put_failure;
|
||||
if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN))
|
||||
goto nla_put_failure;
|
||||
if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
|
||||
goto nla_put_failure;
|
||||
if (chan->flags & IEEE80211_CHAN_NO_IR) {
|
||||
if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
if (chan->flags & IEEE80211_CHAN_RADAR) {
|
||||
if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
|
||||
goto nla_put_failure;
|
||||
@@ -1247,10 +1247,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
||||
if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
|
||||
nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
|
||||
goto nla_put_failure;
|
||||
if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
|
||||
nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ))
|
||||
goto nla_put_failure;
|
||||
|
||||
state->split_start++;
|
||||
if (state->split)
|
||||
break;
|
||||
@@ -1579,6 +1575,11 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
|
||||
if (nl80211_send_coalesce(msg, dev))
|
||||
goto nla_put_failure;
|
||||
|
||||
if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
|
||||
(nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
|
||||
nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
|
||||
goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
break;
|
||||
@@ -2187,7 +2188,7 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
|
||||
}
|
||||
|
||||
static int nl80211_send_chandef(struct sk_buff *msg,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
WARN_ON(!cfg80211_chandef_valid(chandef));
|
||||
|
||||
@@ -3236,6 +3237,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
return PTR_ERR(params.acl);
|
||||
}
|
||||
|
||||
wdev_lock(wdev);
|
||||
err = rdev_start_ap(rdev, dev, ¶ms);
|
||||
if (!err) {
|
||||
wdev->preset_chandef = params.chandef;
|
||||
@@ -3244,6 +3246,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
wdev->ssid_len = params.ssid_len;
|
||||
memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
|
||||
}
|
||||
wdev_unlock(wdev);
|
||||
|
||||
kfree(params.acl);
|
||||
|
||||
@@ -3272,7 +3275,11 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return rdev_change_beacon(rdev, dev, ¶ms);
|
||||
wdev_lock(wdev);
|
||||
err = rdev_change_beacon(rdev, dev, ¶ms);
|
||||
wdev_unlock(wdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
@@ -4478,7 +4485,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct bss_parameters params;
|
||||
int err;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
/* default to not changing parameters */
|
||||
@@ -4544,7 +4553,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
|
||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return rdev_change_bss(rdev, dev, ¶ms);
|
||||
wdev_lock(wdev);
|
||||
err = rdev_change_bss(rdev, dev, ¶ms);
|
||||
wdev_unlock(wdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
|
||||
@@ -5098,7 +5111,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
|
||||
char *alpha2 = NULL;
|
||||
int rem_reg_rules = 0, r = 0;
|
||||
u32 num_rules = 0, rule_idx = 0, size_of_regd;
|
||||
u8 dfs_region = 0;
|
||||
enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
|
||||
struct ieee80211_regdomain *rd = NULL;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
|
||||
@@ -5119,6 +5132,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!reg_is_valid_request(alpha2))
|
||||
return -EINVAL;
|
||||
|
||||
size_of_regd = sizeof(struct ieee80211_regdomain) +
|
||||
num_rules * sizeof(struct ieee80211_reg_rule);
|
||||
|
||||
@@ -5361,10 +5377,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
|
||||
request->flags = nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_SCAN_FLAGS]);
|
||||
if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
|
||||
((request->flags & NL80211_SCAN_FLAG_FLUSH) &&
|
||||
!(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) {
|
||||
if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out_free;
|
||||
}
|
||||
@@ -5604,10 +5618,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||
if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
|
||||
request->flags = nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_SCAN_FLAGS]);
|
||||
if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
|
||||
((request->flags & NL80211_SCAN_FLAG_FLUSH) &&
|
||||
!(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) {
|
||||
if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
|
||||
!(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out_free;
|
||||
}
|
||||
@@ -5670,7 +5682,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
||||
if (err == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (chandef.chan->dfs_state != NL80211_DFS_USABLE)
|
||||
if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
|
||||
return -EINVAL;
|
||||
|
||||
if (!rdev->ops->start_radar_detection)
|
||||
@@ -5810,7 +5822,11 @@ skip_beacons:
|
||||
if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
|
||||
params.block_tx = true;
|
||||
|
||||
return rdev_channel_switch(rdev, dev, ¶ms);
|
||||
wdev_lock(wdev);
|
||||
err = rdev_channel_switch(rdev, dev, ¶ms);
|
||||
wdev_unlock(wdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
|
||||
@@ -7443,10 +7459,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
void *hdr = NULL;
|
||||
u64 cookie;
|
||||
struct sk_buff *msg = NULL;
|
||||
unsigned int wait = 0;
|
||||
bool offchan, no_cck, dont_wait_for_ack;
|
||||
|
||||
dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
|
||||
struct cfg80211_mgmt_tx_params params = {
|
||||
.dont_wait_for_ack =
|
||||
info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
|
||||
};
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_FRAME])
|
||||
return -EINVAL;
|
||||
@@ -7473,24 +7489,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
if (info->attrs[NL80211_ATTR_DURATION]) {
|
||||
if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
|
||||
return -EINVAL;
|
||||
wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
|
||||
params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
|
||||
|
||||
/*
|
||||
* We should wait on the channel for at least a minimum amount
|
||||
* of time (10ms) but no longer than the driver supports.
|
||||
*/
|
||||
if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
|
||||
wait > rdev->wiphy.max_remain_on_channel_duration)
|
||||
if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
|
||||
params.wait > rdev->wiphy.max_remain_on_channel_duration)
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
|
||||
offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
|
||||
params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
|
||||
|
||||
if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
|
||||
if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
|
||||
return -EINVAL;
|
||||
|
||||
no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
|
||||
params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
|
||||
|
||||
/* get the channel if any has been specified, otherwise pass NULL to
|
||||
* the driver. The latter will use the current one
|
||||
@@ -7502,10 +7518,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!chandef.chan && offchan)
|
||||
if (!chandef.chan && params.offchan)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dont_wait_for_ack) {
|
||||
if (!params.dont_wait_for_ack) {
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
@@ -7518,10 +7534,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
|
||||
nla_data(info->attrs[NL80211_ATTR_FRAME]),
|
||||
nla_len(info->attrs[NL80211_ATTR_FRAME]),
|
||||
no_cck, dont_wait_for_ack, &cookie);
|
||||
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
|
||||
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
|
||||
params.chan = chandef.chan;
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie);
|
||||
if (err)
|
||||
goto free_msg;
|
||||
|
||||
@@ -10805,21 +10821,18 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
trace_cfg80211_ch_switch_notify(dev, chandef);
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
|
||||
wdev_lock(wdev);
|
||||
trace_cfg80211_ch_switch_notify(dev, chandef);
|
||||
|
||||
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO &&
|
||||
wdev->iftype != NL80211_IFTYPE_ADHOC &&
|
||||
wdev->iftype != NL80211_IFTYPE_MESH_POINT))
|
||||
goto out;
|
||||
return;
|
||||
|
||||
wdev->channel = chandef->chan;
|
||||
nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ch_switch_notify);
|
||||
|
||||
@@ -10878,7 +10891,7 @@ EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
|
||||
|
||||
void
|
||||
nl80211_radar_notify(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
enum nl80211_radar_event event,
|
||||
struct net_device *netdev, gfp_t gfp)
|
||||
{
|
||||
|
Reference in New Issue
Block a user