d80211: Make common function for frequency/channel selection
This patch creates ieee80211_set_channel and moves the channel selection
and setting code in ieee80211_ioctl_siwfreq to this function. This allows
IBSS code in ieee80211_sta.c to set the channel without using the wireless
extensions interface.
Signed-off-by: Michael Wu <[email protected]>
---
net/d80211/ieee80211_i.h | 1 +
net/d80211/ieee80211_ioctl.c | 47 ++++++++++++++++++++++--------------------
net/d80211/ieee80211_sta.c | 10 +--------
3 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 60d0a22..fa42fb5 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -660,6 +660,7 @@ void ieee80211_stop_scan(struct ieee8021
int ieee80211_set_compression(struct ieee80211_local *local,
struct net_device *dev, struct sta_info *sta);
int ieee80211_init_client(struct net_device *dev);
+int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq);
/* ieee80211_sta.c */
void ieee80211_sta_timer(unsigned long data);
void ieee80211_sta_work(struct work_struct *work);
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index c7300cb..0a1a5eb 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1794,35 +1794,18 @@ static int ieee80211_ioctl_giwmode(struc
return 0;
}
-
-int ieee80211_ioctl_siwfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *freq, char *extra)
+int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
{
- struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hw_mode *mode;
- int c, nfreq, set = 0;
-
- /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
- if (freq->e == 0)
- nfreq = -1;
- else {
- int i, div = 1000000;
- for (i = 0; i < freq->e; i++)
- div /= 10;
- if (div > 0)
- nfreq = freq->m / div;
- else
- return -EINVAL;
- }
+ int c, set = 0;
list_for_each_entry(mode, &local->modes_list, list) {
+ if (!(local->enabled_modes & (1 << mode->mode)))
+ continue;
for (c = 0; c < mode->num_channels; c++) {
struct ieee80211_channel *chan = &mode->channels[c];
if (chan->flag & IEEE80211_CHAN_W_SCAN &&
- ((freq->e == 0 && chan->chan == freq->m) ||
- (freq->e > 0 && nfreq == chan->freq)) &&
- (local->enabled_modes & (1 << mode->mode))) {
+ ((chan->chan == channel) || (chan->freq == freq))) {
/* Use next_mode as the mode preference to
* resolve non-unique channel numbers. */
if (set && mode->mode != local->next_mode)
@@ -1845,6 +1828,26 @@ int ieee80211_ioctl_siwfreq(struct net_d
return -EINVAL;
}
+static int ieee80211_ioctl_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct ieee80211_local *local = dev->ieee80211_ptr;
+
+ /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
+ if (freq->e == 0)
+ return ieee80211_set_channel(local, freq->m, -1);
+ else {
+ int i, div = 1000000;
+ for (i = 0; i < freq->e; i++)
+ div /= 10;
+ if (div > 0)
+ return ieee80211_set_channel(local, -1, freq->m / div);
+ else
+ return -EINVAL;
+ }
+}
+
static int ieee80211_ioctl_giwfreq(struct net_device *dev,
struct iw_request_info *info,
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index a883384..0b56135 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -2004,16 +2004,11 @@ static void ieee80211_sta_new_auth(struc
}
-extern int ieee80211_ioctl_siwfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *freq, char *extra);
-
static int ieee80211_sta_join_ibss(struct net_device *dev,
struct ieee80211_if_sta *ifsta,
struct ieee80211_sta_bss *bss)
{
struct ieee80211_local *local = dev->ieee80211_ptr;
- struct iw_freq rq;
int res, rates, i, j;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
@@ -2041,10 +2036,7 @@ static int ieee80211_sta_join_ibss(struc
sdata->drop_unencrypted = bss->capability &
WLAN_CAPABILITY_PRIVACY ? 1 : 0;
- memset(&rq, 0, sizeof(rq));
- rq.m = bss->freq * 100000;
- rq.e = 1;
- res = ieee80211_ioctl_siwfreq(dev, NULL, &rq, NULL);
+ res = ieee80211_set_channel(local, -1, bss->freq);
if (!(local->oper_channel->flag & IEEE80211_CHAN_W_IBSS)) {
printk(KERN_DEBUG "%s: IBSS not allowed on channel %d "
On Sat, 10 Feb 2007 12:55:17 -0500, Michael Wu wrote:
> This patch creates ieee80211_set_channel and moves the channel selection
> and setting code in ieee80211_ioctl_siwfreq to this function. This allows
> IBSS code in ieee80211_sta.c to set the channel without using the wireless
> extensions interface.
Applied to my tree, thanks for the patch!
Jiri
--
Jiri Benc
SUSE Labs