aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-04-25 19:36:46 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-25 19:36:46 -0400
commit495a1b4eff1a216a3ea171ac137f1807e6555f52 (patch)
tree72d059d6d66fac6a74df33bac2eb40dcd0ea0732 /net
parentad8affd972a705a38e769859c50ee8e749b631da (diff)
parentd3feaf5ad12259927039a675cfb25dc342b403ab (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts: net/mac80211/pm.c
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/Kconfig16
-rw-r--r--net/mac80211/cfg.c59
-rw-r--r--net/mac80211/debugfs.c8
-rw-r--r--net/mac80211/event.c17
-rw-r--r--net/mac80211/ht.c84
-rw-r--r--net/mac80211/ibss.c347
-rw-r--r--net/mac80211/ieee80211_i.h85
-rw-r--r--net/mac80211/iface.c16
-rw-r--r--net/mac80211/main.c122
-rw-r--r--net/mac80211/mlme.c445
-rw-r--r--net/mac80211/pm.c121
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/scan.c28
-rw-r--r--net/mac80211/spectmgmt.c2
-rw-r--r--net/mac80211/sta_info.c71
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/tx.c35
-rw-r--r--net/mac80211/util.c240
-rw-r--r--net/mac80211/wext.c270
-rw-r--r--net/mac80211/wpa.c2
-rw-r--r--net/rfkill/rfkill-input.c69
-rw-r--r--net/rfkill/rfkill.c54
-rw-r--r--net/wimax/op-rfkill.c9
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/core.c27
-rw-r--r--net/wireless/core.h15
-rw-r--r--net/wireless/ibss.c369
-rw-r--r--net/wireless/mlme.c50
-rw-r--r--net/wireless/nl80211.c639
-rw-r--r--net/wireless/nl80211.h32
-rw-r--r--net/wireless/reg.c35
-rw-r--r--net/wireless/scan.c53
-rw-r--r--net/wireless/util.c6
-rw-r--r--net/wireless/wext-compat.c236
34 files changed, 2383 insertions, 1186 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index ecc3faf9f11a..9cbf545e95a2 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -11,6 +11,22 @@ config MAC80211
11 This option enables the hardware independent IEEE 802.11 11 This option enables the hardware independent IEEE 802.11
12 networking stack. 12 networking stack.
13 13
14config MAC80211_DEFAULT_PS
15 bool "enable powersave by default"
16 depends on MAC80211
17 default y
18 help
19 This option enables powersave mode by default.
20
21 If this causes your applications to misbehave you should fix your
22 applications instead -- they need to register their network
23 latency requirement, see Documentation/power/pm_qos_interface.txt.
24
25config MAC80211_DEFAULT_PS_VALUE
26 int
27 default 1 if MAC80211_DEFAULT_PS
28 default 0
29
14menu "Rate control algorithm selection" 30menu "Rate control algorithm selection"
15 depends on MAC80211 != n 31 depends on MAC80211 != n
16 32
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e677b751d468..5e1c230744b5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1167,7 +1167,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
1167 1167
1168 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1168 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1169 sdata->vif.type != NL80211_IFTYPE_ADHOC && 1169 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1170 sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 1170 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
1171 (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
1171 return -EOPNOTSUPP; 1172 return -EOPNOTSUPP;
1172 1173
1173 return ieee80211_request_scan(sdata, req); 1174 return ieee80211_request_scan(sdata, req);
@@ -1267,25 +1268,62 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1267static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, 1268static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
1268 struct cfg80211_deauth_request *req) 1269 struct cfg80211_deauth_request *req)
1269{ 1270{
1270 struct ieee80211_sub_if_data *sdata; 1271 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1271
1272 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1273 1272
1274 /* TODO: req->ie */ 1273 /* TODO: req->ie, req->peer_addr */
1275 return ieee80211_sta_deauthenticate(sdata, req->reason_code); 1274 return ieee80211_sta_deauthenticate(sdata, req->reason_code);
1276} 1275}
1277 1276
1278static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, 1277static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1279 struct cfg80211_disassoc_request *req) 1278 struct cfg80211_disassoc_request *req)
1280{ 1279{
1281 struct ieee80211_sub_if_data *sdata; 1280 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1282
1283 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1284 1281
1285 /* TODO: req->ie */ 1282 /* TODO: req->ie, req->peer_addr */
1286 return ieee80211_sta_disassociate(sdata, req->reason_code); 1283 return ieee80211_sta_disassociate(sdata, req->reason_code);
1287} 1284}
1288 1285
1286static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1287 struct cfg80211_ibss_params *params)
1288{
1289 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1290
1291 return ieee80211_ibss_join(sdata, params);
1292}
1293
1294static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1295{
1296 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1297
1298 return ieee80211_ibss_leave(sdata);
1299}
1300
1301static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1302{
1303 struct ieee80211_local *local = wiphy_priv(wiphy);
1304
1305 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1306 int err;
1307
1308 if (local->ops->set_rts_threshold) {
1309 err = local->ops->set_rts_threshold(
1310 local_to_hw(local), wiphy->rts_threshold);
1311 if (err)
1312 return err;
1313 }
1314 }
1315
1316 if (changed & WIPHY_PARAM_RETRY_SHORT)
1317 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1318 if (changed & WIPHY_PARAM_RETRY_LONG)
1319 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
1320 if (changed &
1321 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1322 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
1323
1324 return 0;
1325}
1326
1289struct cfg80211_ops mac80211_config_ops = { 1327struct cfg80211_ops mac80211_config_ops = {
1290 .add_virtual_intf = ieee80211_add_iface, 1328 .add_virtual_intf = ieee80211_add_iface,
1291 .del_virtual_intf = ieee80211_del_iface, 1329 .del_virtual_intf = ieee80211_del_iface,
@@ -1322,4 +1360,7 @@ struct cfg80211_ops mac80211_config_ops = {
1322 .assoc = ieee80211_assoc, 1360 .assoc = ieee80211_assoc,
1323 .deauth = ieee80211_deauth, 1361 .deauth = ieee80211_deauth,
1324 .disassoc = ieee80211_disassoc, 1362 .disassoc = ieee80211_disassoc,
1363 .join_ibss = ieee80211_join_ibss,
1364 .leave_ibss = ieee80211_leave_ibss,
1365 .set_wiphy_params = ieee80211_set_wiphy_params,
1325}; 1366};
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 210b9b6fecd2..5001328be46b 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -52,13 +52,13 @@ static const struct file_operations name## _ops = { \
52DEBUGFS_READONLY_FILE(frequency, 20, "%d", 52DEBUGFS_READONLY_FILE(frequency, 20, "%d",
53 local->hw.conf.channel->center_freq); 53 local->hw.conf.channel->center_freq);
54DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", 54DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
55 local->rts_threshold); 55 local->hw.wiphy->rts_threshold);
56DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", 56DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
57 local->fragmentation_threshold); 57 local->hw.wiphy->frag_threshold);
58DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", 58DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
59 local->hw.conf.short_frame_max_tx_count); 59 local->hw.wiphy->retry_short);
60DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", 60DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
61 local->hw.conf.long_frame_max_tx_count); 61 local->hw.wiphy->retry_long);
62DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", 62DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
63 local->total_ps_buffered); 63 local->total_ps_buffered);
64DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", 64DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x",
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index 0d95561c0ee0..f288d01a6344 100644
--- a/net/mac80211/event.c
+++ b/net/mac80211/event.c
@@ -12,12 +12,12 @@
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13 13
14/* 14/*
15 * indicate a failed Michael MIC to userspace; the passed packet 15 * Indicate a failed Michael MIC to userspace. If the caller knows the TSC of
16 * (in the variable hdr) must be long enough to extract the TKIP 16 * the frame that generated the MIC failure (i.e., if it was provided by the
17 * fields like TSC 17 * driver or is still in the frame), it should provide that information.
18 */ 18 */
19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
20 struct ieee80211_hdr *hdr) 20 struct ieee80211_hdr *hdr, const u8 *tsc)
21{ 21{
22 union iwreq_data wrqu; 22 union iwreq_data wrqu;
23 char *buf = kmalloc(128, GFP_ATOMIC); 23 char *buf = kmalloc(128, GFP_ATOMIC);
@@ -34,8 +34,9 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
34 kfree(buf); 34 kfree(buf);
35 } 35 }
36 36
37 /* 37 cfg80211_michael_mic_failure(sdata->dev, hdr->addr2,
38 * TODO: re-add support for sending MIC failure indication 38 (hdr->addr1[0] & 0x01) ?
39 * with all info via nl80211 39 NL80211_KEYTYPE_GROUP :
40 */ 40 NL80211_KEYTYPE_PAIRWISE,
41 keyidx, tsc);
41} 42}
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4e3c72f20de7..0891bfb06996 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <net/wireless.h>
18#include <net/mac80211.h> 17#include <net/mac80211.h>
19#include "ieee80211_i.h" 18#include "ieee80211_i.h"
20#include "rate.h" 19#include "rate.h"
@@ -83,89 +82,6 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
83 ht_cap->mcs.rx_mask[32/8] |= 1; 82 ht_cap->mcs.rx_mask[32/8] |= 1;
84} 83}
85 84
86/*
87 * ieee80211_enable_ht should be called only after the operating band
88 * has been determined as ht configuration depends on the hw's
89 * HT abilities for a specific band.
90 */
91u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
92 struct ieee80211_ht_info *hti,
93 u16 ap_ht_cap_flags)
94{
95 struct ieee80211_local *local = sdata->local;
96 struct ieee80211_supported_band *sband;
97 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
98 struct ieee80211_bss_ht_conf ht;
99 struct sta_info *sta;
100 u32 changed = 0;
101 bool enable_ht = true, ht_changed;
102 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
103
104 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
105
106 memset(&ht, 0, sizeof(ht));
107
108 /* HT is not supported */
109 if (!sband->ht_cap.ht_supported)
110 enable_ht = false;
111
112 /* check that channel matches the right operating channel */
113 if (local->hw.conf.channel->center_freq !=
114 ieee80211_channel_to_frequency(hti->control_chan))
115 enable_ht = false;
116
117 if (enable_ht) {
118 channel_type = NL80211_CHAN_HT20;
119
120 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
121 (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
122 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
123 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
124 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
125 channel_type = NL80211_CHAN_HT40PLUS;
126 break;
127 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
128 channel_type = NL80211_CHAN_HT40MINUS;
129 break;
130 }
131 }
132 }
133
134 ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
135 channel_type != local->hw.conf.channel_type;
136
137 local->oper_channel_type = channel_type;
138
139 if (ht_changed) {
140 /* channel_type change automatically detected */
141 ieee80211_hw_config(local, 0);
142
143 rcu_read_lock();
144
145 sta = sta_info_get(local, ifmgd->bssid);
146 if (sta)
147 rate_control_rate_update(local, sband, sta,
148 IEEE80211_RC_HT_CHANGED);
149
150 rcu_read_unlock();
151
152 }
153
154 /* disable HT */
155 if (!enable_ht)
156 return 0;
157
158 ht.operation_mode = le16_to_cpu(hti->operation_mode);
159
160 /* if bss configuration changed store the new one */
161 if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
162 changed |= BSS_CHANGED_HT;
163 sdata->vif.bss_conf.ht = ht;
164 }
165
166 return changed;
167}
168
169void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) 85void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
170{ 86{
171 int i; 87 int i;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3201e1f96365..6030e003180c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -59,74 +59,59 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
59 sdata->u.ibss.bssid, 0); 59 sdata->u.ibss.bssid, 0);
60} 60}
61 61
62static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 62static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
63 const u8 *bssid, const int beacon_int, 63 const u8 *bssid, const int beacon_int,
64 const int freq, 64 struct ieee80211_channel *chan,
65 const size_t supp_rates_len, 65 const size_t supp_rates_len,
66 const u8 *supp_rates, 66 const u8 *supp_rates,
67 const u16 capability, u64 tsf) 67 const u16 capability, u64 tsf)
68{ 68{
69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
70 struct ieee80211_local *local = sdata->local; 70 struct ieee80211_local *local = sdata->local;
71 int res = 0, rates, i, j; 71 int rates, i, j;
72 struct sk_buff *skb; 72 struct sk_buff *skb;
73 struct ieee80211_mgmt *mgmt; 73 struct ieee80211_mgmt *mgmt;
74 u8 *pos; 74 u8 *pos;
75 struct ieee80211_supported_band *sband; 75 struct ieee80211_supported_band *sband;
76 union iwreq_data wrqu;
77 76
78 if (local->ops->reset_tsf) { 77 if (local->ops->reset_tsf) {
79 /* Reset own TSF to allow time synchronization work. */ 78 /* Reset own TSF to allow time synchronization work. */
80 local->ops->reset_tsf(local_to_hw(local)); 79 local->ops->reset_tsf(local_to_hw(local));
81 } 80 }
82 81
83 if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) && 82 skb = ifibss->skb;
84 memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0) 83 rcu_assign_pointer(ifibss->presp, NULL);
85 return res; 84 synchronize_rcu();
85 skb->data = skb->head;
86 skb->len = 0;
87 skb_reset_tail_pointer(skb);
88 skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
86 89
87 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 90 if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
88 if (!skb) { 91 sta_info_flush(sdata->local, sdata);
89 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
90 "response\n", sdata->dev->name);
91 return -ENOMEM;
92 }
93
94 if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) {
95 /* Remove possible STA entries from other IBSS networks. */
96 sta_info_flush_delayed(sdata);
97 }
98 92
99 memcpy(ifibss->bssid, bssid, ETH_ALEN); 93 memcpy(ifibss->bssid, bssid, ETH_ALEN);
100 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
101 if (res)
102 return res;
103 94
104 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10; 95 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
105 96
106 sdata->drop_unencrypted = capability & 97 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
107 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
108
109 res = ieee80211_set_freq(sdata, freq);
110 98
111 if (res) 99 ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
112 return res;
113 100
114 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 101 local->oper_channel = chan;
102 local->oper_channel_type = NL80211_CHAN_NO_HT;
103 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
104 sband = local->hw.wiphy->bands[chan->band];
115 105
116 /* Build IBSS probe response */ 106 /* Build IBSS probe response */
117 107 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
118 skb_reserve(skb, local->hw.extra_tx_headroom);
119
120 mgmt = (struct ieee80211_mgmt *)
121 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
122 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 108 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
123 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 109 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
124 IEEE80211_STYPE_PROBE_RESP); 110 IEEE80211_STYPE_PROBE_RESP);
125 memset(mgmt->da, 0xff, ETH_ALEN); 111 memset(mgmt->da, 0xff, ETH_ALEN);
126 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 112 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
127 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 113 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
128 mgmt->u.beacon.beacon_int = 114 mgmt->u.beacon.beacon_int = cpu_to_le16(local->hw.conf.beacon_int);
129 cpu_to_le16(local->hw.conf.beacon_int);
130 mgmt->u.beacon.timestamp = cpu_to_le64(tsf); 115 mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
131 mgmt->u.beacon.capab_info = cpu_to_le16(capability); 116 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
132 117
@@ -147,7 +132,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
147 pos = skb_put(skb, 2 + 1); 132 pos = skb_put(skb, 2 + 1);
148 *pos++ = WLAN_EID_DS_PARAMS; 133 *pos++ = WLAN_EID_DS_PARAMS;
149 *pos++ = 1; 134 *pos++ = 1;
150 *pos++ = ieee80211_frequency_to_channel(freq); 135 *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
151 } 136 }
152 137
153 pos = skb_put(skb, 2 + 2); 138 pos = skb_put(skb, 2 + 2);
@@ -165,12 +150,15 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
165 memcpy(pos, &supp_rates[8], rates); 150 memcpy(pos, &supp_rates[8], rates);
166 } 151 }
167 152
168 ifibss->probe_resp = skb; 153 if (ifibss->ie_len)
154 memcpy(skb_put(skb, ifibss->ie_len),
155 ifibss->ie, ifibss->ie_len);
156
157 rcu_assign_pointer(ifibss->presp, skb);
169 158
170 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 159 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
171 IEEE80211_IFCC_BEACON_ENABLED); 160 IEEE80211_IFCC_BEACON_ENABLED);
172 161
173
174 rates = 0; 162 rates = 0;
175 for (i = 0; i < supp_rates_len; i++) { 163 for (i = 0; i < supp_rates_len; i++) {
176 int bitrate = (supp_rates[i] & 0x7f) * 5; 164 int bitrate = (supp_rates[i] & 0x7f) * 5;
@@ -181,27 +169,24 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
181 169
182 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates); 170 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
183 171
184 ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET;
185 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 172 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
186 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 173 mod_timer(&ifibss->timer,
174 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
187 175
188 memset(&wrqu, 0, sizeof(wrqu)); 176 cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
189 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); 177 mgmt, skb->len, 0, GFP_KERNEL);
190 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); 178 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
191
192 return res;
193} 179}
194 180
195static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 181static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
196 struct ieee80211_bss *bss) 182 struct ieee80211_bss *bss)
197{ 183{
198 return __ieee80211_sta_join_ibss(sdata, 184 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
199 bss->cbss.bssid, 185 bss->cbss.beacon_interval,
200 bss->cbss.beacon_interval, 186 bss->cbss.channel,
201 bss->cbss.channel->center_freq, 187 bss->supp_rates_len, bss->supp_rates,
202 bss->supp_rates_len, bss->supp_rates, 188 bss->cbss.capability,
203 bss->cbss.capability, 189 bss->cbss.tsf);
204 bss->cbss.tsf);
205} 190}
206 191
207static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 192static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -277,7 +262,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
277 goto put_bss; 262 goto put_bss;
278 263
279 /* we use a fixed BSSID */ 264 /* we use a fixed BSSID */
280 if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET) 265 if (sdata->u.ibss.bssid)
281 goto put_bss; 266 goto put_bss;
282 267
283 /* not an IBSS */ 268 /* not an IBSS */
@@ -369,13 +354,14 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
369 struct sta_info *sta; 354 struct sta_info *sta;
370 int band = local->hw.conf.channel->band; 355 int band = local->hw.conf.channel->band;
371 356
372 /* TODO: Could consider removing the least recently used entry and 357 /*
373 * allow new one to be added. */ 358 * XXX: Consider removing the least recently used entry and
359 * allow new one to be added.
360 */
374 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { 361 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
375 if (net_ratelimit()) { 362 if (net_ratelimit())
376 printk(KERN_DEBUG "%s: No room for a new IBSS STA " 363 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
377 "entry %pM\n", sdata->dev->name, addr); 364 sdata->dev->name, addr);
378 }
379 return NULL; 365 return NULL;
380 } 366 }
381 367
@@ -432,14 +418,15 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
432{ 418{
433 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 419 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
434 420
435 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 421 mod_timer(&ifibss->timer,
422 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
436 423
437 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); 424 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
425
438 if (ieee80211_sta_active_ibss(sdata)) 426 if (ieee80211_sta_active_ibss(sdata))
439 return; 427 return;
440 428
441 if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) && 429 if (ifibss->fixed_channel)
442 (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL)))
443 return; 430 return;
444 431
445 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 432 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
@@ -455,7 +442,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
455 ieee80211_request_scan(sdata, &sdata->local->int_scan_req); 442 ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
456} 443}
457 444
458static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 445static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
459{ 446{
460 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 447 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
461 struct ieee80211_local *local = sdata->local; 448 struct ieee80211_local *local = sdata->local;
@@ -466,7 +453,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
466 u16 capability; 453 u16 capability;
467 int i; 454 int i;
468 455
469 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) { 456 if (ifibss->fixed_bssid) {
470 memcpy(bssid, ifibss->bssid, ETH_ALEN); 457 memcpy(bssid, ifibss->bssid, ETH_ALEN);
471 } else { 458 } else {
472 /* Generate random, not broadcast, locally administered BSSID. Mix in 459 /* Generate random, not broadcast, locally administered BSSID. Mix in
@@ -482,7 +469,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
482 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", 469 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
483 sdata->dev->name, bssid); 470 sdata->dev->name, bssid);
484 471
485 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 472 sband = local->hw.wiphy->bands[ifibss->channel->band];
486 473
487 if (local->hw.conf.beacon_int == 0) 474 if (local->hw.conf.beacon_int == 0)
488 local->hw.conf.beacon_int = 100; 475 local->hw.conf.beacon_int = 100;
@@ -500,24 +487,20 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
500 *pos++ = (u8) (rate / 5); 487 *pos++ = (u8) (rate / 5);
501 } 488 }
502 489
503 return __ieee80211_sta_join_ibss(sdata, 490 __ieee80211_sta_join_ibss(sdata, bssid, local->hw.conf.beacon_int,
504 bssid, local->hw.conf.beacon_int, 491 ifibss->channel, sband->n_bitrates,
505 local->hw.conf.channel->center_freq, 492 supp_rates, capability, 0);
506 sband->n_bitrates, supp_rates,
507 capability, 0);
508} 493}
509 494
510static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) 495static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
511{ 496{
512 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 497 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
513 struct ieee80211_local *local = sdata->local; 498 struct ieee80211_local *local = sdata->local;
514 struct ieee80211_bss *bss; 499 struct ieee80211_bss *bss;
500 struct ieee80211_channel *chan = NULL;
515 const u8 *bssid = NULL; 501 const u8 *bssid = NULL;
516 int active_ibss; 502 int active_ibss;
517 503
518 if (ifibss->ssid_len == 0)
519 return -EINVAL;
520
521 active_ibss = ieee80211_sta_active_ibss(sdata); 504 active_ibss = ieee80211_sta_active_ibss(sdata);
522#ifdef CONFIG_MAC80211_IBSS_DEBUG 505#ifdef CONFIG_MAC80211_IBSS_DEBUG
523 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 506 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
@@ -525,11 +508,15 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
525#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 508#endif /* CONFIG_MAC80211_IBSS_DEBUG */
526 509
527 if (active_ibss) 510 if (active_ibss)
528 return 0; 511 return;
529 512
530 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) 513 if (ifibss->fixed_bssid)
514 bssid = ifibss->bssid;
515 if (ifibss->fixed_channel)
516 chan = ifibss->channel;
517 if (!is_zero_ether_addr(ifibss->bssid))
531 bssid = ifibss->bssid; 518 bssid = ifibss->bssid;
532 bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid, 519 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
533 ifibss->ssid, ifibss->ssid_len, 520 ifibss->ssid, ifibss->ssid_len,
534 WLAN_CAPABILITY_IBSS, 521 WLAN_CAPABILITY_IBSS,
535 WLAN_CAPABILITY_IBSS); 522 WLAN_CAPABILITY_IBSS);
@@ -540,18 +527,14 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
540 "%pM\n", bss->cbss.bssid, ifibss->bssid); 527 "%pM\n", bss->cbss.bssid, ifibss->bssid);
541#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 528#endif /* CONFIG_MAC80211_IBSS_DEBUG */
542 529
543 if (bss && 530 if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
544 (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) ||
545 memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) {
546 int ret;
547
548 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 531 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
549 " based on configured SSID\n", 532 " based on configured SSID\n",
550 sdata->dev->name, bss->cbss.bssid); 533 sdata->dev->name, bss->cbss.bssid);
551 534
552 ret = ieee80211_sta_join_ibss(sdata, bss); 535 ieee80211_sta_join_ibss(sdata, bss);
553 ieee80211_rx_bss_put(local, bss); 536 ieee80211_rx_bss_put(local, bss);
554 return ret; 537 return;
555 } else if (bss) 538 } else if (bss)
556 ieee80211_rx_bss_put(local, bss); 539 ieee80211_rx_bss_put(local, bss);
557 540
@@ -562,29 +545,31 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
562 /* Selected IBSS not found in current scan results - try to scan */ 545 /* Selected IBSS not found in current scan results - try to scan */
563 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED && 546 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
564 !ieee80211_sta_active_ibss(sdata)) { 547 !ieee80211_sta_active_ibss(sdata)) {
565 mod_timer(&ifibss->timer, jiffies + 548 mod_timer(&ifibss->timer,
566 IEEE80211_IBSS_MERGE_INTERVAL); 549 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
567 } else if (time_after(jiffies, local->last_scan_completed + 550 } else if (time_after(jiffies, ifibss->last_scan_completed +
568 IEEE80211_SCAN_INTERVAL)) { 551 IEEE80211_SCAN_INTERVAL)) {
569 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 552 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
570 "join\n", sdata->dev->name); 553 "join\n", sdata->dev->name);
571 554
572 /* XXX maybe racy? */ 555 /* XXX maybe racy? */
573 if (local->scan_req) 556 if (local->scan_req)
574 return -EBUSY; 557 return;
575 558
576 memcpy(local->int_scan_req.ssids[0].ssid, 559 memcpy(local->int_scan_req.ssids[0].ssid,
577 ifibss->ssid, IEEE80211_MAX_SSID_LEN); 560 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
578 local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len; 561 local->int_scan_req.ssids[0].ssid_len =
579 return ieee80211_request_scan(sdata, &local->int_scan_req); 562 ifibss->ssid_len;
563 ieee80211_request_scan(sdata, &local->int_scan_req);
580 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) { 564 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
581 int interval = IEEE80211_SCAN_INTERVAL; 565 int interval = IEEE80211_SCAN_INTERVAL;
582 566
583 if (time_after(jiffies, ifibss->ibss_join_req + 567 if (time_after(jiffies, ifibss->ibss_join_req +
584 IEEE80211_IBSS_JOIN_TIMEOUT)) { 568 IEEE80211_IBSS_JOIN_TIMEOUT)) {
585 if (!(local->oper_channel->flags & 569 if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
586 IEEE80211_CHAN_NO_IBSS)) 570 ieee80211_sta_create_ibss(sdata);
587 return ieee80211_sta_create_ibss(sdata); 571 return;
572 }
588 printk(KERN_DEBUG "%s: IBSS not allowed on" 573 printk(KERN_DEBUG "%s: IBSS not allowed on"
589 " %d MHz\n", sdata->dev->name, 574 " %d MHz\n", sdata->dev->name,
590 local->hw.conf.channel->center_freq); 575 local->hw.conf.channel->center_freq);
@@ -595,11 +580,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
595 } 580 }
596 581
597 ifibss->state = IEEE80211_IBSS_MLME_SEARCH; 582 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
598 mod_timer(&ifibss->timer, jiffies + interval); 583 mod_timer(&ifibss->timer,
599 return 0; 584 round_jiffies(jiffies + interval));
600 } 585 }
601
602 return 0;
603} 586}
604 587
605static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, 588static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -614,7 +597,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
614 u8 *pos, *end; 597 u8 *pos, *end;
615 598
616 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 599 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
617 len < 24 + 2 || !ifibss->probe_resp) 600 len < 24 + 2 || !ifibss->presp)
618 return; 601 return;
619 602
620 if (local->ops->tx_last_beacon) 603 if (local->ops->tx_last_beacon)
@@ -649,13 +632,13 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
649 } 632 }
650 if (pos[1] != 0 && 633 if (pos[1] != 0 &&
651 (pos[1] != ifibss->ssid_len || 634 (pos[1] != ifibss->ssid_len ||
652 memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) { 635 !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
653 /* Ignore ProbeReq for foreign SSID */ 636 /* Ignore ProbeReq for foreign SSID */
654 return; 637 return;
655 } 638 }
656 639
657 /* Reply with ProbeResp */ 640 /* Reply with ProbeResp */
658 skb = skb_copy(ifibss->probe_resp, GFP_KERNEL); 641 skb = skb_copy(ifibss->presp, GFP_KERNEL);
659 if (!skb) 642 if (!skb)
660 return; 643 return;
661 644
@@ -794,89 +777,21 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
794 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 777 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
795 (unsigned long) sdata); 778 (unsigned long) sdata);
796 skb_queue_head_init(&ifibss->skb_queue); 779 skb_queue_head_init(&ifibss->skb_queue);
797
798 ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
799 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
800}
801
802int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata)
803{
804 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
805
806 ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
807
808 if (ifibss->ssid_len)
809 ifibss->flags |= IEEE80211_IBSS_SSID_SET;
810 else
811 ifibss->flags &= ~IEEE80211_IBSS_SSID_SET;
812
813 ifibss->ibss_join_req = jiffies;
814 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
815 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
816
817 return 0;
818}
819
820int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
821{
822 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
823
824 if (len > IEEE80211_MAX_SSID_LEN)
825 return -EINVAL;
826
827 if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) {
828 memset(ifibss->ssid, 0, sizeof(ifibss->ssid));
829 memcpy(ifibss->ssid, ssid, len);
830 ifibss->ssid_len = len;
831 }
832
833 return ieee80211_ibss_commit(sdata);
834}
835
836int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
837{
838 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
839
840 memcpy(ssid, ifibss->ssid, ifibss->ssid_len);
841 *len = ifibss->ssid_len;
842
843 return 0;
844}
845
846int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
847{
848 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
849
850 if (is_valid_ether_addr(bssid)) {
851 memcpy(ifibss->bssid, bssid, ETH_ALEN);
852 ifibss->flags |= IEEE80211_IBSS_BSSID_SET;
853 } else {
854 memset(ifibss->bssid, 0, ETH_ALEN);
855 ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET;
856 }
857
858 if (netif_running(sdata->dev)) {
859 if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
860 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
861 "the low-level driver\n", sdata->dev->name);
862 }
863 }
864
865 return ieee80211_ibss_commit(sdata);
866} 780}
867 781
868/* scan finished notification */ 782/* scan finished notification */
869void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) 783void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
870{ 784{
871 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 785 struct ieee80211_sub_if_data *sdata;
872 struct ieee80211_if_ibss *ifibss;
873 786
874 if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) { 787 mutex_lock(&local->iflist_mtx);
875 ifibss = &sdata->u.ibss; 788 list_for_each_entry(sdata, &local->interfaces, list) {
876 if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) || 789 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
877 !ieee80211_sta_active_ibss(sdata)) 790 continue;
878 ieee80211_sta_find_ibss(sdata); 791 sdata->u.ibss.last_scan_completed = jiffies;
792 ieee80211_sta_find_ibss(sdata);
879 } 793 }
794 mutex_unlock(&local->iflist_mtx);
880} 795}
881 796
882ieee80211_rx_result 797ieee80211_rx_result
@@ -906,3 +821,71 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
906 821
907 return RX_DROP_MONITOR; 822 return RX_DROP_MONITOR;
908} 823}
824
825int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
826 struct cfg80211_ibss_params *params)
827{
828 struct sk_buff *skb;
829
830 memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
831 sdata->u.ibss.ssid_len = params->ssid_len;
832
833 if (params->bssid) {
834 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
835 sdata->u.ibss.fixed_bssid = true;
836 } else
837 sdata->u.ibss.fixed_bssid = false;
838
839 sdata->u.ibss.channel = params->channel;
840 sdata->u.ibss.fixed_channel = params->channel_fixed;
841
842 if (params->ie) {
843 sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
844 GFP_KERNEL);
845 if (sdata->u.ibss.ie)
846 sdata->u.ibss.ie_len = params->ie_len;
847 }
848
849 skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
850 36 /* bitrates */ +
851 34 /* SSID */ +
852 3 /* DS params */ +
853 4 /* IBSS params */ +
854 params->ie_len);
855 if (!skb)
856 return -ENOMEM;
857
858 sdata->u.ibss.skb = skb;
859 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
860 sdata->u.ibss.ibss_join_req = jiffies;
861
862 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
863 queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
864
865 return 0;
866}
867
868int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
869{
870 struct sk_buff *skb;
871
872 del_timer_sync(&sdata->u.ibss.timer);
873 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
874 cancel_work_sync(&sdata->u.ibss.work);
875 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
876
877 sta_info_flush(sdata->local, sdata);
878
879 /* remove beacon */
880 kfree(sdata->u.ibss.ie);
881 skb = sdata->u.ibss.presp;
882 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
883 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
884 synchronize_rcu();
885 kfree_skb(skb);
886
887 skb_queue_purge(&sdata->u.ibss.skb_queue);
888 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
889
890 return 0;
891}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6ed78cb16b3..1579bc92c88d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,7 +24,6 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <net/cfg80211.h> 26#include <net/cfg80211.h>
27#include <net/wireless.h>
28#include <net/iw_handler.h> 27#include <net/iw_handler.h>
29#include <net/mac80211.h> 28#include <net/mac80211.h>
30#include "key.h" 29#include "key.h"
@@ -295,6 +294,8 @@ struct ieee80211_if_managed {
295 int auth_tries; /* retries for auth req */ 294 int auth_tries; /* retries for auth req */
296 int assoc_tries; /* retries for assoc req */ 295 int assoc_tries; /* retries for assoc req */
297 296
297 bool powersave; /* powersave requested for this iface */
298
298 unsigned long request; 299 unsigned long request;
299 300
300 unsigned long last_probe; 301 unsigned long last_probe;
@@ -306,6 +307,8 @@ struct ieee80211_if_managed {
306 int auth_alg; /* currently used IEEE 802.11 authentication algorithm */ 307 int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
307 int auth_transaction; 308 int auth_transaction;
308 309
310 u32 beacon_crc;
311
309 enum { 312 enum {
310 IEEE80211_MFP_DISABLED, 313 IEEE80211_MFP_DISABLED,
311 IEEE80211_MFP_OPTIONAL, 314 IEEE80211_MFP_OPTIONAL,
@@ -319,14 +322,6 @@ struct ieee80211_if_managed {
319 size_t sme_auth_ie_len; 322 size_t sme_auth_ie_len;
320}; 323};
321 324
322enum ieee80211_ibss_flags {
323 IEEE80211_IBSS_AUTO_CHANNEL_SEL = BIT(0),
324 IEEE80211_IBSS_AUTO_BSSID_SEL = BIT(1),
325 IEEE80211_IBSS_BSSID_SET = BIT(2),
326 IEEE80211_IBSS_PREV_BSSID_SET = BIT(3),
327 IEEE80211_IBSS_SSID_SET = BIT(4),
328};
329
330enum ieee80211_ibss_request { 325enum ieee80211_ibss_request {
331 IEEE80211_IBSS_REQ_RUN = 0, 326 IEEE80211_IBSS_REQ_RUN = 0,
332}; 327};
@@ -337,17 +332,20 @@ struct ieee80211_if_ibss {
337 332
338 struct sk_buff_head skb_queue; 333 struct sk_buff_head skb_queue;
339 334
340 u8 ssid[IEEE80211_MAX_SSID_LEN]; 335 unsigned long request;
341 u8 ssid_len; 336 unsigned long last_scan_completed;
342 337 bool fixed_bssid;
343 u32 flags; 338 bool fixed_channel;
344 339
345 u8 bssid[ETH_ALEN]; 340 u8 bssid[ETH_ALEN];
346 341 u8 ssid[IEEE80211_MAX_SSID_LEN];
347 unsigned long request; 342 u8 ssid_len, ie_len;
343 u8 *ie;
344 struct ieee80211_channel *channel;
348 345
349 unsigned long ibss_join_req; 346 unsigned long ibss_join_req;
350 struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ 347 /* probe response/beacon for IBSS */
348 struct sk_buff *presp, *skb;
351 349
352 enum { 350 enum {
353 IEEE80211_IBSS_MLME_SEARCH, 351 IEEE80211_IBSS_MLME_SEARCH,
@@ -626,8 +624,6 @@ struct ieee80211_local {
626 spinlock_t sta_lock; 624 spinlock_t sta_lock;
627 unsigned long num_sta; 625 unsigned long num_sta;
628 struct list_head sta_list; 626 struct list_head sta_list;
629 struct list_head sta_flush_list;
630 struct work_struct sta_flush_work;
631 struct sta_info *sta_hash[STA_HASH_SIZE]; 627 struct sta_info *sta_hash[STA_HASH_SIZE];
632 struct timer_list sta_cleanup; 628 struct timer_list sta_cleanup;
633 629
@@ -647,9 +643,6 @@ struct ieee80211_local {
647 643
648 struct rate_control_ref *rate_ctrl; 644 struct rate_control_ref *rate_ctrl;
649 645
650 int rts_threshold;
651 int fragmentation_threshold;
652
653 struct crypto_blkcipher *wep_tx_tfm; 646 struct crypto_blkcipher *wep_tx_tfm;
654 struct crypto_blkcipher *wep_rx_tfm; 647 struct crypto_blkcipher *wep_rx_tfm;
655 u32 wep_iv; 648 u32 wep_iv;
@@ -671,10 +664,12 @@ struct ieee80211_local {
671 struct cfg80211_scan_request int_scan_req; 664 struct cfg80211_scan_request int_scan_req;
672 struct cfg80211_scan_request *scan_req; 665 struct cfg80211_scan_request *scan_req;
673 struct ieee80211_channel *scan_channel; 666 struct ieee80211_channel *scan_channel;
667 const u8 *orig_ies;
668 int orig_ies_len;
674 int scan_channel_idx; 669 int scan_channel_idx;
670 int scan_ies_len;
675 671
676 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 672 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
677 unsigned long last_scan_completed;
678 struct delayed_work scan_work; 673 struct delayed_work scan_work;
679 struct ieee80211_sub_if_data *scan_sdata; 674 struct ieee80211_sub_if_data *scan_sdata;
680 enum nl80211_channel_type oper_channel_type; 675 enum nl80211_channel_type oper_channel_type;
@@ -736,15 +731,22 @@ struct ieee80211_local {
736 int wifi_wme_noack_test; 731 int wifi_wme_noack_test;
737 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 732 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
738 733
739 bool powersave;
740 bool pspolling; 734 bool pspolling;
735 /*
736 * PS can only be enabled when we have exactly one managed
737 * interface (and monitors) in PS, this then points there.
738 */
739 struct ieee80211_sub_if_data *ps_sdata;
741 struct work_struct dynamic_ps_enable_work; 740 struct work_struct dynamic_ps_enable_work;
742 struct work_struct dynamic_ps_disable_work; 741 struct work_struct dynamic_ps_disable_work;
743 struct timer_list dynamic_ps_timer; 742 struct timer_list dynamic_ps_timer;
743 struct notifier_block network_latency_notifier;
744 744
745 int user_power_level; /* in dBm */ 745 int user_power_level; /* in dBm */
746 int power_constr_level; /* in dBm */ 746 int power_constr_level; /* in dBm */
747 747
748 struct work_struct restart_work;
749
748#ifdef CONFIG_MAC80211_DEBUGFS 750#ifdef CONFIG_MAC80211_DEBUGFS
749 struct local_debugfsdentries { 751 struct local_debugfsdentries {
750 struct dentry *rcdir; 752 struct dentry *rcdir;
@@ -830,7 +832,7 @@ struct ieee802_11_elems {
830 u8 *fh_params; 832 u8 *fh_params;
831 u8 *ds_params; 833 u8 *ds_params;
832 u8 *cf_params; 834 u8 *cf_params;
833 u8 *tim; 835 struct ieee80211_tim_ie *tim;
834 u8 *ibss_params; 836 u8 *ibss_params;
835 u8 *challenge; 837 u8 *challenge;
836 u8 *wpa; 838 u8 *wpa;
@@ -927,12 +929,11 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
927int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); 929int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
928void ieee80211_send_pspoll(struct ieee80211_local *local, 930void ieee80211_send_pspoll(struct ieee80211_local *local,
929 struct ieee80211_sub_if_data *sdata); 931 struct ieee80211_sub_if_data *sdata);
932void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
933int ieee80211_max_network_latency(struct notifier_block *nb,
934 unsigned long data, void *dummy);
930 935
931/* IBSS code */ 936/* IBSS code */
932int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata);
933int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
934int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
935int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
936void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 937void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
937void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); 938void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
938ieee80211_rx_result 939ieee80211_rx_result
@@ -940,6 +941,9 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
940 struct ieee80211_rx_status *rx_status); 941 struct ieee80211_rx_status *rx_status);
941struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 942struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
942 u8 *bssid, u8 *addr, u32 supp_rates); 943 u8 *bssid, u8 *addr, u32 supp_rates);
944int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
945 struct cfg80211_ibss_params *params);
946int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
943 947
944/* scan/BSS handling */ 948/* scan/BSS handling */
945void ieee80211_scan_work(struct work_struct *work); 949void ieee80211_scan_work(struct work_struct *work);
@@ -995,9 +999,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
995void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, 999void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
996 struct ieee80211_ht_cap *ht_cap_ie, 1000 struct ieee80211_ht_cap *ht_cap_ie,
997 struct ieee80211_sta_ht_cap *ht_cap); 1001 struct ieee80211_sta_ht_cap *ht_cap);
998u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
999 struct ieee80211_ht_info *hti,
1000 u16 ap_ht_cap_flags);
1001void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); 1002void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
1002void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, 1003void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
1003 const u8 *da, u16 tid, 1004 const u8 *da, u16 tid,
@@ -1036,15 +1037,22 @@ void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
1036 u16 capab_info, u8 *pwr_constr_elem, 1037 u16 capab_info, u8 *pwr_constr_elem,
1037 u8 pwr_constr_elem_len); 1038 u8 pwr_constr_elem_len);
1038 1039
1039/* Suspend/resume */ 1040/* Suspend/resume and hw reconfiguration */
1041int ieee80211_reconfig(struct ieee80211_local *local);
1042
1040#ifdef CONFIG_PM 1043#ifdef CONFIG_PM
1041int __ieee80211_suspend(struct ieee80211_hw *hw); 1044int __ieee80211_suspend(struct ieee80211_hw *hw);
1042int __ieee80211_resume(struct ieee80211_hw *hw); 1045
1046static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1047{
1048 return ieee80211_reconfig(hw_to_local(hw));
1049}
1043#else 1050#else
1044static inline int __ieee80211_suspend(struct ieee80211_hw *hw) 1051static inline int __ieee80211_suspend(struct ieee80211_hw *hw)
1045{ 1052{
1046 return 0; 1053 return 0;
1047} 1054}
1055
1048static inline int __ieee80211_resume(struct ieee80211_hw *hw) 1056static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1049{ 1057{
1050 return 0; 1058 return 0;
@@ -1060,12 +1068,15 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
1060int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 1068int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
1061 int rate, int erp, int short_preamble); 1069 int rate, int erp, int short_preamble);
1062void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 1070void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
1063 struct ieee80211_hdr *hdr); 1071 struct ieee80211_hdr *hdr, const u8 *tsc);
1064void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); 1072void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
1065void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 1073void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1066 int encrypt); 1074 int encrypt);
1067void ieee802_11_parse_elems(u8 *start, size_t len, 1075void ieee802_11_parse_elems(u8 *start, size_t len,
1068 struct ieee802_11_elems *elems); 1076 struct ieee802_11_elems *elems);
1077u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1078 struct ieee802_11_elems *elems,
1079 u64 filter, u32 crc);
1069int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); 1080int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
1070u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 1081u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1071 enum ieee80211_band band); 1082 enum ieee80211_band band);
@@ -1093,9 +1104,11 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1093 u16 transaction, u16 auth_alg, 1104 u16 transaction, u16 auth_alg,
1094 u8 *extra, size_t extra_len, 1105 u8 *extra, size_t extra_len,
1095 const u8 *bssid, int encrypt); 1106 const u8 *bssid, int encrypt);
1107int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1108 const u8 *ie, size_t ie_len);
1096void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1109void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1097 u8 *ssid, size_t ssid_len, 1110 const u8 *ssid, size_t ssid_len,
1098 u8 *ie, size_t ie_len); 1111 const u8 *ie, size_t ie_len);
1099 1112
1100void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1113void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1101 const size_t supp_rates_len, 1114 const size_t supp_rates_len,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 91e8e1bacaaa..52425975bbbe 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -235,11 +235,7 @@ static int ieee80211_open(struct net_device *dev)
235 netif_addr_unlock_bh(local->mdev); 235 netif_addr_unlock_bh(local->mdev);
236 break; 236 break;
237 case NL80211_IFTYPE_STATION: 237 case NL80211_IFTYPE_STATION:
238 case NL80211_IFTYPE_ADHOC: 238 sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
239 if (sdata->vif.type == NL80211_IFTYPE_STATION)
240 sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
241 else
242 sdata->u.ibss.flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
243 /* fall through */ 239 /* fall through */
244 default: 240 default:
245 conf.vif = &sdata->vif; 241 conf.vif = &sdata->vif;
@@ -317,6 +313,8 @@ static int ieee80211_open(struct net_device *dev)
317 ieee80211_set_wmm_default(sdata); 313 ieee80211_set_wmm_default(sdata);
318 } 314 }
319 315
316 ieee80211_recalc_ps(local, -1);
317
320 /* 318 /*
321 * ieee80211_sta_work is disabled while network interface 319 * ieee80211_sta_work is disabled while network interface
322 * is down. Therefore, some configuration changes may not 320 * is down. Therefore, some configuration changes may not
@@ -325,8 +323,6 @@ static int ieee80211_open(struct net_device *dev)
325 */ 323 */
326 if (sdata->vif.type == NL80211_IFTYPE_STATION) 324 if (sdata->vif.type == NL80211_IFTYPE_STATION)
327 queue_work(local->hw.workqueue, &sdata->u.mgd.work); 325 queue_work(local->hw.workqueue, &sdata->u.mgd.work);
328 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
329 queue_work(local->hw.workqueue, &sdata->u.ibss.work);
330 326
331 netif_tx_start_all_queues(dev); 327 netif_tx_start_all_queues(dev);
332 328
@@ -497,7 +493,6 @@ static int ieee80211_stop(struct net_device *dev)
497 /* fall through */ 493 /* fall through */
498 case NL80211_IFTYPE_ADHOC: 494 case NL80211_IFTYPE_ADHOC:
499 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 495 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
500 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
501 del_timer_sync(&sdata->u.ibss.timer); 496 del_timer_sync(&sdata->u.ibss.timer);
502 cancel_work_sync(&sdata->u.ibss.work); 497 cancel_work_sync(&sdata->u.ibss.work);
503 synchronize_rcu(); 498 synchronize_rcu();
@@ -572,6 +567,8 @@ static int ieee80211_stop(struct net_device *dev)
572 hw_reconf_flags = 0; 567 hw_reconf_flags = 0;
573 } 568 }
574 569
570 ieee80211_recalc_ps(local, -1);
571
575 /* do after stop to avoid reconfiguring when we stop anyway */ 572 /* do after stop to avoid reconfiguring when we stop anyway */
576 if (hw_reconf_flags) 573 if (hw_reconf_flags)
577 ieee80211_hw_config(local, hw_reconf_flags); 574 ieee80211_hw_config(local, hw_reconf_flags);
@@ -649,7 +646,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
649 mesh_rmc_free(sdata); 646 mesh_rmc_free(sdata);
650 break; 647 break;
651 case NL80211_IFTYPE_ADHOC: 648 case NL80211_IFTYPE_ADHOC:
652 kfree_skb(sdata->u.ibss.probe_resp); 649 if (WARN_ON(sdata->u.ibss.presp))
650 kfree_skb(sdata->u.ibss.presp);
653 break; 651 break;
654 case NL80211_IFTYPE_STATION: 652 case NL80211_IFTYPE_STATION:
655 kfree(sdata->u.mgd.extra_ie); 653 kfree(sdata->u.mgd.extra_ie);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index fbcbed6cad01..5320e08434ac 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -21,6 +21,7 @@
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
23#include <linux/bitmap.h> 23#include <linux/bitmap.h>
24#include <linux/pm_qos_params.h>
24#include <net/net_namespace.h> 25#include <net/net_namespace.h>
25#include <net/cfg80211.h> 26#include <net/cfg80211.h>
26 27
@@ -208,7 +209,7 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
208 !!rcu_dereference(sdata->u.ap.beacon); 209 !!rcu_dereference(sdata->u.ap.beacon);
209 break; 210 break;
210 case NL80211_IFTYPE_ADHOC: 211 case NL80211_IFTYPE_ADHOC:
211 conf.enable_beacon = !!sdata->u.ibss.probe_resp; 212 conf.enable_beacon = !!sdata->u.ibss.presp;
212 break; 213 break;
213 case NL80211_IFTYPE_MESH_POINT: 214 case NL80211_IFTYPE_MESH_POINT:
214 conf.enable_beacon = true; 215 conf.enable_beacon = true;
@@ -696,6 +697,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
696} 697}
697EXPORT_SYMBOL(ieee80211_tx_status); 698EXPORT_SYMBOL(ieee80211_tx_status);
698 699
700static void ieee80211_restart_work(struct work_struct *work)
701{
702 struct ieee80211_local *local =
703 container_of(work, struct ieee80211_local, restart_work);
704
705 rtnl_lock();
706 ieee80211_reconfig(local);
707 rtnl_unlock();
708}
709
710void ieee80211_restart_hw(struct ieee80211_hw *hw)
711{
712 struct ieee80211_local *local = hw_to_local(hw);
713
714 /* use this reason, __ieee80211_resume will unblock it */
715 ieee80211_stop_queues_by_reason(hw,
716 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
717
718 schedule_work(&local->restart_work);
719}
720EXPORT_SYMBOL(ieee80211_restart_hw);
721
699struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 722struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
700 const struct ieee80211_ops *ops) 723 const struct ieee80211_ops *ops)
701{ 724{
@@ -728,12 +751,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
728 return NULL; 751 return NULL;
729 752
730 wiphy->privid = mac80211_wiphy_privid; 753 wiphy->privid = mac80211_wiphy_privid;
731 wiphy->max_scan_ssids = 4; 754
732 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ 755 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
733 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - 756 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
734 sizeof(struct cfg80211_bss); 757 sizeof(struct cfg80211_bss);
735 758
736 local = wiphy_priv(wiphy); 759 local = wiphy_priv(wiphy);
760
737 local->hw.wiphy = wiphy; 761 local->hw.wiphy = wiphy;
738 762
739 local->hw.priv = (char *)local + 763 local->hw.priv = (char *)local +
@@ -752,10 +776,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
752 /* set up some defaults */ 776 /* set up some defaults */
753 local->hw.queues = 1; 777 local->hw.queues = 1;
754 local->hw.max_rates = 1; 778 local->hw.max_rates = 1;
755 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 779 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
756 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 780 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
757 local->hw.conf.long_frame_max_tx_count = 4;
758 local->hw.conf.short_frame_max_tx_count = 7;
759 local->hw.conf.radio_enabled = true; 781 local->hw.conf.radio_enabled = true;
760 782
761 INIT_LIST_HEAD(&local->interfaces); 783 INIT_LIST_HEAD(&local->interfaces);
@@ -767,6 +789,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
767 789
768 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 790 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
769 791
792 INIT_WORK(&local->restart_work, ieee80211_restart_work);
793
770 INIT_WORK(&local->dynamic_ps_enable_work, 794 INIT_WORK(&local->dynamic_ps_enable_work,
771 ieee80211_dynamic_ps_enable_work); 795 ieee80211_dynamic_ps_enable_work);
772 INIT_WORK(&local->dynamic_ps_disable_work, 796 INIT_WORK(&local->dynamic_ps_disable_work,
@@ -820,7 +844,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
820 enum ieee80211_band band; 844 enum ieee80211_band band;
821 struct net_device *mdev; 845 struct net_device *mdev;
822 struct ieee80211_master_priv *mpriv; 846 struct ieee80211_master_priv *mpriv;
823 int channels, i, j; 847 int channels, i, j, max_bitrates;
848 bool supp_ht;
849 static const u32 cipher_suites[] = {
850 WLAN_CIPHER_SUITE_WEP40,
851 WLAN_CIPHER_SUITE_WEP104,
852 WLAN_CIPHER_SUITE_TKIP,
853 WLAN_CIPHER_SUITE_CCMP,
854
855 /* keep last -- depends on hw flags! */
856 WLAN_CIPHER_SUITE_AES_CMAC
857 };
824 858
825 /* 859 /*
826 * generic code guarantees at least one band, 860 * generic code guarantees at least one band,
@@ -828,18 +862,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
828 * that hw.conf.channel is assigned 862 * that hw.conf.channel is assigned
829 */ 863 */
830 channels = 0; 864 channels = 0;
865 max_bitrates = 0;
866 supp_ht = false;
831 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 867 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
832 struct ieee80211_supported_band *sband; 868 struct ieee80211_supported_band *sband;
833 869
834 sband = local->hw.wiphy->bands[band]; 870 sband = local->hw.wiphy->bands[band];
835 if (sband && !local->oper_channel) { 871 if (!sband)
872 continue;
873 if (!local->oper_channel) {
836 /* init channel we're on */ 874 /* init channel we're on */
837 local->hw.conf.channel = 875 local->hw.conf.channel =
838 local->oper_channel = 876 local->oper_channel =
839 local->scan_channel = &sband->channels[0]; 877 local->scan_channel = &sband->channels[0];
840 } 878 }
841 if (sband) 879 channels += sband->n_channels;
842 channels += sband->n_channels; 880
881 if (max_bitrates < sband->n_bitrates)
882 max_bitrates = sband->n_bitrates;
883 supp_ht = supp_ht || sband->ht_cap.ht_supported;
843 } 884 }
844 885
845 local->int_scan_req.n_channels = channels; 886 local->int_scan_req.n_channels = channels;
@@ -859,6 +900,37 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
859 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 900 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
860 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; 901 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
861 902
903 /*
904 * Calculate scan IE length -- we need this to alloc
905 * memory and to subtract from the driver limit. It
906 * includes the (extended) supported rates and HT
907 * information -- SSID is the driver's responsibility.
908 */
909 local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */
910 if (supp_ht)
911 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
912
913 if (!local->ops->hw_scan) {
914 /* For hw_scan, driver needs to set these up. */
915 local->hw.wiphy->max_scan_ssids = 4;
916 local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
917 }
918
919 /*
920 * If the driver supports any scan IEs, then assume the
921 * limit includes the IEs mac80211 will add, otherwise
922 * leave it at zero and let the driver sort it out; we
923 * still pass our IEs to the driver but userspace will
924 * not be allowed to in that case.
925 */
926 if (local->hw.wiphy->max_scan_ie_len)
927 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
928
929 local->hw.wiphy->cipher_suites = cipher_suites;
930 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
931 if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
932 local->hw.wiphy->n_cipher_suites--;
933
862 result = wiphy_register(local->hw.wiphy); 934 result = wiphy_register(local->hw.wiphy);
863 if (result < 0) 935 if (result < 0)
864 goto fail_wiphy_register; 936 goto fail_wiphy_register;
@@ -965,25 +1037,38 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
965 } 1037 }
966 } 1038 }
967 1039
1040 local->network_latency_notifier.notifier_call =
1041 ieee80211_max_network_latency;
1042 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
1043 &local->network_latency_notifier);
1044
1045 if (result) {
1046 rtnl_lock();
1047 goto fail_pm_qos;
1048 }
1049
968 return 0; 1050 return 0;
969 1051
970fail_wep: 1052 fail_pm_qos:
1053 ieee80211_led_exit(local);
1054 ieee80211_remove_interfaces(local);
1055 fail_wep:
971 rate_control_deinitialize(local); 1056 rate_control_deinitialize(local);
972fail_rate: 1057 fail_rate:
973 unregister_netdevice(local->mdev); 1058 unregister_netdevice(local->mdev);
974 local->mdev = NULL; 1059 local->mdev = NULL;
975fail_dev: 1060 fail_dev:
976 rtnl_unlock(); 1061 rtnl_unlock();
977 sta_info_stop(local); 1062 sta_info_stop(local);
978fail_sta_info: 1063 fail_sta_info:
979 debugfs_hw_del(local); 1064 debugfs_hw_del(local);
980 destroy_workqueue(local->hw.workqueue); 1065 destroy_workqueue(local->hw.workqueue);
981fail_workqueue: 1066 fail_workqueue:
982 if (local->mdev) 1067 if (local->mdev)
983 free_netdev(local->mdev); 1068 free_netdev(local->mdev);
984fail_mdev_alloc: 1069 fail_mdev_alloc:
985 wiphy_unregister(local->hw.wiphy); 1070 wiphy_unregister(local->hw.wiphy);
986fail_wiphy_register: 1071 fail_wiphy_register:
987 kfree(local->int_scan_req.channels); 1072 kfree(local->int_scan_req.channels);
988 return result; 1073 return result;
989} 1074}
@@ -996,6 +1081,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
996 tasklet_kill(&local->tx_pending_tasklet); 1081 tasklet_kill(&local->tx_pending_tasklet);
997 tasklet_kill(&local->tasklet); 1082 tasklet_kill(&local->tasklet);
998 1083
1084 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
1085 &local->network_latency_notifier);
1086
999 rtnl_lock(); 1087 rtnl_lock();
1000 1088
1001 /* 1089 /*
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 132938b073dc..3610c11286bc 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -17,6 +17,8 @@
17#include <linux/if_arp.h> 17#include <linux/if_arp.h>
18#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/pm_qos_params.h>
21#include <linux/crc32.h>
20#include <net/mac80211.h> 22#include <net/mac80211.h>
21#include <asm/unaligned.h> 23#include <asm/unaligned.h>
22 24
@@ -80,6 +82,89 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
80 return count; 82 return count;
81} 83}
82 84
85/*
86 * ieee80211_enable_ht should be called only after the operating band
87 * has been determined as ht configuration depends on the hw's
88 * HT abilities for a specific band.
89 */
90static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
91 struct ieee80211_ht_info *hti,
92 u16 ap_ht_cap_flags)
93{
94 struct ieee80211_local *local = sdata->local;
95 struct ieee80211_supported_band *sband;
96 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
97 struct ieee80211_bss_ht_conf ht;
98 struct sta_info *sta;
99 u32 changed = 0;
100 bool enable_ht = true, ht_changed;
101 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
102
103 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
104
105 memset(&ht, 0, sizeof(ht));
106
107 /* HT is not supported */
108 if (!sband->ht_cap.ht_supported)
109 enable_ht = false;
110
111 /* check that channel matches the right operating channel */
112 if (local->hw.conf.channel->center_freq !=
113 ieee80211_channel_to_frequency(hti->control_chan))
114 enable_ht = false;
115
116 if (enable_ht) {
117 channel_type = NL80211_CHAN_HT20;
118
119 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
120 (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
121 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
122 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
123 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
124 channel_type = NL80211_CHAN_HT40PLUS;
125 break;
126 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
127 channel_type = NL80211_CHAN_HT40MINUS;
128 break;
129 }
130 }
131 }
132
133 ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
134 channel_type != local->hw.conf.channel_type;
135
136 local->oper_channel_type = channel_type;
137
138 if (ht_changed) {
139 /* channel_type change automatically detected */
140 ieee80211_hw_config(local, 0);
141
142 rcu_read_lock();
143
144 sta = sta_info_get(local, ifmgd->bssid);
145 if (sta)
146 rate_control_rate_update(local, sband, sta,
147 IEEE80211_RC_HT_CHANGED);
148
149 rcu_read_unlock();
150
151 }
152
153 /* disable HT */
154 if (!enable_ht)
155 return 0;
156
157 ht.operation_mode = le16_to_cpu(hti->operation_mode);
158
159 /* if bss configuration changed store the new one */
160 if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
161 changed |= BSS_CHANGED_HT;
162 sdata->vif.bss_conf.ht = ht;
163 }
164
165 return changed;
166}
167
83/* frame sending functions */ 168/* frame sending functions */
84 169
85static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 170static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
@@ -325,6 +410,10 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
325 /* u.deauth.reason_code == u.disassoc.reason_code */ 410 /* u.deauth.reason_code == u.disassoc.reason_code */
326 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 411 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
327 412
413 if (stype == IEEE80211_STYPE_DEAUTH)
414 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
415 else
416 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
328 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); 417 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
329} 418}
330 419
@@ -359,6 +448,166 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
359 ieee80211_tx_skb(sdata, skb, 0); 448 ieee80211_tx_skb(sdata, skb, 0);
360} 449}
361 450
451void ieee80211_send_nullfunc(struct ieee80211_local *local,
452 struct ieee80211_sub_if_data *sdata,
453 int powersave)
454{
455 struct sk_buff *skb;
456 struct ieee80211_hdr *nullfunc;
457 __le16 fc;
458
459 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
460 return;
461
462 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
463 if (!skb) {
464 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
465 "frame\n", sdata->dev->name);
466 return;
467 }
468 skb_reserve(skb, local->hw.extra_tx_headroom);
469
470 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
471 memset(nullfunc, 0, 24);
472 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
473 IEEE80211_FCTL_TODS);
474 if (powersave)
475 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
476 nullfunc->frame_control = fc;
477 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
478 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
479 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
480
481 ieee80211_tx_skb(sdata, skb, 0);
482}
483
484/* powersave */
485static void ieee80211_enable_ps(struct ieee80211_local *local,
486 struct ieee80211_sub_if_data *sdata)
487{
488 struct ieee80211_conf *conf = &local->hw.conf;
489
490 if (conf->dynamic_ps_timeout > 0 &&
491 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
492 mod_timer(&local->dynamic_ps_timer, jiffies +
493 msecs_to_jiffies(conf->dynamic_ps_timeout));
494 } else {
495 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
496 ieee80211_send_nullfunc(local, sdata, 1);
497 conf->flags |= IEEE80211_CONF_PS;
498 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
499 }
500}
501
502static void ieee80211_change_ps(struct ieee80211_local *local)
503{
504 struct ieee80211_conf *conf = &local->hw.conf;
505
506 if (local->ps_sdata) {
507 if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
508 return;
509
510 ieee80211_enable_ps(local, local->ps_sdata);
511 } else if (conf->flags & IEEE80211_CONF_PS) {
512 conf->flags &= ~IEEE80211_CONF_PS;
513 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
514 del_timer_sync(&local->dynamic_ps_timer);
515 cancel_work_sync(&local->dynamic_ps_enable_work);
516 }
517}
518
519/* need to hold RTNL or interface lock */
520void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
521{
522 struct ieee80211_sub_if_data *sdata, *found = NULL;
523 int count = 0;
524
525 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
526 local->ps_sdata = NULL;
527 return;
528 }
529
530 list_for_each_entry(sdata, &local->interfaces, list) {
531 if (!netif_running(sdata->dev))
532 continue;
533 if (sdata->vif.type != NL80211_IFTYPE_STATION)
534 continue;
535 found = sdata;
536 count++;
537 }
538
539 if (count == 1 && found->u.mgd.powersave) {
540 s32 beaconint_us;
541
542 if (latency < 0)
543 latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
544
545 beaconint_us = ieee80211_tu_to_usec(
546 found->vif.bss_conf.beacon_int);
547
548 if (beaconint_us > latency) {
549 local->ps_sdata = NULL;
550 } else {
551 u8 dtimper = found->vif.bss_conf.dtim_period;
552 int maxslp = 1;
553
554 if (dtimper > 1)
555 maxslp = min_t(int, dtimper,
556 latency / beaconint_us);
557
558 local->hw.conf.max_sleep_interval = maxslp;
559 local->ps_sdata = found;
560 }
561 } else {
562 local->ps_sdata = NULL;
563 }
564
565 ieee80211_change_ps(local);
566}
567
568void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
569{
570 struct ieee80211_local *local =
571 container_of(work, struct ieee80211_local,
572 dynamic_ps_disable_work);
573
574 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
575 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
576 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
577 }
578
579 ieee80211_wake_queues_by_reason(&local->hw,
580 IEEE80211_QUEUE_STOP_REASON_PS);
581}
582
583void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
584{
585 struct ieee80211_local *local =
586 container_of(work, struct ieee80211_local,
587 dynamic_ps_enable_work);
588 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
589
590 /* can only happen when PS was just disabled anyway */
591 if (!sdata)
592 return;
593
594 if (local->hw.conf.flags & IEEE80211_CONF_PS)
595 return;
596
597 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
598 ieee80211_send_nullfunc(local, sdata, 1);
599
600 local->hw.conf.flags |= IEEE80211_CONF_PS;
601 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
602}
603
604void ieee80211_dynamic_ps_timer(unsigned long data)
605{
606 struct ieee80211_local *local = (void *) data;
607
608 queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
609}
610
362/* MLME */ 611/* MLME */
363static void ieee80211_sta_wmm_params(struct ieee80211_local *local, 612static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
364 struct ieee80211_if_managed *ifmgd, 613 struct ieee80211_if_managed *ifmgd,
@@ -435,30 +684,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
435 } 684 }
436} 685}
437 686
438static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid)
439{
440 u8 mask;
441 u8 index, indexn1, indexn2;
442 struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim;
443
444 if (unlikely(!tim || elems->tim_len < 4))
445 return false;
446
447 aid &= 0x3fff;
448 index = aid / 8;
449 mask = 1 << (aid & 7);
450
451 indexn1 = tim->bitmap_ctrl & 0xfe;
452 indexn2 = elems->tim_len + indexn1 - 4;
453
454 if (index < indexn1 || index > indexn2)
455 return false;
456
457 index -= indexn1;
458
459 return !!(tim->virtual_map[index] & mask);
460}
461
462static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 687static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
463 u16 capab, bool erp_valid, u8 erp) 688 u16 capab, bool erp_valid, u8 erp)
464{ 689{
@@ -634,18 +859,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
634 bss_info_changed |= BSS_CHANGED_BASIC_RATES; 859 bss_info_changed |= BSS_CHANGED_BASIC_RATES;
635 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 860 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
636 861
637 if (local->powersave) { 862 /* will be same as sdata */
638 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) && 863 if (local->ps_sdata) {
639 local->hw.conf.dynamic_ps_timeout > 0) { 864 mutex_lock(&local->iflist_mtx);
640 mod_timer(&local->dynamic_ps_timer, jiffies + 865 ieee80211_recalc_ps(local, -1);
641 msecs_to_jiffies( 866 mutex_unlock(&local->iflist_mtx);
642 local->hw.conf.dynamic_ps_timeout));
643 } else {
644 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
645 ieee80211_send_nullfunc(local, sdata, 1);
646 conf->flags |= IEEE80211_CONF_PS;
647 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
648 }
649 } 867 }
650 868
651 netif_tx_start_all_queues(sdata->dev); 869 netif_tx_start_all_queues(sdata->dev);
@@ -714,7 +932,7 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
714 " timed out\n", 932 " timed out\n",
715 sdata->dev->name, ifmgd->bssid); 933 sdata->dev->name, ifmgd->bssid);
716 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 934 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
717 ieee80211_sta_send_apinfo(sdata); 935 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
718 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 936 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
719 sdata->local->hw.conf.channel->center_freq, 937 sdata->local->hw.conf.channel->center_freq,
720 ifmgd->ssid, ifmgd->ssid_len); 938 ifmgd->ssid, ifmgd->ssid_len);
@@ -897,7 +1115,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
897 " timed out\n", 1115 " timed out\n",
898 sdata->dev->name, ifmgd->bssid); 1116 sdata->dev->name, ifmgd->bssid);
899 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1117 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
900 ieee80211_sta_send_apinfo(sdata); 1118 cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
901 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 1119 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
902 sdata->local->hw.conf.channel->center_freq, 1120 sdata->local->hw.conf.channel->center_freq,
903 ifmgd->ssid, ifmgd->ssid_len); 1121 ifmgd->ssid, ifmgd->ssid_len);
@@ -1187,7 +1405,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1187 1405
1188 ieee80211_set_disassoc(sdata, true, false, 0); 1406 ieee80211_set_disassoc(sdata, true, false, 0);
1189 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED; 1407 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
1190 cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len); 1408 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len);
1191} 1409}
1192 1410
1193 1411
@@ -1218,7 +1436,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1218 } 1436 }
1219 1437
1220 ieee80211_set_disassoc(sdata, false, false, reason_code); 1438 ieee80211_set_disassoc(sdata, false, false, reason_code);
1221 cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len); 1439 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len);
1222} 1440}
1223 1441
1224 1442
@@ -1287,6 +1505,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1287 * association next time. This works around some broken APs 1505 * association next time. This works around some broken APs
1288 * which do not correctly reject reassociation requests. */ 1506 * which do not correctly reject reassociation requests. */
1289 ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET; 1507 ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1508 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
1509 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
1510 /* Wait for SME to decide what to do next */
1511 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1512 }
1290 return; 1513 return;
1291 } 1514 }
1292 1515
@@ -1518,46 +1741,74 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1518 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1741 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1519} 1742}
1520 1743
1744/*
1745 * This is the canonical list of information elements we care about,
1746 * the filter code also gives us all changes to the Microsoft OUI
1747 * (00:50:F2) vendor IE which is used for WMM which we need to track.
1748 *
1749 * We implement beacon filtering in software since that means we can
1750 * avoid processing the frame here and in cfg80211, and userspace
1751 * will not be able to tell whether the hardware supports it or not.
1752 *
1753 * XXX: This list needs to be dynamic -- userspace needs to be able to
1754 * add items it requires. It also needs to be able to tell us to
1755 * look out for other vendor IEs.
1756 */
1757static const u64 care_about_ies =
1758 (1ULL << WLAN_EID_COUNTRY) |
1759 (1ULL << WLAN_EID_ERP_INFO) |
1760 (1ULL << WLAN_EID_CHANNEL_SWITCH) |
1761 (1ULL << WLAN_EID_PWR_CONSTRAINT) |
1762 (1ULL << WLAN_EID_HT_CAPABILITY) |
1763 (1ULL << WLAN_EID_HT_INFORMATION);
1764
1521static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 1765static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1522 struct ieee80211_mgmt *mgmt, 1766 struct ieee80211_mgmt *mgmt,
1523 size_t len, 1767 size_t len,
1524 struct ieee80211_rx_status *rx_status) 1768 struct ieee80211_rx_status *rx_status)
1525{ 1769{
1526 struct ieee80211_if_managed *ifmgd; 1770 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1527 size_t baselen; 1771 size_t baselen;
1528 struct ieee802_11_elems elems; 1772 struct ieee802_11_elems elems;
1529 struct ieee80211_local *local = sdata->local; 1773 struct ieee80211_local *local = sdata->local;
1530 u32 changed = 0; 1774 u32 changed = 0;
1531 bool erp_valid, directed_tim; 1775 bool erp_valid, directed_tim = false;
1532 u8 erp_value = 0; 1776 u8 erp_value = 0;
1777 u32 ncrc;
1533 1778
1534 /* Process beacon from the current BSS */ 1779 /* Process beacon from the current BSS */
1535 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 1780 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
1536 if (baselen > len) 1781 if (baselen > len)
1537 return; 1782 return;
1538 1783
1539 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); 1784 if (rx_status->freq != local->hw.conf.channel->center_freq)
1540
1541 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
1542
1543 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1544 return; 1785 return;
1545 1786
1546 ifmgd = &sdata->u.mgd;
1547
1548 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) || 1787 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) ||
1549 memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0) 1788 memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0)
1550 return; 1789 return;
1551 1790
1552 if (rx_status->freq != local->hw.conf.channel->center_freq) 1791 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
1792 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
1793 len - baselen, &elems,
1794 care_about_ies, ncrc);
1795
1796 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
1797 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
1798 ifmgd->aid);
1799
1800 ncrc = crc32_be(ncrc, (void *)&directed_tim, sizeof(directed_tim));
1801
1802 if (ncrc == ifmgd->beacon_crc)
1553 return; 1803 return;
1804 ifmgd->beacon_crc = ncrc;
1805
1806 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
1554 1807
1555 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1808 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
1556 elems.wmm_param_len); 1809 elems.wmm_param_len);
1557 1810
1558 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { 1811 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
1559 directed_tim = ieee80211_check_tim(&elems, ifmgd->aid);
1560
1561 if (directed_tim) { 1812 if (directed_tim) {
1562 if (local->hw.conf.dynamic_ps_timeout > 0) { 1813 if (local->hw.conf.dynamic_ps_timeout > 0) {
1563 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 1814 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
@@ -1930,6 +2181,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
1930void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) 2181void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1931{ 2182{
1932 struct ieee80211_if_managed *ifmgd; 2183 struct ieee80211_if_managed *ifmgd;
2184 u32 hw_flags;
1933 2185
1934 ifmgd = &sdata->u.mgd; 2186 ifmgd = &sdata->u.mgd;
1935 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 2187 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
@@ -1949,6 +2201,13 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1949 IEEE80211_STA_AUTO_CHANNEL_SEL; 2201 IEEE80211_STA_AUTO_CHANNEL_SEL;
1950 if (sdata->local->hw.queues >= 4) 2202 if (sdata->local->hw.queues >= 4)
1951 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 2203 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2204
2205 hw_flags = sdata->local->hw.flags;
2206
2207 if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
2208 ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
2209 sdata->local->hw.conf.dynamic_ps_timeout = 500;
2210 }
1952} 2211}
1953 2212
1954/* configuration hooks */ 2213/* configuration hooks */
@@ -2068,9 +2327,6 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
2068 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", 2327 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
2069 sdata->dev->name, reason); 2328 sdata->dev->name, reason);
2070 2329
2071 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2072 return -EINVAL;
2073
2074 ieee80211_set_disassoc(sdata, true, true, reason); 2330 ieee80211_set_disassoc(sdata, true, true, reason);
2075 return 0; 2331 return 0;
2076} 2332}
@@ -2082,9 +2338,6 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
2082 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", 2338 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
2083 sdata->dev->name, reason); 2339 sdata->dev->name, reason);
2084 2340
2085 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2086 return -EINVAL;
2087
2088 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED)) 2341 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED))
2089 return -ENOLINK; 2342 return -ENOLINK;
2090 2343
@@ -2104,75 +2357,17 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2104 rcu_read_unlock(); 2357 rcu_read_unlock();
2105} 2358}
2106 2359
2107void ieee80211_dynamic_ps_disable_work(struct work_struct *work) 2360int ieee80211_max_network_latency(struct notifier_block *nb,
2361 unsigned long data, void *dummy)
2108{ 2362{
2363 s32 latency_usec = (s32) data;
2109 struct ieee80211_local *local = 2364 struct ieee80211_local *local =
2110 container_of(work, struct ieee80211_local, 2365 container_of(nb, struct ieee80211_local,
2111 dynamic_ps_disable_work); 2366 network_latency_notifier);
2112 2367
2113 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 2368 mutex_lock(&local->iflist_mtx);
2114 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 2369 ieee80211_recalc_ps(local, latency_usec);
2115 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 2370 mutex_unlock(&local->iflist_mtx);
2116 }
2117
2118 ieee80211_wake_queues_by_reason(&local->hw,
2119 IEEE80211_QUEUE_STOP_REASON_PS);
2120}
2121
2122void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
2123{
2124 struct ieee80211_local *local =
2125 container_of(work, struct ieee80211_local,
2126 dynamic_ps_enable_work);
2127 /* XXX: using scan_sdata is completely broken! */
2128 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
2129
2130 if (local->hw.conf.flags & IEEE80211_CONF_PS)
2131 return;
2132
2133 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata)
2134 ieee80211_send_nullfunc(local, sdata, 1);
2135
2136 local->hw.conf.flags |= IEEE80211_CONF_PS;
2137 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2138}
2139 2371
2140void ieee80211_dynamic_ps_timer(unsigned long data) 2372 return 0;
2141{
2142 struct ieee80211_local *local = (void *) data;
2143
2144 queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
2145}
2146
2147void ieee80211_send_nullfunc(struct ieee80211_local *local,
2148 struct ieee80211_sub_if_data *sdata,
2149 int powersave)
2150{
2151 struct sk_buff *skb;
2152 struct ieee80211_hdr *nullfunc;
2153 __le16 fc;
2154
2155 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
2156 return;
2157
2158 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
2159 if (!skb) {
2160 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
2161 "frame\n", sdata->dev->name);
2162 return;
2163 }
2164 skb_reserve(skb, local->hw.extra_tx_headroom);
2165
2166 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
2167 memset(nullfunc, 0, 24);
2168 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
2169 IEEE80211_FCTL_TODS);
2170 if (powersave)
2171 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
2172 nullfunc->frame_control = fc;
2173 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
2174 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
2175 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
2176
2177 ieee80211_tx_skb(sdata, skb, 0);
2178} 2373}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 81985d27cbda..b38986c9deef 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -72,119 +72,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
72 return 0; 72 return 0;
73} 73}
74 74
75int __ieee80211_resume(struct ieee80211_hw *hw) 75/*
76{ 76 * __ieee80211_resume() is a static inline which just calls
77 struct ieee80211_local *local = hw_to_local(hw); 77 * ieee80211_reconfig(), which is also needed for hardware
78 struct ieee80211_sub_if_data *sdata; 78 * hang/firmware failure/etc. recovery.
79 struct ieee80211_if_init_conf conf; 79 */
80 struct sta_info *sta;
81 unsigned long flags;
82 int res;
83
84 /* restart hardware */
85 if (local->open_count) {
86 res = local->ops->start(hw);
87
88 ieee80211_led_radio(local, hw->conf.radio_enabled);
89 }
90
91 /* add interfaces */
92 list_for_each_entry(sdata, &local->interfaces, list) {
93 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
94 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
95 netif_running(sdata->dev)) {
96 conf.vif = &sdata->vif;
97 conf.type = sdata->vif.type;
98 conf.mac_addr = sdata->dev->dev_addr;
99 res = local->ops->add_interface(hw, &conf);
100 }
101 }
102
103 /* add STAs back */
104 if (local->ops->sta_notify) {
105 spin_lock_irqsave(&local->sta_lock, flags);
106 list_for_each_entry(sta, &local->sta_list, list) {
107 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
108 sdata = container_of(sdata->bss,
109 struct ieee80211_sub_if_data,
110 u.ap);
111
112 local->ops->sta_notify(hw, &sdata->vif,
113 STA_NOTIFY_ADD, &sta->sta);
114 }
115 spin_unlock_irqrestore(&local->sta_lock, flags);
116 }
117
118 /* Clear Suspend state so that ADDBA requests can be processed */
119
120 rcu_read_lock();
121
122 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
123 list_for_each_entry_rcu(sta, &local->sta_list, list) {
124 clear_sta_flags(sta, WLAN_STA_SUSPEND);
125 }
126 }
127
128 rcu_read_unlock();
129
130 /* add back keys */
131 list_for_each_entry(sdata, &local->interfaces, list)
132 if (netif_running(sdata->dev))
133 ieee80211_enable_keys(sdata);
134
135 /* setup RTS threshold */
136 if (local->ops->set_rts_threshold)
137 local->ops->set_rts_threshold(hw, local->rts_threshold);
138
139 /* reconfigure hardware */
140 ieee80211_hw_config(local, ~0);
141
142 netif_addr_lock_bh(local->mdev);
143 ieee80211_configure_filter(local);
144 netif_addr_unlock_bh(local->mdev);
145
146 /* Finally also reconfigure all the BSS information */
147 list_for_each_entry(sdata, &local->interfaces, list) {
148 u32 changed = ~0;
149 if (!netif_running(sdata->dev))
150 continue;
151 switch (sdata->vif.type) {
152 case NL80211_IFTYPE_STATION:
153 /* disable beacon change bits */
154 changed &= ~IEEE80211_IFCC_BEACON;
155 /* fall through */
156 case NL80211_IFTYPE_ADHOC:
157 case NL80211_IFTYPE_AP:
158 case NL80211_IFTYPE_MESH_POINT:
159 /*
160 * Driver's config_interface can fail if rfkill is
161 * enabled. Accommodate this return code.
162 * FIXME: When mac80211 has knowledge of rfkill
163 * state the code below can change back to:
164 * WARN(ieee80211_if_config(sdata, changed));
165 * ieee80211_bss_info_change_notify(sdata, ~0);
166 */
167 if (ieee80211_if_config(sdata, changed))
168 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
169 sdata->dev->name);
170 else
171 ieee80211_bss_info_change_notify(sdata, ~0);
172 break;
173 case NL80211_IFTYPE_WDS:
174 break;
175 case NL80211_IFTYPE_AP_VLAN:
176 case NL80211_IFTYPE_MONITOR:
177 /* ignore virtual */
178 break;
179 case NL80211_IFTYPE_UNSPECIFIED:
180 case __NL80211_IFTYPE_AFTER_LAST:
181 WARN_ON(1);
182 break;
183 }
184 }
185
186 ieee80211_wake_queues_by_reason(hw,
187 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
188
189 return 0;
190}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9776f73c51ad..a5afb79dab6e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1932,7 +1932,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1932 !ieee80211_is_auth(hdr->frame_control)) 1932 !ieee80211_is_auth(hdr->frame_control))
1933 goto ignore; 1933 goto ignore;
1934 1934
1935 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr); 1935 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL);
1936 ignore: 1936 ignore:
1937 dev_kfree_skb(rx->skb); 1937 dev_kfree_skb(rx->skb);
1938 rx->skb = NULL; 1938 rx->skb = NULL;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 3bf9839f5916..f25b07feabf9 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -253,7 +253,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
253{ 253{
254 struct ieee80211_local *local = sdata->local; 254 struct ieee80211_local *local = sdata->local;
255 255
256 if (!local->powersave) 256 if (!local->ps_sdata)
257 ieee80211_send_nullfunc(local, sdata, 0); 257 ieee80211_send_nullfunc(local, sdata, 0);
258 else { 258 else {
259 /* 259 /*
@@ -285,12 +285,16 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
285 if (WARN_ON(!local->scan_req)) 285 if (WARN_ON(!local->scan_req))
286 return; 286 return;
287 287
288 if (local->hw_scanning) {
289 kfree(local->scan_req->ie);
290 local->scan_req->ie = local->orig_ies;
291 local->scan_req->ie_len = local->orig_ies_len;
292 }
293
288 if (local->scan_req != &local->int_scan_req) 294 if (local->scan_req != &local->int_scan_req)
289 cfg80211_scan_done(local->scan_req, aborted); 295 cfg80211_scan_done(local->scan_req, aborted);
290 local->scan_req = NULL; 296 local->scan_req = NULL;
291 297
292 local->last_scan_completed = jiffies;
293
294 if (local->hw_scanning) { 298 if (local->hw_scanning) {
295 local->hw_scanning = false; 299 local->hw_scanning = false;
296 /* 300 /*
@@ -457,12 +461,28 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
457 } 461 }
458 462
459 if (local->ops->hw_scan) { 463 if (local->ops->hw_scan) {
460 int rc; 464 u8 *ies;
465 int rc, ielen;
466
467 ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
468 local->scan_ies_len + req->ie_len, GFP_KERNEL);
469 if (!ies)
470 return -ENOMEM;
471
472 ielen = ieee80211_build_preq_ies(local, ies,
473 req->ie, req->ie_len);
474 local->orig_ies = req->ie;
475 local->orig_ies_len = req->ie_len;
476 req->ie = ies;
477 req->ie_len = ielen;
461 478
462 local->hw_scanning = true; 479 local->hw_scanning = true;
463 rc = local->ops->hw_scan(local_to_hw(local), req); 480 rc = local->ops->hw_scan(local_to_hw(local), req);
464 if (rc) { 481 if (rc) {
465 local->hw_scanning = false; 482 local->hw_scanning = false;
483 kfree(ies);
484 req->ie_len = local->orig_ies_len;
485 req->ie = local->orig_ies;
466 return rc; 486 return rc;
467 } 487 }
468 local->scan_sdata = scan_sdata; 488 local->scan_sdata = scan_sdata;
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 5f7a2624ed74..48bf78e7fa7a 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include <linux/ieee80211.h> 17#include <linux/ieee80211.h>
18#include <net/wireless.h> 18#include <net/cfg80211.h>
19#include <net/mac80211.h> 19#include <net/mac80211.h>
20#include "ieee80211_i.h" 20#include "ieee80211_i.h"
21#include "sta_info.h" 21#include "sta_info.h"
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c5f14e6bbde2..654a8e963ccb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -686,41 +686,10 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
686} 686}
687#endif 687#endif
688 688
689static void __ieee80211_run_pending_flush(struct ieee80211_local *local)
690{
691 struct sta_info *sta;
692 unsigned long flags;
693
694 ASSERT_RTNL();
695
696 spin_lock_irqsave(&local->sta_lock, flags);
697 while (!list_empty(&local->sta_flush_list)) {
698 sta = list_first_entry(&local->sta_flush_list,
699 struct sta_info, list);
700 list_del(&sta->list);
701 spin_unlock_irqrestore(&local->sta_lock, flags);
702 sta_info_destroy(sta);
703 spin_lock_irqsave(&local->sta_lock, flags);
704 }
705 spin_unlock_irqrestore(&local->sta_lock, flags);
706}
707
708static void ieee80211_sta_flush_work(struct work_struct *work)
709{
710 struct ieee80211_local *local =
711 container_of(work, struct ieee80211_local, sta_flush_work);
712
713 rtnl_lock();
714 __ieee80211_run_pending_flush(local);
715 rtnl_unlock();
716}
717
718void sta_info_init(struct ieee80211_local *local) 689void sta_info_init(struct ieee80211_local *local)
719{ 690{
720 spin_lock_init(&local->sta_lock); 691 spin_lock_init(&local->sta_lock);
721 INIT_LIST_HEAD(&local->sta_list); 692 INIT_LIST_HEAD(&local->sta_list);
722 INIT_LIST_HEAD(&local->sta_flush_list);
723 INIT_WORK(&local->sta_flush_work, ieee80211_sta_flush_work);
724 693
725 setup_timer(&local->sta_cleanup, sta_info_cleanup, 694 setup_timer(&local->sta_cleanup, sta_info_cleanup,
726 (unsigned long)local); 695 (unsigned long)local);
@@ -741,7 +710,6 @@ int sta_info_start(struct ieee80211_local *local)
741void sta_info_stop(struct ieee80211_local *local) 710void sta_info_stop(struct ieee80211_local *local)
742{ 711{
743 del_timer(&local->sta_cleanup); 712 del_timer(&local->sta_cleanup);
744 cancel_work_sync(&local->sta_flush_work);
745#ifdef CONFIG_MAC80211_DEBUGFS 713#ifdef CONFIG_MAC80211_DEBUGFS
746 /* 714 /*
747 * Make sure the debugfs adding work isn't pending after this 715 * Make sure the debugfs adding work isn't pending after this
@@ -752,10 +720,7 @@ void sta_info_stop(struct ieee80211_local *local)
752 cancel_work_sync(&local->sta_debugfs_add); 720 cancel_work_sync(&local->sta_debugfs_add);
753#endif 721#endif
754 722
755 rtnl_lock();
756 sta_info_flush(local, NULL); 723 sta_info_flush(local, NULL);
757 __ieee80211_run_pending_flush(local);
758 rtnl_unlock();
759} 724}
760 725
761/** 726/**
@@ -767,7 +732,7 @@ void sta_info_stop(struct ieee80211_local *local)
767 * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 732 * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs
768 */ 733 */
769int sta_info_flush(struct ieee80211_local *local, 734int sta_info_flush(struct ieee80211_local *local,
770 struct ieee80211_sub_if_data *sdata) 735 struct ieee80211_sub_if_data *sdata)
771{ 736{
772 struct sta_info *sta, *tmp; 737 struct sta_info *sta, *tmp;
773 LIST_HEAD(tmp_list); 738 LIST_HEAD(tmp_list);
@@ -775,7 +740,6 @@ int sta_info_flush(struct ieee80211_local *local,
775 unsigned long flags; 740 unsigned long flags;
776 741
777 might_sleep(); 742 might_sleep();
778 ASSERT_RTNL();
779 743
780 spin_lock_irqsave(&local->sta_lock, flags); 744 spin_lock_irqsave(&local->sta_lock, flags);
781 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 745 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
@@ -795,39 +759,6 @@ int sta_info_flush(struct ieee80211_local *local,
795 return ret; 759 return ret;
796} 760}
797 761
798/**
799 * sta_info_flush_delayed - flush matching STA entries from the STA table
800 *
801 * This function unlinks all stations for a given interface and queues
802 * them for freeing. Note that the workqueue function scheduled here has
803 * to run before any new keys can be added to the system to avoid set_key()
804 * callback ordering issues.
805 *
806 * @sdata: the interface
807 */
808void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata)
809{
810 struct ieee80211_local *local = sdata->local;
811 struct sta_info *sta, *tmp;
812 unsigned long flags;
813 bool work = false;
814
815 spin_lock_irqsave(&local->sta_lock, flags);
816 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
817 if (sdata == sta->sdata) {
818 __sta_info_unlink(&sta);
819 if (sta) {
820 list_add_tail(&sta->list,
821 &local->sta_flush_list);
822 work = true;
823 }
824 }
825 }
826 if (work)
827 schedule_work(&local->sta_flush_work);
828 spin_unlock_irqrestore(&local->sta_lock, flags);
829}
830
831void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 762void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
832 unsigned long exp_time) 763 unsigned long exp_time)
833{ 764{
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 5534d489f506..31a8990ce401 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -442,8 +442,7 @@ void sta_info_init(struct ieee80211_local *local);
442int sta_info_start(struct ieee80211_local *local); 442int sta_info_start(struct ieee80211_local *local);
443void sta_info_stop(struct ieee80211_local *local); 443void sta_info_stop(struct ieee80211_local *local);
444int sta_info_flush(struct ieee80211_local *local, 444int sta_info_flush(struct ieee80211_local *local,
445 struct ieee80211_sub_if_data *sdata); 445 struct ieee80211_sub_if_data *sdata);
446void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata);
447void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 446void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
448 unsigned long exp_time); 447 unsigned long exp_time);
449 448
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3fb04a86444d..1865622003c9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -409,8 +409,24 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
409 sta->sta.addr); 409 sta->sta.addr);
410 } 410 }
411#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 411#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
412 clear_sta_flags(sta, WLAN_STA_PSPOLL); 412 if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
413 /*
414 * The sleeping station with pending data is now snoozing.
415 * It queried us for its buffered frames and will go back
416 * to deep sleep once it got everything.
417 *
418 * inform the driver, in case the hardware does powersave
419 * frame filtering and keeps a station blacklist on its own
420 * (e.g: p54), so that frames can be delivered unimpeded.
421 *
422 * Note: It should be save to disable the filter now.
423 * As, it is really unlikely that we still have any pending
424 * frame for this station in the hw's buffers/fifos left,
425 * that is not rejected with a unsuccessful tx_status yet.
426 */
413 427
428 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
429 }
414 return TX_CONTINUE; 430 return TX_CONTINUE;
415} 431}
416 432
@@ -429,7 +445,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
429static ieee80211_tx_result debug_noinline 445static ieee80211_tx_result debug_noinline
430ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) 446ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
431{ 447{
432 struct ieee80211_key *key; 448 struct ieee80211_key *key = NULL;
433 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 449 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
434 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 450 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
435 451
@@ -500,7 +516,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
500 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 516 sband = tx->local->hw.wiphy->bands[tx->channel->band];
501 517
502 len = min_t(int, tx->skb->len + FCS_LEN, 518 len = min_t(int, tx->skb->len + FCS_LEN,
503 tx->local->fragmentation_threshold); 519 tx->local->hw.wiphy->frag_threshold);
504 520
505 /* set up the tx rate control struct we give the RC algo */ 521 /* set up the tx rate control struct we give the RC algo */
506 txrc.hw = local_to_hw(tx->local); 522 txrc.hw = local_to_hw(tx->local);
@@ -511,8 +527,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
511 txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; 527 txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx;
512 528
513 /* set up RTS protection if desired */ 529 /* set up RTS protection if desired */
514 if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && 530 if (len > tx->local->hw.wiphy->rts_threshold) {
515 len > tx->local->rts_threshold) {
516 txrc.rts = rts = true; 531 txrc.rts = rts = true;
517 } 532 }
518 533
@@ -754,7 +769,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
754 struct sk_buff *skb = tx->skb; 769 struct sk_buff *skb = tx->skb;
755 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 770 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
756 struct ieee80211_hdr *hdr = (void *)skb->data; 771 struct ieee80211_hdr *hdr = (void *)skb->data;
757 int frag_threshold = tx->local->fragmentation_threshold; 772 int frag_threshold = tx->local->hw.wiphy->frag_threshold;
758 int hdrlen; 773 int hdrlen;
759 int fragnum; 774 int fragnum;
760 775
@@ -1072,7 +1087,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1072 1087
1073 if (tx->flags & IEEE80211_TX_FRAGMENTED) { 1088 if (tx->flags & IEEE80211_TX_FRAGMENTED) {
1074 if ((tx->flags & IEEE80211_TX_UNICAST) && 1089 if ((tx->flags & IEEE80211_TX_UNICAST) &&
1075 skb->len + FCS_LEN > local->fragmentation_threshold && 1090 skb->len + FCS_LEN > local->hw.wiphy->frag_threshold &&
1076 !(info->flags & IEEE80211_TX_CTL_AMPDU)) 1091 !(info->flags & IEEE80211_TX_CTL_AMPDU))
1077 tx->flags |= IEEE80211_TX_FRAGMENTED; 1092 tx->flags |= IEEE80211_TX_FRAGMENTED;
1078 else 1093 else
@@ -2086,18 +2101,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
2086 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 2101 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2087 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 2102 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2088 struct ieee80211_hdr *hdr; 2103 struct ieee80211_hdr *hdr;
2104 struct sk_buff *presp = rcu_dereference(ifibss->presp);
2089 2105
2090 if (!ifibss->probe_resp) 2106 if (!presp)
2091 goto out; 2107 goto out;
2092 2108
2093 skb = skb_copy(ifibss->probe_resp, GFP_ATOMIC); 2109 skb = skb_copy(presp, GFP_ATOMIC);
2094 if (!skb) 2110 if (!skb)
2095 goto out; 2111 goto out;
2096 2112
2097 hdr = (struct ieee80211_hdr *) skb->data; 2113 hdr = (struct ieee80211_hdr *) skb->data;
2098 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2114 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2099 IEEE80211_STYPE_BEACON); 2115 IEEE80211_STYPE_BEACON);
2100
2101 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 2116 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
2102 struct ieee80211_mgmt *mgmt; 2117 struct ieee80211_mgmt *mgmt;
2103 u8 *pos; 2118 u8 *pos;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index fdf432f14554..61876eb50b49 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -20,6 +20,7 @@
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/bitmap.h> 22#include <linux/bitmap.h>
23#include <linux/crc32.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/cfg80211.h> 25#include <net/cfg80211.h>
25#include <net/rtnetlink.h> 26#include <net/rtnetlink.h>
@@ -28,6 +29,7 @@
28#include "rate.h" 29#include "rate.h"
29#include "mesh.h" 30#include "mesh.h"
30#include "wme.h" 31#include "wme.h"
32#include "led.h"
31 33
32/* privid for wiphys to determine whether they belong to us or not */ 34/* privid for wiphys to determine whether they belong to us or not */
33void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 35void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -536,8 +538,16 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
536void ieee802_11_parse_elems(u8 *start, size_t len, 538void ieee802_11_parse_elems(u8 *start, size_t len,
537 struct ieee802_11_elems *elems) 539 struct ieee802_11_elems *elems)
538{ 540{
541 ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
542}
543
544u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
545 struct ieee802_11_elems *elems,
546 u64 filter, u32 crc)
547{
539 size_t left = len; 548 size_t left = len;
540 u8 *pos = start; 549 u8 *pos = start;
550 bool calc_crc = filter != 0;
541 551
542 memset(elems, 0, sizeof(*elems)); 552 memset(elems, 0, sizeof(*elems));
543 elems->ie_start = start; 553 elems->ie_start = start;
@@ -551,7 +561,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
551 left -= 2; 561 left -= 2;
552 562
553 if (elen > left) 563 if (elen > left)
554 return; 564 break;
565
566 if (calc_crc && id < 64 && (filter & BIT(id)))
567 crc = crc32_be(crc, pos - 2, elen + 2);
555 568
556 switch (id) { 569 switch (id) {
557 case WLAN_EID_SSID: 570 case WLAN_EID_SSID:
@@ -575,8 +588,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
575 elems->cf_params_len = elen; 588 elems->cf_params_len = elen;
576 break; 589 break;
577 case WLAN_EID_TIM: 590 case WLAN_EID_TIM:
578 elems->tim = pos; 591 if (elen >= sizeof(struct ieee80211_tim_ie)) {
579 elems->tim_len = elen; 592 elems->tim = (void *)pos;
593 elems->tim_len = elen;
594 }
580 break; 595 break;
581 case WLAN_EID_IBSS_PARAMS: 596 case WLAN_EID_IBSS_PARAMS:
582 elems->ibss_params = pos; 597 elems->ibss_params = pos;
@@ -586,15 +601,20 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
586 elems->challenge = pos; 601 elems->challenge = pos;
587 elems->challenge_len = elen; 602 elems->challenge_len = elen;
588 break; 603 break;
589 case WLAN_EID_WPA: 604 case WLAN_EID_VENDOR_SPECIFIC:
590 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 605 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
591 pos[2] == 0xf2) { 606 pos[2] == 0xf2) {
592 /* Microsoft OUI (00:50:F2) */ 607 /* Microsoft OUI (00:50:F2) */
608
609 if (calc_crc)
610 crc = crc32_be(crc, pos - 2, elen + 2);
611
593 if (pos[3] == 1) { 612 if (pos[3] == 1) {
594 /* OUI Type 1 - WPA IE */ 613 /* OUI Type 1 - WPA IE */
595 elems->wpa = pos; 614 elems->wpa = pos;
596 elems->wpa_len = elen; 615 elems->wpa_len = elen;
597 } else if (elen >= 5 && pos[3] == 2) { 616 } else if (elen >= 5 && pos[3] == 2) {
617 /* OUI Type 2 - WMM IE */
598 if (pos[4] == 0) { 618 if (pos[4] == 0) {
599 elems->wmm_info = pos; 619 elems->wmm_info = pos;
600 elems->wmm_info_len = elen; 620 elems->wmm_info_len = elen;
@@ -679,6 +699,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
679 left -= elen; 699 left -= elen;
680 pos += elen; 700 pos += elen;
681 } 701 }
702
703 return crc;
682} 704}
683 705
684void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) 706void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
@@ -831,16 +853,73 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
831 ieee80211_tx_skb(sdata, skb, encrypt); 853 ieee80211_tx_skb(sdata, skb, encrypt);
832} 854}
833 855
856int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
857 const u8 *ie, size_t ie_len)
858{
859 struct ieee80211_supported_band *sband;
860 u8 *pos, *supp_rates_len, *esupp_rates_len = NULL;
861 int i;
862
863 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
864
865 pos = buffer;
866
867 *pos++ = WLAN_EID_SUPP_RATES;
868 supp_rates_len = pos;
869 *pos++ = 0;
870
871 for (i = 0; i < sband->n_bitrates; i++) {
872 struct ieee80211_rate *rate = &sband->bitrates[i];
873
874 if (esupp_rates_len) {
875 *esupp_rates_len += 1;
876 } else if (*supp_rates_len == 8) {
877 *pos++ = WLAN_EID_EXT_SUPP_RATES;
878 esupp_rates_len = pos;
879 *pos++ = 1;
880 } else
881 *supp_rates_len += 1;
882
883 *pos++ = rate->bitrate / 5;
884 }
885
886 if (sband->ht_cap.ht_supported) {
887 __le16 tmp = cpu_to_le16(sband->ht_cap.cap);
888
889 *pos++ = WLAN_EID_HT_CAPABILITY;
890 *pos++ = sizeof(struct ieee80211_ht_cap);
891 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
892 memcpy(pos, &tmp, sizeof(u16));
893 pos += sizeof(u16);
894 /* TODO: needs a define here for << 2 */
895 *pos++ = sband->ht_cap.ampdu_factor |
896 (sband->ht_cap.ampdu_density << 2);
897 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
898 pos += sizeof(sband->ht_cap.mcs);
899 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
900 }
901
902 /*
903 * If adding more here, adjust code in main.c
904 * that calculates local->scan_ies_len.
905 */
906
907 if (ie) {
908 memcpy(pos, ie, ie_len);
909 pos += ie_len;
910 }
911
912 return pos - buffer;
913}
914
834void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 915void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
835 u8 *ssid, size_t ssid_len, 916 const u8 *ssid, size_t ssid_len,
836 u8 *ie, size_t ie_len) 917 const u8 *ie, size_t ie_len)
837{ 918{
838 struct ieee80211_local *local = sdata->local; 919 struct ieee80211_local *local = sdata->local;
839 struct ieee80211_supported_band *sband;
840 struct sk_buff *skb; 920 struct sk_buff *skb;
841 struct ieee80211_mgmt *mgmt; 921 struct ieee80211_mgmt *mgmt;
842 u8 *pos, *supp_rates, *esupp_rates = NULL; 922 u8 *pos;
843 int i;
844 923
845 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 924 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
846 ie_len); 925 ie_len);
@@ -867,31 +946,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
867 *pos++ = WLAN_EID_SSID; 946 *pos++ = WLAN_EID_SSID;
868 *pos++ = ssid_len; 947 *pos++ = ssid_len;
869 memcpy(pos, ssid, ssid_len); 948 memcpy(pos, ssid, ssid_len);
949 pos += ssid_len;
870 950
871 supp_rates = skb_put(skb, 2); 951 skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len));
872 supp_rates[0] = WLAN_EID_SUPP_RATES;
873 supp_rates[1] = 0;
874 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
875
876 for (i = 0; i < sband->n_bitrates; i++) {
877 struct ieee80211_rate *rate = &sband->bitrates[i];
878 if (esupp_rates) {
879 pos = skb_put(skb, 1);
880 esupp_rates[1]++;
881 } else if (supp_rates[1] == 8) {
882 esupp_rates = skb_put(skb, 3);
883 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
884 esupp_rates[1] = 1;
885 pos = &esupp_rates[2];
886 } else {
887 pos = skb_put(skb, 1);
888 supp_rates[1]++;
889 }
890 *pos = rate->bitrate / 5;
891 }
892
893 if (ie)
894 memcpy(skb_put(skb, ie_len), ie, ie_len);
895 952
896 ieee80211_tx_skb(sdata, skb, 0); 953 ieee80211_tx_skb(sdata, skb, 0);
897} 954}
@@ -931,3 +988,120 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
931 } 988 }
932 return supp_rates; 989 return supp_rates;
933} 990}
991
992int ieee80211_reconfig(struct ieee80211_local *local)
993{
994 struct ieee80211_hw *hw = &local->hw;
995 struct ieee80211_sub_if_data *sdata;
996 struct ieee80211_if_init_conf conf;
997 struct sta_info *sta;
998 unsigned long flags;
999 int res;
1000
1001 /* restart hardware */
1002 if (local->open_count) {
1003 res = local->ops->start(hw);
1004
1005 ieee80211_led_radio(local, hw->conf.radio_enabled);
1006 }
1007
1008 /* add interfaces */
1009 list_for_each_entry(sdata, &local->interfaces, list) {
1010 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1011 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1012 netif_running(sdata->dev)) {
1013 conf.vif = &sdata->vif;
1014 conf.type = sdata->vif.type;
1015 conf.mac_addr = sdata->dev->dev_addr;
1016 res = local->ops->add_interface(hw, &conf);
1017 }
1018 }
1019
1020 /* add STAs back */
1021 if (local->ops->sta_notify) {
1022 spin_lock_irqsave(&local->sta_lock, flags);
1023 list_for_each_entry(sta, &local->sta_list, list) {
1024 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1025 sdata = container_of(sdata->bss,
1026 struct ieee80211_sub_if_data,
1027 u.ap);
1028
1029 local->ops->sta_notify(hw, &sdata->vif,
1030 STA_NOTIFY_ADD, &sta->sta);
1031 }
1032 spin_unlock_irqrestore(&local->sta_lock, flags);
1033 }
1034
1035 /* Clear Suspend state so that ADDBA requests can be processed */
1036
1037 rcu_read_lock();
1038
1039 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1040 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1041 clear_sta_flags(sta, WLAN_STA_SUSPEND);
1042 }
1043 }
1044
1045 rcu_read_unlock();
1046
1047 /* setup RTS threshold */
1048 if (local->ops->set_rts_threshold)
1049 local->ops->set_rts_threshold(hw, hw->wiphy->rts_threshold);
1050
1051 /* reconfigure hardware */
1052 ieee80211_hw_config(local, ~0);
1053
1054 netif_addr_lock_bh(local->mdev);
1055 ieee80211_configure_filter(local);
1056 netif_addr_unlock_bh(local->mdev);
1057
1058 /* Finally also reconfigure all the BSS information */
1059 list_for_each_entry(sdata, &local->interfaces, list) {
1060 u32 changed = ~0;
1061 if (!netif_running(sdata->dev))
1062 continue;
1063 switch (sdata->vif.type) {
1064 case NL80211_IFTYPE_STATION:
1065 /* disable beacon change bits */
1066 changed &= ~IEEE80211_IFCC_BEACON;
1067 /* fall through */
1068 case NL80211_IFTYPE_ADHOC:
1069 case NL80211_IFTYPE_AP:
1070 case NL80211_IFTYPE_MESH_POINT:
1071 /*
1072 * Driver's config_interface can fail if rfkill is
1073 * enabled. Accommodate this return code.
1074 * FIXME: When mac80211 has knowledge of rfkill
1075 * state the code below can change back to:
1076 * WARN(ieee80211_if_config(sdata, changed));
1077 * ieee80211_bss_info_change_notify(sdata, ~0);
1078 */
1079 if (ieee80211_if_config(sdata, changed))
1080 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
1081 sdata->dev->name);
1082 else
1083 ieee80211_bss_info_change_notify(sdata, ~0);
1084 break;
1085 case NL80211_IFTYPE_WDS:
1086 break;
1087 case NL80211_IFTYPE_AP_VLAN:
1088 case NL80211_IFTYPE_MONITOR:
1089 /* ignore virtual */
1090 break;
1091 case NL80211_IFTYPE_UNSPECIFIED:
1092 case __NL80211_IFTYPE_AFTER_LAST:
1093 WARN_ON(1);
1094 break;
1095 }
1096 }
1097
1098 /* add back keys */
1099 list_for_each_entry(sdata, &local->interfaces, list)
1100 if (netif_running(sdata->dev))
1101 ieee80211_enable_keys(sdata);
1102
1103 ieee80211_wake_queues_by_reason(hw,
1104 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1105
1106 return 0;
1107}
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 959aa8379ccf..1a649da42c41 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -149,17 +149,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
149 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 149 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
150 150
151 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 151 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
152 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL; 152 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
153 else if (sdata->vif.type == NL80211_IFTYPE_STATION) 153 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
154 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 154 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
155 155
156 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 156 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
157 if (freq->e == 0) { 157 if (freq->e == 0) {
158 if (freq->m < 0) { 158 if (freq->m < 0) {
159 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 159 if (sdata->vif.type == NL80211_IFTYPE_STATION)
160 sdata->u.ibss.flags |=
161 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
162 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
163 sdata->u.mgd.flags |= 160 sdata->u.mgd.flags |=
164 IEEE80211_STA_AUTO_CHANNEL_SEL; 161 IEEE80211_STA_AUTO_CHANNEL_SEL;
165 return 0; 162 return 0;
@@ -183,6 +180,10 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
183 struct iw_freq *freq, char *extra) 180 struct iw_freq *freq, char *extra)
184{ 181{
185 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 182 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
184
185 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
186 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
186 187
187 freq->m = local->hw.conf.channel->center_freq; 188 freq->m = local->hw.conf.channel->center_freq;
188 freq->e = 6; 189 freq->e = 6;
@@ -195,15 +196,17 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
195 struct iw_request_info *info, 196 struct iw_request_info *info,
196 struct iw_point *data, char *ssid) 197 struct iw_point *data, char *ssid)
197{ 198{
198 struct ieee80211_sub_if_data *sdata; 199 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
199 size_t len = data->length; 200 size_t len = data->length;
200 int ret; 201 int ret;
201 202
203 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
204 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
205
202 /* iwconfig uses nul termination in SSID.. */ 206 /* iwconfig uses nul termination in SSID.. */
203 if (len > 0 && ssid[len - 1] == '\0') 207 if (len > 0 && ssid[len - 1] == '\0')
204 len--; 208 len--;
205 209
206 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
207 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 210 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
208 if (data->flags) 211 if (data->flags)
209 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 212 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
@@ -217,8 +220,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
217 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 220 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
218 ieee80211_sta_req_auth(sdata); 221 ieee80211_sta_req_auth(sdata);
219 return 0; 222 return 0;
220 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 223 }
221 return ieee80211_ibss_set_ssid(sdata, ssid, len);
222 224
223 return -EOPNOTSUPP; 225 return -EOPNOTSUPP;
224} 226}
@@ -229,9 +231,13 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
229 struct iw_point *data, char *ssid) 231 struct iw_point *data, char *ssid)
230{ 232{
231 size_t len; 233 size_t len;
232
233 struct ieee80211_sub_if_data *sdata; 234 struct ieee80211_sub_if_data *sdata;
235
234 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 236 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
237
238 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
239 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
240
235 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 241 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
236 int res = ieee80211_sta_get_ssid(sdata, ssid, &len); 242 int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
237 if (res == 0) { 243 if (res == 0) {
@@ -240,14 +246,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
240 } else 246 } else
241 data->flags = 0; 247 data->flags = 0;
242 return res; 248 return res;
243 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
244 int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
245 if (res == 0) {
246 data->length = len;
247 data->flags = 1;
248 } else
249 data->flags = 0;
250 return res;
251 } 249 }
252 250
253 return -EOPNOTSUPP; 251 return -EOPNOTSUPP;
@@ -258,9 +256,11 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
258 struct iw_request_info *info, 256 struct iw_request_info *info,
259 struct sockaddr *ap_addr, char *extra) 257 struct sockaddr *ap_addr, char *extra)
260{ 258{
261 struct ieee80211_sub_if_data *sdata; 259 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
260
261 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
262 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
262 263
263 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
264 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 264 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
265 int ret; 265 int ret;
266 266
@@ -277,16 +277,6 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
277 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 277 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
278 ieee80211_sta_req_auth(sdata); 278 ieee80211_sta_req_auth(sdata);
279 return 0; 279 return 0;
280 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
281 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
282 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
283 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
284 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
285 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
286 else
287 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
288
289 return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
290 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 280 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
291 /* 281 /*
292 * If it is necessary to update the WDS peer address 282 * If it is necessary to update the WDS peer address
@@ -312,9 +302,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
312 struct iw_request_info *info, 302 struct iw_request_info *info,
313 struct sockaddr *ap_addr, char *extra) 303 struct sockaddr *ap_addr, char *extra)
314{ 304{
315 struct ieee80211_sub_if_data *sdata; 305 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
306
307 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
308 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
316 309
317 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
318 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 310 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
319 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) { 311 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
320 ap_addr->sa_family = ARPHRD_ETHER; 312 ap_addr->sa_family = ARPHRD_ETHER;
@@ -322,13 +314,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
322 } else 314 } else
323 memset(&ap_addr->sa_data, 0, ETH_ALEN); 315 memset(&ap_addr->sa_data, 0, ETH_ALEN);
324 return 0; 316 return 0;
325 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
326 if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
327 ap_addr->sa_family = ARPHRD_ETHER;
328 memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
329 } else
330 memset(&ap_addr->sa_data, 0, ETH_ALEN);
331 return 0;
332 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 317 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
333 ap_addr->sa_family = ARPHRD_ETHER; 318 ap_addr->sa_family = ARPHRD_ETHER;
334 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 319 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -487,155 +472,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
487 return 0; 472 return 0;
488} 473}
489 474
490static int ieee80211_ioctl_siwrts(struct net_device *dev,
491 struct iw_request_info *info,
492 struct iw_param *rts, char *extra)
493{
494 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
495
496 if (rts->disabled)
497 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
498 else if (!rts->fixed)
499 /* if the rts value is not fixed, then take default */
500 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
501 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
502 return -EINVAL;
503 else
504 local->rts_threshold = rts->value;
505
506 /* If the wlan card performs RTS/CTS in hardware/firmware,
507 * configure it here */
508
509 if (local->ops->set_rts_threshold)
510 local->ops->set_rts_threshold(local_to_hw(local),
511 local->rts_threshold);
512
513 return 0;
514}
515
516static int ieee80211_ioctl_giwrts(struct net_device *dev,
517 struct iw_request_info *info,
518 struct iw_param *rts, char *extra)
519{
520 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
521
522 rts->value = local->rts_threshold;
523 rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
524 rts->fixed = 1;
525
526 return 0;
527}
528
529
530static int ieee80211_ioctl_siwfrag(struct net_device *dev,
531 struct iw_request_info *info,
532 struct iw_param *frag, char *extra)
533{
534 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
535
536 if (frag->disabled)
537 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
538 else if (!frag->fixed)
539 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
540 else if (frag->value < 256 ||
541 frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
542 return -EINVAL;
543 else {
544 /* Fragment length must be even, so strip LSB. */
545 local->fragmentation_threshold = frag->value & ~0x1;
546 }
547
548 return 0;
549}
550
551static int ieee80211_ioctl_giwfrag(struct net_device *dev,
552 struct iw_request_info *info,
553 struct iw_param *frag, char *extra)
554{
555 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
556
557 frag->value = local->fragmentation_threshold;
558 frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD);
559 frag->fixed = 1;
560
561 return 0;
562}
563
564
565static int ieee80211_ioctl_siwretry(struct net_device *dev,
566 struct iw_request_info *info,
567 struct iw_param *retry, char *extra)
568{
569 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
570
571 if (retry->disabled ||
572 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
573 return -EINVAL;
574
575 if (retry->flags & IW_RETRY_MAX) {
576 local->hw.conf.long_frame_max_tx_count = retry->value;
577 } else if (retry->flags & IW_RETRY_MIN) {
578 local->hw.conf.short_frame_max_tx_count = retry->value;
579 } else {
580 local->hw.conf.long_frame_max_tx_count = retry->value;
581 local->hw.conf.short_frame_max_tx_count = retry->value;
582 }
583
584 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
585
586 return 0;
587}
588
589
590static int ieee80211_ioctl_giwretry(struct net_device *dev,
591 struct iw_request_info *info,
592 struct iw_param *retry, char *extra)
593{
594 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
595
596 retry->disabled = 0;
597 if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
598 /* first return min value, iwconfig will ask max value
599 * later if needed */
600 retry->flags |= IW_RETRY_LIMIT;
601 retry->value = local->hw.conf.short_frame_max_tx_count;
602 if (local->hw.conf.long_frame_max_tx_count !=
603 local->hw.conf.short_frame_max_tx_count)
604 retry->flags |= IW_RETRY_MIN;
605 return 0;
606 }
607 if (retry->flags & IW_RETRY_MAX) {
608 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
609 retry->value = local->hw.conf.long_frame_max_tx_count;
610 }
611
612 return 0;
613}
614
615static int ieee80211_ioctl_siwmlme(struct net_device *dev,
616 struct iw_request_info *info,
617 struct iw_point *data, char *extra)
618{
619 struct ieee80211_sub_if_data *sdata;
620 struct iw_mlme *mlme = (struct iw_mlme *) extra;
621
622 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
623 if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
624 return -EINVAL;
625
626 switch (mlme->cmd) {
627 case IW_MLME_DEAUTH:
628 /* TODO: mlme->addr.sa_data */
629 return ieee80211_sta_deauthenticate(sdata, mlme->reason_code);
630 case IW_MLME_DISASSOC:
631 /* TODO: mlme->addr.sa_data */
632 return ieee80211_sta_disassociate(sdata, mlme->reason_code);
633 default:
634 return -EOPNOTSUPP;
635 }
636}
637
638
639static int ieee80211_ioctl_siwencode(struct net_device *dev, 475static int ieee80211_ioctl_siwencode(struct net_device *dev,
640 struct iw_request_info *info, 476 struct iw_request_info *info,
641 struct iw_point *erq, char *keybuf) 477 struct iw_point *erq, char *keybuf)
@@ -675,7 +511,7 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev,
675 !sdata->default_key, 511 !sdata->default_key,
676 keybuf, erq->length); 512 keybuf, erq->length);
677 513
678 if (!ret) { 514 if (!ret && sdata->vif.type == NL80211_IFTYPE_STATION) {
679 if (remove) 515 if (remove)
680 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED; 516 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
681 else 517 else
@@ -747,7 +583,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
747 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 583 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
748 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 584 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
749 struct ieee80211_conf *conf = &local->hw.conf; 585 struct ieee80211_conf *conf = &local->hw.conf;
750 int ret = 0, timeout = 0; 586 int timeout = 0;
751 bool ps; 587 bool ps;
752 588
753 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) 589 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -779,42 +615,18 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
779 timeout = wrq->value / 1000; 615 timeout = wrq->value / 1000;
780 616
781 set: 617 set:
782 if (ps == local->powersave && timeout == conf->dynamic_ps_timeout) 618 if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
783 return ret; 619 return 0;
784 620
785 local->powersave = ps; 621 sdata->u.mgd.powersave = ps;
786 conf->dynamic_ps_timeout = timeout; 622 conf->dynamic_ps_timeout = timeout;
787 623
788 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 624 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
789 ret = ieee80211_hw_config(local, 625 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
790 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
791 626
792 if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) 627 ieee80211_recalc_ps(local, -1);
793 return ret;
794 628
795 if (conf->dynamic_ps_timeout > 0 && 629 return 0;
796 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
797 mod_timer(&local->dynamic_ps_timer, jiffies +
798 msecs_to_jiffies(conf->dynamic_ps_timeout));
799 } else {
800 if (local->powersave) {
801 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
802 ieee80211_send_nullfunc(local, sdata, 1);
803 conf->flags |= IEEE80211_CONF_PS;
804 ret = ieee80211_hw_config(local,
805 IEEE80211_CONF_CHANGE_PS);
806 } else {
807 conf->flags &= ~IEEE80211_CONF_PS;
808 ret = ieee80211_hw_config(local,
809 IEEE80211_CONF_CHANGE_PS);
810 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
811 ieee80211_send_nullfunc(local, sdata, 0);
812 del_timer_sync(&local->dynamic_ps_timer);
813 cancel_work_sync(&local->dynamic_ps_enable_work);
814 }
815 }
816
817 return ret;
818} 630}
819 631
820static int ieee80211_ioctl_giwpower(struct net_device *dev, 632static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -822,9 +634,9 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
822 union iwreq_data *wrqu, 634 union iwreq_data *wrqu,
823 char *extra) 635 char *extra)
824{ 636{
825 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 637 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
826 638
827 wrqu->power.disabled = !local->powersave; 639 wrqu->power.disabled = !sdata->u.mgd.powersave;
828 640
829 return 0; 641 return 0;
830} 642}
@@ -1099,7 +911,7 @@ static const iw_handler ieee80211_handler[] =
1099 (iw_handler) NULL, /* SIOCGIWTHRSPY */ 911 (iw_handler) NULL, /* SIOCGIWTHRSPY */
1100 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ 912 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
1101 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ 913 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
1102 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */ 914 (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
1103 (iw_handler) NULL, /* SIOCGIWAPLIST */ 915 (iw_handler) NULL, /* SIOCGIWAPLIST */
1104 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ 916 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
1105 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ 917 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
@@ -1111,14 +923,14 @@ static const iw_handler ieee80211_handler[] =
1111 (iw_handler) NULL, /* -- hole -- */ 923 (iw_handler) NULL, /* -- hole -- */
1112 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */ 924 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
1113 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ 925 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
1114 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ 926 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
1115 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ 927 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
1116 (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */ 928 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
1117 (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */ 929 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
1118 (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ 930 (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */
1119 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ 931 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */
1120 (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */ 932 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
1121 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ 933 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
1122 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 934 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
1123 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 935 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
1124 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ 936 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 4f8bfea278f2..dcfae8884b86 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -122,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
122 return RX_DROP_UNUSABLE; 122 return RX_DROP_UNUSABLE;
123 123
124 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, 124 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
125 (void *) skb->data); 125 (void *) skb->data, NULL);
126 return RX_DROP_UNUSABLE; 126 return RX_DROP_UNUSABLE;
127 } 127 }
128 128
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 84efde97c5a7..60a34f3b5f65 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -47,12 +47,6 @@ enum rfkill_global_sched_op {
47 RFKILL_GLOBAL_OP_UNBLOCK, 47 RFKILL_GLOBAL_OP_UNBLOCK,
48}; 48};
49 49
50/*
51 * Currently, the code marked with RFKILL_NEED_SWSET is inactive.
52 * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the
53 * future, when such events are added, that code will be necessary.
54 */
55
56struct rfkill_task { 50struct rfkill_task {
57 struct delayed_work dwork; 51 struct delayed_work dwork;
58 52
@@ -65,14 +59,6 @@ struct rfkill_task {
65 /* pending regular switch operations (1=pending) */ 59 /* pending regular switch operations (1=pending) */
66 unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; 60 unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
67 61
68#ifdef RFKILL_NEED_SWSET
69 /* set operation pending (1=pending) */
70 unsigned long sw_setpending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
71
72 /* desired state for pending set operation (1=unblock) */
73 unsigned long sw_newstate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
74#endif
75
76 /* should the state be complemented (1=yes) */ 62 /* should the state be complemented (1=yes) */
77 unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; 63 unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
78 64
@@ -111,24 +97,6 @@ static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)
111 } 97 }
112} 98}
113 99
114#ifdef RFKILL_NEED_SWSET
115static void __rfkill_handle_normal_op(const enum rfkill_type type,
116 const bool sp, const bool s, const bool c)
117{
118 enum rfkill_state state;
119
120 if (sp)
121 state = (s) ? RFKILL_STATE_UNBLOCKED :
122 RFKILL_STATE_SOFT_BLOCKED;
123 else
124 state = rfkill_get_global_state(type);
125
126 if (c)
127 state = rfkill_state_complement(state);
128
129 rfkill_switch_all(type, state);
130}
131#else
132static void __rfkill_handle_normal_op(const enum rfkill_type type, 100static void __rfkill_handle_normal_op(const enum rfkill_type type,
133 const bool c) 101 const bool c)
134{ 102{
@@ -140,7 +108,6 @@ static void __rfkill_handle_normal_op(const enum rfkill_type type,
140 108
141 rfkill_switch_all(type, state); 109 rfkill_switch_all(type, state);
142} 110}
143#endif
144 111
145static void rfkill_task_handler(struct work_struct *work) 112static void rfkill_task_handler(struct work_struct *work)
146{ 113{
@@ -171,21 +138,11 @@ static void rfkill_task_handler(struct work_struct *work)
171 i < RFKILL_TYPE_MAX) { 138 i < RFKILL_TYPE_MAX) {
172 if (test_and_clear_bit(i, task->sw_pending)) { 139 if (test_and_clear_bit(i, task->sw_pending)) {
173 bool c; 140 bool c;
174#ifdef RFKILL_NEED_SWSET
175 bool sp, s;
176 sp = test_and_clear_bit(i,
177 task->sw_setpending);
178 s = test_bit(i, task->sw_newstate);
179#endif
180 c = test_and_clear_bit(i, 141 c = test_and_clear_bit(i,
181 task->sw_togglestate); 142 task->sw_togglestate);
182 spin_unlock_irq(&task->lock); 143 spin_unlock_irq(&task->lock);
183 144
184#ifdef RFKILL_NEED_SWSET
185 __rfkill_handle_normal_op(i, sp, s, c);
186#else
187 __rfkill_handle_normal_op(i, c); 145 __rfkill_handle_normal_op(i, c);
188#endif
189 146
190 spin_lock_irq(&task->lock); 147 spin_lock_irq(&task->lock);
191 } 148 }
@@ -238,32 +195,6 @@ static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)
238 spin_unlock_irqrestore(&rfkill_task.lock, flags); 195 spin_unlock_irqrestore(&rfkill_task.lock, flags);
239} 196}
240 197
241#ifdef RFKILL_NEED_SWSET
242/* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */
243
244static void rfkill_schedule_set(enum rfkill_type type,
245 enum rfkill_state desired_state)
246{
247 unsigned long flags;
248
249 if (rfkill_is_epo_lock_active())
250 return;
251
252 spin_lock_irqsave(&rfkill_task.lock, flags);
253 if (!rfkill_task.global_op_pending) {
254 set_bit(type, rfkill_task.sw_pending);
255 set_bit(type, rfkill_task.sw_setpending);
256 clear_bit(type, rfkill_task.sw_togglestate);
257 if (desired_state)
258 set_bit(type, rfkill_task.sw_newstate);
259 else
260 clear_bit(type, rfkill_task.sw_newstate);
261 rfkill_schedule_ratelimited();
262 }
263 spin_unlock_irqrestore(&rfkill_task.lock, flags);
264}
265#endif
266
267static void rfkill_schedule_toggle(enum rfkill_type type) 198static void rfkill_schedule_toggle(enum rfkill_type type)
268{ 199{
269 unsigned long flags; 200 unsigned long flags;
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 3eaa39403c13..e2d4510623f2 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -96,6 +96,7 @@ static void update_rfkill_state(struct rfkill *rfkill)
96 } 96 }
97 mutex_unlock(&rfkill->mutex); 97 mutex_unlock(&rfkill->mutex);
98 } 98 }
99 rfkill_led_trigger(rfkill, rfkill->state);
99} 100}
100 101
101/** 102/**
@@ -136,8 +137,9 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
136 oldstate = rfkill->state; 137 oldstate = rfkill->state;
137 138
138 if (rfkill->get_state && !force && 139 if (rfkill->get_state && !force &&
139 !rfkill->get_state(rfkill->data, &newstate)) 140 !rfkill->get_state(rfkill->data, &newstate)) {
140 rfkill->state = newstate; 141 rfkill->state = newstate;
142 }
141 143
142 switch (state) { 144 switch (state) {
143 case RFKILL_STATE_HARD_BLOCKED: 145 case RFKILL_STATE_HARD_BLOCKED:
@@ -172,6 +174,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
172 if (force || rfkill->state != oldstate) 174 if (force || rfkill->state != oldstate)
173 rfkill_uevent(rfkill); 175 rfkill_uevent(rfkill);
174 176
177 rfkill_led_trigger(rfkill, rfkill->state);
175 return retval; 178 return retval;
176} 179}
177 180
@@ -200,10 +203,11 @@ static void __rfkill_switch_all(const enum rfkill_type type,
200 203
201 rfkill_global_states[type].current_state = state; 204 rfkill_global_states[type].current_state = state;
202 list_for_each_entry(rfkill, &rfkill_list, node) { 205 list_for_each_entry(rfkill, &rfkill_list, node) {
203 if ((!rfkill->user_claim) && (rfkill->type == type)) { 206 if (rfkill->type == type) {
204 mutex_lock(&rfkill->mutex); 207 mutex_lock(&rfkill->mutex);
205 rfkill_toggle_radio(rfkill, state, 0); 208 rfkill_toggle_radio(rfkill, state, 0);
206 mutex_unlock(&rfkill->mutex); 209 mutex_unlock(&rfkill->mutex);
210 rfkill_led_trigger(rfkill, rfkill->state);
207 } 211 }
208 } 212 }
209} 213}
@@ -256,6 +260,7 @@ void rfkill_epo(void)
256 RFKILL_STATE_SOFT_BLOCKED; 260 RFKILL_STATE_SOFT_BLOCKED;
257 } 261 }
258 mutex_unlock(&rfkill_global_mutex); 262 mutex_unlock(&rfkill_global_mutex);
263 rfkill_led_trigger(rfkill, rfkill->state);
259} 264}
260EXPORT_SYMBOL_GPL(rfkill_epo); 265EXPORT_SYMBOL_GPL(rfkill_epo);
261 266
@@ -358,6 +363,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
358 rfkill_uevent(rfkill); 363 rfkill_uevent(rfkill);
359 364
360 mutex_unlock(&rfkill->mutex); 365 mutex_unlock(&rfkill->mutex);
366 rfkill_led_trigger(rfkill, rfkill->state);
361 367
362 return 0; 368 return 0;
363} 369}
@@ -447,53 +453,14 @@ static ssize_t rfkill_claim_show(struct device *dev,
447 struct device_attribute *attr, 453 struct device_attribute *attr,
448 char *buf) 454 char *buf)
449{ 455{
450 struct rfkill *rfkill = to_rfkill(dev); 456 return sprintf(buf, "%d\n", 0);
451
452 return sprintf(buf, "%d\n", rfkill->user_claim);
453} 457}
454 458
455static ssize_t rfkill_claim_store(struct device *dev, 459static ssize_t rfkill_claim_store(struct device *dev,
456 struct device_attribute *attr, 460 struct device_attribute *attr,
457 const char *buf, size_t count) 461 const char *buf, size_t count)
458{ 462{
459 struct rfkill *rfkill = to_rfkill(dev); 463 return -EOPNOTSUPP;
460 unsigned long claim_tmp;
461 bool claim;
462 int error;
463
464 if (!capable(CAP_NET_ADMIN))
465 return -EPERM;
466
467 if (rfkill->user_claim_unsupported)
468 return -EOPNOTSUPP;
469
470 error = strict_strtoul(buf, 0, &claim_tmp);
471 if (error)
472 return error;
473 claim = !!claim_tmp;
474
475 /*
476 * Take the global lock to make sure the kernel is not in
477 * the middle of rfkill_switch_all
478 */
479 error = mutex_lock_killable(&rfkill_global_mutex);
480 if (error)
481 return error;
482
483 if (rfkill->user_claim != claim) {
484 if (!claim && !rfkill_epo_lock_active) {
485 mutex_lock(&rfkill->mutex);
486 rfkill_toggle_radio(rfkill,
487 rfkill_global_states[rfkill->type].current_state,
488 0);
489 mutex_unlock(&rfkill->mutex);
490 }
491 rfkill->user_claim = claim;
492 }
493
494 mutex_unlock(&rfkill_global_mutex);
495
496 return error ? error : count;
497} 464}
498 465
499static struct device_attribute rfkill_dev_attrs[] = { 466static struct device_attribute rfkill_dev_attrs[] = {
@@ -559,6 +526,7 @@ static int rfkill_resume(struct device *dev)
559 1); 526 1);
560 527
561 mutex_unlock(&rfkill->mutex); 528 mutex_unlock(&rfkill->mutex);
529 rfkill_led_trigger(rfkill, rfkill->state);
562 } 530 }
563 531
564 return 0; 532 return 0;
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index 2b75aee04217..a3616e2ccb8a 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -113,7 +113,7 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
113 if (state != wimax_dev->rf_hw) { 113 if (state != wimax_dev->rf_hw) {
114 wimax_dev->rf_hw = state; 114 wimax_dev->rf_hw = state;
115 rfkill_state = state == WIMAX_RF_ON ? 115 rfkill_state = state == WIMAX_RF_ON ?
116 RFKILL_STATE_OFF : RFKILL_STATE_ON; 116 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
117 if (wimax_dev->rf_hw == WIMAX_RF_ON 117 if (wimax_dev->rf_hw == WIMAX_RF_ON
118 && wimax_dev->rf_sw == WIMAX_RF_ON) 118 && wimax_dev->rf_sw == WIMAX_RF_ON)
119 wimax_state = WIMAX_ST_READY; 119 wimax_state = WIMAX_ST_READY;
@@ -259,10 +259,10 @@ int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)
259 259
260 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); 260 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
261 switch (state) { 261 switch (state) {
262 case RFKILL_STATE_ON: 262 case RFKILL_STATE_SOFT_BLOCKED:
263 rf_state = WIMAX_RF_OFF; 263 rf_state = WIMAX_RF_OFF;
264 break; 264 break;
265 case RFKILL_STATE_OFF: 265 case RFKILL_STATE_UNBLOCKED:
266 rf_state = WIMAX_RF_ON; 266 rf_state = WIMAX_RF_ON;
267 break; 267 break;
268 default: 268 default:
@@ -361,10 +361,9 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
361 wimax_dev->rfkill = rfkill; 361 wimax_dev->rfkill = rfkill;
362 362
363 rfkill->name = wimax_dev->name; 363 rfkill->name = wimax_dev->name;
364 rfkill->state = RFKILL_STATE_OFF; 364 rfkill->state = RFKILL_STATE_UNBLOCKED;
365 rfkill->data = wimax_dev; 365 rfkill->data = wimax_dev;
366 rfkill->toggle_radio = wimax_rfkill_toggle_radio; 366 rfkill->toggle_radio = wimax_rfkill_toggle_radio;
367 rfkill->user_claim_unsupported = 1;
368 367
369 /* Initialize the input device for the hw key */ 368 /* Initialize the input device for the hw key */
370 input_dev = input_allocate_device(); 369 input_dev = input_allocate_device();
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 6d1e7b27b752..14ea01c4a103 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10 10
11ccflags-y += -D__CHECK_ENDIAN__ 11ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d1f556535f6d..2006a4ee60eb 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -14,7 +14,6 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <net/genetlink.h> 15#include <net/genetlink.h>
16#include <net/cfg80211.h> 16#include <net/cfg80211.h>
17#include <net/wireless.h>
18#include "nl80211.h" 17#include "nl80211.h"
19#include "core.h" 18#include "core.h"
20#include "sysfs.h" 19#include "sysfs.h"
@@ -274,6 +273,16 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
274 drv->wiphy.dev.class = &ieee80211_class; 273 drv->wiphy.dev.class = &ieee80211_class;
275 drv->wiphy.dev.platform_data = drv; 274 drv->wiphy.dev.platform_data = drv;
276 275
276 /*
277 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
278 * Fragmentation and RTS threshold are disabled by default with the
279 * special -1 value.
280 */
281 drv->wiphy.retry_short = 7;
282 drv->wiphy.retry_long = 4;
283 drv->wiphy.frag_threshold = (u32) -1;
284 drv->wiphy.rts_threshold = (u32) -1;
285
277 return &drv->wiphy; 286 return &drv->wiphy;
278} 287}
279EXPORT_SYMBOL(wiphy_new); 288EXPORT_SYMBOL(wiphy_new);
@@ -450,6 +459,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
450 dev->ieee80211_ptr->netdev = dev; 459 dev->ieee80211_ptr->netdev = dev;
451 mutex_unlock(&rdev->devlist_mtx); 460 mutex_unlock(&rdev->devlist_mtx);
452 break; 461 break;
462 case NETDEV_GOING_DOWN:
463 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
464 break;
465 if (!dev->ieee80211_ptr->ssid_len)
466 break;
467 cfg80211_leave_ibss(rdev, dev, true);
468 break;
469 case NETDEV_UP:
470#ifdef CONFIG_WIRELESS_EXT
471 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
472 break;
473 if (!dev->ieee80211_ptr->wext.ssid_len)
474 break;
475 cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext);
476 break;
477#endif
453 case NETDEV_UNREGISTER: 478 case NETDEV_UNREGISTER:
454 mutex_lock(&rdev->devlist_mtx); 479 mutex_lock(&rdev->devlist_mtx);
455 if (!list_empty(&dev->ieee80211_ptr->list)) { 480 if (!list_empty(&dev->ieee80211_ptr->list)) {
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 0a592e4295f0..3e49d3399311 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -10,9 +10,7 @@
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h> 11#include <linux/kref.h>
12#include <linux/rbtree.h> 12#include <linux/rbtree.h>
13#include <linux/mutex.h>
14#include <net/genetlink.h> 13#include <net/genetlink.h>
15#include <net/wireless.h>
16#include <net/cfg80211.h> 14#include <net/cfg80211.h>
17#include "reg.h" 15#include "reg.h"
18 16
@@ -74,10 +72,7 @@ bool wiphy_idx_valid(int wiphy_idx)
74extern struct mutex cfg80211_mutex; 72extern struct mutex cfg80211_mutex;
75extern struct list_head cfg80211_drv_list; 73extern struct list_head cfg80211_drv_list;
76 74
77static inline void assert_cfg80211_lock(void) 75#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
78{
79 WARN_ON(!mutex_is_locked(&cfg80211_mutex));
80}
81 76
82/* 77/*
83 * You can use this to mark a wiphy_idx as not having an associated wiphy. 78 * You can use this to mark a wiphy_idx as not having an associated wiphy.
@@ -148,4 +143,12 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
148void cfg80211_bss_age(struct cfg80211_registered_device *dev, 143void cfg80211_bss_age(struct cfg80211_registered_device *dev,
149 unsigned long age_secs); 144 unsigned long age_secs);
150 145
146/* IBSS */
147int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
148 struct net_device *dev,
149 struct cfg80211_ibss_params *params);
150void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
151int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
152 struct net_device *dev, bool nowext);
153
151#endif /* __NET_WIRELESS_CORE_H */ 154#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
new file mode 100644
index 000000000000..3c38afaed28a
--- /dev/null
+++ b/net/wireless/ibss.c
@@ -0,0 +1,369 @@
1/*
2 * Some IBSS support code for cfg80211.
3 *
4 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
5 */
6
7#include <linux/etherdevice.h>
8#include <linux/if_arp.h>
9#include <net/cfg80211.h>
10#include "nl80211.h"
11
12
13void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
14{
15 struct wireless_dev *wdev = dev->ieee80211_ptr;
16 struct cfg80211_bss *bss;
17#ifdef CONFIG_WIRELESS_EXT
18 union iwreq_data wrqu;
19#endif
20
21 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
22 return;
23
24 if (WARN_ON(!wdev->ssid_len))
25 return;
26
27 if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
28 return;
29
30 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
31 wdev->ssid, wdev->ssid_len,
32 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
33
34 if (WARN_ON(!bss))
35 return;
36
37 if (wdev->current_bss) {
38 cfg80211_unhold_bss(wdev->current_bss);
39 cfg80211_put_bss(wdev->current_bss);
40 }
41
42 cfg80211_hold_bss(bss);
43 wdev->current_bss = bss;
44 memcpy(wdev->bssid, bssid, ETH_ALEN);
45
46 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
47#ifdef CONFIG_WIRELESS_EXT
48 memset(&wrqu, 0, sizeof(wrqu));
49 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
50 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
51#endif
52}
53EXPORT_SYMBOL(cfg80211_ibss_joined);
54
55int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
56 struct net_device *dev,
57 struct cfg80211_ibss_params *params)
58{
59 struct wireless_dev *wdev = dev->ieee80211_ptr;
60 int err;
61
62 if (wdev->ssid_len)
63 return -EALREADY;
64
65#ifdef CONFIG_WIRELESS_EXT
66 wdev->wext.channel = params->channel;
67#endif
68 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
69
70 if (err)
71 return err;
72
73 memcpy(wdev->ssid, params->ssid, params->ssid_len);
74 wdev->ssid_len = params->ssid_len;
75
76 return 0;
77}
78
79void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
80{
81 struct wireless_dev *wdev = dev->ieee80211_ptr;
82
83 if (wdev->current_bss) {
84 cfg80211_unhold_bss(wdev->current_bss);
85 cfg80211_put_bss(wdev->current_bss);
86 }
87
88 wdev->current_bss = NULL;
89 wdev->ssid_len = 0;
90 memset(wdev->bssid, 0, ETH_ALEN);
91#ifdef CONFIG_WIRELESS_EXT
92 if (!nowext)
93 wdev->wext.ssid_len = 0;
94#endif
95}
96
97int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
98 struct net_device *dev, bool nowext)
99{
100 int err;
101
102 err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
103
104 if (err)
105 return err;
106
107 cfg80211_clear_ibss(dev, nowext);
108
109 return 0;
110}
111
112#ifdef CONFIG_WIRELESS_EXT
113static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
114 struct wireless_dev *wdev)
115{
116 enum ieee80211_band band;
117 int i;
118
119 if (!wdev->wext.beacon_interval)
120 wdev->wext.beacon_interval = 100;
121
122 /* try to find an IBSS channel if none requested ... */
123 if (!wdev->wext.channel) {
124 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
125 struct ieee80211_supported_band *sband;
126 struct ieee80211_channel *chan;
127
128 sband = rdev->wiphy.bands[band];
129 if (!sband)
130 continue;
131
132 for (i = 0; i < sband->n_channels; i++) {
133 chan = &sband->channels[i];
134 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
135 continue;
136 if (chan->flags & IEEE80211_CHAN_DISABLED)
137 continue;
138 wdev->wext.channel = chan;
139 break;
140 }
141
142 if (wdev->wext.channel)
143 break;
144 }
145
146 if (!wdev->wext.channel)
147 return -EINVAL;
148 }
149
150 /* don't join -- SSID is not there */
151 if (!wdev->wext.ssid_len)
152 return 0;
153
154 if (!netif_running(wdev->netdev))
155 return 0;
156
157 return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy),
158 wdev->netdev, &wdev->wext);
159}
160
161int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
162 struct iw_request_info *info,
163 struct iw_freq *freq, char *extra)
164{
165 struct wireless_dev *wdev = dev->ieee80211_ptr;
166 struct ieee80211_channel *chan;
167 int err;
168
169 /* call only for ibss! */
170 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
171 return -EINVAL;
172
173 if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
174 return -EOPNOTSUPP;
175
176 chan = cfg80211_wext_freq(wdev->wiphy, freq);
177 if (chan && IS_ERR(chan))
178 return PTR_ERR(chan);
179
180 if (chan &&
181 (chan->flags & IEEE80211_CHAN_NO_IBSS ||
182 chan->flags & IEEE80211_CHAN_DISABLED))
183 return -EINVAL;
184
185 if (wdev->wext.channel == chan)
186 return 0;
187
188 if (wdev->ssid_len) {
189 err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
190 dev, true);
191 if (err)
192 return err;
193 }
194
195 if (chan) {
196 wdev->wext.channel = chan;
197 wdev->wext.channel_fixed = true;
198 } else {
199 /* cfg80211_ibss_wext_join will pick one if needed */
200 wdev->wext.channel_fixed = false;
201 }
202
203 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
204}
205/* temporary symbol - mark GPL - in the future the handler won't be */
206EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
207
208int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
209 struct iw_request_info *info,
210 struct iw_freq *freq, char *extra)
211{
212 struct wireless_dev *wdev = dev->ieee80211_ptr;
213 struct ieee80211_channel *chan = NULL;
214
215 /* call only for ibss! */
216 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
217 return -EINVAL;
218
219 if (wdev->current_bss)
220 chan = wdev->current_bss->channel;
221 else if (wdev->wext.channel)
222 chan = wdev->wext.channel;
223
224 if (chan) {
225 freq->m = chan->center_freq;
226 freq->e = 6;
227 return 0;
228 }
229
230 /* no channel if not joining */
231 return -EINVAL;
232}
233/* temporary symbol - mark GPL - in the future the handler won't be */
234EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
235
236int cfg80211_ibss_wext_siwessid(struct net_device *dev,
237 struct iw_request_info *info,
238 struct iw_point *data, char *ssid)
239{
240 struct wireless_dev *wdev = dev->ieee80211_ptr;
241 size_t len = data->length;
242 int err;
243
244 /* call only for ibss! */
245 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
246 return -EINVAL;
247
248 if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
249 return -EOPNOTSUPP;
250
251 if (wdev->ssid_len) {
252 err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
253 dev, true);
254 if (err)
255 return err;
256 }
257
258 /* iwconfig uses nul termination in SSID.. */
259 if (len > 0 && ssid[len - 1] == '\0')
260 len--;
261
262 wdev->wext.ssid = wdev->ssid;
263 memcpy(wdev->wext.ssid, ssid, len);
264 wdev->wext.ssid_len = len;
265
266 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
267}
268/* temporary symbol - mark GPL - in the future the handler won't be */
269EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
270
271int cfg80211_ibss_wext_giwessid(struct net_device *dev,
272 struct iw_request_info *info,
273 struct iw_point *data, char *ssid)
274{
275 struct wireless_dev *wdev = dev->ieee80211_ptr;
276
277 /* call only for ibss! */
278 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
279 return -EINVAL;
280
281 data->flags = 0;
282
283 if (wdev->ssid_len) {
284 data->flags = 1;
285 data->length = wdev->ssid_len;
286 memcpy(ssid, wdev->ssid, data->length);
287 } else if (wdev->wext.ssid && wdev->wext.ssid_len) {
288 data->flags = 1;
289 data->length = wdev->wext.ssid_len;
290 memcpy(ssid, wdev->wext.ssid, data->length);
291 }
292
293 return 0;
294}
295/* temporary symbol - mark GPL - in the future the handler won't be */
296EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
297
298int cfg80211_ibss_wext_siwap(struct net_device *dev,
299 struct iw_request_info *info,
300 struct sockaddr *ap_addr, char *extra)
301{
302 struct wireless_dev *wdev = dev->ieee80211_ptr;
303 u8 *bssid = ap_addr->sa_data;
304 int err;
305
306 /* call only for ibss! */
307 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
308 return -EINVAL;
309
310 if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
311 return -EOPNOTSUPP;
312
313 if (ap_addr->sa_family != ARPHRD_ETHER)
314 return -EINVAL;
315
316 /* automatic mode */
317 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
318 bssid = NULL;
319
320 /* both automatic */
321 if (!bssid && !wdev->wext.bssid)
322 return 0;
323
324 /* fixed already - and no change */
325 if (wdev->wext.bssid && bssid &&
326 compare_ether_addr(bssid, wdev->wext.bssid) == 0)
327 return 0;
328
329 if (wdev->ssid_len) {
330 err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
331 dev, true);
332 if (err)
333 return err;
334 }
335
336 if (bssid) {
337 memcpy(wdev->wext_bssid, bssid, ETH_ALEN);
338 wdev->wext.bssid = wdev->wext_bssid;
339 } else
340 wdev->wext.bssid = NULL;
341
342 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
343}
344/* temporary symbol - mark GPL - in the future the handler won't be */
345EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
346
347int cfg80211_ibss_wext_giwap(struct net_device *dev,
348 struct iw_request_info *info,
349 struct sockaddr *ap_addr, char *extra)
350{
351 struct wireless_dev *wdev = dev->ieee80211_ptr;
352
353 /* call only for ibss! */
354 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
355 return -EINVAL;
356
357 ap_addr->sa_family = ARPHRD_ETHER;
358
359 if (wdev->wext.bssid) {
360 memcpy(ap_addr->sa_data, wdev->wext.bssid, ETH_ALEN);
361 return 0;
362 }
363
364 memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
365 return 0;
366}
367/* temporary symbol - mark GPL - in the future the handler won't be */
368EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
369#endif
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index bec5721b6f99..42184361a109 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -28,19 +28,55 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
28} 28}
29EXPORT_SYMBOL(cfg80211_send_rx_assoc); 29EXPORT_SYMBOL(cfg80211_send_rx_assoc);
30 30
31void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len) 31void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
32{ 32{
33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
35 nl80211_send_rx_deauth(rdev, dev, buf, len); 35 nl80211_send_deauth(rdev, dev, buf, len);
36} 36}
37EXPORT_SYMBOL(cfg80211_send_rx_deauth); 37EXPORT_SYMBOL(cfg80211_send_deauth);
38 38
39void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf, 39void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
40 size_t len)
41{ 40{
42 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 41 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
43 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 42 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
44 nl80211_send_rx_disassoc(rdev, dev, buf, len); 43 nl80211_send_disassoc(rdev, dev, buf, len);
45} 44}
46EXPORT_SYMBOL(cfg80211_send_rx_disassoc); 45EXPORT_SYMBOL(cfg80211_send_disassoc);
46
47static void cfg80211_wext_disconnected(struct net_device *dev)
48{
49#ifdef CONFIG_WIRELESS_EXT
50 union iwreq_data wrqu;
51 memset(&wrqu, 0, sizeof(wrqu));
52 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
53#endif
54}
55
56void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
57{
58 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
59 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
60 nl80211_send_auth_timeout(rdev, dev, addr);
61 cfg80211_wext_disconnected(dev);
62}
63EXPORT_SYMBOL(cfg80211_send_auth_timeout);
64
65void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
66{
67 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
68 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
69 nl80211_send_assoc_timeout(rdev, dev, addr);
70 cfg80211_wext_disconnected(dev);
71}
72EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
73
74void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
75 enum nl80211_key_type key_type, int key_id,
76 const u8 *tsc)
77{
78 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
79 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
80 nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc);
81}
82EXPORT_SYMBOL(cfg80211_michael_mic_failure);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2456e4ee445e..b1fc98225fd1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -61,6 +61,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, 61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, 62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, 63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
64 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
65 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
66 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
67 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
64 68
65 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 69 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
66 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 70 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -116,8 +120,40 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
116 .len = IEEE80211_MAX_SSID_LEN }, 120 .len = IEEE80211_MAX_SSID_LEN },
117 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, 121 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
118 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, 122 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
123 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
124 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
119}; 125};
120 126
127/* IE validation */
128static bool is_valid_ie_attr(const struct nlattr *attr)
129{
130 const u8 *pos;
131 int len;
132
133 if (!attr)
134 return true;
135
136 pos = nla_data(attr);
137 len = nla_len(attr);
138
139 while (len) {
140 u8 elemlen;
141
142 if (len < 2)
143 return false;
144 len -= 2;
145
146 elemlen = pos[1];
147 if (elemlen > len)
148 return false;
149
150 len -= elemlen;
151 pos += 2 + elemlen;
152 }
153
154 return true;
155}
156
121/* message building helper */ 157/* message building helper */
122static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, 158static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
123 int flags, u8 cmd) 159 int flags, u8 cmd)
@@ -126,6 +162,30 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
126 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); 162 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
127} 163}
128 164
165static int nl80211_msg_put_channel(struct sk_buff *msg,
166 struct ieee80211_channel *chan)
167{
168 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
169 chan->center_freq);
170
171 if (chan->flags & IEEE80211_CHAN_DISABLED)
172 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
173 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
174 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
175 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
176 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
177 if (chan->flags & IEEE80211_CHAN_RADAR)
178 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
179
180 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
181 DBM_TO_MBM(chan->max_power));
182
183 return 0;
184
185 nla_put_failure:
186 return -ENOBUFS;
187}
188
129/* netlink command implementations */ 189/* netlink command implementations */
130 190
131static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 191static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
@@ -149,8 +209,24 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
149 209
150 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); 210 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
151 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 211 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
212
213 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
214 dev->wiphy.retry_short);
215 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
216 dev->wiphy.retry_long);
217 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
218 dev->wiphy.frag_threshold);
219 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
220 dev->wiphy.rts_threshold);
221
152 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 222 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
153 dev->wiphy.max_scan_ssids); 223 dev->wiphy.max_scan_ssids);
224 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
225 dev->wiphy.max_scan_ie_len);
226
227 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
228 sizeof(u32) * dev->wiphy.n_cipher_suites,
229 dev->wiphy.cipher_suites);
154 230
155 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 231 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
156 if (!nl_modes) 232 if (!nl_modes)
@@ -202,20 +278,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
202 goto nla_put_failure; 278 goto nla_put_failure;
203 279
204 chan = &dev->wiphy.bands[band]->channels[i]; 280 chan = &dev->wiphy.bands[band]->channels[i];
205 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
206 chan->center_freq);
207
208 if (chan->flags & IEEE80211_CHAN_DISABLED)
209 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
210 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
211 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
212 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
213 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
214 if (chan->flags & IEEE80211_CHAN_RADAR)
215 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
216 281
217 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 282 if (nl80211_msg_put_channel(msg, chan))
218 DBM_TO_MBM(chan->max_power)); 283 goto nla_put_failure;
219 284
220 nla_nest_end(msg, nl_freq); 285 nla_nest_end(msg, nl_freq);
221 } 286 }
@@ -273,6 +338,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
273 CMD(assoc, ASSOCIATE); 338 CMD(assoc, ASSOCIATE);
274 CMD(deauth, DEAUTHENTICATE); 339 CMD(deauth, DEAUTHENTICATE);
275 CMD(disassoc, DISASSOCIATE); 340 CMD(disassoc, DISASSOCIATE);
341 CMD(join_ibss, JOIN_IBSS);
276 342
277#undef CMD 343#undef CMD
278 nla_nest_end(msg, nl_cmds); 344 nla_nest_end(msg, nl_cmds);
@@ -365,6 +431,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
365 struct cfg80211_registered_device *rdev; 431 struct cfg80211_registered_device *rdev;
366 int result = 0, rem_txq_params = 0; 432 int result = 0, rem_txq_params = 0;
367 struct nlattr *nl_txq_params; 433 struct nlattr *nl_txq_params;
434 u32 changed;
435 u8 retry_short = 0, retry_long = 0;
436 u32 frag_threshold = 0, rts_threshold = 0;
368 437
369 rtnl_lock(); 438 rtnl_lock();
370 439
@@ -479,6 +548,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
479 goto bad_res; 548 goto bad_res;
480 } 549 }
481 550
551 changed = 0;
552
553 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
554 retry_short = nla_get_u8(
555 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
556 if (retry_short == 0) {
557 result = -EINVAL;
558 goto bad_res;
559 }
560 changed |= WIPHY_PARAM_RETRY_SHORT;
561 }
562
563 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
564 retry_long = nla_get_u8(
565 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
566 if (retry_long == 0) {
567 result = -EINVAL;
568 goto bad_res;
569 }
570 changed |= WIPHY_PARAM_RETRY_LONG;
571 }
572
573 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
574 frag_threshold = nla_get_u32(
575 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
576 if (frag_threshold < 256) {
577 result = -EINVAL;
578 goto bad_res;
579 }
580 if (frag_threshold != (u32) -1) {
581 /*
582 * Fragments (apart from the last one) are required to
583 * have even length. Make the fragmentation code
584 * simpler by stripping LSB should someone try to use
585 * odd threshold value.
586 */
587 frag_threshold &= ~0x1;
588 }
589 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
590 }
591
592 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
593 rts_threshold = nla_get_u32(
594 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
595 changed |= WIPHY_PARAM_RTS_THRESHOLD;
596 }
597
598 if (changed) {
599 u8 old_retry_short, old_retry_long;
600 u32 old_frag_threshold, old_rts_threshold;
601
602 if (!rdev->ops->set_wiphy_params) {
603 result = -EOPNOTSUPP;
604 goto bad_res;
605 }
606
607 old_retry_short = rdev->wiphy.retry_short;
608 old_retry_long = rdev->wiphy.retry_long;
609 old_frag_threshold = rdev->wiphy.frag_threshold;
610 old_rts_threshold = rdev->wiphy.rts_threshold;
611
612 if (changed & WIPHY_PARAM_RETRY_SHORT)
613 rdev->wiphy.retry_short = retry_short;
614 if (changed & WIPHY_PARAM_RETRY_LONG)
615 rdev->wiphy.retry_long = retry_long;
616 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
617 rdev->wiphy.frag_threshold = frag_threshold;
618 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
619 rdev->wiphy.rts_threshold = rts_threshold;
620
621 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
622 if (result) {
623 rdev->wiphy.retry_short = old_retry_short;
624 rdev->wiphy.retry_long = old_retry_long;
625 rdev->wiphy.frag_threshold = old_frag_threshold;
626 rdev->wiphy.rts_threshold = old_rts_threshold;
627 }
628 }
482 629
483 bad_res: 630 bad_res:
484 mutex_unlock(&rdev->mtx); 631 mutex_unlock(&rdev->mtx);
@@ -489,6 +636,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
489 636
490 637
491static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, 638static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
639 struct cfg80211_registered_device *rdev,
492 struct net_device *dev) 640 struct net_device *dev)
493{ 641{
494 void *hdr; 642 void *hdr;
@@ -498,6 +646,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
498 return -1; 646 return -1;
499 647
500 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 648 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
649 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
501 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); 650 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
502 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype); 651 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
503 return genlmsg_end(msg, hdr); 652 return genlmsg_end(msg, hdr);
@@ -532,7 +681,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
532 } 681 }
533 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, 682 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
534 cb->nlh->nlmsg_seq, NLM_F_MULTI, 683 cb->nlh->nlmsg_seq, NLM_F_MULTI,
535 wdev->netdev) < 0) { 684 dev, wdev->netdev) < 0) {
536 mutex_unlock(&dev->devlist_mtx); 685 mutex_unlock(&dev->devlist_mtx);
537 goto out; 686 goto out;
538 } 687 }
@@ -566,7 +715,8 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
566 if (!msg) 715 if (!msg)
567 goto out_err; 716 goto out_err;
568 717
569 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0) 718 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
719 dev, netdev) < 0)
570 goto out_free; 720 goto out_free;
571 721
572 dev_put(netdev); 722 dev_put(netdev);
@@ -616,7 +766,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
616 struct cfg80211_registered_device *drv; 766 struct cfg80211_registered_device *drv;
617 struct vif_params params; 767 struct vif_params params;
618 int err, ifindex; 768 int err, ifindex;
619 enum nl80211_iftype type; 769 enum nl80211_iftype otype, ntype;
620 struct net_device *dev; 770 struct net_device *dev;
621 u32 _flags, *flags = NULL; 771 u32 _flags, *flags = NULL;
622 bool change = false; 772 bool change = false;
@@ -630,30 +780,27 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
630 goto unlock_rtnl; 780 goto unlock_rtnl;
631 781
632 ifindex = dev->ifindex; 782 ifindex = dev->ifindex;
633 type = dev->ieee80211_ptr->iftype; 783 otype = ntype = dev->ieee80211_ptr->iftype;
634 dev_put(dev); 784 dev_put(dev);
635 785
636 if (info->attrs[NL80211_ATTR_IFTYPE]) { 786 if (info->attrs[NL80211_ATTR_IFTYPE]) {
637 enum nl80211_iftype ntype;
638
639 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 787 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
640 if (type != ntype) 788 if (otype != ntype)
641 change = true; 789 change = true;
642 type = ntype; 790 if (ntype > NL80211_IFTYPE_MAX) {
643 if (type > NL80211_IFTYPE_MAX) {
644 err = -EINVAL; 791 err = -EINVAL;
645 goto unlock; 792 goto unlock;
646 } 793 }
647 } 794 }
648 795
649 if (!drv->ops->change_virtual_intf || 796 if (!drv->ops->change_virtual_intf ||
650 !(drv->wiphy.interface_modes & (1 << type))) { 797 !(drv->wiphy.interface_modes & (1 << ntype))) {
651 err = -EOPNOTSUPP; 798 err = -EOPNOTSUPP;
652 goto unlock; 799 goto unlock;
653 } 800 }
654 801
655 if (info->attrs[NL80211_ATTR_MESH_ID]) { 802 if (info->attrs[NL80211_ATTR_MESH_ID]) {
656 if (type != NL80211_IFTYPE_MESH_POINT) { 803 if (ntype != NL80211_IFTYPE_MESH_POINT) {
657 err = -EINVAL; 804 err = -EINVAL;
658 goto unlock; 805 goto unlock;
659 } 806 }
@@ -663,7 +810,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
663 } 810 }
664 811
665 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 812 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
666 if (type != NL80211_IFTYPE_MONITOR) { 813 if (ntype != NL80211_IFTYPE_MONITOR) {
667 err = -EINVAL; 814 err = -EINVAL;
668 goto unlock; 815 goto unlock;
669 } 816 }
@@ -678,12 +825,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
678 825
679 if (change) 826 if (change)
680 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, 827 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
681 type, flags, &params); 828 ntype, flags, &params);
682 else 829 else
683 err = 0; 830 err = 0;
684 831
685 dev = __dev_get_by_index(&init_net, ifindex); 832 dev = __dev_get_by_index(&init_net, ifindex);
686 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type)); 833 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
834
835 if (dev && !err && (ntype != otype)) {
836 if (otype == NL80211_IFTYPE_ADHOC)
837 cfg80211_clear_ibss(dev, false);
838 }
687 839
688 unlock: 840 unlock:
689 cfg80211_put_dev(drv); 841 cfg80211_put_dev(drv);
@@ -934,7 +1086,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
934static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 1086static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
935{ 1087{
936 struct cfg80211_registered_device *drv; 1088 struct cfg80211_registered_device *drv;
937 int err; 1089 int err, i;
938 struct net_device *dev; 1090 struct net_device *dev;
939 struct key_params params; 1091 struct key_params params;
940 u8 key_idx = 0; 1092 u8 key_idx = 0;
@@ -1003,6 +1155,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1003 if (err) 1155 if (err)
1004 goto unlock_rtnl; 1156 goto unlock_rtnl;
1005 1157
1158 for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
1159 if (params.cipher == drv->wiphy.cipher_suites[i])
1160 break;
1161 if (i == drv->wiphy.n_cipher_suites) {
1162 err = -EINVAL;
1163 goto out;
1164 }
1165
1006 if (!drv->ops->add_key) { 1166 if (!drv->ops->add_key) {
1007 err = -EOPNOTSUPP; 1167 err = -EOPNOTSUPP;
1008 goto out; 1168 goto out;
@@ -1069,6 +1229,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1069 struct beacon_parameters params; 1229 struct beacon_parameters params;
1070 int haveinfo = 0; 1230 int haveinfo = 0;
1071 1231
1232 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1233 return -EINVAL;
1234
1072 rtnl_lock(); 1235 rtnl_lock();
1073 1236
1074 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1237 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2442,6 +2605,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2442 enum ieee80211_band band; 2605 enum ieee80211_band band;
2443 size_t ie_len; 2606 size_t ie_len;
2444 2607
2608 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2609 return -EINVAL;
2610
2445 rtnl_lock(); 2611 rtnl_lock();
2446 2612
2447 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2613 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2492,6 +2658,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2492 else 2658 else
2493 ie_len = 0; 2659 ie_len = 0;
2494 2660
2661 if (ie_len > wiphy->max_scan_ie_len) {
2662 err = -EINVAL;
2663 goto out;
2664 }
2665
2495 request = kzalloc(sizeof(*request) 2666 request = kzalloc(sizeof(*request)
2496 + sizeof(*ssid) * n_ssids 2667 + sizeof(*ssid) * n_ssids
2497 + sizeof(channel) * n_channels 2668 + sizeof(channel) * n_channels
@@ -2554,7 +2725,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2554 2725
2555 if (info->attrs[NL80211_ATTR_IE]) { 2726 if (info->attrs[NL80211_ATTR_IE]) {
2556 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2727 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2557 memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]), 2728 memcpy((void *)request->ie,
2729 nla_data(info->attrs[NL80211_ATTR_IE]),
2558 request->ie_len); 2730 request->ie_len);
2559 } 2731 }
2560 2732
@@ -2710,6 +2882,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2710 struct wiphy *wiphy; 2882 struct wiphy *wiphy;
2711 int err; 2883 int err;
2712 2884
2885 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2886 return -EINVAL;
2887
2888 if (!info->attrs[NL80211_ATTR_MAC])
2889 return -EINVAL;
2890
2891 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
2892 return -EINVAL;
2893
2713 rtnl_lock(); 2894 rtnl_lock();
2714 2895
2715 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2896 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2731,11 +2912,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2731 goto out; 2912 goto out;
2732 } 2913 }
2733 2914
2734 if (!info->attrs[NL80211_ATTR_MAC]) {
2735 err = -EINVAL;
2736 goto out;
2737 }
2738
2739 wiphy = &drv->wiphy; 2915 wiphy = &drv->wiphy;
2740 memset(&req, 0, sizeof(req)); 2916 memset(&req, 0, sizeof(req));
2741 2917
@@ -2761,13 +2937,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2761 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2937 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2762 } 2938 }
2763 2939
2764 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { 2940 req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
2765 req.auth_type = 2941 if (!nl80211_valid_auth_type(req.auth_type)) {
2766 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 2942 err = -EINVAL;
2767 if (!nl80211_valid_auth_type(req.auth_type)) { 2943 goto out;
2768 err = -EINVAL;
2769 goto out;
2770 }
2771 } 2944 }
2772 2945
2773 err = drv->ops->auth(&drv->wiphy, dev, &req); 2946 err = drv->ops->auth(&drv->wiphy, dev, &req);
@@ -2788,6 +2961,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2788 struct wiphy *wiphy; 2961 struct wiphy *wiphy;
2789 int err; 2962 int err;
2790 2963
2964 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2965 return -EINVAL;
2966
2967 if (!info->attrs[NL80211_ATTR_MAC] ||
2968 !info->attrs[NL80211_ATTR_SSID])
2969 return -EINVAL;
2970
2791 rtnl_lock(); 2971 rtnl_lock();
2792 2972
2793 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2973 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2809,12 +2989,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2809 goto out; 2989 goto out;
2810 } 2990 }
2811 2991
2812 if (!info->attrs[NL80211_ATTR_MAC] ||
2813 !info->attrs[NL80211_ATTR_SSID]) {
2814 err = -EINVAL;
2815 goto out;
2816 }
2817
2818 wiphy = &drv->wiphy; 2992 wiphy = &drv->wiphy;
2819 memset(&req, 0, sizeof(req)); 2993 memset(&req, 0, sizeof(req));
2820 2994
@@ -2856,6 +3030,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2856 struct wiphy *wiphy; 3030 struct wiphy *wiphy;
2857 int err; 3031 int err;
2858 3032
3033 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3034 return -EINVAL;
3035
3036 if (!info->attrs[NL80211_ATTR_MAC])
3037 return -EINVAL;
3038
3039 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3040 return -EINVAL;
3041
2859 rtnl_lock(); 3042 rtnl_lock();
2860 3043
2861 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3044 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2877,24 +3060,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2877 goto out; 3060 goto out;
2878 } 3061 }
2879 3062
2880 if (!info->attrs[NL80211_ATTR_MAC]) {
2881 err = -EINVAL;
2882 goto out;
2883 }
2884
2885 wiphy = &drv->wiphy; 3063 wiphy = &drv->wiphy;
2886 memset(&req, 0, sizeof(req)); 3064 memset(&req, 0, sizeof(req));
2887 3065
2888 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3066 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2889 3067
2890 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3068 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2891 req.reason_code = 3069 if (req.reason_code == 0) {
2892 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3070 /* Reason Code 0 is reserved */
2893 if (req.reason_code == 0) { 3071 err = -EINVAL;
2894 /* Reason Code 0 is reserved */ 3072 goto out;
2895 err = -EINVAL;
2896 goto out;
2897 }
2898 } 3073 }
2899 3074
2900 if (info->attrs[NL80211_ATTR_IE]) { 3075 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2920,6 +3095,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2920 struct wiphy *wiphy; 3095 struct wiphy *wiphy;
2921 int err; 3096 int err;
2922 3097
3098 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3099 return -EINVAL;
3100
3101 if (!info->attrs[NL80211_ATTR_MAC])
3102 return -EINVAL;
3103
3104 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3105 return -EINVAL;
3106
2923 rtnl_lock(); 3107 rtnl_lock();
2924 3108
2925 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3109 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2941,24 +3125,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2941 goto out; 3125 goto out;
2942 } 3126 }
2943 3127
2944 if (!info->attrs[NL80211_ATTR_MAC]) {
2945 err = -EINVAL;
2946 goto out;
2947 }
2948
2949 wiphy = &drv->wiphy; 3128 wiphy = &drv->wiphy;
2950 memset(&req, 0, sizeof(req)); 3129 memset(&req, 0, sizeof(req));
2951 3130
2952 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3131 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2953 3132
2954 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3133 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2955 req.reason_code = 3134 if (req.reason_code == 0) {
2956 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3135 /* Reason Code 0 is reserved */
2957 if (req.reason_code == 0) { 3136 err = -EINVAL;
2958 /* Reason Code 0 is reserved */ 3137 goto out;
2959 err = -EINVAL;
2960 goto out;
2961 }
2962 } 3138 }
2963 3139
2964 if (info->attrs[NL80211_ATTR_IE]) { 3140 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2976,6 +3152,124 @@ unlock_rtnl:
2976 return err; 3152 return err;
2977} 3153}
2978 3154
3155static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3156{
3157 struct cfg80211_registered_device *drv;
3158 struct net_device *dev;
3159 struct cfg80211_ibss_params ibss;
3160 struct wiphy *wiphy;
3161 int err;
3162
3163 memset(&ibss, 0, sizeof(ibss));
3164
3165 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3166 return -EINVAL;
3167
3168 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
3169 !info->attrs[NL80211_ATTR_SSID] ||
3170 !nla_len(info->attrs[NL80211_ATTR_SSID]))
3171 return -EINVAL;
3172
3173 ibss.beacon_interval = 100;
3174
3175 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
3176 ibss.beacon_interval =
3177 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3178 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
3179 return -EINVAL;
3180 }
3181
3182 rtnl_lock();
3183
3184 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3185 if (err)
3186 goto unlock_rtnl;
3187
3188 if (!drv->ops->join_ibss) {
3189 err = -EOPNOTSUPP;
3190 goto out;
3191 }
3192
3193 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3194 err = -EOPNOTSUPP;
3195 goto out;
3196 }
3197
3198 if (!netif_running(dev)) {
3199 err = -ENETDOWN;
3200 goto out;
3201 }
3202
3203 wiphy = &drv->wiphy;
3204
3205 if (info->attrs[NL80211_ATTR_MAC])
3206 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3207 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3208 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3209
3210 if (info->attrs[NL80211_ATTR_IE]) {
3211 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3212 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3213 }
3214
3215 ibss.channel = ieee80211_get_channel(wiphy,
3216 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3217 if (!ibss.channel ||
3218 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
3219 ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
3220 err = -EINVAL;
3221 goto out;
3222 }
3223
3224 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
3225
3226 err = cfg80211_join_ibss(drv, dev, &ibss);
3227
3228out:
3229 cfg80211_put_dev(drv);
3230 dev_put(dev);
3231unlock_rtnl:
3232 rtnl_unlock();
3233 return err;
3234}
3235
3236static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3237{
3238 struct cfg80211_registered_device *drv;
3239 struct net_device *dev;
3240 int err;
3241
3242 rtnl_lock();
3243
3244 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3245 if (err)
3246 goto unlock_rtnl;
3247
3248 if (!drv->ops->leave_ibss) {
3249 err = -EOPNOTSUPP;
3250 goto out;
3251 }
3252
3253 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3254 err = -EOPNOTSUPP;
3255 goto out;
3256 }
3257
3258 if (!netif_running(dev)) {
3259 err = -ENETDOWN;
3260 goto out;
3261 }
3262
3263 err = cfg80211_leave_ibss(drv, dev, false);
3264
3265out:
3266 cfg80211_put_dev(drv);
3267 dev_put(dev);
3268unlock_rtnl:
3269 rtnl_unlock();
3270 return err;
3271}
3272
2979static struct genl_ops nl80211_ops[] = { 3273static struct genl_ops nl80211_ops[] = {
2980 { 3274 {
2981 .cmd = NL80211_CMD_GET_WIPHY, 3275 .cmd = NL80211_CMD_GET_WIPHY,
@@ -3177,6 +3471,18 @@ static struct genl_ops nl80211_ops[] = {
3177 .policy = nl80211_policy, 3471 .policy = nl80211_policy,
3178 .flags = GENL_ADMIN_PERM, 3472 .flags = GENL_ADMIN_PERM,
3179 }, 3473 },
3474 {
3475 .cmd = NL80211_CMD_JOIN_IBSS,
3476 .doit = nl80211_join_ibss,
3477 .policy = nl80211_policy,
3478 .flags = GENL_ADMIN_PERM,
3479 },
3480 {
3481 .cmd = NL80211_CMD_LEAVE_IBSS,
3482 .doit = nl80211_leave_ibss,
3483 .policy = nl80211_policy,
3484 .flags = GENL_ADMIN_PERM,
3485 },
3180}; 3486};
3181static struct genl_multicast_group nl80211_mlme_mcgrp = { 3487static struct genl_multicast_group nl80211_mlme_mcgrp = {
3182 .name = "mlme", 3488 .name = "mlme",
@@ -3375,22 +3681,197 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3375 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE); 3681 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3376} 3682}
3377 3683
3378void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, 3684void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
3379 struct net_device *netdev, const u8 *buf, 3685 struct net_device *netdev, const u8 *buf, size_t len)
3380 size_t len)
3381{ 3686{
3382 nl80211_send_mlme_event(rdev, netdev, buf, len, 3687 nl80211_send_mlme_event(rdev, netdev, buf, len,
3383 NL80211_CMD_DEAUTHENTICATE); 3688 NL80211_CMD_DEAUTHENTICATE);
3384} 3689}
3385 3690
3386void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, 3691void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3387 struct net_device *netdev, const u8 *buf, 3692 struct net_device *netdev, const u8 *buf,
3388 size_t len) 3693 size_t len)
3389{ 3694{
3390 nl80211_send_mlme_event(rdev, netdev, buf, len, 3695 nl80211_send_mlme_event(rdev, netdev, buf, len,
3391 NL80211_CMD_DISASSOCIATE); 3696 NL80211_CMD_DISASSOCIATE);
3392} 3697}
3393 3698
3699void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
3700 struct net_device *netdev, int cmd,
3701 const u8 *addr)
3702{
3703 struct sk_buff *msg;
3704 void *hdr;
3705
3706 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
3707 if (!msg)
3708 return;
3709
3710 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
3711 if (!hdr) {
3712 nlmsg_free(msg);
3713 return;
3714 }
3715
3716 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3717 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3718 NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
3719 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3720
3721 if (genlmsg_end(msg, hdr) < 0) {
3722 nlmsg_free(msg);
3723 return;
3724 }
3725
3726 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3727 return;
3728
3729 nla_put_failure:
3730 genlmsg_cancel(msg, hdr);
3731 nlmsg_free(msg);
3732}
3733
3734void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
3735 struct net_device *netdev, const u8 *addr)
3736{
3737 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
3738 addr);
3739}
3740
3741void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
3742 struct net_device *netdev, const u8 *addr)
3743{
3744 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
3745}
3746
3747void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
3748 struct net_device *netdev, const u8 *bssid,
3749 gfp_t gfp)
3750{
3751 struct sk_buff *msg;
3752 void *hdr;
3753
3754 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
3755 if (!msg)
3756 return;
3757
3758 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
3759 if (!hdr) {
3760 nlmsg_free(msg);
3761 return;
3762 }
3763
3764 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3765 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3766 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
3767
3768 if (genlmsg_end(msg, hdr) < 0) {
3769 nlmsg_free(msg);
3770 return;
3771 }
3772
3773 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
3774 return;
3775
3776 nla_put_failure:
3777 genlmsg_cancel(msg, hdr);
3778 nlmsg_free(msg);
3779}
3780
3781void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3782 struct net_device *netdev, const u8 *addr,
3783 enum nl80211_key_type key_type, int key_id,
3784 const u8 *tsc)
3785{
3786 struct sk_buff *msg;
3787 void *hdr;
3788
3789 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3790 if (!msg)
3791 return;
3792
3793 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
3794 if (!hdr) {
3795 nlmsg_free(msg);
3796 return;
3797 }
3798
3799 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3800 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3801 if (addr)
3802 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3803 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
3804 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
3805 if (tsc)
3806 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
3807
3808 if (genlmsg_end(msg, hdr) < 0) {
3809 nlmsg_free(msg);
3810 return;
3811 }
3812
3813 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3814 return;
3815
3816 nla_put_failure:
3817 genlmsg_cancel(msg, hdr);
3818 nlmsg_free(msg);
3819}
3820
3821void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
3822 struct ieee80211_channel *channel_before,
3823 struct ieee80211_channel *channel_after)
3824{
3825 struct sk_buff *msg;
3826 void *hdr;
3827 struct nlattr *nl_freq;
3828
3829 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
3830 if (!msg)
3831 return;
3832
3833 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
3834 if (!hdr) {
3835 nlmsg_free(msg);
3836 return;
3837 }
3838
3839 /*
3840 * Since we are applying the beacon hint to a wiphy we know its
3841 * wiphy_idx is valid
3842 */
3843 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
3844
3845 /* Before */
3846 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
3847 if (!nl_freq)
3848 goto nla_put_failure;
3849 if (nl80211_msg_put_channel(msg, channel_before))
3850 goto nla_put_failure;
3851 nla_nest_end(msg, nl_freq);
3852
3853 /* After */
3854 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
3855 if (!nl_freq)
3856 goto nla_put_failure;
3857 if (nl80211_msg_put_channel(msg, channel_after))
3858 goto nla_put_failure;
3859 nla_nest_end(msg, nl_freq);
3860
3861 if (genlmsg_end(msg, hdr) < 0) {
3862 nlmsg_free(msg);
3863 return;
3864 }
3865
3866 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
3867
3868 return;
3869
3870nla_put_failure:
3871 genlmsg_cancel(msg, hdr);
3872 nlmsg_free(msg);
3873}
3874
3394/* initialisation/exit functions */ 3875/* initialisation/exit functions */
3395 3876
3396int nl80211_init(void) 3877int nl80211_init(void)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index b77af4ab80be..5c12ad13499b 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -17,11 +17,31 @@ extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, 17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
18 struct net_device *netdev, 18 struct net_device *netdev,
19 const u8 *buf, size_t len); 19 const u8 *buf, size_t len);
20extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, 20extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
21 struct net_device *netdev, 21 struct net_device *netdev,
22 const u8 *buf, size_t len); 22 const u8 *buf, size_t len);
23extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, 23extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
24 struct net_device *netdev, 24 struct net_device *netdev,
25 const u8 *buf, size_t len); 25 const u8 *buf, size_t len);
26extern void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
27 struct net_device *netdev,
28 const u8 *addr);
29extern void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
30 struct net_device *netdev,
31 const u8 *addr);
32extern void
33nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
34 struct net_device *netdev, const u8 *addr,
35 enum nl80211_key_type key_type,
36 int key_id, const u8 *tsc);
37
38extern void
39nl80211_send_beacon_hint_event(struct wiphy *wiphy,
40 struct ieee80211_channel *channel_before,
41 struct ieee80211_channel *channel_after);
42
43void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
44 struct net_device *netdev, const u8 *bssid,
45 gfp_t gfp);
26 46
27#endif /* __NET_WIRELESS_NL80211_H */ 47#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 6c1993d99902..f38cc39fa79e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -37,7 +37,6 @@
37#include <linux/random.h> 37#include <linux/random.h>
38#include <linux/nl80211.h> 38#include <linux/nl80211.h>
39#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40#include <net/wireless.h>
41#include <net/cfg80211.h> 40#include <net/cfg80211.h>
42#include "core.h" 41#include "core.h"
43#include "reg.h" 42#include "reg.h"
@@ -1049,18 +1048,10 @@ static void handle_reg_beacon(struct wiphy *wiphy,
1049 unsigned int chan_idx, 1048 unsigned int chan_idx,
1050 struct reg_beacon *reg_beacon) 1049 struct reg_beacon *reg_beacon)
1051{ 1050{
1052#ifdef CONFIG_CFG80211_REG_DEBUG
1053#define REG_DEBUG_BEACON_FLAG(desc) \
1054 printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
1055 "frequency: %d MHz (Ch %d) on %s\n", \
1056 reg_beacon->chan.center_freq, \
1057 ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
1058 wiphy_name(wiphy));
1059#else
1060#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
1061#endif
1062 struct ieee80211_supported_band *sband; 1051 struct ieee80211_supported_band *sband;
1063 struct ieee80211_channel *chan; 1052 struct ieee80211_channel *chan;
1053 bool channel_changed = false;
1054 struct ieee80211_channel chan_before;
1064 1055
1065 assert_cfg80211_lock(); 1056 assert_cfg80211_lock();
1066 1057
@@ -1070,18 +1061,28 @@ static void handle_reg_beacon(struct wiphy *wiphy,
1070 if (likely(chan->center_freq != reg_beacon->chan.center_freq)) 1061 if (likely(chan->center_freq != reg_beacon->chan.center_freq))
1071 return; 1062 return;
1072 1063
1073 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 1064 if (chan->beacon_found)
1065 return;
1066
1067 chan->beacon_found = true;
1068
1069 chan_before.center_freq = chan->center_freq;
1070 chan_before.flags = chan->flags;
1071
1072 if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
1073 !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
1074 chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 1074 chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
1075 REG_DEBUG_BEACON_FLAG("active scanning"); 1075 channel_changed = true;
1076 } 1076 }
1077 1077
1078 if (chan->flags & IEEE80211_CHAN_NO_IBSS) { 1078 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
1079 !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) {
1079 chan->flags &= ~IEEE80211_CHAN_NO_IBSS; 1080 chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
1080 REG_DEBUG_BEACON_FLAG("beaconing"); 1081 channel_changed = true;
1081 } 1082 }
1082 1083
1083 chan->beacon_found = true; 1084 if (channel_changed)
1084#undef REG_DEBUG_BEACON_FLAG 1085 nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
1085} 1086}
1086 1087
1087/* 1088/*
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2ae65b39b529..723aeb3d9462 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -414,6 +414,55 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
414 return found; 414 return found;
415} 415}
416 416
417struct cfg80211_bss*
418cfg80211_inform_bss(struct wiphy *wiphy,
419 struct ieee80211_channel *channel,
420 const u8 *bssid,
421 u64 timestamp, u16 capability, u16 beacon_interval,
422 const u8 *ie, size_t ielen,
423 s32 signal, gfp_t gfp)
424{
425 struct cfg80211_internal_bss *res;
426 size_t privsz;
427
428 if (WARN_ON(!wiphy))
429 return NULL;
430
431 privsz = wiphy->bss_priv_size;
432
433 if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
434 (signal < 0 || signal > 100)))
435 return NULL;
436
437 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
438 if (!res)
439 return NULL;
440
441 memcpy(res->pub.bssid, bssid, ETH_ALEN);
442 res->pub.channel = channel;
443 res->pub.signal = signal;
444 res->pub.tsf = timestamp;
445 res->pub.beacon_interval = beacon_interval;
446 res->pub.capability = capability;
447 /* point to after the private area */
448 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
449 memcpy(res->pub.information_elements, ie, ielen);
450 res->pub.len_information_elements = ielen;
451
452 kref_init(&res->ref);
453
454 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0);
455 if (!res)
456 return NULL;
457
458 if (res->pub.capability & WLAN_CAPABILITY_ESS)
459 regulatory_hint_found_beacon(wiphy, channel, gfp);
460
461 /* cfg80211_bss_update gives us a referenced result */
462 return &res->pub;
463}
464EXPORT_SYMBOL(cfg80211_inform_bss);
465
417struct cfg80211_bss * 466struct cfg80211_bss *
418cfg80211_inform_bss_frame(struct wiphy *wiphy, 467cfg80211_inform_bss_frame(struct wiphy *wiphy,
419 struct ieee80211_channel *channel, 468 struct ieee80211_channel *channel,
@@ -604,7 +653,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
604 cfg80211_put_dev(rdev); 653 cfg80211_put_dev(rdev);
605 return err; 654 return err;
606} 655}
607EXPORT_SYMBOL(cfg80211_wext_siwscan); 656EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
608 657
609static void ieee80211_scan_add_ies(struct iw_request_info *info, 658static void ieee80211_scan_add_ies(struct iw_request_info *info,
610 struct cfg80211_bss *bss, 659 struct cfg80211_bss *bss,
@@ -913,5 +962,5 @@ int cfg80211_wext_giwscan(struct net_device *dev,
913 cfg80211_put_dev(rdev); 962 cfg80211_put_dev(rdev);
914 return res; 963 return res;
915} 964}
916EXPORT_SYMBOL(cfg80211_wext_giwscan); 965EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
917#endif 966#endif
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 487cdd9bcffc..5f7e997195c7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Wireless utility functions 2 * Wireless utility functions
3 * 3 *
4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6#include <net/wireless.h> 6#include <linux/bitops.h>
7#include <asm/bitops.h> 7#include <net/cfg80211.h>
8#include "core.h" 8#include "core.h"
9 9
10struct ieee80211_rate * 10struct ieee80211_rate *
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 0fd1db6e95bb..5ef82f2ca88f 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -10,8 +10,8 @@
10 10
11#include <linux/wireless.h> 11#include <linux/wireless.h>
12#include <linux/nl80211.h> 12#include <linux/nl80211.h>
13#include <linux/if_arp.h>
13#include <net/iw_handler.h> 14#include <net/iw_handler.h>
14#include <net/wireless.h>
15#include <net/cfg80211.h> 15#include <net/cfg80211.h>
16#include "core.h" 16#include "core.h"
17 17
@@ -57,7 +57,7 @@ int cfg80211_wext_giwname(struct net_device *dev,
57 57
58 return 0; 58 return 0;
59} 59}
60EXPORT_SYMBOL(cfg80211_wext_giwname); 60EXPORT_SYMBOL_GPL(cfg80211_wext_giwname);
61 61
62int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, 62int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
63 u32 *mode, char *extra) 63 u32 *mode, char *extra)
@@ -108,7 +108,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
108 108
109 return ret; 109 return ret;
110} 110}
111EXPORT_SYMBOL(cfg80211_wext_siwmode); 111EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
112 112
113int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, 113int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
114 u32 *mode, char *extra) 114 u32 *mode, char *extra)
@@ -143,7 +143,7 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
143 } 143 }
144 return 0; 144 return 0;
145} 145}
146EXPORT_SYMBOL(cfg80211_wext_giwmode); 146EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode);
147 147
148 148
149int cfg80211_wext_giwrange(struct net_device *dev, 149int cfg80211_wext_giwrange(struct net_device *dev,
@@ -206,7 +206,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
206 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 206 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
207 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 207 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
208 208
209
210 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { 209 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
211 int i; 210 int i;
212 struct ieee80211_supported_band *sband; 211 struct ieee80211_supported_band *sband;
@@ -240,4 +239,229 @@ int cfg80211_wext_giwrange(struct net_device *dev,
240 239
241 return 0; 240 return 0;
242} 241}
243EXPORT_SYMBOL(cfg80211_wext_giwrange); 242EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
243
244int cfg80211_wext_siwmlme(struct net_device *dev,
245 struct iw_request_info *info,
246 struct iw_point *data, char *extra)
247{
248 struct wireless_dev *wdev = dev->ieee80211_ptr;
249 struct iw_mlme *mlme = (struct iw_mlme *)extra;
250 struct cfg80211_registered_device *rdev;
251 union {
252 struct cfg80211_disassoc_request disassoc;
253 struct cfg80211_deauth_request deauth;
254 } cmd;
255
256 if (!wdev)
257 return -EOPNOTSUPP;
258
259 rdev = wiphy_to_dev(wdev->wiphy);
260
261 if (wdev->iftype != NL80211_IFTYPE_STATION)
262 return -EINVAL;
263
264 if (mlme->addr.sa_family != ARPHRD_ETHER)
265 return -EINVAL;
266
267 memset(&cmd, 0, sizeof(cmd));
268
269 switch (mlme->cmd) {
270 case IW_MLME_DEAUTH:
271 if (!rdev->ops->deauth)
272 return -EOPNOTSUPP;
273 cmd.deauth.peer_addr = mlme->addr.sa_data;
274 cmd.deauth.reason_code = mlme->reason_code;
275 return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth);
276 case IW_MLME_DISASSOC:
277 if (!rdev->ops->disassoc)
278 return -EOPNOTSUPP;
279 cmd.disassoc.peer_addr = mlme->addr.sa_data;
280 cmd.disassoc.reason_code = mlme->reason_code;
281 return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc);
282 default:
283 return -EOPNOTSUPP;
284 }
285}
286EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
287
288
289/**
290 * cfg80211_wext_freq - get wext frequency for non-"auto"
291 * @wiphy: the wiphy
292 * @freq: the wext freq encoding
293 *
294 * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
295 */
296struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
297 struct iw_freq *freq)
298{
299 if (freq->e == 0) {
300 if (freq->m < 0)
301 return NULL;
302 else
303 return ieee80211_get_channel(wiphy,
304 ieee80211_channel_to_frequency(freq->m));
305 } else {
306 int i, div = 1000000;
307 for (i = 0; i < freq->e; i++)
308 div /= 10;
309 if (div > 0)
310 return ieee80211_get_channel(wiphy, freq->m / div);
311 else
312 return ERR_PTR(-EINVAL);
313 }
314
315}
316EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
317
318int cfg80211_wext_siwrts(struct net_device *dev,
319 struct iw_request_info *info,
320 struct iw_param *rts, char *extra)
321{
322 struct wireless_dev *wdev = dev->ieee80211_ptr;
323 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
324 u32 orts = wdev->wiphy->rts_threshold;
325 int err;
326
327 if (rts->disabled || !rts->fixed)
328 wdev->wiphy->rts_threshold = (u32) -1;
329 else if (rts->value < 0)
330 return -EINVAL;
331 else
332 wdev->wiphy->rts_threshold = rts->value;
333
334 err = rdev->ops->set_wiphy_params(wdev->wiphy,
335 WIPHY_PARAM_RTS_THRESHOLD);
336 if (err)
337 wdev->wiphy->rts_threshold = orts;
338
339 return err;
340}
341EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts);
342
343int cfg80211_wext_giwrts(struct net_device *dev,
344 struct iw_request_info *info,
345 struct iw_param *rts, char *extra)
346{
347 struct wireless_dev *wdev = dev->ieee80211_ptr;
348
349 rts->value = wdev->wiphy->rts_threshold;
350 rts->disabled = rts->value == (u32) -1;
351 rts->fixed = 1;
352
353 return 0;
354}
355EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts);
356
357int cfg80211_wext_siwfrag(struct net_device *dev,
358 struct iw_request_info *info,
359 struct iw_param *frag, char *extra)
360{
361 struct wireless_dev *wdev = dev->ieee80211_ptr;
362 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
363 u32 ofrag = wdev->wiphy->frag_threshold;
364 int err;
365
366 if (frag->disabled || !frag->fixed)
367 wdev->wiphy->frag_threshold = (u32) -1;
368 else if (frag->value < 256)
369 return -EINVAL;
370 else {
371 /* Fragment length must be even, so strip LSB. */
372 wdev->wiphy->frag_threshold = frag->value & ~0x1;
373 }
374
375 err = rdev->ops->set_wiphy_params(wdev->wiphy,
376 WIPHY_PARAM_FRAG_THRESHOLD);
377 if (err)
378 wdev->wiphy->frag_threshold = ofrag;
379
380 return err;
381}
382EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag);
383
384int cfg80211_wext_giwfrag(struct net_device *dev,
385 struct iw_request_info *info,
386 struct iw_param *frag, char *extra)
387{
388 struct wireless_dev *wdev = dev->ieee80211_ptr;
389
390 frag->value = wdev->wiphy->frag_threshold;
391 frag->disabled = frag->value == (u32) -1;
392 frag->fixed = 1;
393
394 return 0;
395}
396EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
397
398int cfg80211_wext_siwretry(struct net_device *dev,
399 struct iw_request_info *info,
400 struct iw_param *retry, char *extra)
401{
402 struct wireless_dev *wdev = dev->ieee80211_ptr;
403 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
404 u32 changed = 0;
405 u8 olong = wdev->wiphy->retry_long;
406 u8 oshort = wdev->wiphy->retry_short;
407 int err;
408
409 if (retry->disabled ||
410 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
411 return -EINVAL;
412
413 if (retry->flags & IW_RETRY_LONG) {
414 wdev->wiphy->retry_long = retry->value;
415 changed |= WIPHY_PARAM_RETRY_LONG;
416 } else if (retry->flags & IW_RETRY_SHORT) {
417 wdev->wiphy->retry_short = retry->value;
418 changed |= WIPHY_PARAM_RETRY_SHORT;
419 } else {
420 wdev->wiphy->retry_short = retry->value;
421 wdev->wiphy->retry_long = retry->value;
422 changed |= WIPHY_PARAM_RETRY_LONG;
423 changed |= WIPHY_PARAM_RETRY_SHORT;
424 }
425
426 if (!changed)
427 return 0;
428
429 err = rdev->ops->set_wiphy_params(wdev->wiphy, changed);
430 if (err) {
431 wdev->wiphy->retry_short = oshort;
432 wdev->wiphy->retry_long = olong;
433 }
434
435 return err;
436}
437EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
438
439int cfg80211_wext_giwretry(struct net_device *dev,
440 struct iw_request_info *info,
441 struct iw_param *retry, char *extra)
442{
443 struct wireless_dev *wdev = dev->ieee80211_ptr;
444
445 retry->disabled = 0;
446
447 if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
448 /*
449 * First return short value, iwconfig will ask long value
450 * later if needed
451 */
452 retry->flags |= IW_RETRY_LIMIT;
453 retry->value = wdev->wiphy->retry_short;
454 if (wdev->wiphy->retry_long != wdev->wiphy->retry_short)
455 retry->flags |= IW_RETRY_LONG;
456
457 return 0;
458 }
459
460 if (retry->flags & IW_RETRY_LONG) {
461 retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
462 retry->value = wdev->wiphy->retry_long;
463 }
464
465 return 0;
466}
467EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);