2011-01-07 05:25:05

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

Extend channel to frequency mapping for 802.11j Japan 4.9GHz band, according to
IEEE802.11 section 17.3.8.3.2 and Annex J. Because there are now overlapping
channel numbers in the 2GHz and 5GHz band we can't map from channel to
frequency without knowing the band. This is no problem as in most contexts we
know the band. In places where we don't know the band (and WEXT compatibility)
we assume the 2GHz band for channels below 14.

This patch does not implement all channel to frequency mappings defined in
802.11, it's just an extension for 802.11j 20MHz channels. 5MHz and 10MHz
channels as well as 802.11y channels have been omitted.

Signed-off-by: Bruno Randolf <[email protected]>
---
include/net/cfg80211.h | 3 ++-
net/mac80211/ibss.c | 3 ++-
net/mac80211/mesh.c | 2 +-
net/mac80211/mlme.c | 8 +++++---
net/mac80211/scan.c | 3 ++-
net/wireless/reg.c | 6 +++---
net/wireless/util.c | 36 ++++++++++++++++++++++--------------
net/wireless/wext-compat.c | 5 ++++-
8 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bcc9f44..cfaac36 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1788,8 +1788,9 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
/**
* ieee80211_channel_to_frequency - convert channel number to frequency
* @chan: channel number
+ * @band: band, necessary due to channel number overlap
*/
-extern int ieee80211_channel_to_frequency(int chan);
+extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);

/**
* ieee80211_frequency_to_channel - convert frequency to channel number
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 53c7077..775fb63 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -270,7 +270,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
enum ieee80211_band band = rx_status->band;

if (elems->ds_params && elems->ds_params_len == 1)
- freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
+ freq = ieee80211_channel_to_frequency(elems->ds_params[0],
+ band);
else
freq = rx_status->freq;

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index ca3af46..1430cdc 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
&elems);

if (elems.ds_params && elems.ds_params_len == 1)
- freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
+ freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
else
freq = rx_status->freq;

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 45fbb9e..33bd6d4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -176,7 +176,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,

/* check that channel matches the right operating channel */
if (local->hw.conf.channel->center_freq !=
- ieee80211_channel_to_frequency(hti->control_chan))
+ ieee80211_channel_to_frequency(hti->control_chan, sband->band))
enable_ht = false;

if (enable_ht) {
@@ -429,7 +429,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
container_of((void *)bss, struct cfg80211_bss, priv);
struct ieee80211_channel *new_ch;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
+ int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
+ cbss->channel->band);

ASSERT_MGD_MTX(ifmgd);

@@ -1519,7 +1520,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
}

if (elems->ds_params && elems->ds_params_len == 1)
- freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
+ freq = ieee80211_channel_to_frequency(elems->ds_params[0],
+ rx_status->band);
else
freq = rx_status->freq;

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index fb274db..1ef73be 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
ieee802_11_parse_elems(elements, skb->len - baselen, &elems);

if (elems.ds_params && elems.ds_params_len == 1)
- freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
+ freq = ieee80211_channel_to_frequency(elems.ds_params[0],
+ rx_status->band);
else
freq = rx_status->freq;

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 37693b6..c565689 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1801,9 +1801,9 @@ void regulatory_hint_disconnect(void)

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))
+ if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) ||
+ freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) ||
+ freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ))
return true;
return false;
}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 7620ae2..4ed065d 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -29,29 +29,37 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
}
EXPORT_SYMBOL(ieee80211_get_response_rate);

-int ieee80211_channel_to_frequency(int chan)
+int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
{
- if (chan < 14)
- return 2407 + chan * 5;
-
- if (chan == 14)
- return 2484;
-
- /* FIXME: 802.11j 17.3.8.3.2 */
- return (chan + 1000) * 5;
+ /* see 802.11 17.3.8.3.2 and Annex J
+ * there are overlapping channel numbers in 5GHz and 2GHz bands */
+ if (band == IEEE80211_BAND_5GHZ) {
+ if (chan >= 182 && chan <= 196)
+ return 4000 + chan * 5;
+ else
+ return 5000 + chan * 5;
+ } else { /* IEEE80211_BAND_2GHZ */
+ if (chan == 14)
+ return 2484;
+ else if (chan < 14)
+ return 2407 + chan * 5;
+ else
+ return 0; /* not supported */
+ }
}
EXPORT_SYMBOL(ieee80211_channel_to_frequency);

int ieee80211_frequency_to_channel(int freq)
{
+ /* see 802.11 17.3.8.3.2 and Annex J */
if (freq == 2484)
return 14;
-
- if (freq < 2484)
+ else if (freq < 2484)
return (freq - 2407) / 5;
-
- /* FIXME: 802.11j 17.3.8.3.2 */
- return freq/5 - 1000;
+ else if (freq >= 4910 && freq <= 4980)
+ return (freq - 4000) / 5;
+ else
+ return (freq - 5000) / 5;
}
EXPORT_SYMBOL(ieee80211_frequency_to_channel);

diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 3e5dbd4..7f1f4ec 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -267,9 +267,12 @@ int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq)
* -EINVAL for impossible things.
*/
if (freq->e == 0) {
+ enum ieee80211_band band = IEEE80211_BAND_2GHZ;
if (freq->m < 0)
return 0;
- return ieee80211_channel_to_frequency(freq->m);
+ if (freq->m > 14)
+ band = IEEE80211_BAND_5GHZ;
+ return ieee80211_channel_to_frequency(freq->m, band);
} else {
int i, div = 1000000;
for (i = 0; i < freq->e; i++)



2011-01-11 15:09:28

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Tue, 2011-01-11 at 08:16 -0500, Brian Prodoehl wrote:
> On Tue, Jan 11, 2011 at 7:18 AM, Johannes Berg
> <[email protected]> wrote:
> > On Tue, 2011-01-11 at 18:17 +0900, Bruno Randolf wrote:
> >
> >> > compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c 2011-0
> >> > 1-07 15:03:59.000000000 -0500
> >> > +++
> >> > compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c 2011-01-08
> >> > 07:51:23.947290769 -0500
> >> > @@ -607,7 +607,8 @@
> >> > /* No channel, no luck */
> >> > if (chan_no != -1) {
> >> > struct wiphy *wiphy = priv->wdev->wiphy;
> >> > - int freq = ieee80211_channel_to_frequency(chan_no);
> >> > + int freq = ieee80211_channel_to_frequency(chan_no,
> >> > + chan_no <= 14 ? IEEE80211_BAND_2GHZ :
> >> IEEE80211_BAND_5GHZ);
> >>
> >> The whole point of having the band argument is to avoid this. We now have
> >> overlapping channel numbers: channel 8 and 12 are defined in 5GHz as well as
> >> in 2.4GHz (that is for 20MHz channel width, there are more for 10 and 5MHz
> >> width, but we don't support that yet). The band has to come from the hardware
> >> or driver configuration.
> >
> > I don't think libertas (or orinoco) support the frequencies that
> > overlap, and they use the channel number in HW config, so it should be
> > fine.
> >
> > johannes
>
> That's what it looked like to me, as well, for libertas. For rt2x00,
> with it's dependence on binary firmwares from Ralink, extending the
> channel set seems very far from trivial. Ralink advertises compliance
> with 802.11j (http://web.ralinktech.com/ralink/data/RT2800.pdf). A
> year and a half ago I asked them directly what that compliance means
> (4.9GHz channels? 10MHz channel width? misprint?) and didn't get a
> response. A way to pull the band for rt2x00 didn't pop out at me, but
> if the maintainers have suggestions, that'll be great. Also, if they
> have some idea what the level of 802.11j compliance is, I'd love to
> know!

While some libertas/fullmac devices do apparently support A, I haven't
seen any in person or heard of them in real use. And the current
libertas driver certainly doesn't support 802.11a and wont, unless we
magically find a part that does.

Dan



2011-01-08 03:44:02

by Bruno Randolf

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Friday 07 January 2011 21:53:25 Brian Prodoehl wrote:
> > Do all drivers still build with this patch? I applied the previous
> > RFC version of this patch to a late-December cut of compat-wireless,
> > and had to touch the receive-handling code in a half-dozen or so
> > drivers due to the API changes.

I have to confess, I didn't check the drivers. Just tested with ath5k. Before
this gets merged we have to fix all drivers which use these functions, true. I
will try to do that next week...

> Ah, I see. All the driver changes I needed were because
> ieee80211_channel_to_frequency() changed with the RFC patch, and this
> patch keeps ieee80211_channel_to_frequency() the same. Good stuff.

Uh? This patch also changes ieee80211_channel_to_frequency(). Bad stuff. ;)

bruno

2011-01-07 12:53:26

by Brian Prodoehl

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Fri, Jan 7, 2011 at 7:45 AM, Brian Prodoehl <[email protected]> wrote:
> On Fri, Jan 7, 2011 at 12:26 AM, Bruno Randolf <[email protected]> wrote:
>> Extend channel to frequency mapping for 802.11j Japan 4.9GHz band, according to
>> IEEE802.11 section 17.3.8.3.2 and Annex J. Because there are now overlapping
>> channel numbers in the 2GHz and 5GHz band we can't map from channel to
>> frequency without knowing the band. This is no problem as in most contexts we
>> know the band. In places where we don't know the band (and WEXT compatibility)
>> we assume the 2GHz band for channels below 14.
>>
>> This patch does not implement all channel to frequency mappings defined in
>> 802.11, it's just an extension for 802.11j 20MHz channels. 5MHz and 10MHz
>> channels as well as 802.11y channels have been omitted.
>>
>> Signed-off-by: Bruno Randolf <[email protected]>
>> ---
>> ?include/net/cfg80211.h ? ? | ? ?3 ++-
>> ?net/mac80211/ibss.c ? ? ? ?| ? ?3 ++-
>> ?net/mac80211/mesh.c ? ? ? ?| ? ?2 +-
>> ?net/mac80211/mlme.c ? ? ? ?| ? ?8 +++++---
>> ?net/mac80211/scan.c ? ? ? ?| ? ?3 ++-
>> ?net/wireless/reg.c ? ? ? ? | ? ?6 +++---
>> ?net/wireless/util.c ? ? ? ?| ? 36 ++++++++++++++++++++++--------------
>> ?net/wireless/wext-compat.c | ? ?5 ++++-
>> ?8 files changed, 41 insertions(+), 25 deletions(-)
>>
>> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
>> index bcc9f44..cfaac36 100644
>> --- a/include/net/cfg80211.h
>> +++ b/include/net/cfg80211.h
>> @@ -1788,8 +1788,9 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
>> ?/**
>> ?* ieee80211_channel_to_frequency - convert channel number to frequency
>> ?* @chan: channel number
>> + * @band: band, necessary due to channel number overlap
>> ?*/
>> -extern int ieee80211_channel_to_frequency(int chan);
>> +extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);
>>
>> ?/**
>> ?* ieee80211_frequency_to_channel - convert frequency to channel number
>> diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
>> index 53c7077..775fb63 100644
>> --- a/net/mac80211/ibss.c
>> +++ b/net/mac80211/ibss.c
>> @@ -270,7 +270,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
>> ? ? ? ?enum ieee80211_band band = rx_status->band;
>>
>> ? ? ? ?if (elems->ds_params && elems->ds_params_len == 1)
>> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
>> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0],
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? band);
>> ? ? ? ?else
>> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>>
>> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
>> index ca3af46..1430cdc 100644
>> --- a/net/mac80211/mesh.c
>> +++ b/net/mac80211/mesh.c
>> @@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &elems);
>>
>> ? ? ? ?if (elems.ds_params && elems.ds_params_len == 1)
>> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
>> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
>> ? ? ? ?else
>> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>>
>> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
>> index 45fbb9e..33bd6d4 100644
>> --- a/net/mac80211/mlme.c
>> +++ b/net/mac80211/mlme.c
>> @@ -176,7 +176,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
>>
>> ? ? ? ?/* check that channel matches the right operating channel */
>> ? ? ? ?if (local->hw.conf.channel->center_freq !=
>> - ? ? ? ? ? ieee80211_channel_to_frequency(hti->control_chan))
>> + ? ? ? ? ? ieee80211_channel_to_frequency(hti->control_chan, sband->band))
>> ? ? ? ? ? ? ? ?enable_ht = false;
>>
>> ? ? ? ?if (enable_ht) {
>> @@ -429,7 +429,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
>> ? ? ? ? ? ? ? ?container_of((void *)bss, struct cfg80211_bss, priv);
>> ? ? ? ?struct ieee80211_channel *new_ch;
>> ? ? ? ?struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
>> - ? ? ? int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
>> + ? ? ? int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cbss->channel->band);
>>
>> ? ? ? ?ASSERT_MGD_MTX(ifmgd);
>>
>> @@ -1519,7 +1520,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
>> ? ? ? ?}
>>
>> ? ? ? ?if (elems->ds_params && elems->ds_params_len == 1)
>> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
>> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0],
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rx_status->band);
>> ? ? ? ?else
>> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>>
>> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
>> index fb274db..1ef73be 100644
>> --- a/net/mac80211/scan.c
>> +++ b/net/mac80211/scan.c
>> @@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
>> ? ? ? ?ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
>>
>> ? ? ? ?if (elems.ds_params && elems.ds_params_len == 1)
>> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
>> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0],
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rx_status->band);
>> ? ? ? ?else
>> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>>
>> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
>> index 37693b6..c565689 100644
>> --- a/net/wireless/reg.c
>> +++ b/net/wireless/reg.c
>> @@ -1801,9 +1801,9 @@ void regulatory_hint_disconnect(void)
>>
>> ?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))
>> + ? ? ? if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) ||
>> + ? ? ? ? ? freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) ||
>> + ? ? ? ? ? freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ))
>> ? ? ? ? ? ? ? ?return true;
>> ? ? ? ?return false;
>> ?}
>> diff --git a/net/wireless/util.c b/net/wireless/util.c
>> index 7620ae2..4ed065d 100644
>> --- a/net/wireless/util.c
>> +++ b/net/wireless/util.c
>> @@ -29,29 +29,37 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
>> ?}
>> ?EXPORT_SYMBOL(ieee80211_get_response_rate);
>>
>> -int ieee80211_channel_to_frequency(int chan)
>> +int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
>> ?{
>> - ? ? ? if (chan < 14)
>> - ? ? ? ? ? ? ? return 2407 + chan * 5;
>> -
>> - ? ? ? if (chan == 14)
>> - ? ? ? ? ? ? ? return 2484;
>> -
>> - ? ? ? /* FIXME: 802.11j 17.3.8.3.2 */
>> - ? ? ? return (chan + 1000) * 5;
>> + ? ? ? /* see 802.11 17.3.8.3.2 and Annex J
>> + ? ? ? ?* there are overlapping channel numbers in 5GHz and 2GHz bands */
>> + ? ? ? if (band == IEEE80211_BAND_5GHZ) {
>> + ? ? ? ? ? ? ? if (chan >= 182 && chan <= 196)
>> + ? ? ? ? ? ? ? ? ? ? ? return 4000 + chan * 5;
>> + ? ? ? ? ? ? ? else
>> + ? ? ? ? ? ? ? ? ? ? ? return 5000 + chan * 5;
>> + ? ? ? } else { /* IEEE80211_BAND_2GHZ */
>> + ? ? ? ? ? ? ? if (chan == 14)
>> + ? ? ? ? ? ? ? ? ? ? ? return 2484;
>> + ? ? ? ? ? ? ? else if (chan < 14)
>> + ? ? ? ? ? ? ? ? ? ? ? return 2407 + chan * 5;
>> + ? ? ? ? ? ? ? else
>> + ? ? ? ? ? ? ? ? ? ? ? return 0; /* not supported */
>> + ? ? ? }
>> ?}
>> ?EXPORT_SYMBOL(ieee80211_channel_to_frequency);
>>
>> ?int ieee80211_frequency_to_channel(int freq)
>> ?{
>> + ? ? ? /* see 802.11 17.3.8.3.2 and Annex J */
>> ? ? ? ?if (freq == 2484)
>> ? ? ? ? ? ? ? ?return 14;
>> -
>> - ? ? ? if (freq < 2484)
>> + ? ? ? else if (freq < 2484)
>> ? ? ? ? ? ? ? ?return (freq - 2407) / 5;
>> -
>> - ? ? ? /* FIXME: 802.11j 17.3.8.3.2 */
>> - ? ? ? return freq/5 - 1000;
>> + ? ? ? else if (freq >= 4910 && freq <= 4980)
>> + ? ? ? ? ? ? ? return (freq - 4000) / 5;
>> + ? ? ? else
>> + ? ? ? ? ? ? ? return (freq - 5000) / 5;
>> ?}
>> ?EXPORT_SYMBOL(ieee80211_frequency_to_channel);
>>
>> diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
>> index 3e5dbd4..7f1f4ec 100644
>> --- a/net/wireless/wext-compat.c
>> +++ b/net/wireless/wext-compat.c
>> @@ -267,9 +267,12 @@ int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq)
>> ? ? ? ? * -EINVAL for impossible things.
>> ? ? ? ? */
>> ? ? ? ?if (freq->e == 0) {
>> + ? ? ? ? ? ? ? enum ieee80211_band band = IEEE80211_BAND_2GHZ;
>> ? ? ? ? ? ? ? ?if (freq->m < 0)
>> ? ? ? ? ? ? ? ? ? ? ? ?return 0;
>> - ? ? ? ? ? ? ? return ieee80211_channel_to_frequency(freq->m);
>> + ? ? ? ? ? ? ? if (freq->m > 14)
>> + ? ? ? ? ? ? ? ? ? ? ? band = IEEE80211_BAND_5GHZ;
>> + ? ? ? ? ? ? ? return ieee80211_channel_to_frequency(freq->m, band);
>> ? ? ? ?} else {
>> ? ? ? ? ? ? ? ?int i, div = 1000000;
>> ? ? ? ? ? ? ? ?for (i = 0; i < freq->e; i++)
>
>
> Do all drivers still build with this patch? ?I applied the previous
> RFC version of this patch to a late-December cut of compat-wireless,
> and had to touch the receive-handling code in a half-dozen or so
> drivers due to the API changes.
>
> -Brian

Ah, I see. All the driver changes I needed were because
ieee80211_channel_to_frequency() changed with the RFC patch, and this
patch keeps ieee80211_channel_to_frequency() the same. Good stuff.

2011-01-11 12:18:56

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Tue, 2011-01-11 at 18:17 +0900, Bruno Randolf wrote:

> > compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c 2011-0
> > 1-07 15:03:59.000000000 -0500
> > +++
> > compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c 2011-01-08
> > 07:51:23.947290769 -0500
> > @@ -607,7 +607,8 @@
> > /* No channel, no luck */
> > if (chan_no != -1) {
> > struct wiphy *wiphy = priv->wdev->wiphy;
> > - int freq = ieee80211_channel_to_frequency(chan_no);
> > + int freq = ieee80211_channel_to_frequency(chan_no,
> > + chan_no <= 14 ? IEEE80211_BAND_2GHZ :
> IEEE80211_BAND_5GHZ);
>
> The whole point of having the band argument is to avoid this. We now have
> overlapping channel numbers: channel 8 and 12 are defined in 5GHz as well as
> in 2.4GHz (that is for 20MHz channel width, there are more for 10 and 5MHz
> width, but we don't support that yet). The band has to come from the hardware
> or driver configuration.

I don't think libertas (or orinoco) support the frequencies that
overlap, and they use the channel number in HW config, so it should be
fine.

johannes


2011-01-08 13:08:43

by Brian Prodoehl

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Fri, Jan 7, 2011 at 10:43 PM, Bruno Randolf <[email protected]> wrote:
> On Friday 07 January 2011 21:53:25 Brian Prodoehl wrote:
>> > Do all drivers still build with this patch? ?I applied the previous
>> > RFC version of this patch to a late-December cut of compat-wireless,
>> > and had to touch the receive-handling code in a half-dozen or so
>> > drivers due to the API changes.
>
> I have to confess, I didn't check the drivers. Just tested with ath5k. Before
> this gets merged we have to fix all drivers which use these functions, true. I
> will try to do that next week...
>
>> Ah, I see. ?All the driver changes I needed were because
>> ieee80211_channel_to_frequency() changed with the RFC patch, and this
>> patch keeps ieee80211_channel_to_frequency() the same. ?Good stuff.
>
> Uh? This patch also changes ieee80211_channel_to_frequency(). Bad stuff. ;)
>
> bruno

I guess I saw what I wanted to see when I took a second look at the
re-posted patch. Here are compile-fixes to all the affected drivers.
The following drivers are affected: mwl8k, iwlwifi, iwmc3200wifi,
libertas, rt2x00, wl1251 and wl12xx. So I guess these driver fixes
need to be split into seven patches. I don't use any of these
drivers, so I can't really vouch for if I'm pulling the band the
correct way for each. I'm happy to split and submit, but I wouldn't
mind another set of eyes on these changes.


Index: compat-wireless-2011-01-07/drivers/net/wireless/mwl8k.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/mwl8k.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/mwl8k.c 2011-01-08
07:51:23.843290770 -0500
@@ -834,7 +834,7 @@
} else {
status->band = IEEE80211_BAND_2GHZ;
}
- status->freq = ieee80211_channel_to_frequency(rxd->channel);
+ status->freq = ieee80211_channel_to_frequency(rxd->channel, status->band);

*qos = rxd->qos_control;

@@ -931,7 +931,7 @@
} else {
status->band = IEEE80211_BAND_2GHZ;
}
- status->freq = ieee80211_channel_to_frequency(rxd->channel);
+ status->freq = ieee80211_channel_to_frequency(rxd->channel, status->band);

