2009-02-20 06:04:56

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 0/5] cfg80211: enhance world roaming

This series enhances world roaming through a few set of
enhancements. We world roam when OLD_REG is disabled and
CRDA _is_ installed and when we have had no regulatory
hint from anything yet (country IE, userspace, or driver).
If you lack CRDA and you also have OLD_REG you also world roam.

We finish this work by defaulting OLD_REG to no due to these
new changes. At this point I'd even be inclined to simply remove
OLD_REG, your comments are greatly welcomed on this.

This patch series *should not* be applied yet as it breaks Intel's
iwlwifi drivers as noted in my recent e-mail about this [1]. Once that
is fixed this should be ready.

This series depends on the last one I just posted. If you'd like to
test you can get all the patches in one file in my home dir, it will
contain my 15 patches from my previous series and the patches from
this new series [2].

[1] http://marc.info/?l=linux-wireless&m=123510494021757&w=2
[2] http://www.kernel.org/pub/linux/kernel/people/mcgrof/patches/cfg80211/2009-02-20/all-reg.patch

Luis R. Rodriguez (5):
cfg80211: enable active-scan / beaconing on Ch 1-11 for world regdom
cfg80211: enable 5 GHz world roaming channels
cfg80211: Add AP beacon regulatory hints
ath9k: follow beacon hints on reg_notifier when world roaming
cfg80211: default OLD_REG to n

Documentation/feature-removal-schedule.txt | 5 +-
drivers/net/wireless/ath9k/regd.c | 93 +++++++----
include/net/wireless.h | 21 +++
net/wireless/Kconfig | 2 +-
net/wireless/core.c | 5 +-
net/wireless/reg.c | 240 +++++++++++++++++++++++++++-
net/wireless/scan.c | 3 +
7 files changed, 329 insertions(+), 40 deletions(-)



2009-02-20 06:05:05

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 2/5] cfg80211: enable 5 GHz world roaming channels

The current static world regulatory domain is too restrictive,
we can use some 5 GHz channels world wide so long as they do not
touch frequencies which require DFS. The compromise is we must
also enforce passive scanning and disallow usage of a mode of
operation that beacons: (AP | IBSS | Mesh)

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 8f64575..8e86505 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -73,11 +73,22 @@ static spinlock_t reg_requests_lock;

/* We keep a static world regulatory domain in case of the absence of CRDA */
static const struct ieee80211_regdomain world_regdom = {
- .n_reg_rules = 1,
+ .n_reg_rules = 3,
.alpha2 = "00",
.reg_rules = {
/* IEEE 802.11b/g, channels 1..11 */
REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
+ /* IEEE 802.11a, channel 36..48 */
+ REG_RULE(5180-10, 5240+10, 40, 6, 23,
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS),
+
+ /* NB: 5260 MHz - 5700 MHz requies DFS */
+
+ /* IEEE 802.11a, channel 149..165 */
+ REG_RULE(5745-10, 5825+10, 40, 6, 23,
+ NL80211_RRF_PASSIVE_SCAN |
+ NL80211_RRF_NO_IBSS),
}
};

--
1.6.0.3


2009-02-20 06:05:09

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 1/5] cfg80211: enable active-scan / beaconing on Ch 1-11 for world regdom

This enables active scan and beaconing on Channels 1 through 11
on the static world regulatory domain.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 605299f..8f64575 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -76,9 +76,8 @@ static const struct ieee80211_regdomain world_regdom = {
.n_reg_rules = 1,
.alpha2 = "00",
.reg_rules = {
- REG_RULE(2412-10, 2462+10, 40, 6, 20,
- NL80211_RRF_PASSIVE_SCAN |
- NL80211_RRF_NO_IBSS),
+ /* IEEE 802.11b/g, channels 1..11 */
+ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
}
};

--
1.6.0.3


2009-02-20 06:08:41

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH 0/5] cfg80211: enhance world roaming

On Fri, Feb 20, 2009 at 01:04:29AM -0500, Luis R. Rodriguez wrote:
> This series enhances world roaming through a few set of
> enhancements. We world roam when OLD_REG is disabled and
> CRDA _is_ installed and when we have had no regulatory
> hint from anything yet (country IE, userspace, or driver).

> If you lack CRDA and you also have OLD_REG you also world roam.

