Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev)
|
||||
struct net_device *dev, bool notify)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
int err;
|
||||
@@ -30,20 +30,21 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
memset(&wdev->chandef, 0, sizeof(wdev->chandef));
|
||||
wdev->ssid_len = 0;
|
||||
rdev_set_qos_map(rdev, dev, NULL);
|
||||
nl80211_send_ap_stopped(wdev);
|
||||
if (notify)
|
||||
nl80211_send_ap_stopped(wdev);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev)
|
||||
struct net_device *dev, bool notify)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
int err;
|
||||
|
||||
wdev_lock(wdev);
|
||||
err = __cfg80211_stop_ap(rdev, dev);
|
||||
err = __cfg80211_stop_ap(rdev, dev, notify);
|
||||
wdev_unlock(wdev);
|
||||
|
||||
return err;
|
||||
|
@@ -490,6 +490,62 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
|
||||
return r;
|
||||
}
|
||||
|
||||
static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
|
||||
u32 center_freq,
|
||||
u32 bandwidth)
|
||||
{
|
||||
struct ieee80211_channel *c;
|
||||
u32 start_freq, end_freq, freq;
|
||||
unsigned int dfs_cac_ms = 0;
|
||||
|
||||
start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
|
||||
end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
|
||||
|
||||
for (freq = start_freq; freq <= end_freq; freq += 20) {
|
||||
c = ieee80211_get_channel(wiphy, freq);
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
if (c->flags & IEEE80211_CHAN_DISABLED)
|
||||
return 0;
|
||||
|
||||
if (!(c->flags & IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
|
||||
if (c->dfs_cac_ms > dfs_cac_ms)
|
||||
dfs_cac_ms = c->dfs_cac_ms;
|
||||
}
|
||||
|
||||
return dfs_cac_ms;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
int width;
|
||||
unsigned int t1 = 0, t2 = 0;
|
||||
|
||||
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
|
||||
return 0;
|
||||
|
||||
width = cfg80211_chandef_get_width(chandef);
|
||||
if (width < 0)
|
||||
return 0;
|
||||
|
||||
t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
|
||||
chandef->center_freq1,
|
||||
width);
|
||||
|
||||
if (!chandef->center_freq2)
|
||||
return t1;
|
||||
|
||||
t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
|
||||
chandef->center_freq2,
|
||||
width);
|
||||
|
||||
return max(t1, t2);
|
||||
}
|
||||
|
||||
static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
|
||||
u32 center_freq, u32 bandwidth,
|
||||
|
@@ -783,7 +783,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
cfg80211_stop_ap(rdev, dev);
|
||||
cfg80211_stop_ap(rdev, dev, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@@ -166,7 +166,6 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
|
||||
mutex_unlock(&wdev->mtx);
|
||||
}
|
||||
|
||||
#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
|
||||
#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
|
||||
|
||||
static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
|
||||
@@ -246,10 +245,6 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
|
||||
unsigned long age_secs);
|
||||
|
||||
/* IBSS */
|
||||
int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_ibss_params *params,
|
||||
struct cfg80211_cached_keys *connkeys);
|
||||
int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_ibss_params *params,
|
||||
@@ -283,7 +278,7 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
|
||||
|
||||
/* AP */
|
||||
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev);
|
||||
struct net_device *dev, bool notify);
|
||||
|
||||
/* MLME */
|
||||
int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
|
||||
@@ -402,6 +397,9 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
|
||||
|
||||
void cfg80211_dfs_channels_update_work(struct work_struct *work);
|
||||
|
||||
unsigned int
|
||||
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
|
||||
const struct cfg80211_chan_def *chandef);
|
||||
|
||||
static inline int
|
||||
cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
|
||||
|
@@ -66,6 +66,7 @@ function parse_reg_rule()
|
||||
units = $8
|
||||
sub(/\)/, "", units)
|
||||
sub(/,/, "", units)
|
||||
dfs_cac = $9
|
||||
if (units == "mW") {
|
||||
if (power == 100) {
|
||||
power = 20
|
||||
@@ -78,7 +79,12 @@ function parse_reg_rule()
|
||||
} else {
|
||||
print "Unknown power value in database!"
|
||||
}
|
||||
} else {
|
||||
dfs_cac = $8
|
||||
}
|
||||
sub(/,/, "", dfs_cac)
|
||||
sub(/\(/, "", dfs_cac)
|
||||
sub(/\)/, "", dfs_cac)
|
||||
flagstr = ""
|
||||
for (i=8; i<=NF; i++)
|
||||
flagstr = flagstr $i
|
||||
@@ -111,7 +117,7 @@ function parse_reg_rule()
|
||||
|
||||
}
|
||||
flags = flags "0"
|
||||
printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags
|
||||
printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
|
||||
rules++
|
||||
}
|
||||
|
||||
|
@@ -82,10 +82,10 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ibss_joined);
|
||||
|
||||
int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_ibss_params *params,
|
||||
struct cfg80211_cached_keys *connkeys)
|
||||
static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_ibss_params *params,
|
||||
struct cfg80211_cached_keys *connkeys)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct ieee80211_channel *check_chan;
|
||||
|
@@ -778,7 +778,7 @@ void cfg80211_cac_event(struct net_device *netdev,
|
||||
switch (event) {
|
||||
case NL80211_RADAR_CAC_FINISHED:
|
||||
timeout = wdev->cac_start_time +
|
||||
msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
|
||||
msecs_to_jiffies(wdev->cac_time_ms);
|
||||
WARN_ON(!time_after_eq(jiffies, timeout));
|
||||
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
|
||||
break;
|
||||
|
@@ -593,6 +593,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
|
||||
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
|
||||
time))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_u32(msg,
|
||||
NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
|
||||
chan->dfs_cac_ms))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3328,7 +3332,7 @@ static int nl80211_stop_ap(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];
|
||||
|
||||
return cfg80211_stop_ap(rdev, dev);
|
||||
return cfg80211_stop_ap(rdev, dev, false);
|
||||
}
|
||||
|
||||
static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
|
||||
@@ -4614,6 +4618,7 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] =
|
||||
[NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int parse_reg_rule(struct nlattr *tb[],
|
||||
@@ -4649,6 +4654,10 @@ static int parse_reg_rule(struct nlattr *tb[],
|
||||
power_rule->max_antenna_gain =
|
||||
nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
|
||||
|
||||
if (tb[NL80211_ATTR_DFS_CAC_TIME])
|
||||
reg_rule->dfs_cac_ms =
|
||||
nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5136,7 +5145,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
|
||||
nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
|
||||
power_rule->max_antenna_gain) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
|
||||
power_rule->max_eirp))
|
||||
power_rule->max_eirp) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
|
||||
reg_rule->dfs_cac_ms))
|
||||
goto nla_put_failure_rcu;
|
||||
|
||||
nla_nest_end(msg, nl_reg_rule);
|
||||
@@ -5768,6 +5779,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_chan_def chandef;
|
||||
enum nl80211_dfs_regions dfs_region;
|
||||
unsigned int cac_time_ms;
|
||||
int err;
|
||||
|
||||
dfs_region = reg_get_dfs_region(wdev->wiphy);
|
||||
@@ -5803,11 +5815,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
|
||||
cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
|
||||
if (WARN_ON(!cac_time_ms))
|
||||
cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
||||
|
||||
err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef,
|
||||
cac_time_ms);
|
||||
if (!err) {
|
||||
wdev->chandef = chandef;
|
||||
wdev->cac_started = true;
|
||||
wdev->cac_start_time = jiffies;
|
||||
wdev->cac_time_ms = cac_time_ms;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@@ -91,10 +91,6 @@ static struct regulatory_request __rcu *last_request =
|
||||
/* To trigger userspace events */
|
||||
static struct platform_device *reg_pdev;
|
||||
|
||||
static const struct device_type reg_device_type = {
|
||||
.uevent = reg_device_uevent,
|
||||
};
|
||||
|
||||
/*
|
||||
* Central wireless core regulatory domains, we only need two,
|
||||
* the current one and a world regulatory domain in case we have no
|
||||
@@ -244,19 +240,21 @@ static char user_alpha2[2];
|
||||
module_param(ieee80211_regdom, charp, 0444);
|
||||
MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
|
||||
|
||||
static void reg_kfree_last_request(void)
|
||||
static void reg_free_request(struct regulatory_request *lr)
|
||||
{
|
||||
struct regulatory_request *lr;
|
||||
|
||||
lr = get_last_request();
|
||||
|
||||
if (lr != &core_request_world && lr)
|
||||
kfree_rcu(lr, rcu_head);
|
||||
}
|
||||
|
||||
static void reg_update_last_request(struct regulatory_request *request)
|
||||
{
|
||||
reg_kfree_last_request();
|
||||
struct regulatory_request *lr;
|
||||
|
||||
lr = get_last_request();
|
||||
if (lr == request)
|
||||
return;
|
||||
|
||||
reg_free_request(lr);
|
||||
rcu_assign_pointer(last_request, request);
|
||||
}
|
||||
|
||||
@@ -487,11 +485,16 @@ static inline void reg_regdb_query(const char *alpha2) {}
|
||||
|
||||
/*
|
||||
* This lets us keep regulatory code which is updated on a regulatory
|
||||
* basis in userspace. Country information is filled in by
|
||||
* reg_device_uevent
|
||||
* basis in userspace.
|
||||
*/
|
||||
static int call_crda(const char *alpha2)
|
||||
{
|
||||
char country[12];
|
||||
char *env[] = { country, NULL };
|
||||
|
||||
snprintf(country, sizeof(country), "COUNTRY=%c%c",
|
||||
alpha2[0], alpha2[1]);
|
||||
|
||||
if (!is_world_regdom((char *) alpha2))
|
||||
pr_info("Calling CRDA for country: %c%c\n",
|
||||
alpha2[0], alpha2[1]);
|
||||
@@ -501,7 +504,7 @@ static int call_crda(const char *alpha2)
|
||||
/* query internal regulatory database (if it exists) */
|
||||
reg_regdb_query(alpha2);
|
||||
|
||||
return kobject_uevent(®_pdev->dev.kobj, KOBJ_CHANGE);
|
||||
return kobject_uevent_env(®_pdev->dev.kobj, KOBJ_CHANGE, env);
|
||||
}
|
||||
|
||||
static enum reg_request_treatment
|
||||
@@ -755,6 +758,9 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
|
||||
power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
|
||||
power_rule2->max_antenna_gain);
|
||||
|
||||
intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms,
|
||||
rule2->dfs_cac_ms);
|
||||
|
||||
if (!is_valid_reg_rule(intersected_rule))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1077,6 +1083,14 @@ static void handle_channel(struct wiphy *wiphy,
|
||||
min_t(int, chan->orig_mag,
|
||||
MBI_TO_DBI(power_rule->max_antenna_gain));
|
||||
chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
|
||||
|
||||
if (chan->flags & IEEE80211_CHAN_RADAR) {
|
||||
if (reg_rule->dfs_cac_ms)
|
||||
chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
|
||||
else
|
||||
chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
|
||||
}
|
||||
|
||||
if (chan->orig_mpwr) {
|
||||
/*
|
||||
* Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
|
||||
@@ -2255,9 +2269,9 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
||||
const struct ieee80211_reg_rule *reg_rule = NULL;
|
||||
const struct ieee80211_freq_range *freq_range = NULL;
|
||||
const struct ieee80211_power_rule *power_rule = NULL;
|
||||
char bw[32];
|
||||
char bw[32], cac_time[32];
|
||||
|
||||
pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n");
|
||||
pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
|
||||
|
||||
for (i = 0; i < rd->n_reg_rules; i++) {
|
||||
reg_rule = &rd->reg_rules[i];
|
||||
@@ -2272,23 +2286,32 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
||||
snprintf(bw, sizeof(bw), "%d KHz",
|
||||
freq_range->max_bandwidth_khz);
|
||||
|
||||
if (reg_rule->flags & NL80211_RRF_DFS)
|
||||
scnprintf(cac_time, sizeof(cac_time), "%u s",
|
||||
reg_rule->dfs_cac_ms/1000);
|
||||
else
|
||||
scnprintf(cac_time, sizeof(cac_time), "N/A");
|
||||
|
||||
|
||||
/*
|
||||
* There may not be documentation for max antenna gain
|
||||
* in certain regions
|
||||
*/
|
||||
if (power_rule->max_antenna_gain)
|
||||
pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm)\n",
|
||||
pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
|
||||
freq_range->start_freq_khz,
|
||||
freq_range->end_freq_khz,
|
||||
bw,
|
||||
power_rule->max_antenna_gain,
|
||||
power_rule->max_eirp);
|
||||
power_rule->max_eirp,
|
||||
cac_time);
|
||||
else
|
||||
pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm)\n",
|
||||
pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
|
||||
freq_range->start_freq_khz,
|
||||
freq_range->end_freq_khz,
|
||||
bw,
|
||||
power_rule->max_eirp);
|
||||
power_rule->max_eirp,
|
||||
cac_time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2361,9 +2384,6 @@ static int reg_set_rd_user(const struct ieee80211_regdomain *rd,
|
||||
{
|
||||
const struct ieee80211_regdomain *intersected_rd = NULL;
|
||||
|
||||
if (is_world_regdom(rd->alpha2))
|
||||
return -EINVAL;
|
||||
|
||||
if (!regdom_changes(rd->alpha2))
|
||||
return -EALREADY;
|
||||
|
||||
@@ -2552,26 +2572,6 @@ int set_regdom(const struct ieee80211_regdomain *rd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct regulatory_request *lr;
|
||||
u8 alpha2[2];
|
||||
bool add = false;
|
||||
|
||||
rcu_read_lock();
|
||||
lr = get_last_request();
|
||||
if (lr && !lr->processed) {
|
||||
memcpy(alpha2, lr->alpha2, 2);
|
||||
add = true;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (add)
|
||||
return add_uevent_var(env, "COUNTRY=%c%c",
|
||||
alpha2[0], alpha2[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wiphy_regulatory_register(struct wiphy *wiphy)
|
||||
{
|
||||
struct regulatory_request *lr;
|
||||
@@ -2622,8 +2622,6 @@ int __init regulatory_init(void)
|
||||
if (IS_ERR(reg_pdev))
|
||||
return PTR_ERR(reg_pdev);
|
||||
|
||||
reg_pdev->dev.type = ®_device_type;
|
||||
|
||||
spin_lock_init(®_requests_lock);
|
||||
spin_lock_init(®_pending_beacons_lock);
|
||||
|
||||
|
@@ -26,7 +26,6 @@ enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy);
|
||||
int regulatory_hint_user(const char *alpha2,
|
||||
enum nl80211_user_reg_hint_type user_reg_hint_type);
|
||||
|
||||
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
void wiphy_regulatory_register(struct wiphy *wiphy);
|
||||
void wiphy_regulatory_deregister(struct wiphy *wiphy);
|
||||
|
||||
|
@@ -659,9 +659,6 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
|
||||
continue;
|
||||
if (ssidlen && ie[1] != ssidlen)
|
||||
continue;
|
||||
/* that would be odd ... */
|
||||
if (bss->pub.beacon_ies)
|
||||
continue;
|
||||
if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
|
||||
continue;
|
||||
if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
|
||||
@@ -680,7 +677,8 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
|
||||
/* Returned bss is reference counted and must be cleaned up appropriately. */
|
||||
static struct cfg80211_internal_bss *
|
||||
cfg80211_bss_update(struct cfg80211_registered_device *dev,
|
||||
struct cfg80211_internal_bss *tmp)
|
||||
struct cfg80211_internal_bss *tmp,
|
||||
bool signal_valid)
|
||||
{
|
||||
struct cfg80211_internal_bss *found = NULL;
|
||||
|
||||
@@ -765,7 +763,12 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
|
||||
}
|
||||
|
||||
found->pub.beacon_interval = tmp->pub.beacon_interval;
|
||||
found->pub.signal = tmp->pub.signal;
|
||||
/*
|
||||
* don't update the signal if beacon was heard on
|
||||
* adjacent channel.
|
||||
*/
|
||||
if (signal_valid)
|
||||
found->pub.signal = tmp->pub.signal;
|
||||
found->pub.capability = tmp->pub.capability;
|
||||
found->ts = tmp->ts;
|
||||
} else {
|
||||
@@ -869,13 +872,14 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
|
||||
/* Returned bss is reference counted and must be cleaned up appropriately. */
|
||||
struct cfg80211_bss*
|
||||
cfg80211_inform_bss_width(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *channel,
|
||||
struct ieee80211_channel *rx_channel,
|
||||
enum nl80211_bss_scan_width scan_width,
|
||||
const u8 *bssid, u64 tsf, u16 capability,
|
||||
u16 beacon_interval, const u8 *ie, size_t ielen,
|
||||
s32 signal, gfp_t gfp)
|
||||
{
|
||||
struct cfg80211_bss_ies *ies;
|
||||
struct ieee80211_channel *channel;
|
||||
struct cfg80211_internal_bss tmp = {}, *res;
|
||||
|
||||
if (WARN_ON(!wiphy))
|
||||
@@ -885,7 +889,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
|
||||
(signal < 0 || signal > 100)))
|
||||
return NULL;
|
||||
|
||||
channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel);
|
||||
channel = cfg80211_get_bss_channel(wiphy, ie, ielen, rx_channel);
|
||||
if (!channel)
|
||||
return NULL;
|
||||
|
||||
@@ -913,7 +917,8 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
|
||||
rcu_assign_pointer(tmp.pub.beacon_ies, ies);
|
||||
rcu_assign_pointer(tmp.pub.ies, ies);
|
||||
|
||||
res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
|
||||
res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
|
||||
rx_channel == channel);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
@@ -929,20 +934,21 @@ EXPORT_SYMBOL(cfg80211_inform_bss_width);
|
||||
/* Returned bss is reference counted and must be cleaned up appropriately. */
|
||||
struct cfg80211_bss *
|
||||
cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *channel,
|
||||
struct ieee80211_channel *rx_channel,
|
||||
enum nl80211_bss_scan_width scan_width,
|
||||
struct ieee80211_mgmt *mgmt, size_t len,
|
||||
s32 signal, gfp_t gfp)
|
||||
{
|
||||
struct cfg80211_internal_bss tmp = {}, *res;
|
||||
struct cfg80211_bss_ies *ies;
|
||||
struct ieee80211_channel *channel;
|
||||
size_t ielen = len - offsetof(struct ieee80211_mgmt,
|
||||
u.probe_resp.variable);
|
||||
|
||||
BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
|
||||
offsetof(struct ieee80211_mgmt, u.beacon.variable));
|
||||
|
||||
trace_cfg80211_inform_bss_width_frame(wiphy, channel, scan_width, mgmt,
|
||||
trace_cfg80211_inform_bss_width_frame(wiphy, rx_channel, scan_width, mgmt,
|
||||
len, signal);
|
||||
|
||||
if (WARN_ON(!mgmt))
|
||||
@@ -959,7 +965,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
|
||||
return NULL;
|
||||
|
||||
channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
|
||||
ielen, channel);
|
||||
ielen, rx_channel);
|
||||
if (!channel)
|
||||
return NULL;
|
||||
|
||||
@@ -983,7 +989,8 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
|
||||
tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
|
||||
tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
|
||||
|
||||
res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
|
||||
res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
|
||||
rx_channel == channel);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
|
@@ -64,7 +64,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
|
||||
int n_channels, err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
ASSERT_RDEV_LOCK(rdev);
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
|
||||
if (rdev->scan_req || rdev->scan_msg)
|
||||
|
@@ -838,7 +838,6 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
ASSERT_RTNL();
|
||||
ASSERT_RDEV_LOCK(rdev);
|
||||
|
||||
list_for_each_entry(wdev, &rdev->wdev_list, list)
|
||||
cfg80211_process_wdev_events(wdev);
|
||||
@@ -851,7 +850,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||
int err;
|
||||
enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
|
||||
|
||||
ASSERT_RDEV_LOCK(rdev);
|
||||
ASSERT_RTNL();
|
||||
|
||||
/* don't support changing VLANs, you just re-create them */
|
||||
if (otype == NL80211_IFTYPE_AP_VLAN)
|
||||
@@ -886,7 +885,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||
|
||||
switch (otype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
cfg80211_stop_ap(rdev, dev);
|
||||
cfg80211_stop_ap(rdev, dev, true);
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
cfg80211_leave_ibss(rdev, dev, false);
|
||||
|
@@ -21,7 +21,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
|
||||
const u8 *prev_bssid = NULL;
|
||||
int err, i;
|
||||
|
||||
ASSERT_RDEV_LOCK(rdev);
|
||||
ASSERT_RTNL();
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
|
||||
if (!netif_running(wdev->netdev))
|
||||
|
Reference in New Issue
Block a user