*qos = rxd->qos_control;

Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-3945.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-3945.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-3945.c 2011-01-08
07:51:23.867290769 -0500
@@ -594,10 +594,10 @@

rx_status.flag = 0;
rx_status.mactime = le64_to_cpu(rx_end->timestamp);
- rx_status.freq =
- ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ rx_status.freq =
+ ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), rx_status.band);

rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
if (rx_status.band == IEEE80211_BAND_5GHZ)
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-agn-lib.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-agn-lib.c 2011-01-08
07:51:23.883290769 -0500
@@ -1157,10 +1157,10 @@

/* rx_status carries information about the packet to mac80211 */
rx_status.mactime = le64_to_cpu(phy_res->timestamp);
- rx_status.freq =
- ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ rx_status.freq =
+ ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
rx_status.band);
rx_status.rate_idx =
iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
rx_status.flag = 0;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-core.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwlwifi/iwl-core.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwlwifi/iwl-core.c 2011-01-08
07:51:23.903290769 -0500
@@ -227,7 +227,10 @@
geo_ch = &sband->channels[sband->n_channels++];

geo_ch->center_freq =
- ieee80211_channel_to_frequency(ch->channel);
+ ieee80211_channel_to_frequency(ch->channel,
+ is_channel_a_band(ch) ?
+ IEEE80211_BAND_5GHZ :
+ IEEE80211_BAND_2GHZ);
geo_ch->max_power = ch->max_power_avg;
geo_ch->max_antenna_gain = 0xff;
geo_ch->hw_value = ch->channel;
Index: compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwmc3200wifi/rx.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/rx.c 2011-01-08
07:51:23.919290769 -0500
@@ -536,6 +536,7 @@
struct ieee80211_channel *chan;
struct iwm_umac_notif_assoc_complete *complete =
(struct iwm_umac_notif_assoc_complete *)buf;
+ u8 band = complete->band;

IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
complete->bssid, complete->status);
@@ -543,7 +544,9 @@
switch (le32_to_cpu(complete->status)) {
case UMAC_ASSOC_COMPLETE_SUCCESS:
chan = ieee80211_get_channel(wiphy,
- ieee80211_channel_to_frequency(complete->channel));
+ ieee80211_channel_to_frequency(complete->channel,
+ (band == UMAC_BAND_2GHZ) ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
/* Associated to a unallowed channel, disassociate. */
__iwm_invalidate_mlme_profile(iwm);
@@ -841,7 +844,9 @@
goto err;
}

- freq = ieee80211_channel_to_frequency(umac_bss->channel);
+ freq = ieee80211_channel_to_frequency(umac_bss->channel,
+ umac_bss->band == UMAC_BAND_2GHZ ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
channel = ieee80211_get_channel(wiphy, freq);
signal = umac_bss->rssi * 100;

Index: compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/cfg80211.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/iwmc3200wifi/cfg80211.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/iwmc3200wifi/cfg80211.c 2011-01-08
07:51:23.927290769 -0500
@@ -287,7 +287,9 @@
return -EINVAL;
}

- freq = ieee80211_channel_to_frequency(umac_bss->channel);
+ freq = ieee80211_channel_to_frequency(umac_bss->channel,
+ umac_bss->band == UMAC_BAND_2GHZ ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
channel = ieee80211_get_channel(wiphy, freq);
signal = umac_bss->rssi * 100;

Index: compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c 2011-01-08
07:51:23.947290769 -0500
@@ -607,7 +607,8 @@
/* No channel, no luck */
if (chan_no != -1) {
struct wiphy *wiphy = priv->wdev->wiphy;
- int freq = ieee80211_channel_to_frequency(chan_no);
+ int freq = ieee80211_channel_to_frequency(chan_no,
+ chan_no <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
struct ieee80211_channel *channel =
ieee80211_get_channel(wiphy, freq);

@@ -1597,7 +1598,8 @@
lbs_deb_enter(LBS_DEB_CFG80211);

survey->channel = ieee80211_get_channel(wiphy,
- ieee80211_channel_to_frequency(priv->channel));
+ ieee80211_channel_to_frequency(priv->channel,
+ priv->channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));

ret = lbs_get_rssi(priv, &signal, &noise);
if (ret == 0) {
Index: compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/rt2x00/rt2x00dev.c 2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c 2011-01-08
07:51:23.971290769 -0500
@@ -649,7 +649,8 @@
const int channel, const int tx_power,
const int value)
{
- entry->center_freq = ieee80211_channel_to_frequency(channel);
+ entry->center_freq = ieee80211_channel_to_frequency(channel,
+ channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
entry->hw_value = value;
entry->max_power = tx_power;
entry->max_antenna_gain = 0xff;
Index: compat-wireless-2011-01-07/drivers/net/wireless/wl1251/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/wl1251/rx.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/wl1251/rx.c 2011-01-08
07:51:23.987290769 -0500
@@ -78,7 +78,7 @@
*/
wl->noise = desc->rssi - desc->snr / 2;

- status->freq = ieee80211_channel_to_frequency(desc->channel);
+ status->freq = ieee80211_channel_to_frequency(desc->channel, status->band);

status->flag |= RX_FLAG_TSFT;

Index: compat-wireless-2011-01-07/drivers/net/wireless/wl12xx/rx.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/wl12xx/rx.c 2011-01-07
15:04:00.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/wl12xx/rx.c 2011-01-08
07:51:24.003290769 -0500
@@ -76,7 +76,7 @@
*/
wl->noise = desc->rssi - (desc->snr >> 1);

- status->freq = ieee80211_channel_to_frequency(desc->channel);
+ status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band);

if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;

2011-01-07 12:45:01

by Brian Prodoehl

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Fri, Jan 7, 2011 at 12:26 AM, Bruno Randolf <[email protected]> wrote:
> Extend channel to frequency mapping for 802.11j Japan 4.9GHz band, according to
> IEEE802.11 section 17.3.8.3.2 and Annex J. Because there are now overlapping
> channel numbers in the 2GHz and 5GHz band we can't map from channel to
> frequency without knowing the band. This is no problem as in most contexts we
> know the band. In places where we don't know the band (and WEXT compatibility)
> we assume the 2GHz band for channels below 14.
>
> This patch does not implement all channel to frequency mappings defined in
> 802.11, it's just an extension for 802.11j 20MHz channels. 5MHz and 10MHz
> channels as well as 802.11y channels have been omitted.
>
> Signed-off-by: Bruno Randolf <[email protected]>
> ---
> ?include/net/cfg80211.h ? ? | ? ?3 ++-
> ?net/mac80211/ibss.c ? ? ? ?| ? ?3 ++-
> ?net/mac80211/mesh.c ? ? ? ?| ? ?2 +-
> ?net/mac80211/mlme.c ? ? ? ?| ? ?8 +++++---
> ?net/mac80211/scan.c ? ? ? ?| ? ?3 ++-
> ?net/wireless/reg.c ? ? ? ? | ? ?6 +++---
> ?net/wireless/util.c ? ? ? ?| ? 36 ++++++++++++++++++++++--------------
> ?net/wireless/wext-compat.c | ? ?5 ++++-
> ?8 files changed, 41 insertions(+), 25 deletions(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index bcc9f44..cfaac36 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1788,8 +1788,9 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
> ?/**
> ?* ieee80211_channel_to_frequency - convert channel number to frequency
> ?* @chan: channel number
> + * @band: band, necessary due to channel number overlap
> ?*/
> -extern int ieee80211_channel_to_frequency(int chan);
> +extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);
>
> ?/**
> ?* ieee80211_frequency_to_channel - convert frequency to channel number
> diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
> index 53c7077..775fb63 100644
> --- a/net/mac80211/ibss.c
> +++ b/net/mac80211/ibss.c
> @@ -270,7 +270,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
> ? ? ? ?enum ieee80211_band band = rx_status->band;
>
> ? ? ? ?if (elems->ds_params && elems->ds_params_len == 1)
> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0],
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? band);
> ? ? ? ?else
> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>
> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
> index ca3af46..1430cdc 100644
> --- a/net/mac80211/mesh.c
> +++ b/net/mac80211/mesh.c
> @@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &elems);
>
> ? ? ? ?if (elems.ds_params && elems.ds_params_len == 1)
> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
> ? ? ? ?else
> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index 45fbb9e..33bd6d4 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -176,7 +176,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
>
> ? ? ? ?/* check that channel matches the right operating channel */
> ? ? ? ?if (local->hw.conf.channel->center_freq !=
> - ? ? ? ? ? ieee80211_channel_to_frequency(hti->control_chan))
> + ? ? ? ? ? ieee80211_channel_to_frequency(hti->control_chan, sband->band))
> ? ? ? ? ? ? ? ?enable_ht = false;
>
> ? ? ? ?if (enable_ht) {
> @@ -429,7 +429,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
> ? ? ? ? ? ? ? ?container_of((void *)bss, struct cfg80211_bss, priv);
> ? ? ? ?struct ieee80211_channel *new_ch;
> ? ? ? ?struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> - ? ? ? int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
> + ? ? ? int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cbss->channel->band);
>
> ? ? ? ?ASSERT_MGD_MTX(ifmgd);
>
> @@ -1519,7 +1520,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
> ? ? ? ?}
>
> ? ? ? ?if (elems->ds_params && elems->ds_params_len == 1)
> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems->ds_params[0],
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rx_status->band);
> ? ? ? ?else
> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index fb274db..1ef73be 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
> ? ? ? ?ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
>
> ? ? ? ?if (elems.ds_params && elems.ds_params_len == 1)
> - ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
> + ? ? ? ? ? ? ? freq = ieee80211_channel_to_frequency(elems.ds_params[0],
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rx_status->band);
> ? ? ? ?else
> ? ? ? ? ? ? ? ?freq = rx_status->freq;
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 37693b6..c565689 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -1801,9 +1801,9 @@ void regulatory_hint_disconnect(void)
>
> ?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))
> + ? ? ? if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) ||
> + ? ? ? ? ? freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) ||
> + ? ? ? ? ? freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ))
> ? ? ? ? ? ? ? ?return true;
> ? ? ? ?return false;
> ?}
> diff --git a/net/wireless/util.c b/net/wireless/util.c
> index 7620ae2..4ed065d 100644
> --- a/net/wireless/util.c
> +++ b/net/wireless/util.c
> @@ -29,29 +29,37 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
> ?}
> ?EXPORT_SYMBOL(ieee80211_get_response_rate);
>
> -int ieee80211_channel_to_frequency(int chan)
> +int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
> ?{
> - ? ? ? if (chan < 14)
> - ? ? ? ? ? ? ? return 2407 + chan * 5;
> -
> - ? ? ? if (chan == 14)
> - ? ? ? ? ? ? ? return 2484;
> -
> - ? ? ? /* FIXME: 802.11j 17.3.8.3.2 */
> - ? ? ? return (chan + 1000) * 5;
> + ? ? ? /* see 802.11 17.3.8.3.2 and Annex J
> + ? ? ? ?* there are overlapping channel numbers in 5GHz and 2GHz bands */
> + ? ? ? if (band == IEEE80211_BAND_5GHZ) {
> + ? ? ? ? ? ? ? if (chan >= 182 && chan <= 196)
> + ? ? ? ? ? ? ? ? ? ? ? return 4000 + chan * 5;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? return 5000 + chan * 5;
> + ? ? ? } else { /* IEEE80211_BAND_2GHZ */
> + ? ? ? ? ? ? ? if (chan == 14)
> + ? ? ? ? ? ? ? ? ? ? ? return 2484;
> + ? ? ? ? ? ? ? else if (chan < 14)
> + ? ? ? ? ? ? ? ? ? ? ? return 2407 + chan * 5;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? return 0; /* not supported */
> + ? ? ? }
> ?}
> ?EXPORT_SYMBOL(ieee80211_channel_to_frequency);
>
> ?int ieee80211_frequency_to_channel(int freq)
> ?{
> + ? ? ? /* see 802.11 17.3.8.3.2 and Annex J */
> ? ? ? ?if (freq == 2484)
> ? ? ? ? ? ? ? ?return 14;
> -
> - ? ? ? if (freq < 2484)
> + ? ? ? else if (freq < 2484)
> ? ? ? ? ? ? ? ?return (freq - 2407) / 5;
> -
> - ? ? ? /* FIXME: 802.11j 17.3.8.3.2 */
> - ? ? ? return freq/5 - 1000;
> + ? ? ? else if (freq >= 4910 && freq <= 4980)
> + ? ? ? ? ? ? ? return (freq - 4000) / 5;
> + ? ? ? else
> + ? ? ? ? ? ? ? return (freq - 5000) / 5;
> ?}
> ?EXPORT_SYMBOL(ieee80211_frequency_to_channel);
>
> diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
> index 3e5dbd4..7f1f4ec 100644
> --- a/net/wireless/wext-compat.c
> +++ b/net/wireless/wext-compat.c
> @@ -267,9 +267,12 @@ int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq)
> ? ? ? ? * -EINVAL for impossible things.
> ? ? ? ? */
> ? ? ? ?if (freq->e == 0) {
> + ? ? ? ? ? ? ? enum ieee80211_band band = IEEE80211_BAND_2GHZ;
> ? ? ? ? ? ? ? ?if (freq->m < 0)
> ? ? ? ? ? ? ? ? ? ? ? ?return 0;
> - ? ? ? ? ? ? ? return ieee80211_channel_to_frequency(freq->m);
> + ? ? ? ? ? ? ? if (freq->m > 14)
> + ? ? ? ? ? ? ? ? ? ? ? band = IEEE80211_BAND_5GHZ;
> + ? ? ? ? ? ? ? return ieee80211_channel_to_frequency(freq->m, band);
> ? ? ? ?} else {
> ? ? ? ? ? ? ? ?int i, div = 1000000;
> ? ? ? ? ? ? ? ?for (i = 0; i < freq->e; i++)


Do all drivers still build with this patch? I applied the previous
RFC version of this patch to a late-December cut of compat-wireless,
and had to touch the receive-handling code in a half-dozen or so
drivers due to the API changes.

-Brian

2011-01-11 09:16:45

by Bruno Randolf

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Sat January 8 2011 22:08:41 Brian Prodoehl wrote:
> I guess I saw what I wanted to see when I took a second look at the
> re-posted patch. Here are compile-fixes to all the affected drivers.
> The following drivers are affected: mwl8k, iwlwifi, iwmc3200wifi,
> libertas, rt2x00, wl1251 and wl12xx. So I guess these driver fixes
> need to be split into seven patches. I don't use any of these
> drivers, so I can't really vouch for if I'm pulling the band the
> correct way for each. I'm happy to split and submit, but I wouldn't
> mind another set of eyes on these changes.

Thanks! I would say these changes have to be merged with my patch, so it can
be applied without breaking git bisect for the affected drivers.

> compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c 2011-0
> 1-07 15:03:59.000000000 -0500
> +++
> compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c 2011-01-08
> 07:51:23.947290769 -0500
> @@ -607,7 +607,8 @@
> /* No channel, no luck */
> if (chan_no != -1) {
> struct wiphy *wiphy = priv->wdev->wiphy;
> - int freq = ieee80211_channel_to_frequency(chan_no);
> + int freq = ieee80211_channel_to_frequency(chan_no,
> + chan_no <= 14 ? IEEE80211_BAND_2GHZ :
IEEE80211_BAND_5GHZ);

The whole point of having the band argument is to avoid this. We now have
overlapping channel numbers: channel 8 and 12 are defined in 5GHz as well as
in 2.4GHz (that is for 20MHz channel width, there are more for 10 and 5MHz
width, but we don't support that yet). The band has to come from the hardware
or driver configuration.

> @@ -1597,7 +1598,8 @@
> lbs_deb_enter(LBS_DEB_CFG80211);
>
> survey->channel = ieee80211_get_channel(wiphy,
> - ieee80211_channel_to_frequency(priv->channel));
> + ieee80211_channel_to_frequency(priv->channel,
> + priv->channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ));

Same here.

> compat-wireless-2011-01-07.orig/drivers/net/wireless/rt2x00/rt2x00dev.c 20
> 11-01-07 15:03:59.000000000 -0500
> +++
> compat-wireless-2011-01-07/drivers/net/wireless/rt2x00/rt2x00dev.c
2011-01
> -08 07:51:23.971290769 -0500
> @@ -649,7 +649,8 @@
> const int channel, const int tx_power,
> const int value)
> {
> - entry->center_freq = ieee80211_channel_to_frequency(channel);
> + entry->center_freq = ieee80211_channel_to_frequency(channel,
> + channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);

And here.

So the two problematic drivers are libertas and rt2x00. I'm Cc'ing the
maintainers, and hope that they have better insight into how to fix this than
we.

bruno

2011-01-07 11:43:30

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Fri, 2011-01-07 at 14:26 +0900, Bruno Randolf wrote:
> Extend channel to frequency mapping for 802.11j Japan 4.9GHz band, according to
> IEEE802.11 section 17.3.8.3.2 and Annex J. Because there are now overlapping
> channel numbers in the 2GHz and 5GHz band we can't map from channel to
> frequency without knowing the band. This is no problem as in most contexts we
> know the band. In places where we don't know the band (and WEXT compatibility)
> we assume the 2GHz band for channels below 14.
>
> This patch does not implement all channel to frequency mappings defined in
> 802.11, it's just an extension for 802.11j 20MHz channels. 5MHz and 10MHz
> channels as well as 802.11y channels have been omitted.

Reviewed-by: Johannes Berg <[email protected]>

> Signed-off-by: Bruno Randolf <[email protected]>
> ---
> include/net/cfg80211.h | 3 ++-
> net/mac80211/ibss.c | 3 ++-
> net/mac80211/mesh.c | 2 +-
> net/mac80211/mlme.c | 8 +++++---
> net/mac80211/scan.c | 3 ++-
> net/wireless/reg.c | 6 +++---
> net/wireless/util.c | 36 ++++++++++++++++++++++--------------
> net/wireless/wext-compat.c | 5 ++++-
> 8 files changed, 41 insertions(+), 25 deletions(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index bcc9f44..cfaac36 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1788,8 +1788,9 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
> /**
> * ieee80211_channel_to_frequency - convert channel number to frequency
> * @chan: channel number
> + * @band: band, necessary due to channel number overlap
> */
> -extern int ieee80211_channel_to_frequency(int chan);
> +extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);
>
> /**
> * ieee80211_frequency_to_channel - convert frequency to channel number
> diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
> index 53c7077..775fb63 100644
> --- a/net/mac80211/ibss.c
> +++ b/net/mac80211/ibss.c
> @@ -270,7 +270,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
> enum ieee80211_band band = rx_status->band;
>
> if (elems->ds_params && elems->ds_params_len == 1)
> - freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
> + freq = ieee80211_channel_to_frequency(elems->ds_params[0],
> + band);
> else
> freq = rx_status->freq;
>
> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
> index ca3af46..1430cdc 100644
> --- a/net/mac80211/mesh.c
> +++ b/net/mac80211/mesh.c
> @@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
> &elems);
>
> if (elems.ds_params && elems.ds_params_len == 1)
> - freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
> + freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
> else
> freq = rx_status->freq;
>
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index 45fbb9e..33bd6d4 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -176,7 +176,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
>
> /* check that channel matches the right operating channel */
> if (local->hw.conf.channel->center_freq !=
> - ieee80211_channel_to_frequency(hti->control_chan))
> + ieee80211_channel_to_frequency(hti->control_chan, sband->band))
> enable_ht = false;
>
> if (enable_ht) {
> @@ -429,7 +429,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
> container_of((void *)bss, struct cfg80211_bss, priv);
> struct ieee80211_channel *new_ch;
> struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> - int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
> + int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
> + cbss->channel->band);
>
> ASSERT_MGD_MTX(ifmgd);
>
> @@ -1519,7 +1520,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
> }
>
> if (elems->ds_params && elems->ds_params_len == 1)
> - freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
> + freq = ieee80211_channel_to_frequency(elems->ds_params[0],
> + rx_status->band);
> else
> freq = rx_status->freq;
>
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index fb274db..1ef73be 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
> ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
>
> if (elems.ds_params && elems.ds_params_len == 1)
> - freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
> + freq = ieee80211_channel_to_frequency(elems.ds_params[0],
> + rx_status->band);
> else
> freq = rx_status->freq;
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 37693b6..c565689 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -1801,9 +1801,9 @@ void regulatory_hint_disconnect(void)
>
> 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))
> + if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) ||
> + freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) ||
> + freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ))
> return true;
> return false;
> }
> diff --git a/net/wireless/util.c b/net/wireless/util.c
> index 7620ae2..4ed065d 100644
> --- a/net/wireless/util.c
> +++ b/net/wireless/util.c
> @@ -29,29 +29,37 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
> }
> EXPORT_SYMBOL(ieee80211_get_response_rate);
>
> -int ieee80211_channel_to_frequency(int chan)
> +int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
> {
> - if (chan < 14)
> - return 2407 + chan * 5;
> -
> - if (chan == 14)
> - return 2484;
> -
> - /* FIXME: 802.11j 17.3.8.3.2 */
> - return (chan + 1000) * 5;
> + /* see 802.11 17.3.8.3.2 and Annex J
> + * there are overlapping channel numbers in 5GHz and 2GHz bands */
> + if (band == IEEE80211_BAND_5GHZ) {
> + if (chan >= 182 && chan <= 196)
> + return 4000 + chan * 5;
> + else
> + return 5000 + chan * 5;
> + } else { /* IEEE80211_BAND_2GHZ */
> + if (chan == 14)
> + return 2484;
> + else if (chan < 14)
> + return 2407 + chan * 5;
> + else
> + return 0; /* not supported */
> + }
> }
> EXPORT_SYMBOL(ieee80211_channel_to_frequency);
>
> int ieee80211_frequency_to_channel(int freq)
> {
> + /* see 802.11 17.3.8.3.2 and Annex J */
> if (freq == 2484)
> return 14;
> -
> - if (freq < 2484)
> + else if (freq < 2484)
> return (freq - 2407) / 5;
> -
> - /* FIXME: 802.11j 17.3.8.3.2 */
> - return freq/5 - 1000;
> + else if (freq >= 4910 && freq <= 4980)
> + return (freq - 4000) / 5;
> + else
> + return (freq - 5000) / 5;
> }
> EXPORT_SYMBOL(ieee80211_frequency_to_channel);
>
> diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
> index 3e5dbd4..7f1f4ec 100644
> --- a/net/wireless/wext-compat.c
> +++ b/net/wireless/wext-compat.c
> @@ -267,9 +267,12 @@ int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq)
> * -EINVAL for impossible things.
> */
> if (freq->e == 0) {
> + enum ieee80211_band band = IEEE80211_BAND_2GHZ;
> if (freq->m < 0)
> return 0;
> - return ieee80211_channel_to_frequency(freq->m);
> + if (freq->m > 14)
> + band = IEEE80211_BAND_5GHZ;
> + return ieee80211_channel_to_frequency(freq->m, band);
> } else {
> int i, div = 1000000;
> for (i = 0; i < freq->e; i++)
>
>



2011-01-11 13:16:17

by Brian Prodoehl

[permalink] [raw]
Subject: Re: [PATCH] cfg80211: Extend channel to frequency mapping for 802.11j

On Tue, Jan 11, 2011 at 7:18 AM, Johannes Berg
<[email protected]> wrote:
> On Tue, 2011-01-11 at 18:17 +0900, Bruno Randolf wrote:
>
>> > compat-wireless-2011-01-07.orig/drivers/net/wireless/libertas/cfg.c 2011-0
>> > 1-07 15:03:59.000000000 -0500
>> > +++
>> > compat-wireless-2011-01-07/drivers/net/wireless/libertas/cfg.c ? ? ?2011-01-08
>> > 07:51:23.947290769 -0500
>> > @@ -607,7 +607,8 @@
>> > ? ? ? ? ? ? /* No channel, no luck */
>> > ? ? ? ? ? ? if (chan_no != -1) {
>> > ? ? ? ? ? ? ? ? ? ? struct wiphy *wiphy = priv->wdev->wiphy;
>> > - ? ? ? ? ? ? ? ? ? int freq = ieee80211_channel_to_frequency(chan_no);
>> > + ? ? ? ? ? ? ? ? ? int freq = ieee80211_channel_to_frequency(chan_no,
>> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? chan_no <= 14 ? IEEE80211_BAND_2GHZ :
>> IEEE80211_BAND_5GHZ);
>>
>> The whole point of having the band argument is to avoid this. We now have
>> overlapping channel numbers: channel 8 and 12 are defined in 5GHz as well as
>> in 2.4GHz (that is for 20MHz channel width, there are more for 10 and 5MHz
>> width, but we don't support that yet). The band has to come from the hardware
>> or driver configuration.
>
> I don't think libertas (or orinoco) support the frequencies that
> overlap, and they use the channel number in HW config, so it should be
> fine.
>
> johannes

That's what it looked like to me, as well, for libertas. For rt2x00,
with it's dependence on binary firmwares from Ralink, extending the
channel set seems very far from trivial. Ralink advertises compliance
with 802.11j (http://web.ralinktech.com/ralink/data/RT2800.pdf). A
year and a half ago I asked them directly what that compliance means
(4.9GHz channels? 10MHz channel width? misprint?) and didn't get a
response. A way to pull the band for rt2x00 didn't pop out at me, but
if the maintainers have suggestions, that'll be great. Also, if they
have some idea what the level of 802.11j compliance is, I'd love to
know!

-Brian