I mean if you have CRDA and you have OLD_REG _disabled_ you also world
roam.

Luis


2009-02-20 06:05:07

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 4/5] ath9k: follow beacon hints on reg_notifier when world roaming

If we are roaming we allow to follow beacon hints.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath9k/regd.c | 93 ++++++++++++++++++++++++-------------
1 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index eb0d1b7..f4595e2 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -160,13 +160,18 @@ static bool ath9k_is_radar_freq(u16 center_freq)
}

/*
- * Enable adhoc on 5 GHz if allowed by 11d.
- * Remove passive scan if channel is allowed by 11d,
- * except when on radar frequencies.
+ * N.B: These exception rules do not apply radar freqs.
+ *
+ * - We enable adhoc (or beaconing) if allowed by 11d
+ * - We enable active scan if the channel is allowed by 11d
+ * - If no country IE has been processed and a we determine we have
+ * received a beacon on a channel we can enable active scan and
+ * adhoc (or beaconing).
*/
-static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy,
+static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy,
enum reg_set_by setby)
{
+ enum ieee80211_band band;
struct ieee80211_supported_band *sband;
const struct ieee80211_reg_rule *reg_rule;
struct ieee80211_channel *ch;
@@ -174,29 +179,50 @@ static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy,
u32 bandwidth = 0;
int r;

- if (setby != REGDOM_SET_BY_COUNTRY_IE)
- return;
- if (!wiphy->bands[IEEE80211_BAND_5GHZ])
- return;
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {

- sband = wiphy->bands[IEEE80211_BAND_5GHZ];
- for (i = 0; i < sband->n_channels; i++) {
- ch = &sband->channels[i];
- r = freq_reg_info(wiphy, ch->center_freq,
- &bandwidth, &reg_rule);
- if (r)
+ if (!wiphy->bands[band])
continue;
- /* If 11d had a rule for this channel ensure we enable adhoc
- * if it allows us to use it. Note that we would have disabled
- * it by applying our static world regdomain by default during
- * probe */
- if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
- ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
- if (!ath9k_is_radar_freq(ch->center_freq))
- continue;
- if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
- ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+
+ sband = wiphy->bands[band];
+
+ for (i = 0; i < sband->n_channels; i++) {
+
+ ch = &sband->channels[i];
+
+ if (ath9k_is_radar_freq(ch->center_freq) ||
+ (ch->flags & IEEE80211_CHAN_RADAR))
+ continue;
+
+ if (setby == REGDOM_SET_BY_COUNTRY_IE) {
+ r = freq_reg_info(wiphy, ch->center_freq,
+ &bandwidth, &reg_rule);
+ if (r)
+ continue;
+ /*
+ * If 11d had a rule for this channel ensure
+ * we enable adhoc/beaconing if it allows us to
+ * use it. Note that we would have disabled it
+ * by applying our static world regdomain by
+ * default during init, prior to calling our
+ * regulatory_hint().
+ */
+ if (!(reg_rule->flags &
+ NL80211_RRF_NO_IBSS))
+ ch->flags &=
+ ~IEEE80211_CHAN_NO_IBSS;
+ if (!(reg_rule->flags &
+ NL80211_RRF_PASSIVE_SCAN))
+ ch->flags &=
+ ~IEEE80211_CHAN_PASSIVE_SCAN;
+ } else {
+ if (ch->beacon_found)
+ ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN);
+ }
+ }
}
+
}

/* Allows active scan scan on Ch 12 and 13 */
@@ -209,11 +235,12 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
u32 bandwidth = 0;
int r;

- /* Force passive scan on Channels 12-13 */
sband = wiphy->bands[IEEE80211_BAND_2GHZ];

- /* If no country IE has been received always enable active scan
- * on these channels */
+ /*
+ * If no country IE has been received always enable active scan
+ * on these channels. This is only done for specific regulatory SKUs
+ */
if (setby != REGDOM_SET_BY_COUNTRY_IE) {
ch = &sband->channels[11]; /* CH 12 */
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
@@ -224,10 +251,12 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
return;
}

- /* If a country IE has been recieved check its rule for this
+ /*
+ * If a country IE has been recieved check its rule for this
* channel first before enabling active scan. The passive scan
- * would have been enforced by the initial probe processing on
- * our custom regulatory domain. */
+ * would have been enforced by the initial processing of our
+ * custom regulatory domain.
+ */

