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(wiphy
, 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(wiphy
, 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(wiphy
, &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(wiphy
, &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_auth_timeout(struct net_device
*dev
, const u8
*addr
)
192 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
193 struct wiphy
*wiphy
= wdev
->wiphy
;
194 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
196 trace_cfg80211_send_auth_timeout(dev
, addr
);
199 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
200 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
201 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
202 WLAN_STATUS_UNSPECIFIED_FAILURE
,
207 EXPORT_SYMBOL(cfg80211_send_auth_timeout
);
209 void cfg80211_send_assoc_timeout(struct net_device
*dev
, const u8
*addr
)
211 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
212 struct wiphy
*wiphy
= wdev
->wiphy
;
213 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
215 trace_cfg80211_send_assoc_timeout(dev
, addr
);
218 nl80211_send_assoc_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
219 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
220 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
221 WLAN_STATUS_UNSPECIFIED_FAILURE
,
226 EXPORT_SYMBOL(cfg80211_send_assoc_timeout
);
228 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
229 enum nl80211_key_type key_type
, int key_id
,
230 const u8
*tsc
, gfp_t gfp
)
232 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
233 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
234 #ifdef CONFIG_CFG80211_WEXT
235 union iwreq_data wrqu
;
236 char *buf
= kmalloc(128, gfp
);
239 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
240 "keyid=%d %scast addr=%pM)", key_id
,
241 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
243 memset(&wrqu
, 0, sizeof(wrqu
));
244 wrqu
.data
.length
= strlen(buf
);
245 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
250 trace_cfg80211_michael_mic_failure(dev
, addr
, key_type
, key_id
, tsc
);
251 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
253 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
255 /* some MLME handling for userspace SME */
256 int __cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
257 struct net_device
*dev
,
258 struct ieee80211_channel
*chan
,
259 enum nl80211_auth_type auth_type
,
261 const u8
*ssid
, int ssid_len
,
262 const u8
*ie
, int ie_len
,
263 const u8
*key
, int key_len
, int key_idx
,
264 const u8
*sae_data
, int sae_data_len
)
266 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
267 struct cfg80211_auth_request req
;
270 ASSERT_WDEV_LOCK(wdev
);
272 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
273 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 4)
276 if (wdev
->current_bss
&&
277 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
280 memset(&req
, 0, sizeof(req
));
284 req
.sae_data
= sae_data
;
285 req
.sae_data_len
= sae_data_len
;
286 req
.auth_type
= auth_type
;
287 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
288 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
290 req
.key_len
= key_len
;
291 req
.key_idx
= key_idx
;
295 err
= cfg80211_can_use_chan(rdev
, wdev
, req
.bss
->channel
,
300 err
= rdev_auth(rdev
, dev
, &req
);
303 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
307 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
308 struct net_device
*dev
, struct ieee80211_channel
*chan
,
309 enum nl80211_auth_type auth_type
, const u8
*bssid
,
310 const u8
*ssid
, int ssid_len
,
311 const u8
*ie
, int ie_len
,
312 const u8
*key
, int key_len
, int key_idx
,
313 const u8
*sae_data
, int sae_data_len
)
317 mutex_lock(&rdev
->devlist_mtx
);
318 wdev_lock(dev
->ieee80211_ptr
);
319 err
= __cfg80211_mlme_auth(rdev
, dev
, chan
, auth_type
, bssid
,
320 ssid
, ssid_len
, ie
, ie_len
,
321 key
, key_len
, key_idx
,
322 sae_data
, sae_data_len
);
323 wdev_unlock(dev
->ieee80211_ptr
);
324 mutex_unlock(&rdev
->devlist_mtx
);
329 /* Do a logical ht_capa &= ht_capa_mask. */
330 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
331 const struct ieee80211_ht_cap
*ht_capa_mask
)
336 memset(ht_capa
, 0, sizeof(*ht_capa
));
341 p2
= (u8
*)(ht_capa_mask
);
342 for (i
= 0; i
<sizeof(*ht_capa
); i
++)
346 /* Do a logical ht_capa &= ht_capa_mask. */
347 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap
*vht_capa
,
348 const struct ieee80211_vht_cap
*vht_capa_mask
)
352 if (!vht_capa_mask
) {
353 memset(vht_capa
, 0, sizeof(*vht_capa
));
357 p1
= (u8
*)(vht_capa
);
358 p2
= (u8
*)(vht_capa_mask
);
359 for (i
= 0; i
< sizeof(*vht_capa
); i
++)
363 int __cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
364 struct net_device
*dev
,
365 struct ieee80211_channel
*chan
,
367 const u8
*ssid
, int ssid_len
,
368 struct cfg80211_assoc_request
*req
)
370 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
372 bool was_connected
= false;
374 ASSERT_WDEV_LOCK(wdev
);
376 if (wdev
->current_bss
&& req
->prev_bssid
&&
377 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, req
->prev_bssid
)) {
379 * Trying to reassociate: Allow this to proceed and let the old
380 * association to be dropped when the new one is completed.
382 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
383 was_connected
= true;
384 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
386 } else if (wdev
->current_bss
)
389 cfg80211_oper_and_ht_capa(&req
->ht_capa_mask
,
390 rdev
->wiphy
.ht_capa_mod_mask
);
391 cfg80211_oper_and_vht_capa(&req
->vht_capa_mask
,
392 rdev
->wiphy
.vht_capa_mod_mask
);
394 req
->bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
395 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
398 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
402 err
= cfg80211_can_use_chan(rdev
, wdev
, chan
, CHAN_MODE_SHARED
);
406 err
= rdev_assoc(rdev
, dev
, req
);
411 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
412 cfg80211_put_bss(&rdev
->wiphy
, req
->bss
);
418 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
419 struct net_device
*dev
,
420 struct ieee80211_channel
*chan
,
422 const u8
*ssid
, int ssid_len
,
423 struct cfg80211_assoc_request
*req
)
425 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
428 mutex_lock(&rdev
->devlist_mtx
);
430 err
= __cfg80211_mlme_assoc(rdev
, dev
, chan
, bssid
,
431 ssid
, ssid_len
, req
);
433 mutex_unlock(&rdev
->devlist_mtx
);
438 int __cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
439 struct net_device
*dev
, const u8
*bssid
,
440 const u8
*ie
, int ie_len
, u16 reason
,
441 bool local_state_change
)
443 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
444 struct cfg80211_deauth_request req
= {
446 .reason_code
= reason
,
449 .local_state_change
= local_state_change
,
452 ASSERT_WDEV_LOCK(wdev
);
454 if (local_state_change
&& (!wdev
->current_bss
||
455 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
458 return rdev_deauth(rdev
, dev
, &req
);
461 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
462 struct net_device
*dev
, const u8
*bssid
,
463 const u8
*ie
, int ie_len
, u16 reason
,
464 bool local_state_change
)
466 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
470 err
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
477 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
478 struct net_device
*dev
, const u8
*bssid
,
479 const u8
*ie
, int ie_len
, u16 reason
,
480 bool local_state_change
)
482 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
483 struct cfg80211_disassoc_request req
;
485 ASSERT_WDEV_LOCK(wdev
);
487 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
490 if (WARN(!wdev
->current_bss
, "sme_state=%d\n", wdev
->sme_state
))
493 memset(&req
, 0, sizeof(req
));
494 req
.reason_code
= reason
;
495 req
.local_state_change
= local_state_change
;
498 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
499 req
.bss
= &wdev
->current_bss
->pub
;
503 return rdev_disassoc(rdev
, dev
, &req
);
506 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
507 struct net_device
*dev
, const u8
*bssid
,
508 const u8
*ie
, int ie_len
, u16 reason
,
509 bool local_state_change
)
511 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
515 err
= __cfg80211_mlme_disassoc(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
522 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
523 struct net_device
*dev
)
525 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
526 struct cfg80211_deauth_request req
;
529 ASSERT_WDEV_LOCK(wdev
);
531 if (!rdev
->ops
->deauth
)
534 memset(&req
, 0, sizeof(req
));
535 req
.reason_code
= WLAN_REASON_DEAUTH_LEAVING
;
539 if (!wdev
->current_bss
)
542 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
544 rdev_deauth(rdev
, dev
, &req
);
546 if (wdev
->current_bss
) {
547 cfg80211_unhold_bss(wdev
->current_bss
);
548 cfg80211_put_bss(&rdev
->wiphy
, &wdev
->current_bss
->pub
);
549 wdev
->current_bss
= NULL
;
553 struct cfg80211_mgmt_registration
{
554 struct list_head list
;
565 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_portid
,
566 u16 frame_type
, const u8
*match_data
,
569 struct wiphy
*wiphy
= wdev
->wiphy
;
570 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
571 struct cfg80211_mgmt_registration
*reg
, *nreg
;
575 if (!wdev
->wiphy
->mgmt_stypes
)
578 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
581 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
584 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
585 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
588 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
592 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
594 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
595 int mlen
= min(match_len
, reg
->match_len
);
597 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
600 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
611 memcpy(nreg
->match
, match_data
, match_len
);
612 nreg
->match_len
= match_len
;
613 nreg
->nlportid
= snd_portid
;
614 nreg
->frame_type
= cpu_to_le16(frame_type
);
615 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
617 if (rdev
->ops
->mgmt_frame_register
)
618 rdev_mgmt_frame_register(rdev
, wdev
, frame_type
, true);
621 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
626 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlportid
)
628 struct wiphy
*wiphy
= wdev
->wiphy
;
629 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
630 struct cfg80211_mgmt_registration
*reg
, *tmp
;
632 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
634 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
635 if (reg
->nlportid
!= nlportid
)
638 if (rdev
->ops
->mgmt_frame_register
) {
639 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
641 rdev_mgmt_frame_register(rdev
, wdev
,
645 list_del(®
->list
);
649 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
651 if (nlportid
&& rdev
->crit_proto_nlportid
== nlportid
) {
652 rdev
->crit_proto_nlportid
= 0;
653 rdev_crit_proto_stop(rdev
, wdev
);
656 if (nlportid
== wdev
->ap_unexpected_nlportid
)
657 wdev
->ap_unexpected_nlportid
= 0;
660 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
662 struct cfg80211_mgmt_registration
*reg
, *tmp
;
664 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
666 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
667 list_del(®
->list
);
671 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
674 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
675 struct wireless_dev
*wdev
,
676 struct ieee80211_channel
*chan
, bool offchan
,
677 unsigned int wait
, const u8
*buf
, size_t len
,
678 bool no_cck
, bool dont_wait_for_ack
, u64
*cookie
)
680 const struct ieee80211_mgmt
*mgmt
;
683 if (!wdev
->wiphy
->mgmt_stypes
)
686 if (!rdev
->ops
->mgmt_tx
)
692 mgmt
= (const struct ieee80211_mgmt
*) buf
;
694 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
697 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
698 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
701 if (ieee80211_is_action(mgmt
->frame_control
) &&
702 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
707 switch (wdev
->iftype
) {
708 case NL80211_IFTYPE_ADHOC
:
709 case NL80211_IFTYPE_STATION
:
710 case NL80211_IFTYPE_P2P_CLIENT
:
711 if (!wdev
->current_bss
) {
716 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
723 * check for IBSS DA must be done by driver as
724 * cfg80211 doesn't track the stations
726 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
729 /* for station, check that DA is the AP */
730 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
736 case NL80211_IFTYPE_AP
:
737 case NL80211_IFTYPE_P2P_GO
:
738 case NL80211_IFTYPE_AP_VLAN
:
739 if (!ether_addr_equal(mgmt
->bssid
, wdev_address(wdev
)))
742 case NL80211_IFTYPE_MESH_POINT
:
743 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
748 * check for mesh DA must be done by driver as
749 * cfg80211 doesn't track the stations
752 case NL80211_IFTYPE_P2P_DEVICE
:
754 * fall through, P2P device only supports
755 * public action frames
767 if (!ether_addr_equal(mgmt
->sa
, wdev_address(wdev
)))
770 /* Transmit the Action frame as requested by user space */
771 return rdev_mgmt_tx(rdev
, wdev
, chan
, offchan
,
772 wait
, buf
, len
, no_cck
, dont_wait_for_ack
,
776 bool cfg80211_rx_mgmt(struct wireless_dev
*wdev
, int freq
, int sig_mbm
,
777 const u8
*buf
, size_t len
, gfp_t gfp
)
779 struct wiphy
*wiphy
= wdev
->wiphy
;
780 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
781 struct cfg80211_mgmt_registration
*reg
;
782 const struct ieee80211_txrx_stypes
*stypes
=
783 &wiphy
->mgmt_stypes
[wdev
->iftype
];
784 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
788 __le16 ftype
= mgmt
->frame_control
&
789 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
792 trace_cfg80211_rx_mgmt(wdev
, freq
, sig_mbm
);
793 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
795 if (!(stypes
->rx
& BIT(stype
))) {
796 trace_cfg80211_return_bool(false);
800 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
801 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
803 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
805 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
806 if (reg
->frame_type
!= ftype
)
809 if (reg
->match_len
> data_len
)
812 if (memcmp(reg
->match
, data
, reg
->match_len
))
817 /* Indicate the received Action frame to user space */
818 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlportid
,
827 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
829 trace_cfg80211_return_bool(result
);
832 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
834 void cfg80211_dfs_channels_update_work(struct work_struct
*work
)
836 struct delayed_work
*delayed_work
;
837 struct cfg80211_registered_device
*rdev
;
838 struct cfg80211_chan_def chandef
;
839 struct ieee80211_supported_band
*sband
;
840 struct ieee80211_channel
*c
;
842 bool check_again
= false;
843 unsigned long timeout
, next_time
= 0;
846 delayed_work
= container_of(work
, struct delayed_work
, work
);
847 rdev
= container_of(delayed_work
, struct cfg80211_registered_device
,
848 dfs_update_channels_wk
);
849 wiphy
= &rdev
->wiphy
;
851 mutex_lock(&cfg80211_mutex
);
852 for (bandid
= 0; bandid
< IEEE80211_NUM_BANDS
; bandid
++) {
853 sband
= wiphy
->bands
[bandid
];
857 for (i
= 0; i
< sband
->n_channels
; i
++) {
858 c
= &sband
->channels
[i
];
860 if (c
->dfs_state
!= NL80211_DFS_UNAVAILABLE
)
863 timeout
= c
->dfs_state_entered
+
864 IEEE80211_DFS_MIN_NOP_TIME_MS
;
866 if (time_after_eq(jiffies
, timeout
)) {
867 c
->dfs_state
= NL80211_DFS_USABLE
;
868 cfg80211_chandef_create(&chandef
, c
,
871 nl80211_radar_notify(rdev
, &chandef
,
872 NL80211_RADAR_NOP_FINISHED
,
878 next_time
= timeout
- jiffies
;
880 next_time
= min(next_time
, timeout
- jiffies
);
884 mutex_unlock(&cfg80211_mutex
);
886 /* reschedule if there are other channels waiting to be cleared again */
888 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
893 void cfg80211_radar_event(struct wiphy
*wiphy
,
894 struct cfg80211_chan_def
*chandef
,
897 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
898 unsigned long timeout
;
900 trace_cfg80211_radar_event(wiphy
, chandef
);
902 /* only set the chandef supplied channel to unavailable, in
903 * case the radar is detected on only one of multiple channels
904 * spanned by the chandef.
906 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_UNAVAILABLE
);
908 timeout
= msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS
);
909 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
912 nl80211_radar_notify(rdev
, chandef
, NL80211_RADAR_DETECTED
, NULL
, gfp
);
914 EXPORT_SYMBOL(cfg80211_radar_event
);
916 void cfg80211_cac_event(struct net_device
*netdev
,
917 enum nl80211_radar_event event
, gfp_t gfp
)
919 struct wireless_dev
*wdev
= netdev
->ieee80211_ptr
;
920 struct wiphy
*wiphy
= wdev
->wiphy
;
921 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
922 struct cfg80211_chan_def chandef
;
923 unsigned long timeout
;
925 trace_cfg80211_cac_event(netdev
, event
);
927 if (WARN_ON(!wdev
->cac_started
))
930 if (WARN_ON(!wdev
->channel
))
933 cfg80211_chandef_create(&chandef
, wdev
->channel
, NL80211_CHAN_NO_HT
);
936 case NL80211_RADAR_CAC_FINISHED
:
937 timeout
= wdev
->cac_start_time
+
938 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS
);
939 WARN_ON(!time_after_eq(jiffies
, timeout
));
940 cfg80211_set_dfs_state(wiphy
, &chandef
, NL80211_DFS_AVAILABLE
);
942 case NL80211_RADAR_CAC_ABORTED
:
948 wdev
->cac_started
= false;
950 nl80211_radar_notify(rdev
, &chandef
, event
, netdev
, gfp
);
952 EXPORT_SYMBOL(cfg80211_cac_event
);