From: Richard Farina <sidhayn@gmail.com>
To: David Kilroy <kilroyd@googlemail.com>
Cc: linux-wireless@vger.kernel.org, simon@thekelleys.org.uk,
jussi.kivilinna@mbnet.fi, acme@ghostprotocols.net,
pe1rxq@amsat.org
Subject: Re: [PATCH] wireless: Add channel/frequency conversions to ieee80211.h
Date: Tue, 23 Dec 2008 11:09:51 -0500 [thread overview]
Message-ID: <49510D4F.7060102@gmail.com> (raw)
In-Reply-To: <1230041018-13341-1-git-send-email-kilroyd@googlemail.com>
David Kilroy wrote:
> Added mappings for FHSS, DSSS and OFDM channels - with macros to point
> HR DSSS and ERP to the DSSS mappings. Currently just static inline
> functions.
>
> Use the new functions in the older fullmac drivers. This eliminates a
> number of const static buffers and removes a couple of range checks that
> are now redundant.
>
> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
> ---
>
> This has changed from the RFC as follows:
>
> - freq_to_chan conversions return the channel with the closest
> center frequency (instead of rounding down)
> - Remove a couple frequency checks which are now redundant
> - Leaving the WE exponents alone
>
> Also note this changes the frequency reported by wl3501 for channel 14.
> I've assumed this is a fix...
>
> ---
> drivers/net/wireless/airo.c | 25 ++-----
> drivers/net/wireless/atmel.c | 20 ++---
> drivers/net/wireless/orinoco/orinoco.c | 33 ++++-----
> drivers/net/wireless/rndis_wlan.c | 13 ++--
> drivers/net/wireless/wl3501_cs.c | 9 +--
> drivers/net/wireless/zd1201.c | 7 +-
> include/linux/ieee80211.h | 116 ++++++++++++++++++++++++++++++++
> 7 files changed, 155 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
> index 45f8384..35f28ee 100644
> --- a/drivers/net/wireless/airo.c
> +++ b/drivers/net/wireless/airo.c
> @@ -1070,10 +1070,6 @@ static WifiCtlHdr wifictlhdr8023 = {
> }
> };
>
> -// Frequency list (map channels to frequencies)
> -static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
> - 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
> -
> // A few details needed for WEP (Wireless Equivalent Privacy)
> #define MAX_KEY_SIZE 13 // 128 (?) bits
> #define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
> @@ -5735,16 +5731,12 @@ static int airo_set_freq(struct net_device *dev,
> int rc = -EINPROGRESS; /* Call commit handler */
>
> /* If setting by frequency, convert to a channel */
> - if((fwrq->e == 1) &&
> - (fwrq->m >= (int) 2.412e8) &&
> - (fwrq->m <= (int) 2.487e8)) {
> + if(fwrq->e == 1) {
> int f = fwrq->m / 100000;
> - int c = 0;
> - while((c < 14) && (f != frequency_list[c]))
> - c++;
> +
> /* Hack to fall through... */
> fwrq->e = 0;
> - fwrq->m = c + 1;
> + fwrq->m = ieee80211_freq_to_dsss_chan(f);
> }
> /* Setting by channel number */
> if((fwrq->m > 1000) || (fwrq->e > 0))
> @@ -5788,7 +5780,7 @@ static int airo_get_freq(struct net_device *dev,
>
> ch = le16_to_cpu(status_rid.channel);
> if((ch > 0) && (ch < 15)) {
> - fwrq->m = frequency_list[ch - 1] * 100000;
> + fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
> fwrq->e = 1;
> } else {
> fwrq->m = ch;
> @@ -6805,8 +6797,8 @@ static int airo_get_range(struct net_device *dev,
> k = 0;
> for(i = 0; i < 14; i++) {
> range->freq[k].i = i + 1; /* List index */
> - range->freq[k].m = frequency_list[i] * 100000;
> - range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
> + range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
> + range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
> }
> range->num_frequency = k;
>
> @@ -7199,10 +7191,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
> /* Add frequency */
> iwe.cmd = SIOCGIWFREQ;
> iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
> - /* iwe.u.freq.m containt the channel (starting 1), our
> - * frequency_list array start at index 0...
> - */
> - iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
> + iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000;
> iwe.u.freq.e = 1;
> current_ev = iwe_stream_add_event(info, current_ev, end_buf,
> &iwe, IW_EV_FREQ_LEN);
> diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
> index f551ec0..28dedb8 100644
> --- a/drivers/net/wireless/atmel.c
> +++ b/drivers/net/wireless/atmel.c
> @@ -2207,9 +2207,6 @@ static int atmel_get_frag(struct net_device *dev,
> return 0;
> }
>
> -static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
> - 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
> -
> static int atmel_set_freq(struct net_device *dev,
> struct iw_request_info *info,
> struct iw_freq *fwrq,
> @@ -2219,16 +2216,12 @@ static int atmel_set_freq(struct net_device *dev,
> int rc = -EINPROGRESS; /* Call commit handler */
>
> /* If setting by frequency, convert to a channel */
> - if ((fwrq->e == 1) &&
> - (fwrq->m >= (int) 241200000) &&
> - (fwrq->m <= (int) 248700000)) {
> + if (fwrq->e == 1) {
> int f = fwrq->m / 100000;
> - int c = 0;
> - while ((c < 14) && (f != frequency_list[c]))
> - c++;
> +
> /* Hack to fall through... */
> fwrq->e = 0;
> - fwrq->m = c + 1;
> + fwrq->m = ieee80211_freq_to_dsss_chan(f);
> }
> /* Setting by channel number */
> if ((fwrq->m > 1000) || (fwrq->e > 0))
> @@ -2387,8 +2380,11 @@ static int atmel_get_range(struct net_device *dev,
> if (range->num_channels != 0) {
> for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
> range->freq[k].i = i; /* List index */
> - range->freq[k].m = frequency_list[i - 1] * 100000;
> - range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
> +
> + /* Values in MHz -> * 10^5 * 10 */
> + range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) *
> + 100000);
> + range->freq[k++].e = 1;
> }
> range->num_frequency = k;
> }
> diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
> index b33e13f..bef7360 100644
> --- a/drivers/net/wireless/orinoco/orinoco.c
> +++ b/drivers/net/wireless/orinoco/orinoco.c
> @@ -178,12 +178,7 @@ static const struct ethtool_ops orinoco_ethtool_ops;
> /* Data tables */
> /********************************************************************/
>
> -/* The frequency of each channel in MHz */
> -static const long channel_frequency[] = {
> - 2412, 2417, 2422, 2427, 2432, 2437, 2442,
> - 2447, 2452, 2457, 2462, 2467, 2472, 2484
> -};
> -#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
> +#define NUM_CHANNELS 14
>
> /* This tables gives the actual meanings of the bitrate IDs returned
> * by the firmware. */
> @@ -3724,13 +3719,13 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
> return err;
> }
>
> -static long orinoco_hw_get_freq(struct orinoco_private *priv)
> +static int orinoco_hw_get_freq(struct orinoco_private *priv)
> {
>
> hermes_t *hw = &priv->hw;
> int err = 0;
> u16 channel;
> - long freq = 0;
> + int freq = 0;
> unsigned long flags;
>
> if (orinoco_lock(priv, &flags) != 0)
> @@ -3753,7 +3748,7 @@ static long orinoco_hw_get_freq(struct orinoco_private *priv)
> goto out;
>
> }
> - freq = channel_frequency[channel-1] * 100000;
> + freq = ieee80211_dsss_chan_to_freq(channel);
>
> out:
> orinoco_unlock(priv, &flags);
> @@ -3980,7 +3975,8 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
> for (i = 0; i < NUM_CHANNELS; i++) {
> if (priv->channel_mask & (1 << i)) {
> range->freq[k].i = i + 1;
> - range->freq[k].m = channel_frequency[i] * 100000;
> + range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
> + 100000);
> range->freq[k].e = 1;
> k++;
> }
> @@ -4328,16 +4324,15 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
> /* Setting by channel number */
> chan = frq->m;
> } else {
> - /* Setting by frequency - search the table */
> - int mult = 1;
> + /* Setting by frequency */
> + int denom = 1;
> int i;
>
> + /* Calculate denominator to rescale to MHz */
> for (i = 0; i < (6 - frq->e); i++)
> - mult *= 10;
> + denom *= 10;
>
> - for (i = 0; i < NUM_CHANNELS; i++)
> - if (frq->m == (channel_frequency[i] * mult))
> - chan = i+1;
> + chan = ieee80211_freq_to_dsss_chan(frq->m / denom);
> }
>
> if ( (chan < 1) || (chan > NUM_CHANNELS) ||
> @@ -4374,7 +4369,7 @@ static int orinoco_ioctl_getfreq(struct net_device *dev,
> return tmp;
> }
>
> - frq->m = tmp;
> + frq->m = tmp * 100000;
> frq->e = 1;
>
> return 0;
> @@ -5595,7 +5590,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
> current_ev = iwe_stream_add_event(info, current_ev, end_buf,
> &iwe, IW_EV_FREQ_LEN);
>
> - iwe.u.freq.m = channel_frequency[channel-1] * 100000;
> + iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
> iwe.u.freq.e = 1;
> current_ev = iwe_stream_add_event(info, current_ev, end_buf,
> &iwe, IW_EV_FREQ_LEN);
> @@ -5746,7 +5741,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
> current_ev = iwe_stream_add_event(info, current_ev, end_buf,
> &iwe, IW_EV_FREQ_LEN);
>
> - iwe.u.freq.m = channel_frequency[channel-1] * 100000;
> + iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
> iwe.u.freq.e = 1;
> current_ev = iwe_stream_add_event(info, current_ev, end_buf,
> &iwe, IW_EV_FREQ_LEN);
> diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
> index ed5785a..78a3ba8 100644
> --- a/drivers/net/wireless/rndis_wlan.c
> +++ b/drivers/net/wireless/rndis_wlan.c
> @@ -369,9 +369,6 @@ struct rndis_wext_private {
> };
>
>
> -static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
> - 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
> -
> static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
>
> static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
> @@ -640,8 +637,8 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
> static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
> {
> if (freq->m < 1000 && freq->e == 0) {
> - if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan))
> - *dsconfig = freq_chan[freq->m - 1] * 1000;
> + if (freq->m >= 1 && freq->m <= 14)
> + *dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000;
> else
> return -1;
> } else {
> @@ -1178,11 +1175,11 @@ static int rndis_iw_get_range(struct net_device *dev,
> range->throughput = 11 * 1000 * 1000 / 2;
> }
>
> - range->num_channels = ARRAY_SIZE(freq_chan);
> + range->num_channels = 14;
>
> - for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) {
> + for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
> range->freq[i].i = i + 1;
> - range->freq[i].m = freq_chan[i] * 100000;
> + range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
> range->freq[i].e = 1;
> }
> range->num_frequency = i;
> diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
> index 68789c6..5e41756 100644
> --- a/drivers/net/wireless/wl3501_cs.c
> +++ b/drivers/net/wireless/wl3501_cs.c
> @@ -44,6 +44,7 @@
> #include <linux/slab.h>
> #include <linux/string.h>
> #include <linux/wireless.h>
> +#include <linux/ieee80211.h>
>
> #include <net/iw_handler.h>
>
> @@ -111,12 +112,6 @@ static void wl3501_release(struct pcmcia_device *link);
> */
> static dev_info_t wl3501_dev_info = "wl3501_cs";
>
> -static int wl3501_chan2freq[] = {
> - [0] = 2412, [1] = 2417, [2] = 2422, [3] = 2427, [4] = 2432,
> - [5] = 2437, [6] = 2442, [7] = 2447, [8] = 2452, [9] = 2457,
> - [10] = 2462, [11] = 2467, [12] = 2472, [13] = 2477,
> -};
> -
> static const struct {
> int reg_domain;
> int min, max, deflt;
> @@ -1512,7 +1507,7 @@ static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info,
> {
> struct wl3501_card *this = netdev_priv(dev);
>
> - wrqu->freq.m = wl3501_chan2freq[this->chan - 1] * 100000;
> + wrqu->freq.m = ieee80211_dsss_chan_to_freq(this->chan) * 100000;
> wrqu->freq.e = 1;
> return 0;
> }
> diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
> index 45a5747..59e00eb 100644
> --- a/drivers/net/wireless/zd1201.c
> +++ b/drivers/net/wireless/zd1201.c
> @@ -921,10 +921,9 @@ static int zd1201_set_freq(struct net_device *dev,
> if (freq->e == 0)
> channel = freq->m;
> else {
> - if (freq->m >= 2482)
> - channel = 14;
> - if (freq->m >= 2407)
> - channel = (freq->m-2407)/5;
> + channel = ieee80211_freq_to_dsss_chan(freq->m);
> + if (channel < 0)
> + channel = 0;
> }
>
> err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel);
> diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
> index c4e6ca1..cade255 100644
> --- a/include/linux/ieee80211.h
> +++ b/include/linux/ieee80211.h
> @@ -1185,4 +1185,120 @@ static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)
> return hdr->addr1;
> }
>
> +/**
> + * ieee80211_fhss_chan_to_freq - get channel frequency
> + * @channel: the FHSS channel
> + *
> + * Convert IEEE802.11 FHSS channel to frequency (MHz)
> + * Ref IEEE 802.11-2007 section 14.6
> + */
> +static inline int ieee80211_fhss_chan_to_freq(int channel)
> +{
> + if ((channel > 1) && (channel < 96))
> + return channel + 2400;
> + else
> + return -1;
> +}
> +
> +/**
> + * ieee80211_freq_to_fhss_chan - get channel
> + * @freq: the channels frequency
> + *
> + * Convert frequency (MHz) to IEEE802.11 FHSS channel
> + * Ref IEEE 802.11-2007 section 14.6
> + */
> +static inline int ieee80211_freq_to_fhss_chan(int freq)
> +{
> + if ((freq > 2401) && (freq < 2496))
> + return freq - 2400;
> + else
> + return -1;
> +}
> +
> +/**
> + * ieee80211_dsss_chan_to_freq - get channel center frequency
> + * @channel: the DSSS channel
> + *
> + * Convert IEEE802.11 DSSS channel to the center frequency (MHz).
> + * Ref IEEE 802.11-2007 section 15.6
> + */
> +static inline int ieee80211_dsss_chan_to_freq(int channel)
> +{
> + if ((channel > 0) && (channel < 14))
> + return 2407 + (channel * 5);
> + else if (channel == 14)
> + return 2484;
> + else
> + return -1;
> +}
> +
> +/**
> + * ieee80211_freq_to_dsss_chan - get channel
> + * @freq: the frequency
> + *
> + * Convert frequency (MHz) to IEEE802.11 DSSS channel
> + * Ref IEEE 802.11-2007 section 15.6
> + *
> + * This routine selects the channel with the closest center frequency.
> + */
> +static inline int ieee80211_freq_to_dsss_chan(int freq)
> +{
> + if ((freq >= 2410) && (freq < 2475))
> + return (freq - 2405) / 5;
> + else if ((freq >= 2482) && (freq < 2487))
> + return 14;
> + else
> + return -1;
> +}
> +
> +/* Convert IEEE802.11 HR DSSS channel to frequency (MHz) and back
> + * Ref IEEE 802.11-2007 section 18.4.6.2
> + *
> + * The channels and frequencies are the same as those defined for DSSS
> + */
> +#define ieee80211_hr_chan_to_freq(chan) ieee80211_dsss_chan_to_freq(chan)
> +#define ieee80211_freq_to_hr_chan(freq) ieee80211_freq_to_dsss_chan(freq)
> +
> +/* Convert IEEE802.11 ERP channel to frequency (MHz) and back
> + * Ref IEEE 802.11-2007 section 19.4.2
> + */
> +#define ieee80211_erp_chan_to_freq(chan) ieee80211_hr_chan_to_freq(chan)
> +#define ieee80211_freq_to_erp_chan(freq) ieee80211_freq_to_hr_chan(freq)
> +
> +/**
> + * ieee80211_ofdm_chan_to_freq - get channel center frequency
> + * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz
> + * @channel: the OFDM channel
> + *
> + * Convert IEEE802.11 OFDM channel to center frequency (MHz)
> + * Ref IEEE 802.11-2007 section 17.3.8.3.2
> + */
> +static inline int ieee80211_ofdm_chan_to_freq(int s_freq, int channel)
> +{
> + if ((channel > 0) && (channel <= 200) &&
> + (s_freq >= 4000))
> + return s_freq + (channel * 5);
> + else
> + return -1;
> +}
>
Any desire to make 184-196 work? These are the 4.9 GHz channels.
> +
> +/**
> + * ieee80211_freq_to_ofdm_channel - get channel
> + * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz
> + * @freq: the frequency
> + *
> + * Convert frequency (MHz) to IEEE802.11 OFDM channel
> + * Ref IEEE 802.11-2007 section 17.3.8.3.2
> + *
> + * This routine selects the channel with the closest center frequency.
> + */
> +static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq)
> +{
> + if ((freq > (s_freq + 2)) && (freq <= (s_freq + 1202)) &&
> + (s_freq >= 4000))
> + return (freq + 2 - s_freq) / 5;
> + else
> + return -1;
> +}
> +
>
Same as above.
> #endif /* LINUX_IEEE80211_H */
>
I checked this all out pretty specifically, seems to work well. As if
anyone cares but:
ACKED-By: Rick Farina
next prev parent reply other threads:[~2008-12-23 16:10 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-23 14:03 [PATCH] wireless: Add channel/frequency conversions to ieee80211.h David Kilroy
2008-12-23 14:11 ` Arnaldo Carvalho de Melo
2008-12-23 16:09 ` Richard Farina [this message]
2008-12-23 20:22 ` Dave
2008-12-23 22:18 ` Richard Farina
2008-12-23 22:47 ` Dave
2008-12-23 20:30 ` Jeroen Vreeken
2008-12-24 21:57 ` Jussi Kivilinna
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49510D4F.7060102@gmail.com \
--to=sidhayn@gmail.com \
--cc=acme@ghostprotocols.net \
--cc=jussi.kivilinna@mbnet.fi \
--cc=kilroyd@googlemail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=pe1rxq@amsat.org \
--cc=simon@thekelleys.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).