Commit 6bad8766 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by John W. Linville

cfg80211: send regulatory beacon hint events to userspace

This informs userspace when a change has occured on a world
roaming wiphy's channel which has lifted some restrictions
due to a regulatory beacon hint.

Because this is now sent to userspace through the regulatory
multicast group we remove the debug prints we used to use as
they are no longer necessary.
Acked-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5dab3b8a
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright 2008 Michael Wu <flamingice@sourmilk.net> * Copyright 2008 Michael Wu <flamingice@sourmilk.net>
* Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com> * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>
* Copyright 2008 Michael Buesch <mb@bu3sch.de> * Copyright 2008 Michael Buesch <mb@bu3sch.de>
* Copyright 2008 Luis R. Rodriguez <lrodriguez@atheros.com> * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com>
* Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
* Copyright 2008 Colin McCabe <colin@cozybit.com> * Copyright 2008 Colin McCabe <colin@cozybit.com>
* *
...@@ -166,6 +166,22 @@ ...@@ -166,6 +166,22 @@
* set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
* %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
* to (%NL80211_ATTR_REG_ALPHA2). * to (%NL80211_ATTR_REG_ALPHA2).
* @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
* has been found while world roaming thus enabling active scan or
* any mode of operation that initiates TX (beacons) on a channel
* where we would not have been able to do either before. As an example
* if you are world roaming (regulatory domain set to world or if your
* driver is using a custom world roaming regulatory domain) and while
* doing a passive scan on the 5 GHz band you find an AP there (if not
* on a DFS channel) you will now be able to actively scan for that AP
* or use AP mode on your card on that same channel. Note that this will
* never be used for channels 1-11 on the 2 GHz band as they are always
* enabled world wide. This beacon hint is only sent if your device had
* either disabled active scanning or beaconing on a channel. We send to
* userspace the wiphy on which we removed a restriction from
* (%NL80211_ATTR_WIPHY) and the channel on which this occurred
* before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
* the beacon hint was processed.
* *
* @NL80211_CMD_AUTHENTICATE: authentication request and notification. * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
* This command is used both as a command (request to authenticate) and * This command is used both as a command (request to authenticate) and
...@@ -270,6 +286,8 @@ enum nl80211_commands { ...@@ -270,6 +286,8 @@ enum nl80211_commands {
NL80211_CMD_MICHAEL_MIC_FAILURE, NL80211_CMD_MICHAEL_MIC_FAILURE,
NL80211_CMD_REG_BEACON_HINT,
/* add new commands above here */ /* add new commands above here */
/* used to define NL80211_CMD_MAX below */ /* used to define NL80211_CMD_MAX below */
...@@ -288,6 +306,7 @@ enum nl80211_commands { ...@@ -288,6 +306,7 @@ enum nl80211_commands {
#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE #define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE #define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
/** /**
* enum nl80211_attrs - nl80211 netlink attributes * enum nl80211_attrs - nl80211 netlink attributes
...@@ -423,6 +442,17 @@ enum nl80211_commands { ...@@ -423,6 +442,17 @@ enum nl80211_commands {
* @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
* a u32 * a u32
* *
* @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
* due to considerations from a beacon hint. This attribute reflects
* the state of the channel _before_ the beacon hint processing. This
* attributes consists of a nested attribute containing
* NL80211_FREQUENCY_ATTR_*
* @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
* due to considerations from a beacon hint. This attribute reflects
* the state of the channel _after_ the beacon hint processing. This
* attributes consists of a nested attribute containing
* NL80211_FREQUENCY_ATTR_*
*
* @NL80211_ATTR_MAX: highest attribute number currently defined * @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use * @__NL80211_ATTR_AFTER_LAST: internal use
*/ */
...@@ -511,6 +541,8 @@ enum nl80211_attrs { ...@@ -511,6 +541,8 @@ enum nl80211_attrs {
NL80211_ATTR_MAX_SCAN_IE_LEN, NL80211_ATTR_MAX_SCAN_IE_LEN,
NL80211_ATTR_FREQ_BEFORE,
NL80211_ATTR_FREQ_AFTER,
/* add attributes here, update the policy in nl80211.c */ /* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST, __NL80211_ATTR_AFTER_LAST,
......
...@@ -3491,6 +3491,60 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, ...@@ -3491,6 +3491,60 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
nlmsg_free(msg); nlmsg_free(msg);
} }
void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
struct ieee80211_channel *channel_before,
struct ieee80211_channel *channel_after)
{
struct sk_buff *msg;
void *hdr;
struct nlattr *nl_freq;
msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
if (!msg)
return;
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
if (!hdr) {
nlmsg_free(msg);
return;
}
/*
* Since we are applying the beacon hint to a wiphy we know its
* wiphy_idx is valid
*/
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
/* Before */
nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
if (!nl_freq)
goto nla_put_failure;
if (nl80211_msg_put_channel(msg, channel_before))
goto nla_put_failure;
nla_nest_end(msg, nl_freq);
/* After */
nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
if (!nl_freq)
goto nla_put_failure;
if (nl80211_msg_put_channel(msg, channel_after))
goto nla_put_failure;
nla_nest_end(msg, nl_freq);
if (genlmsg_end(msg, hdr) < 0) {
nlmsg_free(msg);
return;
}
genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
return;
nla_put_failure:
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
}
/* initialisation/exit functions */ /* initialisation/exit functions */
int nl80211_init(void) int nl80211_init(void)
......
...@@ -29,4 +29,9 @@ nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, ...@@ -29,4 +29,9 @@ nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
enum nl80211_key_type key_type, enum nl80211_key_type key_type,
int key_id, const u8 *tsc); int key_id, const u8 *tsc);
extern void
nl80211_send_beacon_hint_event(struct wiphy *wiphy,
struct ieee80211_channel *channel_before,
struct ieee80211_channel *channel_after);
#endif /* __NET_WIRELESS_NL80211_H */ #endif /* __NET_WIRELESS_NL80211_H */
...@@ -1049,18 +1049,10 @@ static void handle_reg_beacon(struct wiphy *wiphy, ...@@ -1049,18 +1049,10 @@ static void handle_reg_beacon(struct wiphy *wiphy,
unsigned int chan_idx, unsigned int chan_idx,
struct reg_beacon *reg_beacon) struct reg_beacon *reg_beacon)
{ {
#ifdef CONFIG_CFG80211_REG_DEBUG
#define REG_DEBUG_BEACON_FLAG(desc) \
printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
"frequency: %d MHz (Ch %d) on %s\n", \
reg_beacon->chan.center_freq, \
ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
wiphy_name(wiphy));
#else
#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
#endif
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
bool channel_changed = false;
struct ieee80211_channel chan_before;
assert_cfg80211_lock(); assert_cfg80211_lock();
...@@ -1070,20 +1062,28 @@ static void handle_reg_beacon(struct wiphy *wiphy, ...@@ -1070,20 +1062,28 @@ static void handle_reg_beacon(struct wiphy *wiphy,
if (likely(chan->center_freq != reg_beacon->chan.center_freq)) if (likely(chan->center_freq != reg_beacon->chan.center_freq))
return; return;
if (chan->beacon_found)
return;
chan->beacon_found = true;
chan_before.center_freq = chan->center_freq;
chan_before.flags = chan->flags;
if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
!(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) { !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
REG_DEBUG_BEACON_FLAG("active scanning"); channel_changed = true;
} }
if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
!(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) { !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) {
chan->flags &= ~IEEE80211_CHAN_NO_IBSS; chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
REG_DEBUG_BEACON_FLAG("beaconing"); channel_changed = true;
} }
chan->beacon_found = true; if (channel_changed)
#undef REG_DEBUG_BEACON_FLAG nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
} }
/* /*
......
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