aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c244
1 files changed, 134 insertions, 110 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 29ac8e1a509..18bd0e55060 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -19,33 +19,6 @@
19#include "rate.h" 19#include "rate.h"
20#include "mesh.h" 20#include "mesh.h"
21 21
22static bool nl80211_type_check(enum nl80211_iftype type)
23{
24 switch (type) {
25 case NL80211_IFTYPE_ADHOC:
26 case NL80211_IFTYPE_STATION:
27 case NL80211_IFTYPE_MONITOR:
28#ifdef CONFIG_MAC80211_MESH
29 case NL80211_IFTYPE_MESH_POINT:
30#endif
31 case NL80211_IFTYPE_AP:
32 case NL80211_IFTYPE_AP_VLAN:
33 case NL80211_IFTYPE_WDS:
34 return true;
35 default:
36 return false;
37 }
38}
39
40static bool nl80211_params_check(enum nl80211_iftype type,
41 struct vif_params *params)
42{
43 if (!nl80211_type_check(type))
44 return false;
45
46 return true;
47}
48
49static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 22static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
50 enum nl80211_iftype type, u32 *flags, 23 enum nl80211_iftype type, u32 *flags,
51 struct vif_params *params) 24 struct vif_params *params)
@@ -55,9 +28,6 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
55 struct ieee80211_sub_if_data *sdata; 28 struct ieee80211_sub_if_data *sdata;
56 int err; 29 int err;
57 30
58 if (!nl80211_params_check(type, params))
59 return -EINVAL;
60
61 err = ieee80211_if_add(local, name, &dev, type, params); 31 err = ieee80211_if_add(local, name, &dev, type, params);
62 if (err || type != NL80211_IFTYPE_MONITOR || !flags) 32 if (err || type != NL80211_IFTYPE_MONITOR || !flags)
63 return err; 33 return err;
@@ -82,12 +52,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
82 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 52 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
83 int ret; 53 int ret;
84 54
85 if (ieee80211_sdata_running(sdata))
86 return -EBUSY;
87
88 if (!nl80211_params_check(type, params))
89 return -EINVAL;
90
91 ret = ieee80211_if_change_type(sdata, type); 55 ret = ieee80211_if_change_type(sdata, type);
92 if (ret) 56 if (ret)
93 return ret; 57 return ret;
@@ -104,54 +68,71 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
104 params && params->use_4addr >= 0) 68 params && params->use_4addr >= 0)
105 sdata->u.mgd.use_4addr = params->use_4addr; 69 sdata->u.mgd.use_4addr = params->use_4addr;
106 70
107 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) 71 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
108 sdata->u.mntr_flags = *flags; 72 struct ieee80211_local *local = sdata->local;
73
74 if (ieee80211_sdata_running(sdata)) {
75 /*
76 * Prohibit MONITOR_FLAG_COOK_FRAMES to be
77 * changed while the interface is up.
78 * Else we would need to add a lot of cruft
79 * to update everything:
80 * cooked_mntrs, monitor and all fif_* counters
81 * reconfigure hardware
82 */
83 if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
84 (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
85 return -EBUSY;
86
87 ieee80211_adjust_monitor_flags(sdata, -1);
88 sdata->u.mntr_flags = *flags;
89 ieee80211_adjust_monitor_flags(sdata, 1);
90
91 ieee80211_configure_filter(local);
92 } else {
93 /*
94 * Because the interface is down, ieee80211_do_stop
95 * and ieee80211_do_open take care of "everything"
96 * mentioned in the comment above.
97 */
98 sdata->u.mntr_flags = *flags;
99 }
100 }
109 101
110 return 0; 102 return 0;
111} 103}
112 104
113static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
114 u8 key_idx, const u8 *mac_addr, 106 u8 key_idx, bool pairwise, const u8 *mac_addr,
115 struct key_params *params) 107 struct key_params *params)
116{ 108{
117 struct ieee80211_sub_if_data *sdata; 109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
118 struct sta_info *sta = NULL; 110 struct sta_info *sta = NULL;
119 enum ieee80211_key_alg alg;
120 struct ieee80211_key *key; 111 struct ieee80211_key *key;
121 int err; 112 int err;
122 113
123 if (!netif_running(dev)) 114 if (!ieee80211_sdata_running(sdata))
124 return -ENETDOWN; 115 return -ENETDOWN;
125 116
126 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 117 /* reject WEP and TKIP keys if WEP failed to initialize */
127
128 switch (params->cipher) { 118 switch (params->cipher) {
129 case WLAN_CIPHER_SUITE_WEP40: 119 case WLAN_CIPHER_SUITE_WEP40:
130 case WLAN_CIPHER_SUITE_WEP104:
131 alg = ALG_WEP;
132 break;
133 case WLAN_CIPHER_SUITE_TKIP: 120 case WLAN_CIPHER_SUITE_TKIP:
134 alg = ALG_TKIP; 121 case WLAN_CIPHER_SUITE_WEP104:
135 break; 122 if (IS_ERR(sdata->local->wep_tx_tfm))
136 case WLAN_CIPHER_SUITE_CCMP: 123 return -EINVAL;
137 alg = ALG_CCMP;
138 break;
139 case WLAN_CIPHER_SUITE_AES_CMAC:
140 alg = ALG_AES_CMAC;
141 break; 124 break;
142 default: 125 default:
143 return -EINVAL; 126 break;
144 } 127 }
145 128
146 /* reject WEP and TKIP keys if WEP failed to initialize */ 129 key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
147 if ((alg == ALG_WEP || alg == ALG_TKIP) && 130 params->key, params->seq_len, params->seq);
148 IS_ERR(sdata->local->wep_tx_tfm)) 131 if (IS_ERR(key))
149 return -EINVAL; 132 return PTR_ERR(key);
150 133
151 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, 134 if (pairwise)
152 params->seq_len, params->seq); 135 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
153 if (!key)
154 return -ENOMEM;
155 136
156 mutex_lock(&sdata->local->sta_mtx); 137 mutex_lock(&sdata->local->sta_mtx);
157 138
@@ -164,9 +145,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
164 } 145 }
165 } 146 }
166 147
167 ieee80211_key_link(key, sdata, sta); 148 err = ieee80211_key_link(key, sdata, sta);
149 if (err)
150 ieee80211_key_free(sdata->local, key);
168 151
169 err = 0;
170 out_unlock: 152 out_unlock:
171 mutex_unlock(&sdata->local->sta_mtx); 153 mutex_unlock(&sdata->local->sta_mtx);
172 154
@@ -174,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
174} 156}
175 157
176static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 158static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
177 u8 key_idx, const u8 *mac_addr) 159 u8 key_idx, bool pairwise, const u8 *mac_addr)
178{ 160{
179 struct ieee80211_sub_if_data *sdata; 161 struct ieee80211_sub_if_data *sdata;
180 struct sta_info *sta; 162 struct sta_info *sta;
@@ -191,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
191 if (!sta) 173 if (!sta)
192 goto out_unlock; 174 goto out_unlock;
193 175
194 if (sta->key) { 176 if (pairwise) {
195 ieee80211_key_free(sdata->local, sta->key); 177 if (sta->ptk) {
196 WARN_ON(sta->key); 178 ieee80211_key_free(sdata->local, sta->ptk);
197 ret = 0; 179 ret = 0;
180 }
181 } else {
182 if (sta->gtk[key_idx]) {
183 ieee80211_key_free(sdata->local,
184 sta->gtk[key_idx]);
185 ret = 0;
186 }
198 } 187 }
199 188
200 goto out_unlock; 189 goto out_unlock;
@@ -216,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
216} 205}
217 206
218static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 207static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
219 u8 key_idx, const u8 *mac_addr, void *cookie, 208 u8 key_idx, bool pairwise, const u8 *mac_addr,
209 void *cookie,
220 void (*callback)(void *cookie, 210 void (*callback)(void *cookie,
221 struct key_params *params)) 211 struct key_params *params))
222{ 212{
@@ -224,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
224 struct sta_info *sta = NULL; 214 struct sta_info *sta = NULL;
225 u8 seq[6] = {0}; 215 u8 seq[6] = {0};
226 struct key_params params; 216 struct key_params params;
227 struct ieee80211_key *key; 217 struct ieee80211_key *key = NULL;
228 u32 iv32; 218 u32 iv32;
229 u16 iv16; 219 u16 iv16;
230 int err = -ENOENT; 220 int err = -ENOENT;
@@ -238,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
238 if (!sta) 228 if (!sta)
239 goto out; 229 goto out;
240 230
241 key = sta->key; 231 if (pairwise)
232 key = sta->ptk;
233 else if (key_idx < NUM_DEFAULT_KEYS)
234 key = sta->gtk[key_idx];
242 } else 235 } else
243 key = sdata->keys[key_idx]; 236 key = sdata->keys[key_idx];
244 237
@@ -247,10 +240,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
247 240
248 memset(&params, 0, sizeof(params)); 241 memset(&params, 0, sizeof(params));
249 242
250 switch (key->conf.alg) { 243 params.cipher = key->conf.cipher;
251 case ALG_TKIP:
252 params.cipher = WLAN_CIPHER_SUITE_TKIP;
253 244
245 switch (key->conf.cipher) {
246 case WLAN_CIPHER_SUITE_TKIP:
254 iv32 = key->u.tkip.tx.iv32; 247 iv32 = key->u.tkip.tx.iv32;
255 iv16 = key->u.tkip.tx.iv16; 248 iv16 = key->u.tkip.tx.iv16;
256 249
@@ -268,8 +261,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
268 params.seq = seq; 261 params.seq = seq;
269 params.seq_len = 6; 262 params.seq_len = 6;
270 break; 263 break;
271 case ALG_CCMP: 264 case WLAN_CIPHER_SUITE_CCMP:
272 params.cipher = WLAN_CIPHER_SUITE_CCMP;
273 seq[0] = key->u.ccmp.tx_pn[5]; 265 seq[0] = key->u.ccmp.tx_pn[5];
274 seq[1] = key->u.ccmp.tx_pn[4]; 266 seq[1] = key->u.ccmp.tx_pn[4];
275 seq[2] = key->u.ccmp.tx_pn[3]; 267 seq[2] = key->u.ccmp.tx_pn[3];
@@ -279,14 +271,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
279 params.seq = seq; 271 params.seq = seq;
280 params.seq_len = 6; 272 params.seq_len = 6;
281 break; 273 break;
282 case ALG_WEP: 274 case WLAN_CIPHER_SUITE_AES_CMAC:
283 if (key->conf.keylen == 5)
284 params.cipher = WLAN_CIPHER_SUITE_WEP40;
285 else
286 params.cipher = WLAN_CIPHER_SUITE_WEP104;
287 break;
288 case ALG_AES_CMAC:
289 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
290 seq[0] = key->u.aes_cmac.tx_pn[5]; 275 seq[0] = key->u.aes_cmac.tx_pn[5];
291 seq[1] = key->u.aes_cmac.tx_pn[4]; 276 seq[1] = key->u.aes_cmac.tx_pn[4];
292 seq[2] = key->u.aes_cmac.tx_pn[3]; 277 seq[2] = key->u.aes_cmac.tx_pn[3];
@@ -342,13 +327,19 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
342 STATION_INFO_TX_BYTES | 327 STATION_INFO_TX_BYTES |
343 STATION_INFO_RX_PACKETS | 328 STATION_INFO_RX_PACKETS |
344 STATION_INFO_TX_PACKETS | 329 STATION_INFO_TX_PACKETS |
345 STATION_INFO_TX_BITRATE; 330 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED |
332 STATION_INFO_TX_BITRATE |
333 STATION_INFO_RX_DROP_MISC;
346 334
347 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 335 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
348 sinfo->rx_bytes = sta->rx_bytes; 336 sinfo->rx_bytes = sta->rx_bytes;
349 sinfo->tx_bytes = sta->tx_bytes; 337 sinfo->tx_bytes = sta->tx_bytes;
350 sinfo->rx_packets = sta->rx_packets; 338 sinfo->rx_packets = sta->rx_packets;
351 sinfo->tx_packets = sta->tx_packets; 339 sinfo->tx_packets = sta->tx_packets;
340 sinfo->tx_retries = sta->tx_retry_count;
341 sinfo->tx_failed = sta->tx_retry_failed;
342 sinfo->rx_dropped_misc = sta->rx_dropped;
352 343
353 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 344 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
354 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 345 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -634,6 +625,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
634 struct sta_info *sta, 625 struct sta_info *sta,
635 struct station_parameters *params) 626 struct station_parameters *params)
636{ 627{
628 unsigned long flags;
637 u32 rates; 629 u32 rates;
638 int i, j; 630 int i, j;
639 struct ieee80211_supported_band *sband; 631 struct ieee80211_supported_band *sband;
@@ -642,7 +634,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
642 634
643 sband = local->hw.wiphy->bands[local->oper_channel->band]; 635 sband = local->hw.wiphy->bands[local->oper_channel->band];
644 636
645 spin_lock_bh(&sta->lock); 637 spin_lock_irqsave(&sta->flaglock, flags);
646 mask = params->sta_flags_mask; 638 mask = params->sta_flags_mask;
647 set = params->sta_flags_set; 639 set = params->sta_flags_set;
648 640
@@ -669,7 +661,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
669 if (set & BIT(NL80211_STA_FLAG_MFP)) 661 if (set & BIT(NL80211_STA_FLAG_MFP))
670 sta->flags |= WLAN_STA_MFP; 662 sta->flags |= WLAN_STA_MFP;
671 } 663 }
672 spin_unlock_bh(&sta->lock); 664 spin_unlock_irqrestore(&sta->flaglock, flags);
673 665
674 /* 666 /*
675 * cfg80211 validates this (1-2007) and allows setting the AID 667 * cfg80211 validates this (1-2007) and allows setting the AID
@@ -1143,9 +1135,9 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1143 p.uapsd = false; 1135 p.uapsd = false;
1144 1136
1145 if (drv_conf_tx(local, params->queue, &p)) { 1137 if (drv_conf_tx(local, params->queue, &p)) {
1146 printk(KERN_DEBUG "%s: failed to set TX queue " 1138 wiphy_debug(local->hw.wiphy,
1147 "parameters for queue %d\n", 1139 "failed to set TX queue parameters for queue %d\n",
1148 wiphy_name(local->hw.wiphy), params->queue); 1140 params->queue);
1149 return -EINVAL; 1141 return -EINVAL;
1150 } 1142 }
1151 1143
@@ -1207,15 +1199,26 @@ static int ieee80211_scan(struct wiphy *wiphy,
1207 struct net_device *dev, 1199 struct net_device *dev,
1208 struct cfg80211_scan_request *req) 1200 struct cfg80211_scan_request *req)
1209{ 1201{
1210 struct ieee80211_sub_if_data *sdata; 1202 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1211
1212 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1213 1203
1214 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1204 switch (ieee80211_vif_type_p2p(&sdata->vif)) {
1215 sdata->vif.type != NL80211_IFTYPE_ADHOC && 1205 case NL80211_IFTYPE_STATION:
1216 sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 1206 case NL80211_IFTYPE_ADHOC:
1217 (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon)) 1207 case NL80211_IFTYPE_MESH_POINT:
1208 case NL80211_IFTYPE_P2P_CLIENT:
1209 break;
1210 case NL80211_IFTYPE_P2P_GO:
1211 if (sdata->local->ops->hw_scan)
1212 break;
1213 /* FIXME: implement NoA while scanning in software */
1214 return -EOPNOTSUPP;
1215 case NL80211_IFTYPE_AP:
1216 if (sdata->u.ap.beacon)
1217 return -EOPNOTSUPP;
1218 break;
1219 default:
1218 return -EOPNOTSUPP; 1220 return -EOPNOTSUPP;
1221 }
1219 1222
1220 return ieee80211_request_scan(sdata, req); 1223 return ieee80211_request_scan(sdata, req);
1221} 1224}
@@ -1362,7 +1365,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1362} 1365}
1363 1366
1364static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, 1367static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
1365 u8 *addr) 1368 const u8 *addr)
1366{ 1369{
1367 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1370 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1368 1371
@@ -1411,7 +1414,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1411 if (!sdata->u.mgd.associated || 1414 if (!sdata->u.mgd.associated ||
1412 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { 1415 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1413 mutex_lock(&sdata->local->iflist_mtx); 1416 mutex_lock(&sdata->local->iflist_mtx);
1414 ieee80211_recalc_smps(sdata->local, sdata); 1417 ieee80211_recalc_smps(sdata->local);
1415 mutex_unlock(&sdata->local->iflist_mtx); 1418 mutex_unlock(&sdata->local->iflist_mtx);
1416 return 0; 1419 return 0;
1417 } 1420 }
@@ -1541,11 +1544,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
1541 return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); 1544 return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
1542} 1545}
1543 1546
1544static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, 1547static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1545 struct ieee80211_channel *chan, 1548 struct ieee80211_channel *chan,
1546 enum nl80211_channel_type channel_type, 1549 enum nl80211_channel_type channel_type,
1547 bool channel_type_valid, 1550 bool channel_type_valid,
1548 const u8 *buf, size_t len, u64 *cookie) 1551 const u8 *buf, size_t len, u64 *cookie)
1549{ 1552{
1550 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1553 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1551 struct ieee80211_local *local = sdata->local; 1554 struct ieee80211_local *local = sdata->local;
@@ -1566,7 +1569,11 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
1566 1569
1567 switch (sdata->vif.type) { 1570 switch (sdata->vif.type) {
1568 case NL80211_IFTYPE_ADHOC: 1571 case NL80211_IFTYPE_ADHOC:
1569 if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1572 case NL80211_IFTYPE_AP:
1573 case NL80211_IFTYPE_AP_VLAN:
1574 case NL80211_IFTYPE_P2P_GO:
1575 if (!ieee80211_is_action(mgmt->frame_control) ||
1576 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1570 break; 1577 break;
1571 rcu_read_lock(); 1578 rcu_read_lock();
1572 sta = sta_info_get(sdata, mgmt->da); 1579 sta = sta_info_get(sdata, mgmt->da);
@@ -1575,8 +1582,7 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
1575 return -ENOLINK; 1582 return -ENOLINK;
1576 break; 1583 break;
1577 case NL80211_IFTYPE_STATION: 1584 case NL80211_IFTYPE_STATION:
1578 if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) 1585 case NL80211_IFTYPE_P2P_CLIENT:
1579 flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1580 break; 1586 break;
1581 default: 1587 default:
1582 return -EOPNOTSUPP; 1588 return -EOPNOTSUPP;
@@ -1598,6 +1604,23 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
1598 return 0; 1604 return 0;
1599} 1605}
1600 1606
1607static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
1608 struct net_device *dev,
1609 u16 frame_type, bool reg)
1610{
1611 struct ieee80211_local *local = wiphy_priv(wiphy);
1612
1613 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
1614 return;
1615
1616 if (reg)
1617 local->probe_req_reg++;
1618 else
1619 local->probe_req_reg--;
1620
1621 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
1622}
1623
1601struct cfg80211_ops mac80211_config_ops = { 1624struct cfg80211_ops mac80211_config_ops = {
1602 .add_virtual_intf = ieee80211_add_iface, 1625 .add_virtual_intf = ieee80211_add_iface,
1603 .del_virtual_intf = ieee80211_del_iface, 1626 .del_virtual_intf = ieee80211_del_iface,
@@ -1647,6 +1670,7 @@ struct cfg80211_ops mac80211_config_ops = {
1647 .set_bitrate_mask = ieee80211_set_bitrate_mask, 1670 .set_bitrate_mask = ieee80211_set_bitrate_mask,
1648 .remain_on_channel = ieee80211_remain_on_channel, 1671 .remain_on_channel = ieee80211_remain_on_channel,
1649 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1672 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1650 .action = ieee80211_action, 1673 .mgmt_tx = ieee80211_mgmt_tx,
1651 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, 1674 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1675 .mgmt_frame_register = ieee80211_mgmt_frame_register,
1652}; 1676};