ch = &sband->channels[11]; /* CH 12 */
r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
@@ -290,10 +319,10 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby)
case 0x63:
case 0x66:
case 0x67:
- ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby);
+ ath9k_reg_apply_beaconing_flags(wiphy, setby);
break;
case 0x68:
- ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby);
+ ath9k_reg_apply_beaconing_flags(wiphy, setby);
ath9k_reg_apply_active_scan_flags(wiphy, setby);
break;
}
--
1.6.0.3


2009-02-20 19:59:54

by Gábor Stefanik

[permalink] [raw]
Subject: Re: [PATCH 1/5] cfg80211: enable active-scan / beaconing on Ch 1-11 for world regdom

On Fri, Feb 20, 2009 at 7:04 AM, Luis R. Rodriguez
<[email protected]> wrote:
> This enables active scan and beaconing on Channels 1 through 11
> on the static world regulatory domain.
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> =A0net/wireless/reg.c | =A0 =A05 ++---
> =A01 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 605299f..8f64575 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -76,9 +76,8 @@ static const struct ieee80211_regdomain world_regdo=
m =3D {
> =A0 =A0 =A0 =A0.n_reg_rules =3D 1,
> =A0 =A0 =A0 =A0.alpha2 =3D =A0"00",
> =A0 =A0 =A0 =A0.reg_rules =3D {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 REG_RULE(2412-10, 2462+10, 40, 6, 20,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 NL80211_RRF_PASSIVE_SCA=
N |
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 NL80211_RRF_NO_IBSS),
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* IEEE 802.11b/g, channels 1..11 */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0=
),
> =A0 =A0 =A0 =A0}
> =A0};
>
> --
> 1.6.0.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wirel=
ess" in
> the body of a message to [email protected]
> More majordomo info at =A0http://vger.kernel.org/majordomo-info.html
>

Are you sure there is no area of the world where the allowed range is
stricter than b/g 1-11?
Otherwise I am inclined to NACK this.

--=20
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

2009-02-20 06:04:55

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 3/5] cfg80211: Add AP beacon regulatory hints

When devices are world roaming they cannot beacon or do active scan
on 5 GHz or on channels 12, 13 and 14 on the 2 GHz band. Although
we have a good regulatory API some cards may _always_ world roam, this
is also true when a system does not have CRDA present. Devices doing world
roaming can still passive scan, if they find a beacon from an AP on
one of the world roaming frequencies we make the assumption we can do
the same and we also remove the passive scan requirement.

This adds support for providing beacon regulatory hints based on scans.
This works for devices that do either hardware or software scanning.
If a channel has not yet been marked as having had a beacon present
on it we queue the beacon hint processing into the workqueue.

All wireless devices will benefit from beacon regulatory hints from
any wireless device on a system including new devices connected to
the system at a later time.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
include/net/wireless.h | 21 +++++
net/wireless/core.c | 5 +-
net/wireless/reg.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++-
net/wireless/scan.c | 3 +
4 files changed, 252 insertions(+), 3 deletions(-)

diff --git a/include/net/wireless.h b/include/net/wireless.h
index 1f4707d..13f7aef 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -69,6 +69,9 @@ enum ieee80211_channel_flags {
* @band: band this channel belongs to.
* @max_antenna_gain: maximum antenna gain in dBi
* @max_power: maximum transmission power (in dBm)
+ * @beacon_found: helper to regulatory code to indicate when a beacon
+ * has been found on this channel. Use regulatory_hint_found_beacon()
+ * to enable this, this is is useful only on 5 GHz band.
* @orig_mag: internal use
* @orig_mpwr: internal use
*/
@@ -80,6 +83,7 @@ struct ieee80211_channel {
u32 flags;
int max_antenna_gain;
int max_power;
+ bool beacon_found;
u32 orig_flags;
int orig_mag, orig_mpwr;
};
@@ -425,6 +429,23 @@ extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
extern void regulatory_hint_11d(struct wiphy *wiphy,
u8 *country_ie,
u8 country_ie_len);
+/**
+ * regulatory_hint_found_beacon - hints a beacon was found on a channel
+ * @wiphy: the wireless device where the beacon was found on
+ * @beacon_chan: the channel on which the beacon was found on
+ * @gfp: context flags
+ *
+ * This informs the wireless core that a beacon from an AP was found on
+ * the channel provided. This allows the wireless core to make educated
+ * guesses on regulatory to help with world roaming. This is only used for
+ * world roaming -- when we do not know our current location. This is
+ * only useful on channels 12, 13 and 14 on the 2 GHz band as all other
+ * channels are already enabled by the world regulatory domain (channels
+ * 1-11); and on non-radar 5 GHz channels.
+ */
+extern int regulatory_hint_found_beacon(struct wiphy *wiphy,
+ struct ieee80211_channel *beacon_chan,
+ gfp_t gfp);

/**
* wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
diff --git a/net/wireless/core.c b/net/wireless/core.c
index b1a354b..dd7f222 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -32,8 +32,9 @@ MODULE_DESCRIPTION("wireless configuration support");
LIST_HEAD(cfg80211_drv_list);

/*
- * This is used to protect the cfg80211_drv_list, cfg80211_regdomain, and
- * the last reguluatory request receipt in regd.c
+ * This is used to protect the cfg80211_drv_list, cfg80211_regdomain,
+ * country_ie_regdomain, the reg_beacon_list and the the last regulatory
+ * request receipt (last_request).
*/
DEFINE_MUTEX(cfg80211_mutex);

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 8e86505..67a193a 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -68,9 +68,22 @@ const struct ieee80211_regdomain *cfg80211_regdomain;
*/
static const struct ieee80211_regdomain *country_ie_regdomain;

+/* Used to queue up regulatory hints */
static LIST_HEAD(reg_requests_list);
static spinlock_t reg_requests_lock;

+/* Used to queue up beacon hints for review */
+static LIST_HEAD(reg_pending_beacons);
+static spinlock_t reg_pending_beacons_lock;
+
+/* Used to keep track of processed beacon hints */
+static LIST_HEAD(reg_beacon_list);
+
+struct reg_beacon {
+ struct list_head list;
+ struct ieee80211_channel chan;
+};
+
/* We keep a static world regulatory domain in case of the absence of CRDA */
static const struct ieee80211_regdomain world_regdom = {
.n_reg_rules = 3,
@@ -1011,16 +1024,120 @@ static void update_all_wiphy_regulatory(enum reg_set_by setby)
wiphy_update_regulatory(&drv->wiphy, setby);
}

+static void handle_reg_beacon(struct wiphy *wiphy,
+ unsigned int chan_idx,
+ 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_channel *chan;
+
+ assert_cfg80211_lock();
+
+ sband = wiphy->bands[reg_beacon->chan.band];
+ chan = &sband->channels[chan_idx];
+
+ if (likely(chan->center_freq != reg_beacon->chan.center_freq))
+ return;
+
+ if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+ chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ REG_DEBUG_BEACON_FLAG("active scanning");
+ }
+
+ if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
+ chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
+ REG_DEBUG_BEACON_FLAG("beaconing");
+ }
+
+ chan->beacon_found = true;
+#undef REG_DEBUG_BEACON_FLAG
+}
+
+/*
+ * Called when a scan on a wiphy finds a beacon on
+ * new channel
+ */
+static void wiphy_update_new_beacon(struct wiphy *wiphy,
+ struct reg_beacon *reg_beacon)
+{
+ unsigned int i;
+ struct ieee80211_supported_band *sband;
+
+ assert_cfg80211_lock();
+
+ if (!wiphy->bands[reg_beacon->chan.band])
+ return;
+
+ sband = wiphy->bands[reg_beacon->chan.band];
+
+ for (i = 0; i < sband->n_channels; i++)
+ handle_reg_beacon(wiphy, i, reg_beacon);
+}
+
+/*
+ * Called upon reg changes or a new wiphy is added
+ */
+static void wiphy_update_beacon_reg(struct wiphy *wiphy)
+{
+ unsigned int i;
+ struct ieee80211_supported_band *sband;
+ struct reg_beacon *reg_beacon;
+
+ assert_cfg80211_lock();
+
+ if (list_empty(&reg_beacon_list))
+ return;
+
+ list_for_each_entry(reg_beacon, &reg_beacon_list, list) {
+ if (!wiphy->bands[reg_beacon->chan.band])
+ continue;
+ sband = wiphy->bands[reg_beacon->chan.band];
+ for (i = 0; i < sband->n_channels; i++)
+ handle_reg_beacon(wiphy, i, reg_beacon);
+ }
+}
+
+static bool reg_is_world_roaming(struct wiphy *wiphy)
+{
+ if (is_world_regdom(cfg80211_regdomain->alpha2) ||
+ (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
+ return true;
+ if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE &&
+ wiphy->custom_regulatory)
+ return true;
+ return false;
+}
+
+/* Reap the advantages of previously found beacons */
+static void reg_process_beacons(struct wiphy *wiphy)
+{
+ if (!reg_is_world_roaming(wiphy))
+ return;
+ wiphy_update_beacon_reg(wiphy);
+}
+
void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
{
enum ieee80211_band band;

if (ignore_reg_update(wiphy, setby))
- return;
+ goto out;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (wiphy->bands[band])
handle_band(wiphy, band);
}
+out:
+ reg_process_beacons(wiphy);
if (wiphy->reg_notifier)
wiphy->reg_notifier(wiphy, last_request);
}
@@ -1314,6 +1431,7 @@ out:
return r;
}

+/* Processes regulatory hints, this is all the REGDOM_SET_BY_* */
static void reg_process_pending_hints(void)
{
struct regulatory_request *reg_request;
@@ -1344,9 +1462,44 @@ static void reg_process_pending_hints(void)
spin_unlock(&reg_requests_lock);
}

+/* Processes beacon hints -- this has nothing to do with country IEs */
+static void reg_process_pending_beacon_hints(void)
+{
+ struct cfg80211_registered_device *drv;
+ struct reg_beacon *pending_beacon, *tmp;
+
+ mutex_lock(&cfg80211_mutex);
+
+ /* This goes through the _pending_ beacon list */
+ spin_lock_bh(&reg_pending_beacons_lock);
+
+ if (list_empty(&reg_pending_beacons)) {
+ spin_unlock_bh(&reg_pending_beacons_lock);
+ goto out;
+ }
+
+ list_for_each_entry_safe(pending_beacon, tmp,
+ &reg_pending_beacons, list) {
+
+ list_del_init(&pending_beacon->list);
+
+ /* Applies the beacon hint to current wiphys */
+ list_for_each_entry(drv, &cfg80211_drv_list, list)
+ wiphy_update_new_beacon(&drv->wiphy, pending_beacon);
+
+ /* Remembers the beacon hint for new wiphys or reg changes */
+ list_add_tail(&pending_beacon->list, &reg_beacon_list);
+ }
+
+ spin_unlock_bh(&reg_pending_beacons_lock);
+out:
+ mutex_unlock(&cfg80211_mutex);
+}
+
static void reg_todo(struct work_struct *work)
{
reg_process_pending_hints();
+ reg_process_pending_beacon_hints();
}

static DECLARE_WORK(reg_work, reg_todo);
@@ -1587,6 +1740,57 @@ out:
}
EXPORT_SYMBOL(regulatory_hint_11d);

+static bool freq_is_chan_12_13_14(u16 freq)
+{
+ if (freq == ieee80211_channel_to_frequency(12) ||
+ freq == ieee80211_channel_to_frequency(13) ||
+ freq == ieee80211_channel_to_frequency(14))
+ return true;
+ return false;
+}
+
+int regulatory_hint_found_beacon(struct wiphy *wiphy,
+ struct ieee80211_channel *beacon_chan,
+ gfp_t gfp)
+{
+ struct reg_beacon *reg_beacon;
+
+ if (likely((beacon_chan->beacon_found ||
+ (beacon_chan->flags & IEEE80211_CHAN_RADAR) ||
+ (beacon_chan->band == IEEE80211_BAND_2GHZ &&
+ !freq_is_chan_12_13_14(beacon_chan->center_freq)))))
+ return 0;
+
+ reg_beacon = kzalloc(sizeof(struct reg_beacon), gfp);
+ if (!reg_beacon)
+ return -ENOMEM;
+
+#ifdef CONFIG_CFG80211_REG_DEBUG
+ printk(KERN_DEBUG "cfg80211: Found new beacon on "
+ "frequency: %d MHz (Ch %d) on %s\n",
+ beacon_chan->center_freq,
+ ieee80211_frequency_to_channel(beacon_chan->center_freq),
+ wiphy_name(wiphy));
+#endif
+ memcpy(&reg_beacon->chan, beacon_chan,
+ sizeof(struct ieee80211_channel));
+
+
+ /*
+ * Since we can be called from BH or and non-BH context
+ * we must use spin_lock_bh()
+ */
+ spin_lock_bh(&reg_pending_beacons_lock);
+ list_add_tail(&reg_beacon->list, &reg_pending_beacons);
+ spin_unlock_bh(&reg_pending_beacons_lock);
+
+ schedule_work(&reg_work);
+
+ return 0;
+}
+EXPORT_SYMBOL(regulatory_hint_found_beacon);
+
+
static void print_rd_rules(const struct ieee80211_regdomain *rd)
{
unsigned int i;
@@ -1908,6 +2112,7 @@ int regulatory_init(void)
return PTR_ERR(reg_pdev);

spin_lock_init(&reg_requests_lock);
+ spin_lock_init(&reg_pending_beacons_lock);

#ifdef CONFIG_WIRELESS_OLD_REGULATORY
cfg80211_regdomain = static_regdom(ieee80211_regdom);
@@ -1951,6 +2156,7 @@ int regulatory_init(void)
void regulatory_exit(void)
{
struct regulatory_request *reg_request, *tmp;
+ struct reg_beacon *reg_beacon, *btmp;

cancel_work_sync(&reg_work);

@@ -1965,6 +2171,24 @@ void regulatory_exit(void)

platform_device_unregister(reg_pdev);

+ spin_lock_bh(&reg_pending_beacons_lock);
+ if (!list_empty(&reg_pending_beacons)) {
+ list_for_each_entry_safe(reg_beacon, btmp,
+ &reg_pending_beacons, list) {
+ list_del(&reg_beacon->list);
+ kfree(reg_beacon);
+ }
+ }
+ spin_unlock_bh(&reg_pending_beacons_lock);
+
+ if (!list_empty(&reg_beacon_list)) {
+ list_for_each_entry_safe(reg_beacon, btmp,
+ &reg_beacon_list, list) {
+ list_del(&reg_beacon->list);
+ kfree(reg_beacon);
+ }
+ }
+
spin_lock(&reg_requests_lock);
if (!list_empty(&reg_requests_list)) {
list_for_each_entry_safe(reg_request, tmp,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 6060065..280dbcd 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -430,6 +430,9 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
if (!res)
return NULL;

+ if (res->pub.capability & WLAN_CAPABILITY_ESS)
+ regulatory_hint_found_beacon(wiphy, channel, gfp);
+
/* cfg80211_bss_update gives us a referenced result */
return &res->pub;
}
--
1.6.0.3


2009-02-20 17:07:02

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 3/5] cfg80211: Add AP beacon regulatory hints

On Fri, 2009-02-20 at 01:04 -0500, Luis R. Rodriguez wrote:

> +/**
> + * regulatory_hint_found_beacon - hints a beacon was found on a channel
> + * @wiphy: the wireless device where the beacon was found on
> + * @beacon_chan: the channel on which the beacon was found on
> + * @gfp: context flags
> + *
> + * This informs the wireless core that a beacon from an AP was found on
> + * the channel provided. This allows the wireless core to make educated
> + * guesses on regulatory to help with world roaming. This is only used for
> + * world roaming -- when we do not know our current location. This is
> + * only useful on channels 12, 13 and 14 on the 2 GHz band as all other
> + * channels are already enabled by the world regulatory domain (channels
> + * 1-11); and on non-radar 5 GHz channels.
> + */
> +extern int regulatory_hint_found_beacon(struct wiphy *wiphy,
> + struct ieee80211_channel *beacon_chan,
> + gfp_t gfp);

Remove the extern please; also, you don't need to export this function
in a public header file, reg.h should be fine.

johannes


Attachments:
signature.asc (836.00 B)
This is a digitally signed message part

2009-02-20 20:34:56

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 3/5] cfg80211: Add AP beacon regulatory hints

On Fri, Feb 20, 2009 at 9:06 AM, Johannes Berg
<[email protected]> wrote:
> On Fri, 2009-02-20 at 01:04 -0500, Luis R. Rodriguez wrote:
>
>> +/**
>> + * regulatory_hint_found_beacon - hints a beacon was found on a channel
>> + * @wiphy: the wireless device where the beacon was found on
>> + * @beacon_chan: the channel on which the beacon was found on
>> + * @gfp: context flags
>> + *
>> + * This informs the wireless core that a beacon from an AP was found on
>> + * the channel provided. This allows the wireless core to make educated
>> + * guesses on regulatory to help with world roaming. This is only used for
>> + * world roaming -- when we do not know our current location. This is
>> + * only useful on channels 12, 13 and 14 on the 2 GHz band as all other
>> + * channels are already enabled by the world regulatory domain (channels
>> + * 1-11); and on non-radar 5 GHz channels.
>> + */
>> +extern int regulatory_hint_found_beacon(struct wiphy *wiphy,
>> + struct ieee80211_channel *beacon_chan,
>> + gfp_t gfp);
>
> Remove the extern please; also, you don't need to export this function
> in a public header file, reg.h should be fine.

Ah that's right your new scan stuff ensures even cfg80211 drivers
benefit from all this already. Sweet, will change it.

Luis

2009-02-20 20:08:54

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 1/5] cfg80211: enable active-scan / beaconing on Ch 1-11 for world regdom

On Fri, Feb 20, 2009 at 11:59 AM, G=C3=A1bor Stefanik
<[email protected]> wrote:
> On Fri, Feb 20, 2009 at 7:04 AM, Luis R. Rodriguez
> <[email protected]> wrote:
>> This enables active scan and beaconing on Channels 1 through 11
>> on the static world regulatory domain.
>>
>> Signed-off-by: Luis R. Rodriguez <[email protected]>
>> ---
>> net/wireless/reg.c | 5 ++---
>> 1 files changed, 2 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
>> index 605299f..8f64575 100644
>> --- a/net/wireless/reg.c
>> +++ b/net/wireless/reg.c
>> @@ -76,9 +76,8 @@ static const struct ieee80211_regdomain world_regd=
om =3D {
>> .n_reg_rules =3D 1,
>> .alpha2 =3D "00",
>> .reg_rules =3D {
>> - REG_RULE(2412-10, 2462+10, 40, 6, 20,
>> - NL80211_RRF_PASSIVE_SCAN |
>> - NL80211_RRF_NO_IBSS),
>> + /* IEEE 802.11b/g, channels 1..11 */
>> + REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
>> }
>> };
>>
>> --
>> 1.6.0.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wire=
less" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> Are you sure there is no area of the world where the allowed range is
> stricter than b/g 1-11?
> Otherwise I am inclined to NACK this.

That is the value of our world regulatory domain in wireless-regdb and
that itself is the product of the intersection of all currently known
regulatory domains, so yes, hence the patch.

Luis

2009-02-20 06:04:57

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 5/5] cfg80211: default OLD_REG to n

Since we are not following the schedule to remove OLD_REG by 2.6.29
lets simply set it to default to n for 2.6.30 and schedule its
removal for 2.6.31

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
Documentation/feature-removal-schedule.txt | 5 +++--
net/wireless/Kconfig | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index ac98851..bf83b02 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -7,7 +7,7 @@ be removed from this file.
---------------------------

What: old static regulatory information and ieee80211_regdom module parameter
-When: 2.6.29
+When: 2.6.31
Why: The old regulatory infrastructure has been replaced with a new one
which does not require statically defined regulatory domains. We do
not want to keep static regulatory domains in the kernel due to the
@@ -19,7 +19,8 @@ Why: The old regulatory infrastructure has been replaced with a new one
and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was
set. We also kept around the ieee80211_regdom module parameter in case
some applications were relying on it. Changing regulatory domains
- can now be done instead by using nl80211, as is done with iw.
+ can now be done instead by using nl80211, as is done with iw, or
+ wpa_supplicant.
Who: Luis R. Rodriguez <[email protected]>

---------------------------
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index e28e2b8..009f5b8 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -25,7 +25,7 @@ config NL80211

config WIRELESS_OLD_REGULATORY
bool "Old wireless static regulatory definitions"
- default y
+ default n
---help---
This option enables the old static regulatory information
and uses it within the new framework. This is available
--
1.6.0.3