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 --- 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 "