2 * cfg80211 MLME SAP interface
4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/etherdevice.h>
10 #include <linux/netdevice.h>
11 #include <linux/nl80211.h>
12 #include <linux/slab.h>
13 #include <linux/wireless.h>
14 #include <net/cfg80211.h>
15 #include <net/iw_handler.h>
21 void cfg80211_send_rx_auth(struct net_device
*dev
, const u8
*buf
, size_t len
)
23 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
24 struct wiphy
*wiphy
= wdev
->wiphy
;
25 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
27 trace_cfg80211_send_rx_auth(dev
);
30 nl80211_send_rx_auth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
31 cfg80211_sme_rx_auth(dev
, buf
, len
);
35 EXPORT_SYMBOL(cfg80211_send_rx_auth
);
37 void cfg80211_send_rx_assoc(struct net_device
*dev
, struct cfg80211_bss
*bss
,
38 const u8
*buf
, size_t len
)
41 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
42 struct wiphy
*wiphy
= wdev
->wiphy
;
43 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
44 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
45 u8
*ie
= mgmt
->u
.assoc_resp
.variable
;
46 int ieoffs
= offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
48 trace_cfg80211_send_rx_assoc(dev
, bss
);
51 status_code
= le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
54 * This is a bit of a hack, we don't notify userspace of
55 * a (re-)association reply if we tried to send a reassoc
56 * and got a reject -- we only try again with an assoc
57 * frame instead of reassoc.
59 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
&&
60 cfg80211_sme_failed_reassoc(wdev
)) {
61 cfg80211_put_bss(bss
);
65 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
67 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
) {
68 cfg80211_sme_failed_assoc(wdev
);
70 * do not call connect_result() now because the
71 * sme will schedule work that does it later.
73 cfg80211_put_bss(bss
);
77 if (!wdev
->conn
&& wdev
->sme_state
== CFG80211_SME_IDLE
) {
79 * This is for the userspace SME, the CONNECTING
80 * state will be changed to CONNECTED by
81 * __cfg80211_connect_result() below.
83 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
86 /* this consumes the bss reference */
87 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, ie
, len
- ieoffs
,
89 status_code
== WLAN_STATUS_SUCCESS
, bss
);
93 EXPORT_SYMBOL(cfg80211_send_rx_assoc
);
95 void __cfg80211_send_deauth(struct net_device
*dev
,
96 const u8
*buf
, size_t len
)
98 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
99 struct wiphy
*wiphy
= wdev
->wiphy
;
100 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
101 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
102 const u8
*bssid
= mgmt
->bssid
;
103 bool was_current
= false;
105 trace___cfg80211_send_deauth(dev
);
106 ASSERT_WDEV_LOCK(wdev
);
108 if (wdev
->current_bss
&&
109 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
110 cfg80211_unhold_bss(wdev
->current_bss
);
111 cfg80211_put_bss(&wdev
->current_bss
->pub
);
112 wdev
->current_bss
= NULL
;
116 nl80211_send_deauth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
118 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
&& was_current
) {
122 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
124 from_ap
= !ether_addr_equal(mgmt
->sa
, dev
->dev_addr
);
125 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
126 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
) {
127 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
128 WLAN_STATUS_UNSPECIFIED_FAILURE
,
132 EXPORT_SYMBOL(__cfg80211_send_deauth
);
134 void cfg80211_send_deauth(struct net_device
*dev
, const u8
*buf
, size_t len
)
136 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
139 __cfg80211_send_deauth(dev
, buf
, len
);
142 EXPORT_SYMBOL(cfg80211_send_deauth
);
144 void __cfg80211_send_disassoc(struct net_device
*dev
,
145 const u8
*buf
, size_t len
)
147 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
148 struct wiphy
*wiphy
= wdev
->wiphy
;
149 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
150 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
151 const u8
*bssid
= mgmt
->bssid
;
155 trace___cfg80211_send_disassoc(dev
);
156 ASSERT_WDEV_LOCK(wdev
);
158 nl80211_send_disassoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
160 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
163 if (wdev
->current_bss
&&
164 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
165 cfg80211_sme_disassoc(dev
, wdev
->current_bss
);
166 cfg80211_unhold_bss(wdev
->current_bss
);
167 cfg80211_put_bss(&wdev
->current_bss
->pub
);
168 wdev
->current_bss
= NULL
;
173 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
175 from_ap
= !ether_addr_equal(mgmt
->sa
, dev
->dev_addr
);
176 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
178 EXPORT_SYMBOL(__cfg80211_send_disassoc
);
180 void cfg80211_send_disassoc(struct net_device
*dev
, const u8
*buf
, size_t len
)
182 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
185 __cfg80211_send_disassoc(dev
, buf
, len
);
188 EXPORT_SYMBOL(cfg80211_send_disassoc
);
190 void cfg80211_send_unprot_deauth(struct net_device
*dev
, const u8
*buf
,
193 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
194 struct wiphy
*wiphy
= wdev
->wiphy
;
195 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
197 trace_cfg80211_send_unprot_deauth(dev
);
198 nl80211_send_unprot_deauth(rdev
, dev
, buf
, len
, GFP_ATOMIC
);
200 EXPORT_SYMBOL(cfg80211_send_unprot_deauth
);
202 void cfg80211_send_unprot_disassoc(struct net_device
*dev
, const u8
*buf
,
205 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
206 struct wiphy
*wiphy
= wdev
->wiphy
;
207 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
209 trace_cfg80211_send_unprot_disassoc(dev
);
210 nl80211_send_unprot_disassoc(rdev
, dev
, buf
, len
, GFP_ATOMIC
);
212 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc
);
214 void cfg80211_send_auth_timeout(struct net_device
*dev
, const u8
*addr
)
216 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
217 struct wiphy
*wiphy
= wdev
->wiphy
;
218 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
220 trace_cfg80211_send_auth_timeout(dev
, addr
);
223 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
224 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
225 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
226 WLAN_STATUS_UNSPECIFIED_FAILURE
,
231 EXPORT_SYMBOL(cfg80211_send_auth_timeout
);
233 void cfg80211_send_assoc_timeout(struct net_device
*dev
, const u8
*addr
)
235 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
236 struct wiphy
*wiphy
= wdev
->wiphy
;
237 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
239 trace_cfg80211_send_assoc_timeout(dev
, addr
);
242 nl80211_send_assoc_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
243 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
244 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
245 WLAN_STATUS_UNSPECIFIED_FAILURE
,
250 EXPORT_SYMBOL(cfg80211_send_assoc_timeout
);
252 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
253 enum nl80211_key_type key_type
, int key_id
,
254 const u8
*tsc
, gfp_t gfp
)
256 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
257 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
258 #ifdef CONFIG_CFG80211_WEXT
259 union iwreq_data wrqu
;
260 char *buf
= kmalloc(128, gfp
);
263 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
264 "keyid=%d %scast addr=%pM)", key_id
,
265 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
267 memset(&wrqu
, 0, sizeof(wrqu
));
268 wrqu
.data
.length
= strlen(buf
);
269 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
274 trace_cfg80211_michael_mic_failure(dev
, addr
, key_type
, key_id
, tsc
);
275 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
277 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
279 /* some MLME handling for userspace SME */
280 int __cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
281 struct net_device
*dev
,
282 struct ieee80211_channel
*chan
,
283 enum nl80211_auth_type auth_type
,
285 const u8
*ssid
, int ssid_len
,
286 const u8
*ie
, int ie_len
,
287 const u8
*key
, int key_len
, int key_idx
,
288 const u8
*sae_data
, int sae_data_len
)
290 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
291 struct cfg80211_auth_request req
;
294 ASSERT_WDEV_LOCK(wdev
);
296 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
297 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 4)
300 if (wdev
->current_bss
&&
301 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
304 memset(&req
, 0, sizeof(req
));
308 req
.sae_data
= sae_data
;
309 req
.sae_data_len
= sae_data_len
;
310 req
.auth_type
= auth_type
;
311 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
312 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
314 req
.key_len
= key_len
;
315 req
.key_idx
= key_idx
;
319 err
= cfg80211_can_use_chan(rdev
, wdev
, req
.bss
->channel
,
324 err
= rdev_auth(rdev
, dev
, &req
);
327 cfg80211_put_bss(req
.bss
);
331 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
332 struct net_device
*dev
, struct ieee80211_channel
*chan
,
333 enum nl80211_auth_type auth_type
, const u8
*bssid
,
334 const u8
*ssid
, int ssid_len
,
335 const u8
*ie
, int ie_len
,
336 const u8
*key
, int key_len
, int key_idx
,
337 const u8
*sae_data
, int sae_data_len
)
341 mutex_lock(&rdev
->devlist_mtx
);
342 wdev_lock(dev
->ieee80211_ptr
);
343 err
= __cfg80211_mlme_auth(rdev
, dev
, chan
, auth_type
, bssid
,
344 ssid
, ssid_len
, ie
, ie_len
,
345 key
, key_len
, key_idx
,
346 sae_data
, sae_data_len
);
347 wdev_unlock(dev
->ieee80211_ptr
);
348 mutex_unlock(&rdev
->devlist_mtx
);
353 /* Do a logical ht_capa &= ht_capa_mask. */
354 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
355 const struct ieee80211_ht_cap
*ht_capa_mask
)
360 memset(ht_capa
, 0, sizeof(*ht_capa
));
365 p2
= (u8
*)(ht_capa_mask
);
366 for (i
= 0; i
<sizeof(*ht_capa
); i
++)
370 int __cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
371 struct net_device
*dev
,
372 struct ieee80211_channel
*chan
,
373 const u8
*bssid
, const u8
*prev_bssid
,
374 const u8
*ssid
, int ssid_len
,
375 const u8
*ie
, int ie_len
, bool use_mfp
,
376 struct cfg80211_crypto_settings
*crypt
,
377 u32 assoc_flags
, struct ieee80211_ht_cap
*ht_capa
,
378 struct ieee80211_ht_cap
*ht_capa_mask
)
380 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
381 struct cfg80211_assoc_request req
;
383 bool was_connected
= false;
385 ASSERT_WDEV_LOCK(wdev
);
387 memset(&req
, 0, sizeof(req
));
389 if (wdev
->current_bss
&& prev_bssid
&&
390 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, prev_bssid
)) {
392 * Trying to reassociate: Allow this to proceed and let the old
393 * association to be dropped when the new one is completed.
395 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
396 was_connected
= true;
397 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
399 } else if (wdev
->current_bss
)
404 memcpy(&req
.crypto
, crypt
, sizeof(req
.crypto
));
405 req
.use_mfp
= use_mfp
;
406 req
.prev_bssid
= prev_bssid
;
407 req
.flags
= assoc_flags
;
409 memcpy(&req
.ht_capa
, ht_capa
, sizeof(req
.ht_capa
));
411 memcpy(&req
.ht_capa_mask
, ht_capa_mask
,
412 sizeof(req
.ht_capa_mask
));
413 cfg80211_oper_and_ht_capa(&req
.ht_capa_mask
,
414 rdev
->wiphy
.ht_capa_mod_mask
);
416 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
417 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
420 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
424 err
= cfg80211_can_use_chan(rdev
, wdev
, req
.bss
->channel
,
429 err
= rdev_assoc(rdev
, dev
, &req
);
434 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
435 cfg80211_put_bss(req
.bss
);
441 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
442 struct net_device
*dev
,
443 struct ieee80211_channel
*chan
,
444 const u8
*bssid
, const u8
*prev_bssid
,
445 const u8
*ssid
, int ssid_len
,
446 const u8
*ie
, int ie_len
, bool use_mfp
,
447 struct cfg80211_crypto_settings
*crypt
,
448 u32 assoc_flags
, struct ieee80211_ht_cap
*ht_capa
,
449 struct ieee80211_ht_cap
*ht_capa_mask
)
451 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
454 mutex_lock(&rdev
->devlist_mtx
);
456 err
= __cfg80211_mlme_assoc(rdev
, dev
, chan
, bssid
, prev_bssid
,
457 ssid
, ssid_len
, ie
, ie_len
, use_mfp
, crypt
,
458 assoc_flags
, ht_capa
, ht_capa_mask
);
460 mutex_unlock(&rdev
->devlist_mtx
);
465 int __cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
466 struct net_device
*dev
, const u8
*bssid
,
467 const u8
*ie
, int ie_len
, u16 reason
,
468 bool local_state_change
)
470 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
471 struct cfg80211_deauth_request req
= {
473 .reason_code
= reason
,
476 .local_state_change
= local_state_change
,
479 ASSERT_WDEV_LOCK(wdev
);
481 if (local_state_change
&& (!wdev
->current_bss
||
482 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
485 return rdev_deauth(rdev
, dev
, &req
);
488 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
489 struct net_device
*dev
, const u8
*bssid
,
490 const u8
*ie
, int ie_len
, u16 reason
,
491 bool local_state_change
)
493 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
497 err
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
504 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
505 struct net_device
*dev
, const u8
*bssid
,
506 const u8
*ie
, int ie_len
, u16 reason
,
507 bool local_state_change
)
509 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
510 struct cfg80211_disassoc_request req
;
512 ASSERT_WDEV_LOCK(wdev
);
514 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
517 if (WARN_ON(!wdev
->current_bss
))
520 memset(&req
, 0, sizeof(req
));
521 req
.reason_code
= reason
;
522 req
.local_state_change
= local_state_change
;
525 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
526 req
.bss
= &wdev
->current_bss
->pub
;
530 return rdev_disassoc(rdev
, dev
, &req
);
533 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
534 struct net_device
*dev
, const u8
*bssid
,
535 const u8
*ie
, int ie_len
, u16 reason
,
536 bool local_state_change
)
538 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
542 err
= __cfg80211_mlme_disassoc(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
549 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
550 struct net_device
*dev
)
552 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
553 struct cfg80211_deauth_request req
;
556 ASSERT_WDEV_LOCK(wdev
);
558 if (!rdev
->ops
->deauth
)
561 memset(&req
, 0, sizeof(req
));
562 req
.reason_code
= WLAN_REASON_DEAUTH_LEAVING
;
566 if (!wdev
->current_bss
)
569 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
571 rdev_deauth(rdev
, dev
, &req
);
573 if (wdev
->current_bss
) {
574 cfg80211_unhold_bss(wdev
->current_bss
);
575 cfg80211_put_bss(&wdev
->current_bss
->pub
);
576 wdev
->current_bss
= NULL
;
580 void cfg80211_ready_on_channel(struct wireless_dev
*wdev
, u64 cookie
,
581 struct ieee80211_channel
*chan
,
582 unsigned int duration
, gfp_t gfp
)
584 struct wiphy
*wiphy
= wdev
->wiphy
;
585 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
587 trace_cfg80211_ready_on_channel(wdev
, cookie
, chan
, duration
);
588 nl80211_send_remain_on_channel(rdev
, wdev
, cookie
, chan
, duration
, gfp
);
590 EXPORT_SYMBOL(cfg80211_ready_on_channel
);
592 void cfg80211_remain_on_channel_expired(struct wireless_dev
*wdev
, u64 cookie
,
593 struct ieee80211_channel
*chan
,
596 struct wiphy
*wiphy
= wdev
->wiphy
;
597 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
599 trace_cfg80211_ready_on_channel_expired(wdev
, cookie
, chan
);
600 nl80211_send_remain_on_channel_cancel(rdev
, wdev
, cookie
, chan
, gfp
);
602 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired
);
604 void cfg80211_new_sta(struct net_device
*dev
, const u8
*mac_addr
,
605 struct station_info
*sinfo
, gfp_t gfp
)
607 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
608 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
610 trace_cfg80211_new_sta(dev
, mac_addr
, sinfo
);
611 nl80211_send_sta_event(rdev
, dev
, mac_addr
, sinfo
, gfp
);
613 EXPORT_SYMBOL(cfg80211_new_sta
);
615 void cfg80211_del_sta(struct net_device
*dev
, const u8
*mac_addr
, gfp_t gfp
)
617 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
618 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
620 trace_cfg80211_del_sta(dev
, mac_addr
);
621 nl80211_send_sta_del_event(rdev
, dev
, mac_addr
, gfp
);
623 EXPORT_SYMBOL(cfg80211_del_sta
);
625 void cfg80211_conn_failed(struct net_device
*dev
, const u8
*mac_addr
,
626 enum nl80211_connect_failed_reason reason
,
629 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
630 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
632 nl80211_send_conn_failed_event(rdev
, dev
, mac_addr
, reason
, gfp
);
634 EXPORT_SYMBOL(cfg80211_conn_failed
);
636 struct cfg80211_mgmt_registration
{
637 struct list_head list
;
648 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_portid
,
649 u16 frame_type
, const u8
*match_data
,
652 struct wiphy
*wiphy
= wdev
->wiphy
;
653 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
654 struct cfg80211_mgmt_registration
*reg
, *nreg
;
658 if (!wdev
->wiphy
->mgmt_stypes
)
661 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
664 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
667 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
668 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
671 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
675 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
677 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
678 int mlen
= min(match_len
, reg
->match_len
);
680 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
683 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
694 memcpy(nreg
->match
, match_data
, match_len
);
695 nreg
->match_len
= match_len
;
696 nreg
->nlportid
= snd_portid
;
697 nreg
->frame_type
= cpu_to_le16(frame_type
);
698 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
700 if (rdev
->ops
->mgmt_frame_register
)
701 rdev_mgmt_frame_register(rdev
, wdev
, frame_type
, true);
704 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
709 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlportid
)
711 struct wiphy
*wiphy
= wdev
->wiphy
;
712 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
713 struct cfg80211_mgmt_registration
*reg
, *tmp
;
715 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
717 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
718 if (reg
->nlportid
!= nlportid
)
721 if (rdev
->ops
->mgmt_frame_register
) {
722 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
724 rdev_mgmt_frame_register(rdev
, wdev
,
728 list_del(®
->list
);
732 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
734 if (nlportid
== wdev
->ap_unexpected_nlportid
)
735 wdev
->ap_unexpected_nlportid
= 0;
738 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
740 struct cfg80211_mgmt_registration
*reg
, *tmp
;
742 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
744 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
745 list_del(®
->list
);
749 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
752 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
753 struct wireless_dev
*wdev
,
754 struct ieee80211_channel
*chan
, bool offchan
,
755 unsigned int wait
, const u8
*buf
, size_t len
,
756 bool no_cck
, bool dont_wait_for_ack
, u64
*cookie
)
758 const struct ieee80211_mgmt
*mgmt
;
761 if (!wdev
->wiphy
->mgmt_stypes
)
764 if (!rdev
->ops
->mgmt_tx
)
770 mgmt
= (const struct ieee80211_mgmt
*) buf
;
772 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
775 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
776 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
779 if (ieee80211_is_action(mgmt
->frame_control
) &&
780 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
785 switch (wdev
->iftype
) {
786 case NL80211_IFTYPE_ADHOC
:
787 case NL80211_IFTYPE_STATION
:
788 case NL80211_IFTYPE_P2P_CLIENT
:
789 if (!wdev
->current_bss
) {
794 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
801 * check for IBSS DA must be done by driver as
802 * cfg80211 doesn't track the stations
804 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
807 /* for station, check that DA is the AP */
808 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
814 case NL80211_IFTYPE_AP
:
815 case NL80211_IFTYPE_P2P_GO
:
816 case NL80211_IFTYPE_AP_VLAN
:
817 if (!ether_addr_equal(mgmt
->bssid
, wdev_address(wdev
)))
820 case NL80211_IFTYPE_MESH_POINT
:
821 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
826 * check for mesh DA must be done by driver as
827 * cfg80211 doesn't track the stations
830 case NL80211_IFTYPE_P2P_DEVICE
:
832 * fall through, P2P device only supports
833 * public action frames
845 if (!ether_addr_equal(mgmt
->sa
, wdev_address(wdev
)))
848 /* Transmit the Action frame as requested by user space */
849 return rdev_mgmt_tx(rdev
, wdev
, chan
, offchan
,
850 wait
, buf
, len
, no_cck
, dont_wait_for_ack
,
854 bool cfg80211_rx_mgmt(struct wireless_dev
*wdev
, int freq
, int sig_mbm
,
855 const u8
*buf
, size_t len
, gfp_t gfp
)
857 struct wiphy
*wiphy
= wdev
->wiphy
;
858 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
859 struct cfg80211_mgmt_registration
*reg
;
860 const struct ieee80211_txrx_stypes
*stypes
=
861 &wiphy
->mgmt_stypes
[wdev
->iftype
];
862 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
866 __le16 ftype
= mgmt
->frame_control
&
867 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
870 trace_cfg80211_rx_mgmt(wdev
, freq
, sig_mbm
);
871 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
873 if (!(stypes
->rx
& BIT(stype
))) {
874 trace_cfg80211_return_bool(false);
878 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
879 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
881 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
883 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
884 if (reg
->frame_type
!= ftype
)
887 if (reg
->match_len
> data_len
)
890 if (memcmp(reg
->match
, data
, reg
->match_len
))
895 /* Indicate the received Action frame to user space */
896 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlportid
,
905 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
907 trace_cfg80211_return_bool(result
);
910 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
912 void cfg80211_mgmt_tx_status(struct wireless_dev
*wdev
, u64 cookie
,
913 const u8
*buf
, size_t len
, bool ack
, gfp_t gfp
)
915 struct wiphy
*wiphy
= wdev
->wiphy
;
916 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
918 trace_cfg80211_mgmt_tx_status(wdev
, cookie
, ack
);
920 /* Indicate TX status of the Action frame to user space */
921 nl80211_send_mgmt_tx_status(rdev
, wdev
, cookie
, buf
, len
, ack
, gfp
);
923 EXPORT_SYMBOL(cfg80211_mgmt_tx_status
);
925 void cfg80211_cqm_rssi_notify(struct net_device
*dev
,
926 enum nl80211_cqm_rssi_threshold_event rssi_event
,
929 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
930 struct wiphy
*wiphy
= wdev
->wiphy
;
931 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
933 trace_cfg80211_cqm_rssi_notify(dev
, rssi_event
);
935 /* Indicate roaming trigger event to user space */
936 nl80211_send_cqm_rssi_notify(rdev
, dev
, rssi_event
, gfp
);
938 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify
);
940 void cfg80211_cqm_pktloss_notify(struct net_device
*dev
,
941 const u8
*peer
, u32 num_packets
, gfp_t gfp
)
943 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
944 struct wiphy
*wiphy
= wdev
->wiphy
;
945 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
947 trace_cfg80211_cqm_pktloss_notify(dev
, peer
, num_packets
);
949 /* Indicate roaming trigger event to user space */
950 nl80211_send_cqm_pktloss_notify(rdev
, dev
, peer
, num_packets
, gfp
);
952 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify
);
954 void cfg80211_cqm_txe_notify(struct net_device
*dev
,
955 const u8
*peer
, u32 num_packets
,
956 u32 rate
, u32 intvl
, gfp_t gfp
)
958 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
959 struct wiphy
*wiphy
= wdev
->wiphy
;
960 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
962 nl80211_send_cqm_txe_notify(rdev
, dev
, peer
, num_packets
,
965 EXPORT_SYMBOL(cfg80211_cqm_txe_notify
);
967 void cfg80211_gtk_rekey_notify(struct net_device
*dev
, const u8
*bssid
,
968 const u8
*replay_ctr
, gfp_t gfp
)
970 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
971 struct wiphy
*wiphy
= wdev
->wiphy
;
972 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
974 trace_cfg80211_gtk_rekey_notify(dev
, bssid
);
975 nl80211_gtk_rekey_notify(rdev
, dev
, bssid
, replay_ctr
, gfp
);
977 EXPORT_SYMBOL(cfg80211_gtk_rekey_notify
);
979 void cfg80211_pmksa_candidate_notify(struct net_device
*dev
, int index
,
980 const u8
*bssid
, bool preauth
, gfp_t gfp
)
982 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
983 struct wiphy
*wiphy
= wdev
->wiphy
;
984 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
986 trace_cfg80211_pmksa_candidate_notify(dev
, index
, bssid
, preauth
);
987 nl80211_pmksa_candidate_notify(rdev
, dev
, index
, bssid
, preauth
, gfp
);
989 EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify
);
991 void cfg80211_ch_switch_notify(struct net_device
*dev
,
992 struct cfg80211_chan_def
*chandef
)
994 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
995 struct wiphy
*wiphy
= wdev
->wiphy
;
996 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
998 trace_cfg80211_ch_switch_notify(dev
, chandef
);
1002 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
1003 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
))
1006 wdev
->channel
= chandef
->chan
;
1007 nl80211_ch_switch_notify(rdev
, dev
, chandef
, GFP_KERNEL
);
1012 EXPORT_SYMBOL(cfg80211_ch_switch_notify
);
1014 bool cfg80211_rx_spurious_frame(struct net_device
*dev
,
1015 const u8
*addr
, gfp_t gfp
)
1017 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1020 trace_cfg80211_rx_spurious_frame(dev
, addr
);
1022 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
1023 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
)) {
1024 trace_cfg80211_return_bool(false);
1027 ret
= nl80211_unexpected_frame(dev
, addr
, gfp
);
1028 trace_cfg80211_return_bool(ret
);
1031 EXPORT_SYMBOL(cfg80211_rx_spurious_frame
);
1033 bool cfg80211_rx_unexpected_4addr_frame(struct net_device
*dev
,
1034 const u8
*addr
, gfp_t gfp
)
1036 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1039 trace_cfg80211_rx_unexpected_4addr_frame(dev
, addr
);
1041 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
1042 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
&&
1043 wdev
->iftype
!= NL80211_IFTYPE_AP_VLAN
)) {
1044 trace_cfg80211_return_bool(false);
1047 ret
= nl80211_unexpected_4addr_frame(dev
, addr
, gfp
);
1048 trace_cfg80211_return_bool(ret
);
1051 EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame
);