aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-15 07:42:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-15 15:05:58 -0400
commit7e9debe9789456426ec8574ead879e33da19ee57 (patch)
treed1158594e3b9ea1b54e6e24f7bf370a68e6105eb /net
parentdb2e6bd4e966a36c6b2f1921feb3537e8254415c (diff)
mac80211: disconnect when user changes channel
If we do not disconnect when a channel switch is requested, we end up eventually detection beacon loss from the AP and then disconnecting, without ever really telling the AP, so we might just as well disconnect right away. Additionally, this fixes a problem with iwlwifi where the driver will clear some internal state on channel changes like this and then get confused when we actually go clear that state from mac80211. It may look like this patch drops the no-IBSS check, but that is already handled by cfg80211 in the wext handler it provides for IBSS (cfg80211_ibss_wext_siwfreq). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c5
-rw-r--r--net/mac80211/util.c25
-rw-r--r--net/mac80211/wext.c31
4 files changed, 31 insertions, 31 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f41fe1f1430c..68eb5052179a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1101,7 +1101,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
1101u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, 1101u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1102 struct ieee802_11_elems *elems, 1102 struct ieee802_11_elems *elems,
1103 u64 filter, u32 crc); 1103 u64 filter, u32 crc);
1104int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
1105u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 1104u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1106 enum ieee80211_band band); 1105 enum ieee80211_band band);
1107 1106
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e5de9cea0034..84e59b9b493a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2223,7 +2223,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
2223 capa_mask, capa_val); 2223 capa_mask, capa_val);
2224 2224
2225 if (bss) { 2225 if (bss) {
2226 ieee80211_set_freq(sdata, bss->cbss.channel->center_freq); 2226 local->oper_channel = bss->cbss.channel;
2227 local->oper_channel_type = NL80211_CHAN_NO_HT;
2228 ieee80211_hw_config(local, 0);
2229
2227 if (!(ifmgd->flags & IEEE80211_STA_SSID_SET)) 2230 if (!(ifmgd->flags & IEEE80211_STA_SSID_SET))
2228 ieee80211_sta_set_ssid(sdata, bss->ssid, 2231 ieee80211_sta_set_ssid(sdata, bss->ssid,
2229 bss->ssid_len); 2232 bss->ssid_len);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 66ce96a69f31..915e77769312 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -774,31 +774,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
774 dev_queue_xmit(skb); 774 dev_queue_xmit(skb);
775} 775}
776 776
777int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
778{
779 int ret = -EINVAL;
780 struct ieee80211_channel *chan;
781 struct ieee80211_local *local = sdata->local;
782
783 chan = ieee80211_get_channel(local->hw.wiphy, freqMHz);
784
785 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
786 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
787 chan->flags & IEEE80211_CHAN_NO_IBSS)
788 return ret;
789 local->oper_channel = chan;
790 local->oper_channel_type = NL80211_CHAN_NO_HT;
791
792 if (local->sw_scanning || local->hw_scanning)
793 ret = 0;
794 else
795 ret = ieee80211_hw_config(
796 local, IEEE80211_CONF_CHANGE_CHANNEL);
797 }
798
799 return ret;
800}
801
802u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 777u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
803 enum ieee80211_band band) 778 enum ieee80211_band band)
804{ 779{
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index d2d81b103341..1da81f456744 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -55,6 +55,8 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
55 struct iw_freq *freq, char *extra) 55 struct iw_freq *freq, char *extra)
56{ 56{
57 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 57 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
58 struct ieee80211_local *local = sdata->local;
59 struct ieee80211_channel *chan;
58 60
59 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 61 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
60 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); 62 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
@@ -69,17 +71,38 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
69 IEEE80211_STA_AUTO_CHANNEL_SEL; 71 IEEE80211_STA_AUTO_CHANNEL_SEL;
70 return 0; 72 return 0;
71 } else 73 } else
72 return ieee80211_set_freq(sdata, 74 chan = ieee80211_get_channel(local->hw.wiphy,
73 ieee80211_channel_to_frequency(freq->m)); 75 ieee80211_channel_to_frequency(freq->m));
74 } else { 76 } else {
75 int i, div = 1000000; 77 int i, div = 1000000;
76 for (i = 0; i < freq->e; i++) 78 for (i = 0; i < freq->e; i++)
77 div /= 10; 79 div /= 10;
78 if (div > 0) 80 if (div <= 0)
79 return ieee80211_set_freq(sdata, freq->m / div);
80 else
81 return -EINVAL; 81 return -EINVAL;
82 chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div);
82 } 83 }
84
85 if (!chan)
86 return -EINVAL;
87
88 if (chan->flags & IEEE80211_CHAN_DISABLED)
89 return -EINVAL;
90
91 /*
92 * no change except maybe auto -> fixed, ignore the HT
93 * setting so you can fix a channel you're on already
94 */
95 if (local->oper_channel == chan)
96 return 0;
97
98 if (sdata->vif.type == NL80211_IFTYPE_STATION)
99 ieee80211_sta_req_auth(sdata);
100
101 local->oper_channel = chan;
102 local->oper_channel_type = NL80211_CHAN_NO_HT;
103 ieee80211_hw_config(local, 0);
104
105 return 0;
83} 106}
84 107
85 108