Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
3a999e6eb5
99 changed files with 4107 additions and 3211 deletions
|
@ -94,21 +94,6 @@ config CFG80211_DEBUGFS
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config WIRELESS_OLD_REGULATORY
|
||||
bool "Old wireless static regulatory definitions"
|
||||
default n
|
||||
depends on CFG80211
|
||||
---help---
|
||||
This option enables the old static regulatory information
|
||||
and uses it within the new framework. This option is available
|
||||
for historical reasons and it is advised to leave it off.
|
||||
|
||||
For details see:
|
||||
|
||||
http://wireless.kernel.org/en/developers/Regulatory
|
||||
|
||||
Say N and if you say Y, please tell us why. The default is N.
|
||||
|
||||
config CFG80211_INTERNAL_REGDB
|
||||
bool "use statically compiled regulatory rules database" if EMBEDDED
|
||||
default n
|
||||
|
|
|
@ -41,12 +41,45 @@ rdev_fixed_channel(struct cfg80211_registered_device *rdev,
|
|||
return result;
|
||||
}
|
||||
|
||||
struct ieee80211_channel *
|
||||
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
|
||||
int freq, enum nl80211_channel_type channel_type)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
struct ieee80211_sta_ht_cap *ht_cap;
|
||||
|
||||
chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
|
||||
/* Primary channel not allowed */
|
||||
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
return NULL;
|
||||
|
||||
if (channel_type == NL80211_CHAN_HT40MINUS &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
return NULL;
|
||||
else if (channel_type == NL80211_CHAN_HT40PLUS &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
return NULL;
|
||||
|
||||
ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
|
||||
|
||||
if (channel_type != NL80211_CHAN_NO_HT) {
|
||||
if (!ht_cap->ht_supported)
|
||||
return NULL;
|
||||
|
||||
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
|
||||
ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
int rdev_set_freq(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *for_wdev,
|
||||
int freq, enum nl80211_channel_type channel_type)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
struct ieee80211_sta_ht_cap *ht_cap;
|
||||
int result;
|
||||
|
||||
if (rdev_fixed_channel(rdev, for_wdev))
|
||||
|
@ -55,30 +88,10 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
|
|||
if (!rdev->ops->set_channel)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
chan = ieee80211_get_channel(&rdev->wiphy, freq);
|
||||
|
||||
/* Primary channel not allowed */
|
||||
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
chan = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
if (channel_type == NL80211_CHAN_HT40MINUS &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
|
||||
return -EINVAL;
|
||||
else if (channel_type == NL80211_CHAN_HT40PLUS &&
|
||||
chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
|
||||
return -EINVAL;
|
||||
|
||||
ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
|
||||
|
||||
if (channel_type != NL80211_CHAN_NO_HT) {
|
||||
if (!ht_cap->ht_supported)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
|
||||
ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type);
|
||||
if (result)
|
||||
return result;
|
||||
|
|
|
@ -374,6 +374,9 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
|
|||
struct ieee80211_channel *
|
||||
rdev_fixed_channel(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *for_wdev);
|
||||
struct ieee80211_channel *
|
||||
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
|
||||
int freq, enum nl80211_channel_type channel_type);
|
||||
int rdev_set_freq(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *for_wdev,
|
||||
int freq, enum nl80211_channel_type channel_type);
|
||||
|
|
|
@ -93,7 +93,18 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
WARN_ON(!bss);
|
||||
/*
|
||||
* We might be coming here because the driver reported
|
||||
* a successful association at the same time as the
|
||||
* user requested a deauth. In that case, we will have
|
||||
* removed the BSS from the auth_bsses list due to the
|
||||
* deauth request when the assoc response makes it. If
|
||||
* the two code paths acquire the lock the other way
|
||||
* around, that's just the standard situation of a
|
||||
* deauth being requested while connected.
|
||||
*/
|
||||
if (!bss)
|
||||
goto out;
|
||||
} else if (wdev->conn) {
|
||||
cfg80211_sme_failed_assoc(wdev);
|
||||
/*
|
||||
|
@ -680,3 +691,40 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp)
|
||||
{
|
||||
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type,
|
||||
duration, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ready_on_channel);
|
||||
|
||||
void cfg80211_remain_on_channel_expired(struct net_device *dev,
|
||||
u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan,
|
||||
channel_type, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
|
||||
|
||||
void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
|
||||
struct station_info *sinfo, gfp_t gfp)
|
||||
{
|
||||
struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_new_sta);
|
||||
|
|
|
@ -141,6 +141,8 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
|
|||
[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
|
||||
.len = WLAN_PMKID_LEN },
|
||||
[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
|
||||
};
|
||||
|
||||
/* policy for the attributes */
|
||||
|
@ -569,6 +571,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
|
|||
CMD(set_pmksa, SET_PMKSA);
|
||||
CMD(del_pmksa, DEL_PMKSA);
|
||||
CMD(flush_pmksa, FLUSH_PMKSA);
|
||||
CMD(remain_on_channel, REMAIN_ON_CHANNEL);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
|
||||
i++;
|
||||
NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
|
||||
|
@ -1639,7 +1642,7 @@ static int parse_station_flags(struct genl_info *info,
|
|||
|
||||
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
|
||||
int flags, struct net_device *dev,
|
||||
u8 *mac_addr, struct station_info *sinfo)
|
||||
const u8 *mac_addr, struct station_info *sinfo)
|
||||
{
|
||||
void *hdr;
|
||||
struct nlattr *sinfoattr, *txrate;
|
||||
|
@ -2550,12 +2553,6 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
|
||||
|
||||
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
|
||||
/* We ignore world regdom requests with the old regdom setup */
|
||||
if (is_world_regdom(data))
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
r = regulatory_hint_user(data);
|
||||
|
||||
return r;
|
||||
|
@ -4289,6 +4286,143 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
}
|
||||
|
||||
static int nl80211_remain_on_channel(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct net_device *dev;
|
||||
struct ieee80211_channel *chan;
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
u64 cookie;
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
u32 freq, duration;
|
||||
int err;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
|
||||
!info->attrs[NL80211_ATTR_DURATION])
|
||||
return -EINVAL;
|
||||
|
||||
duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
|
||||
|
||||
/*
|
||||
* We should be on that channel for at least one jiffie,
|
||||
* and more than 5 seconds seems excessive.
|
||||
*/
|
||||
if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
|
||||
return -EINVAL;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
|
||||
if (err)
|
||||
goto unlock_rtnl;
|
||||
|
||||
if (!rdev->ops->remain_on_channel) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!netif_running(dev)) {
|
||||
err = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
|
||||
channel_type = nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
|
||||
if (channel_type != NL80211_CHAN_NO_HT &&
|
||||
channel_type != NL80211_CHAN_HT20 &&
|
||||
channel_type != NL80211_CHAN_HT40PLUS &&
|
||||
channel_type != NL80211_CHAN_HT40MINUS)
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
chan = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (chan == NULL) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
|
||||
NL80211_CMD_REMAIN_ON_CHANNEL);
|
||||
|
||||
if (IS_ERR(hdr)) {
|
||||
err = PTR_ERR(hdr);
|
||||
goto free_msg;
|
||||
}
|
||||
|
||||
err = rdev->ops->remain_on_channel(&rdev->wiphy, dev, chan,
|
||||
channel_type, duration, &cookie);
|
||||
|
||||
if (err)
|
||||
goto free_msg;
|
||||
|
||||
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
err = genlmsg_reply(msg, info);
|
||||
goto out;
|
||||
|
||||
nla_put_failure:
|
||||
err = -ENOBUFS;
|
||||
free_msg:
|
||||
nlmsg_free(msg);
|
||||
out:
|
||||
cfg80211_unlock_rdev(rdev);
|
||||
dev_put(dev);
|
||||
unlock_rtnl:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct net_device *dev;
|
||||
u64 cookie;
|
||||
int err;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_COOKIE])
|
||||
return -EINVAL;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
|
||||
if (err)
|
||||
goto unlock_rtnl;
|
||||
|
||||
if (!rdev->ops->cancel_remain_on_channel) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!netif_running(dev)) {
|
||||
err = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
|
||||
|
||||
err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
|
||||
|
||||
out:
|
||||
cfg80211_unlock_rdev(rdev);
|
||||
dev_put(dev);
|
||||
unlock_rtnl:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct genl_ops nl80211_ops[] = {
|
||||
{
|
||||
.cmd = NL80211_CMD_GET_WIPHY,
|
||||
|
@ -4551,8 +4685,20 @@ static struct genl_ops nl80211_ops[] = {
|
|||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
|
||||
{
|
||||
.cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
|
||||
.doit = nl80211_remain_on_channel,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
|
||||
.doit = nl80211_cancel_remain_on_channel,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct genl_multicast_group nl80211_mlme_mcgrp = {
|
||||
.name = "mlme",
|
||||
};
|
||||
|
@ -5140,6 +5286,89 @@ nla_put_failure:
|
|||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
static void nl80211_send_remain_on_chan_event(
|
||||
int cmd, struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type);
|
||||
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
|
||||
|
||||
if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL)
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
|
||||
|
||||
if (genlmsg_end(msg, hdr) < 0) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
|
||||
nl80211_mlme_mcgrp.id, gfp);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
|
||||
rdev, netdev, cookie, chan,
|
||||
channel_type, duration, gfp);
|
||||
}
|
||||
|
||||
void nl80211_send_remain_on_channel_cancel(
|
||||
struct cfg80211_registered_device *rdev, struct net_device *netdev,
|
||||
u64 cookie, struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
|
||||
rdev, netdev, cookie, chan,
|
||||
channel_type, 0, gfp);
|
||||
}
|
||||
|
||||
void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, const u8 *mac_addr,
|
||||
struct station_info *sinfo, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
|
||||
msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (nl80211_send_station(msg, 0, 0, 0, dev, mac_addr, sinfo) < 0) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
|
||||
nl80211_mlme_mcgrp.id, gfp);
|
||||
}
|
||||
|
||||
/* initialisation/exit functions */
|
||||
|
||||
int nl80211_init(void)
|
||||
|
|
|
@ -59,4 +59,19 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
|
|||
struct net_device *netdev, const u8 *bssid,
|
||||
gfp_t gfp);
|
||||
|
||||
void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
unsigned int duration, gfp_t gfp);
|
||||
void nl80211_send_remain_on_channel_cancel(
|
||||
struct cfg80211_registered_device *rdev, struct net_device *netdev,
|
||||
u64 cookie, struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type, gfp_t gfp);
|
||||
|
||||
void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, const u8 *mac_addr,
|
||||
struct station_info *sinfo, gfp_t gfp);
|
||||
|
||||
#endif /* __NET_WIRELESS_NL80211_H */
|
||||
|
|
|
@ -129,78 +129,6 @@ static char *ieee80211_regdom = "00";
|
|||
module_param(ieee80211_regdom, charp, 0444);
|
||||
MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
|
||||
|
||||
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
|
||||
/*
|
||||
* We assume 40 MHz bandwidth for the old regulatory work.
|
||||
* We make emphasis we are using the exact same frequencies
|
||||
* as before
|
||||
*/
|
||||
|
||||
static const struct ieee80211_regdomain us_regdom = {
|
||||
.n_reg_rules = 6,
|
||||
.alpha2 = "US",
|
||||
.reg_rules = {
|
||||
/* IEEE 802.11b/g, channels 1..11 */
|
||||
REG_RULE(2412-10, 2462+10, 40, 6, 27, 0),
|
||||
/* IEEE 802.11a, channel 36..48 */
|
||||
REG_RULE(5180-10, 5240+10, 40, 6, 17, 0),
|
||||
/* IEEE 802.11a, channels 48..64 */
|
||||
REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS),
|
||||
/* IEEE 802.11a, channels 100..124 */
|
||||
REG_RULE(5500-10, 5590+10, 40, 6, 20, NL80211_RRF_DFS),
|
||||
/* IEEE 802.11a, channels 132..144 */
|
||||
REG_RULE(5660-10, 5700+10, 40, 6, 20, NL80211_RRF_DFS),
|
||||
/* IEEE 802.11a, channels 149..165, outdoor */
|
||||
REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain jp_regdom = {
|
||||
.n_reg_rules = 6,
|
||||
.alpha2 = "JP",
|
||||
.reg_rules = {
|
||||
/* IEEE 802.11b/g, channels 1..11 */
|
||||
REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
|
||||
/* IEEE 802.11b/g, channels 12..13 */
|
||||
REG_RULE(2467-10, 2472+10, 20, 6, 20, 0),
|
||||
/* IEEE 802.11b/g, channel 14 */
|
||||
REG_RULE(2484-10, 2484+10, 20, 6, 20, NL80211_RRF_NO_OFDM),
|
||||
/* IEEE 802.11a, channels 36..48 */
|
||||
REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
|
||||
/* IEEE 802.11a, channels 52..64 */
|
||||
REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS),
|
||||
/* IEEE 802.11a, channels 100..144 */
|
||||
REG_RULE(5500-10, 5700+10, 40, 6, 23, NL80211_RRF_DFS),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain *static_regdom(char *alpha2)
|
||||
{
|
||||
if (alpha2[0] == 'U' && alpha2[1] == 'S')
|
||||
return &us_regdom;
|
||||
if (alpha2[0] == 'J' && alpha2[1] == 'P')
|
||||
return &jp_regdom;
|
||||
/* Use world roaming rules for "EU", since it was a pseudo
|
||||
domain anyway... */
|
||||
if (alpha2[0] == 'E' && alpha2[1] == 'U')
|
||||
return &world_regdom;
|
||||
/* Default, world roaming rules */
|
||||
return &world_regdom;
|
||||
}
|
||||
|
||||
static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
|
||||
{
|
||||
if (rd == &us_regdom || rd == &jp_regdom || rd == &world_regdom)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void reset_regdomains(void)
|
||||
{
|
||||
/* avoid freeing static information or freeing something twice */
|
||||
|
@ -210,8 +138,6 @@ static void reset_regdomains(void)
|
|||
cfg80211_world_regdom = NULL;
|
||||
if (cfg80211_regdomain == &world_regdom)
|
||||
cfg80211_regdomain = NULL;
|
||||
if (is_old_static_regdom(cfg80211_regdomain))
|
||||
cfg80211_regdomain = NULL;
|
||||
|
||||
kfree(cfg80211_regdomain);
|
||||
kfree(cfg80211_world_regdom);
|
||||
|
@ -1490,8 +1416,6 @@ static int ignore_request(struct wiphy *wiphy,
|
|||
return REG_INTERSECT;
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
|
||||
if (is_old_static_regdom(cfg80211_regdomain))
|
||||
return 0;
|
||||
if (regdom_changes(pending_request->alpha2))
|
||||
return 0;
|
||||
return -EALREADY;
|
||||
|
@ -1528,8 +1452,7 @@ static int ignore_request(struct wiphy *wiphy,
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (!is_old_static_regdom(cfg80211_regdomain) &&
|
||||
!regdom_changes(pending_request->alpha2))
|
||||
if (!regdom_changes(pending_request->alpha2))
|
||||
return -EALREADY;
|
||||
|
||||
return 0;
|
||||
|
@ -2111,8 +2034,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|||
* If someone else asked us to change the rd lets only bother
|
||||
* checking if the alpha2 changes if CRDA was already called
|
||||
*/
|
||||
if (!is_old_static_regdom(cfg80211_regdomain) &&
|
||||
!regdom_changes(rd->alpha2))
|
||||
if (!regdom_changes(rd->alpha2))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2311,15 +2233,8 @@ int regulatory_init(void)
|
|||
spin_lock_init(®_requests_lock);
|
||||
spin_lock_init(®_pending_beacons_lock);
|
||||
|
||||
#ifdef CONFIG_WIRELESS_OLD_REGULATORY
|
||||
cfg80211_regdomain = static_regdom(ieee80211_regdom);
|
||||
|
||||
printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
|
||||
print_regdomain_info(cfg80211_regdomain);
|
||||
#else
|
||||
cfg80211_regdomain = cfg80211_world_regdom;
|
||||
|
||||
#endif
|
||||
/* We always try to get an update for the static regdomain */
|
||||
err = regulatory_hint_core(cfg80211_regdomain->alpha2);
|
||||
if (err) {
|
||||
|
|
|
@ -601,7 +601,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
|
|||
struct cfg80211_registered_device *rdev;
|
||||
struct wiphy *wiphy;
|
||||
struct iw_scan_req *wreq = NULL;
|
||||
struct cfg80211_scan_request *creq;
|
||||
struct cfg80211_scan_request *creq = NULL;
|
||||
int i, err, n_channels = 0;
|
||||
enum ieee80211_band band;
|
||||
|
||||
|
@ -694,8 +694,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
|
|||
/* translate "Scan for SSID" request */
|
||||
if (wreq) {
|
||||
if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
|
||||
if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
|
||||
return -EINVAL;
|
||||
if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
|
||||
creq->ssids[0].ssid_len = wreq->essid_len;
|
||||
}
|
||||
|
@ -707,12 +709,15 @@ int cfg80211_wext_siwscan(struct net_device *dev,
|
|||
err = rdev->ops->scan(wiphy, dev, creq);
|
||||
if (err) {
|
||||
rdev->scan_req = NULL;
|
||||
kfree(creq);
|
||||
/* creq will be freed below */
|
||||
} else {
|
||||
nl80211_send_scan_start(rdev, dev);
|
||||
/* creq now owned by driver */
|
||||
creq = NULL;
|
||||
dev_hold(dev);
|
||||
}
|
||||
out:
|
||||
kfree(creq);
|
||||
cfg80211_unlock_rdev(rdev);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue