2008-11-05 19:13:40

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

From: Abhijeet Kolekar <[email protected]>

A new wireless regulatory API has been added and
static definitions of regulatory alpha2 have been removed.
As a result of this 5Ghz channels have been disabled by default.
Patch takes care of this by setting the regulatory domain
by reading the EEPROM contents.
It uses regulatory_hint function to dynamically set the regulatory
channels.

This patch is related to bug 11870 at bugzilla.kernel.org. With
correct regulatory information the number of channels to scan
will be correct and not zero as seen in that bug.

This patch eliminates the need for wireless to be compiled with
CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
iwlwifi.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
Could you please send up to 2.6.28? This patch is not valid for
wireless-testing - we will send another patch when regulatory_struct_hint
is available.

drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++
drivers/net/wireless/iwlwifi/iwl-core.c | 83 +++++++++++++++++++++++++++++--
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +
4 files changed, 86 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 321dbc8..067f5b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4345,6 +4345,11 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (err)
IWL_ERROR("failed to create debugfs files\n");

+ err = iwl_set_reg_domain(priv);
+ if (err) {
+ IWL_ERROR("Failed to set regulatory domain (error %d)\n", err);
+ goto out_remove_sysfs;
+ }
err = iwl_rfkill_init(priv);
if (err)
IWL_ERROR("Unable to initialize RFKILL system. "
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 4c312c5..b36966d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -456,6 +456,39 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
}
}

+ /* Regulatory Domains
+ * After 2.6.29 , driver has to pass regulatory domain or alpha2 to
+ * core wireless CRDA using regulatory_hint api
+ */
+
+/**
+ * iwl_set_reg_domain - Set Regulatory Domain
+ */
+
+int iwl_set_reg_domain(struct iwl_priv *priv)
+{
+ int err;
+
+ IWL_DEBUG_INFO("Setting Regulatory Domain\n");
+ err = regulatory_hint(priv->hw->wiphy, NULL, priv->rd);
+ if (err) {
+ if (err == -EALREADY)
+ err = 0;
+ kfree(priv->rd);
+ }
+ return err;
+}
+EXPORT_SYMBOL(iwl_set_reg_domain);
+
+#define REG_RULES(rule, start, end, bw, gain, eirp, reg_flags) { \
+ rule.freq_range.start_freq_khz = (start) * 1000; \
+ rule.freq_range.end_freq_khz = (end) * 1000; \
+ rule.freq_range.max_bandwidth_khz = (bw) * 1000; \
+ rule.power_rule.max_antenna_gain = (gain) * 100; \
+ rule.power_rule.max_eirp = (eirp) * 100; \
+ rule.flags = reg_flags; \
+ }
+
/**
* iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
*/
@@ -466,7 +499,9 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
struct ieee80211_channel *channels;
struct ieee80211_channel *geo_ch;
struct ieee80211_rate *rates;
- int i = 0;
+ int i = 0, reg_flags = 0, reg_count;
+ struct ieee80211_reg_rule *reg_rule;
+ int size_of_regd;

if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
@@ -475,14 +510,22 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
return 0;
}

+ reg_rule = kzalloc(sizeof(struct ieee80211_reg_rule) *
+ priv->channel_count, GFP_KERNEL);
+ if (!reg_rule)
+ return -ENOMEM;
+
channels = kzalloc(sizeof(struct ieee80211_channel) *
priv->channel_count, GFP_KERNEL);
- if (!channels)
+ if (!channels) {
+ kfree(reg_rule);
return -ENOMEM;
+ }

rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
GFP_KERNEL);
if (!rates) {
+ kfree(reg_rule);
kfree(channels);
return -ENOMEM;
}
@@ -513,7 +556,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)

iwlcore_init_hw_rates(priv, rates);

- for (i = 0; i < priv->channel_count; i++) {
+ for (i = 0, reg_count = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];

/* FIXME: might be removed if scan is OK */
@@ -534,11 +577,15 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
geo_ch->hw_value = ch->channel;

if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
+ if (!(ch->flags & EEPROM_CHANNEL_IBSS)) {
geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
+ reg_flags |= NL80211_RRF_NO_IBSS;
+ }

- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
+ if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) {
geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+ reg_flags |= NL80211_RRF_PASSIVE_SCAN;
+ }

if (ch->flags & EEPROM_CHANNEL_RADAR)
geo_ch->flags |= IEEE80211_CHAN_RADAR;
@@ -554,6 +601,13 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/* Save flags for reg domain usage */
geo_ch->orig_flags = geo_ch->flags;

+ /* Add new Regulatory channel */
+ REG_RULES(reg_rule[reg_count], geo_ch->center_freq - 20,
+ geo_ch->center_freq + 20, 40, geo_ch->max_antenna_gain,
+ geo_ch->max_power, reg_flags);
+ reg_flags = 0;
+ reg_count++;
+
IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
@@ -576,8 +630,27 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->bands[IEEE80211_BAND_2GHZ].n_channels,
priv->bands[IEEE80211_BAND_5GHZ].n_channels);

+ size_of_regd = sizeof(struct ieee80211_regdomain) +
+ (reg_count * sizeof(struct ieee80211_reg_rule));
+
+ priv->rd = kzalloc(size_of_regd, GFP_KERNEL);
+ if (!priv->rd) {
+ kfree(reg_rule);
+ kfree(channels);
+ kfree(rates);
+ return -ENOMEM;
+ }
+
+ priv->rd->n_reg_rules = reg_count;
+ strncpy(priv->rd->alpha2, "99", 2);
+
+ for (i = 0; i < reg_count; i++) {
+ memcpy(&priv->rd->reg_rules[i], &reg_rule[i],
+ sizeof(struct ieee80211_reg_rule));
+ }

set_bit(STATUS_GEO_CONFIGURED, &priv->status);
+ kfree(reg_rule);

return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 288b6a8..94ef48c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -194,6 +194,7 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
int iwl_hw_nic_init(struct iwl_priv *priv);
int iwl_setup_mac(struct iwl_priv *priv);
int iwl_set_hw_params(struct iwl_priv *priv);
+int iwl_set_reg_domain(struct iwl_priv *priv);
int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
/* "keep warm" functions */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c018121..bfe6f6e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -775,6 +775,8 @@ struct iwl_priv {
struct ieee80211_rate *ieee_rates;
struct iwl_cfg *cfg;

+ struct ieee80211_regdomain *rd; /*Regulatroy Domain Information */
+
/* temporary frame storage list */
struct list_head free_frames;
int frames_count;
--
1.5.4.3



2008-11-06 14:31:08

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Wed, Nov 05, 2008 at 11:17:22PM +0100, Marcel Holtmann wrote:

>> This patch is related to bug 11870 at bugzilla.kernel.org. With
>> correct regulatory information the number of channels to scan
>> will be correct and not zero as seen in that bug.
>>
>> This patch eliminates the need for wireless to be compiled with
>> CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
>> iwlwifi.
>
> so this is still for 2.6.28, but for 2.6.29 and wireless-testing the API
> changed and we need a separate or different patch.
>
> John, Dave what is your take on pushing this to Linus this late in the
> merge window? I personally think we should do that. And if not, then
> change the Intel wireless Kconfig to select
> CONFIG_WIRELESS_OLD_REGULATORY by default at least.

CONFIG_WIRELESS_OLD_REGULATORY is already 'default y' now. I don't
really see why iwlwifi should _require_ that if someone decides to
choose a non-default configuration.

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-11-12 21:44:30

by Reinette Chatre

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Wed, 2008-11-12 at 13:29 -0800, John W. Linville wrote:
> On Thu, Nov 06, 2008 at 08:49:50AM -0500, John W. Linville wrote:
> > On Wed, Nov 05, 2008 at 11:17:22PM +0100, Marcel Holtmann wrote:
> >
> > >> This patch is related to bug 11870 at bugzilla.kernel.org. With
> > >> correct regulatory information the number of channels to scan
> > >> will be correct and not zero as seen in that bug.
> > >>
> > >> This patch eliminates the need for wireless to be compiled with
> > >> CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
> > >> iwlwifi.
> > >
> > > so this is still for 2.6.28, but for 2.6.29 and wireless-testing the API
> > > changed and we need a separate or different patch.
> > >
> > > John, Dave what is your take on pushing this to Linus this late in the
> > > merge window? I personally think we should do that. And if not, then
> > > change the Intel wireless Kconfig to select
> > > CONFIG_WIRELESS_OLD_REGULATORY by default at least.
> >
> > CONFIG_WIRELESS_OLD_REGULATORY is already 'default y' now. I don't
> > really see why iwlwifi should _require_ that if someone decides to
> > choose a non-default configuration.
>
> In case this was unclear, I'm dropping these patches for 2.6.28.

ok.

> The original post said different patches are needed for -next anyway.

The patches needed for -next was recently submitted by Luis (http://marc.info/?l=linux-wireless&m=122610969314498&w=2 ).

Reinette


2008-11-12 21:31:11

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, Nov 06, 2008 at 08:49:50AM -0500, John W. Linville wrote:
> On Wed, Nov 05, 2008 at 11:17:22PM +0100, Marcel Holtmann wrote:
>
> >> This patch is related to bug 11870 at bugzilla.kernel.org. With
> >> correct regulatory information the number of channels to scan
> >> will be correct and not zero as seen in that bug.
> >>
> >> This patch eliminates the need for wireless to be compiled with
> >> CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
> >> iwlwifi.
> >
> > so this is still for 2.6.28, but for 2.6.29 and wireless-testing the API
> > changed and we need a separate or different patch.
> >
> > John, Dave what is your take on pushing this to Linus this late in the
> > merge window? I personally think we should do that. And if not, then
> > change the Intel wireless Kconfig to select
> > CONFIG_WIRELESS_OLD_REGULATORY by default at least.
>
> CONFIG_WIRELESS_OLD_REGULATORY is already 'default y' now. I don't
> really see why iwlwifi should _require_ that if someone decides to
> choose a non-default configuration.

In case this was unclear, I'm dropping these patches for 2.6.28.
The original post said different patches are needed for -next anyway.

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-11-05 22:40:39

by Reinette Chatre

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Wed, 2008-11-05 at 14:17 -0800, Marcel Holtmann wrote:

> so this is still for 2.6.28, but for 2.6.29 and wireless-testing the
> API changed and we need a separate or different patch.

Correct. The API has not been finalized yet, when it is there will be a
patch for iwlwifi.

Reinette



2008-11-06 15:08:21

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, Nov 6, 2008 at 4:58 PM, Johannes Berg <[email protected]> wrote:
> On Thu, 2008-11-06 at 16:54 +0200, Tomas Winkler wrote:
>> On Thu, Nov 6, 2008 at 4:51 PM, Johannes Berg <[email protected]> wrote:
>> > On Thu, 2008-11-06 at 16:47 +0200, Tomas Winkler wrote:
>> >
>> >> The problem with missing A band is that this info was supplied to
>> >> driver too late. after registration otherwise
>> >> the iwlwifi dealt properly with missing band This was change in design
>> >> that wasn't reflected in the driver.
>> >>
>> >> This can happen _regardless_ of the setting of old regulatory,
>> >>
>> >> With old regulatory the channel was known prior to registration
>> >
>> > Ah, you mean the driver wasn't updated (and previously not prepared) to
>> > handle changing regulatory information?
>>
>> Yep.
>
> That's fixed now though, right? At least I thought it was fixed by some
> change but I can't seem to find it now.

Yeah it's fixed but if someone will disable the same way G band it
will fail. Should never happen though
Tomas

2008-11-06 01:07:16

by Zhu Yi

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, 2008-11-06 at 06:17 +0800, Marcel Holtmann wrote:
> so this is still for 2.6.28, but for 2.6.29 and wireless-testing the
> API changed and we need a separate or different patch.
>
> John, Dave what is your take on pushing this to Linus this late in
> the
> merge window? I personally think we should do that. And if not, then
> change the Intel wireless Kconfig to select
> CONFIG_WIRELESS_OLD_REGULATORY by default at least.

Agreed.

Thanks,
-yi


2008-11-06 14:40:48

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, 2008-11-06 at 15:37 +0100, Johannes Berg wrote:

> I agree, also, I thought the problem was that iwlwifi misbehaved if
> there were no active channels in the 5 GHz band and there was a patch to
> fix that? This can happen _regardless_ of the setting of old regulatory,
> it just happens that without the setting, the default is no 5 GHz
> channels, while with it the default has 5 GHz channels.

Or put it this way: regardless of the OLD_REGULATORY setting, what will
happen if you install iw and crda and do:

# iw set reg IL

(if you don't have crda installed, then run the above command and
afterwards run "COUNTRY=IL ./crda")

I was under the impression that would run into the same bug as not
having OLD_REGULATORY turned on.

johannes


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

2008-11-06 14:54:08

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, Nov 6, 2008 at 4:51 PM, Johannes Berg <[email protected]> wrote:
> On Thu, 2008-11-06 at 16:47 +0200, Tomas Winkler wrote:
>
>> The problem with missing A band is that this info was supplied to
>> driver too late. after registration otherwise
>> the iwlwifi dealt properly with missing band This was change in design
>> that wasn't reflected in the driver.
>>
>> This can happen _regardless_ of the setting of old regulatory,
>>
>> With old regulatory the channel was known prior to registration
>
> Ah, you mean the driver wasn't updated (and previously not prepared) to
> handle changing regulatory information?

Yep.
Tomas

2008-11-06 14:37:37

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, 2008-11-06 at 08:49 -0500, John W. Linville wrote:
> On Wed, Nov 05, 2008 at 11:17:22PM +0100, Marcel Holtmann wrote:
>
> >> This patch is related to bug 11870 at bugzilla.kernel.org. With
> >> correct regulatory information the number of channels to scan
> >> will be correct and not zero as seen in that bug.
> >>
> >> This patch eliminates the need for wireless to be compiled with
> >> CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
> >> iwlwifi.
> >
> > so this is still for 2.6.28, but for 2.6.29 and wireless-testing the API
> > changed and we need a separate or different patch.
> >
> > John, Dave what is your take on pushing this to Linus this late in the
> > merge window? I personally think we should do that. And if not, then
> > change the Intel wireless Kconfig to select
> > CONFIG_WIRELESS_OLD_REGULATORY by default at least.
>
> CONFIG_WIRELESS_OLD_REGULATORY is already 'default y' now. I don't
> really see why iwlwifi should _require_ that if someone decides to
> choose a non-default configuration.

I agree, also, I thought the problem was that iwlwifi misbehaved if
there were no active channels in the 5 GHz band and there was a patch to
fix that? This can happen _regardless_ of the setting of old regulatory,
it just happens that without the setting, the default is no 5 GHz
channels, while with it the default has 5 GHz channels.

johannes


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

2008-11-06 14:51:48

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, 2008-11-06 at 16:47 +0200, Tomas Winkler wrote:

> The problem with missing A band is that this info was supplied to
> driver too late. after registration otherwise
> the iwlwifi dealt properly with missing band This was change in design
> that wasn't reflected in the driver.
>
> This can happen _regardless_ of the setting of old regulatory,
>
> With old regulatory the channel was known prior to registration

Ah, you mean the driver wasn't updated (and previously not prepared) to
handle changing regulatory information?

johannes


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

2008-11-05 22:17:25

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

Hi Reinette,

> A new wireless regulatory API has been added and
> static definitions of regulatory alpha2 have been removed.
> As a result of this 5Ghz channels have been disabled by default.
> Patch takes care of this by setting the regulatory domain
> by reading the EEPROM contents.
> It uses regulatory_hint function to dynamically set the regulatory
> channels.
>
> This patch is related to bug 11870 at bugzilla.kernel.org. With
> correct regulatory information the number of channels to scan
> will be correct and not zero as seen in that bug.
>
> This patch eliminates the need for wireless to be compiled with
> CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
> iwlwifi.

so this is still for 2.6.28, but for 2.6.29 and wireless-testing the
API changed and we need a separate or different patch.

John, Dave what is your take on pushing this to Linus this late in the
merge window? I personally think we should do that. And if not, then
change the Intel wireless Kconfig to select
CONFIG_WIRELESS_OLD_REGULATORY by default at least.

Regards

Marcel


2008-11-06 14:47:06

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, Nov 6, 2008 at 4:37 PM, Johannes Berg <[email protected]> wrote:
> On Thu, 2008-11-06 at 08:49 -0500, John W. Linville wrote:
>> On Wed, Nov 05, 2008 at 11:17:22PM +0100, Marcel Holtmann wrote:
>>
>> >> This patch is related to bug 11870 at bugzilla.kernel.org. With
>> >> correct regulatory information the number of channels to scan
>> >> will be correct and not zero as seen in that bug.
>> >>
>> >> This patch eliminates the need for wireless to be compiled with
>> >> CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
>> >> iwlwifi.
>> >
>> > so this is still for 2.6.28, but for 2.6.29 and wireless-testing the API
>> > changed and we need a separate or different patch.
>> >
>> > John, Dave what is your take on pushing this to Linus this late in the
>> > merge window? I personally think we should do that. And if not, then
>> > change the Intel wireless Kconfig to select
>> > CONFIG_WIRELESS_OLD_REGULATORY by default at least.
>>
>> CONFIG_WIRELESS_OLD_REGULATORY is already 'default y' now. I don't
>> really see why iwlwifi should _require_ that if someone decides to
>> choose a non-default configuration.
>
> I agree, also, I thought the problem was that iwlwifi misbehaved if
> there were no active channels in the 5 GHz band and there was a patch to
> fix that?
The problem with missing A band is that this info was supplied to
driver too late. after registration otherwise
the iwlwifi dealt properly with missing band This was change in design
that wasn't reflected in the driver.

This can happen _regardless_ of the setting of old regulatory,

With old regulatory the channel was known prior to registration

Tomas

2008-11-06 14:58:06

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/2 2.6.28] iwlwifi : Fix channel scanning/association in 5Ghz band

On Thu, 2008-11-06 at 16:54 +0200, Tomas Winkler wrote:
> On Thu, Nov 6, 2008 at 4:51 PM, Johannes Berg <[email protected]> wrote:
> > On Thu, 2008-11-06 at 16:47 +0200, Tomas Winkler wrote:
> >
> >> The problem with missing A band is that this info was supplied to
> >> driver too late. after registration otherwise
> >> the iwlwifi dealt properly with missing band This was change in design
> >> that wasn't reflected in the driver.
> >>
> >> This can happen _regardless_ of the setting of old regulatory,
> >>
> >> With old regulatory the channel was known prior to registration
> >
> > Ah, you mean the driver wasn't updated (and previously not prepared) to
> > handle changing regulatory information?
>
> Yep.

That's fixed now though, right? At least I thought it was fixed by some
change but I can't seem to find it now.

johannes


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

2008-11-05 19:13:39

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 2/2 2.6.28] iwl3945 : Fix channel scanning/association in 5Ghz band

From: Abhijeet Kolekar <[email protected]>

A new wireless regulatory API has been added and
static definitions of regulatory alpha2 have been removed.
As a result of this 5Ghz channels have been disabled by default.
Patch takes care of this by setting the regulatory domain
by reading the EEPROM contents.
It uses regulatory_hint function to dynamically set the regulatory
channels.

This patch is related to bug 11870 at bugzilla.kernel.org. With
correct regulatory information the number of channels to scan
will be correct and not zero as seen in that bug.

This patch eliminates the need for wireless to be compiled with
CONFIG_WIRELESS_OLD_REGULATORY to get correct regulatory behavior with
iwl3945.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
Could you please send up to 2.6.28? This patch is not valid for
wireless-testing - we will send another patch when regulatory_struct_hint
is available.

drivers/net/wireless/iwlwifi/iwl-3945.h | 3 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 89 +++++++++++++++++++++++++--
2 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bdd3247..f095b13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -626,6 +626,7 @@ extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv);
extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv);
extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv);
extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv);
+extern int iwl3945_set_reg_domain(struct iwl3945_priv *priv);
extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv);
extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv);
extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv);
@@ -705,6 +706,8 @@ struct iwl3945_priv {
struct ieee80211_rate *ieee_rates;
struct iwl_3945_cfg *cfg; /* device configuration */

+ struct ieee80211_regdomain *rd; /*Regulatroy Domain Information */
+
/* temporary frame storage list */
struct list_head free_frames;
int frames_count;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d15a2c9..f956c5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4936,6 +4936,38 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
}
}
}
+/* Regulatory Domains
+* After 2.6.29 , driver has to pass regulatory domain or alpha2 to
+* core wireless CRDA using regulatory_hint api
+*/
+
+/**
+ * iwl3945_set_reg_domain - Set Regulatory Domain
+ */
+
+int iwl3945_set_reg_domain(struct iwl3945_priv *priv)
+{
+ int err;
+
+ IWL_DEBUG_INFO("Setting Regulatory Domain\n");
+ err = regulatory_hint(priv->hw->wiphy, NULL, priv->rd);
+ if (err) {
+ if (err == -EALREADY)
+ err = 0;
+ kfree(priv->rd);
+ }
+
+ return err;
+}
+
+#define REG_RULES(rule, start, end, bw, gain, eirp, reg_flags) { \
+ rule.freq_range.start_freq_khz = (start) * 1000; \
+ rule.freq_range.end_freq_khz = (end) * 1000; \
+ rule.freq_range.max_bandwidth_khz = (bw) * 1000; \
+ rule.power_rule.max_antenna_gain = (gain) * 100; \
+ rule.power_rule.max_eirp = (eirp) * 100; \
+ rule.flags = reg_flags; \
+ }

/**
* iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
@@ -4947,7 +4979,9 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
struct ieee80211_channel *channels;
struct ieee80211_channel *geo_ch;
struct ieee80211_rate *rates;
- int i = 0;
+ int i = 0, reg_flags = 0, reg_count;
+ struct ieee80211_reg_rule *reg_rule;
+ int size_of_regd;

if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
@@ -4956,14 +4990,22 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
return 0;
}

+ reg_rule = kzalloc(sizeof(struct ieee80211_reg_rule) *
+ priv->channel_count, GFP_KERNEL);
+ if (!reg_rule)
+ return -ENOMEM;
+
channels = kzalloc(sizeof(struct ieee80211_channel) *
priv->channel_count, GFP_KERNEL);
- if (!channels)
+ if (!channels) {
+ kfree(reg_rule);
return -ENOMEM;
+ }

rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
GFP_KERNEL);
if (!rates) {
+ kfree(reg_rule);
kfree(channels);
return -ENOMEM;
}
@@ -4986,7 +5028,7 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)

iwl3945_init_hw_rates(priv, rates);

- for (i = 0; i < priv->channel_count; i++) {
+ for (i = 0, reg_count = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];

/* FIXME: might be removed if scan is OK*/
@@ -5006,11 +5048,15 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
geo_ch->hw_value = ch->channel;

if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
+ if (!(ch->flags & EEPROM_CHANNEL_IBSS)) {
+ reg_flags |= NL80211_RRF_NO_IBSS;
geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
+ }

- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
+ if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) {
+ reg_flags |= NL80211_RRF_PASSIVE_SCAN;
geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+ }

if (ch->flags & EEPROM_CHANNEL_RADAR)
geo_ch->flags |= IEEE80211_CHAN_RADAR;
@@ -5025,6 +5071,13 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
/* Save flags for reg domain usage */
geo_ch->orig_flags = geo_ch->flags;

+ /* Add new Regulatory channel */
+ REG_RULES(reg_rule[reg_count], geo_ch->center_freq - 20,
+ geo_ch->center_freq + 20, 40, geo_ch->max_antenna_gain,
+ geo_ch->max_power, reg_flags);
+ reg_flags = 0;
+ reg_count++;
+
IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
@@ -5054,8 +5107,28 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->bands[IEEE80211_BAND_5GHZ];

+ size_of_regd = sizeof(struct ieee80211_regdomain) +
+ (reg_count * sizeof(struct ieee80211_reg_rule));
+
+ priv->rd = kzalloc(size_of_regd, GFP_KERNEL);
+ if (!priv->rd) {
+ kfree(reg_rule);
+ kfree(channels);
+ kfree(rates);
+ return -ENOMEM;
+ }
+
+ priv->rd->n_reg_rules = reg_count;
+ strncpy(priv->rd->alpha2, "99", 2);
+
+ for (i = 0; i < reg_count; i++) {
+ memcpy(&priv->rd->reg_rules[i], &reg_rule[i],
+ sizeof(struct ieee80211_reg_rule));
+ }
+
set_bit(STATUS_GEO_CONFIGURED, &priv->status);

+ kfree(reg_rule);
return 0;
}

@@ -8071,6 +8144,12 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_save_state(pdev);
pci_disable_device(pdev);

+ err = iwl3945_set_reg_domain(priv);
+ if (err) {
+ IWL_ERROR("Failed to set regulatory domain (error %d)\n", err);
+ goto out_free_geos;
+ }
+
err = iwl3945_rfkill_init(priv);
if (err)
IWL_ERROR("Unable to initialize RFKILL system. "
--
1.5.4.3