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_rx_assoc_resp(struct net_device
*dev
, struct cfg80211_bss
*bss
,
22 const u8
*buf
, size_t len
)
25 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
26 struct wiphy
*wiphy
= wdev
->wiphy
;
27 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
28 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
29 u8
*ie
= mgmt
->u
.assoc_resp
.variable
;
30 int ieoffs
= offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
32 trace_cfg80211_send_rx_assoc(dev
, bss
);
34 status_code
= le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
37 * This is a bit of a hack, we don't notify userspace of
38 * a (re-)association reply if we tried to send a reassoc
39 * and got a reject -- we only try again with an assoc
40 * frame instead of reassoc.
42 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
&&
43 cfg80211_sme_failed_reassoc(wdev
)) {
44 cfg80211_put_bss(wiphy
, bss
);
48 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
50 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
) {
51 cfg80211_sme_failed_assoc(wdev
);
53 * do not call connect_result() now because the
54 * sme will schedule work that does it later.
56 cfg80211_put_bss(wiphy
, bss
);
60 if (!wdev
->conn
&& wdev
->sme_state
== CFG80211_SME_IDLE
) {
62 * This is for the userspace SME, the CONNECTING
63 * state will be changed to CONNECTED by
64 * __cfg80211_connect_result() below.
66 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
69 /* this consumes the bss reference */
70 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, ie
, len
- ieoffs
,
72 status_code
== WLAN_STATUS_SUCCESS
, bss
);
74 EXPORT_SYMBOL(cfg80211_rx_assoc_resp
);
76 static void cfg80211_process_deauth(struct net_device
*dev
,
77 const u8
*buf
, size_t len
)
79 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
80 struct wiphy
*wiphy
= wdev
->wiphy
;
81 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
82 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
83 const u8
*bssid
= mgmt
->bssid
;
84 bool was_current
= false;
86 if (wdev
->current_bss
&&
87 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
88 cfg80211_unhold_bss(wdev
->current_bss
);
89 cfg80211_put_bss(wiphy
, &wdev
->current_bss
->pub
);
90 wdev
->current_bss
= NULL
;
94 nl80211_send_deauth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
96 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
&& was_current
) {
100 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
102 from_ap
= !ether_addr_equal(mgmt
->sa
, dev
->dev_addr
);
103 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
104 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
) {
105 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
106 WLAN_STATUS_UNSPECIFIED_FAILURE
,
111 static void cfg80211_process_disassoc(struct net_device
*dev
,
112 const u8
*buf
, size_t len
)
114 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
115 struct wiphy
*wiphy
= wdev
->wiphy
;
116 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
117 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
118 const u8
*bssid
= mgmt
->bssid
;
122 nl80211_send_disassoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
124 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
127 if (wdev
->current_bss
&&
128 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
129 cfg80211_sme_disassoc(dev
, wdev
->current_bss
);
130 cfg80211_unhold_bss(wdev
->current_bss
);
131 cfg80211_put_bss(wiphy
, &wdev
->current_bss
->pub
);
132 wdev
->current_bss
= NULL
;
136 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
138 from_ap
= !ether_addr_equal(mgmt
->sa
, dev
->dev_addr
);
139 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
142 void cfg80211_rx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
144 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
145 struct wiphy
*wiphy
= wdev
->wiphy
;
146 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
147 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
149 ASSERT_WDEV_LOCK(wdev
);
151 trace_cfg80211_rx_mlme_mgmt(dev
, buf
, len
);
153 if (WARN_ON(len
< 2))
156 if (ieee80211_is_auth(mgmt
->frame_control
)) {
157 nl80211_send_rx_auth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
158 cfg80211_sme_rx_auth(dev
, buf
, len
);
159 } else if (ieee80211_is_deauth(mgmt
->frame_control
)) {
160 cfg80211_process_deauth(dev
, buf
, len
);
161 } else if (ieee80211_is_disassoc(mgmt
->frame_control
)) {
162 cfg80211_process_disassoc(dev
, buf
, len
);
165 EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt
);
167 void cfg80211_auth_timeout(struct net_device
*dev
, const u8
*addr
)
169 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
170 struct wiphy
*wiphy
= wdev
->wiphy
;
171 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
173 trace_cfg80211_send_auth_timeout(dev
, addr
);
175 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
176 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
177 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
178 WLAN_STATUS_UNSPECIFIED_FAILURE
,
181 EXPORT_SYMBOL(cfg80211_auth_timeout
);
183 void cfg80211_assoc_timeout(struct net_device
*dev
, const u8
*addr
)
185 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
186 struct wiphy
*wiphy
= wdev
->wiphy
;
187 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
189 trace_cfg80211_send_assoc_timeout(dev
, addr
);
191 nl80211_send_assoc_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
192 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
193 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
194 WLAN_STATUS_UNSPECIFIED_FAILURE
,
197 EXPORT_SYMBOL(cfg80211_assoc_timeout
);
199 void cfg80211_tx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
201 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
202 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
204 ASSERT_WDEV_LOCK(wdev
);
206 trace_cfg80211_tx_mlme_mgmt(dev
, buf
, len
);
208 if (WARN_ON(len
< 2))
211 if (ieee80211_is_deauth(mgmt
->frame_control
))
212 cfg80211_process_deauth(dev
, buf
, len
);
214 cfg80211_process_disassoc(dev
, buf
, len
);
216 EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt
);
218 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
219 enum nl80211_key_type key_type
, int key_id
,
220 const u8
*tsc
, gfp_t gfp
)
222 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
223 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
224 #ifdef CONFIG_CFG80211_WEXT
225 union iwreq_data wrqu
;
226 char *buf
= kmalloc(128, gfp
);
229 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
230 "keyid=%d %scast addr=%pM)", key_id
,
231 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
233 memset(&wrqu
, 0, sizeof(wrqu
));
234 wrqu
.data
.length
= strlen(buf
);
235 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
240 trace_cfg80211_michael_mic_failure(dev
, addr
, key_type
, key_id
, tsc
);
241 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
243 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
245 /* some MLME handling for userspace SME */
246 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
247 struct net_device
*dev
,
248 struct ieee80211_channel
*chan
,
249 enum nl80211_auth_type auth_type
,
251 const u8
*ssid
, int ssid_len
,
252 const u8
*ie
, int ie_len
,
253 const u8
*key
, int key_len
, int key_idx
,
254 const u8
*sae_data
, int sae_data_len
)
256 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
257 struct cfg80211_auth_request req
= {
260 .sae_data
= sae_data
,
261 .sae_data_len
= sae_data_len
,
262 .auth_type
= auth_type
,
269 ASSERT_WDEV_LOCK(wdev
);
271 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
272 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 4)
275 if (wdev
->current_bss
&&
276 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
279 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
280 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
284 err
= cfg80211_can_use_chan(rdev
, wdev
, req
.bss
->channel
,
289 err
= rdev_auth(rdev
, dev
, &req
);
292 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
296 /* Do a logical ht_capa &= ht_capa_mask. */
297 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
298 const struct ieee80211_ht_cap
*ht_capa_mask
)
303 memset(ht_capa
, 0, sizeof(*ht_capa
));
308 p2
= (u8
*)(ht_capa_mask
);
309 for (i
= 0; i
<sizeof(*ht_capa
); i
++)
313 /* Do a logical ht_capa &= ht_capa_mask. */
314 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap
*vht_capa
,
315 const struct ieee80211_vht_cap
*vht_capa_mask
)
319 if (!vht_capa_mask
) {
320 memset(vht_capa
, 0, sizeof(*vht_capa
));
324 p1
= (u8
*)(vht_capa
);
325 p2
= (u8
*)(vht_capa_mask
);
326 for (i
= 0; i
< sizeof(*vht_capa
); i
++)
330 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
331 struct net_device
*dev
,
332 struct ieee80211_channel
*chan
,
334 const u8
*ssid
, int ssid_len
,
335 struct cfg80211_assoc_request
*req
)
337 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
339 bool was_connected
= false;
341 ASSERT_WDEV_LOCK(wdev
);
343 if (wdev
->current_bss
&& req
->prev_bssid
&&
344 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, req
->prev_bssid
)) {
346 * Trying to reassociate: Allow this to proceed and let the old
347 * association to be dropped when the new one is completed.
349 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
350 was_connected
= true;
351 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
353 } else if (wdev
->current_bss
)
356 cfg80211_oper_and_ht_capa(&req
->ht_capa_mask
,
357 rdev
->wiphy
.ht_capa_mod_mask
);
358 cfg80211_oper_and_vht_capa(&req
->vht_capa_mask
,
359 rdev
->wiphy
.vht_capa_mod_mask
);
361 req
->bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
362 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
365 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
369 err
= cfg80211_can_use_chan(rdev
, wdev
, chan
, CHAN_MODE_SHARED
);
373 err
= rdev_assoc(rdev
, dev
, req
);
378 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
379 cfg80211_put_bss(&rdev
->wiphy
, req
->bss
);
385 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
386 struct net_device
*dev
, const u8
*bssid
,
387 const u8
*ie
, int ie_len
, u16 reason
,
388 bool local_state_change
)
390 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
391 struct cfg80211_deauth_request req
= {
393 .reason_code
= reason
,
396 .local_state_change
= local_state_change
,
399 ASSERT_WDEV_LOCK(wdev
);
401 if (local_state_change
&& (!wdev
->current_bss
||
402 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
405 return rdev_deauth(rdev
, dev
, &req
);
408 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
409 struct net_device
*dev
, const u8
*bssid
,
410 const u8
*ie
, int ie_len
, u16 reason
,
411 bool local_state_change
)
413 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
414 struct cfg80211_disassoc_request req
= {
415 .reason_code
= reason
,
416 .local_state_change
= local_state_change
,
421 ASSERT_WDEV_LOCK(wdev
);
423 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
426 if (WARN(!wdev
->current_bss
, "sme_state=%d\n", wdev
->sme_state
))
429 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
430 req
.bss
= &wdev
->current_bss
->pub
;
434 return rdev_disassoc(rdev
, dev
, &req
);
437 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
438 struct net_device
*dev
)
440 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
442 struct cfg80211_deauth_request req
= {
443 .reason_code
= WLAN_REASON_DEAUTH_LEAVING
,
447 ASSERT_WDEV_LOCK(wdev
);
449 if (!rdev
->ops
->deauth
)
452 if (!wdev
->current_bss
)
455 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
456 rdev_deauth(rdev
, dev
, &req
);
458 if (wdev
->current_bss
) {
459 cfg80211_unhold_bss(wdev
->current_bss
);
460 cfg80211_put_bss(&rdev
->wiphy
, &wdev
->current_bss
->pub
);
461 wdev
->current_bss
= NULL
;
465 struct cfg80211_mgmt_registration
{
466 struct list_head list
;
477 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_portid
,
478 u16 frame_type
, const u8
*match_data
,
481 struct wiphy
*wiphy
= wdev
->wiphy
;
482 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
483 struct cfg80211_mgmt_registration
*reg
, *nreg
;
487 if (!wdev
->wiphy
->mgmt_stypes
)
490 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
493 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
496 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
497 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
500 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
504 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
506 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
507 int mlen
= min(match_len
, reg
->match_len
);
509 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
512 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
523 memcpy(nreg
->match
, match_data
, match_len
);
524 nreg
->match_len
= match_len
;
525 nreg
->nlportid
= snd_portid
;
526 nreg
->frame_type
= cpu_to_le16(frame_type
);
527 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
529 if (rdev
->ops
->mgmt_frame_register
)
530 rdev_mgmt_frame_register(rdev
, wdev
, frame_type
, true);
533 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
538 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlportid
)
540 struct wiphy
*wiphy
= wdev
->wiphy
;
541 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
542 struct cfg80211_mgmt_registration
*reg
, *tmp
;
544 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
546 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
547 if (reg
->nlportid
!= nlportid
)
550 if (rdev
->ops
->mgmt_frame_register
) {
551 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
553 rdev_mgmt_frame_register(rdev
, wdev
,
557 list_del(®
->list
);
561 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
563 if (nlportid
&& rdev
->crit_proto_nlportid
== nlportid
) {
564 rdev
->crit_proto_nlportid
= 0;
565 rdev_crit_proto_stop(rdev
, wdev
);
568 if (nlportid
== wdev
->ap_unexpected_nlportid
)
569 wdev
->ap_unexpected_nlportid
= 0;
572 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
574 struct cfg80211_mgmt_registration
*reg
, *tmp
;
576 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
578 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
579 list_del(®
->list
);
583 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
586 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
587 struct wireless_dev
*wdev
,
588 struct ieee80211_channel
*chan
, bool offchan
,
589 unsigned int wait
, const u8
*buf
, size_t len
,
590 bool no_cck
, bool dont_wait_for_ack
, u64
*cookie
)
592 const struct ieee80211_mgmt
*mgmt
;
595 if (!wdev
->wiphy
->mgmt_stypes
)
598 if (!rdev
->ops
->mgmt_tx
)
604 mgmt
= (const struct ieee80211_mgmt
*) buf
;
606 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
609 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
610 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
613 if (ieee80211_is_action(mgmt
->frame_control
) &&
614 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
619 switch (wdev
->iftype
) {
620 case NL80211_IFTYPE_ADHOC
:
621 case NL80211_IFTYPE_STATION
:
622 case NL80211_IFTYPE_P2P_CLIENT
:
623 if (!wdev
->current_bss
) {
628 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
635 * check for IBSS DA must be done by driver as
636 * cfg80211 doesn't track the stations
638 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
641 /* for station, check that DA is the AP */
642 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
648 case NL80211_IFTYPE_AP
:
649 case NL80211_IFTYPE_P2P_GO
:
650 case NL80211_IFTYPE_AP_VLAN
:
651 if (!ether_addr_equal(mgmt
->bssid
, wdev_address(wdev
)))
654 case NL80211_IFTYPE_MESH_POINT
:
655 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
660 * check for mesh DA must be done by driver as
661 * cfg80211 doesn't track the stations
664 case NL80211_IFTYPE_P2P_DEVICE
:
666 * fall through, P2P device only supports
667 * public action frames
679 if (!ether_addr_equal(mgmt
->sa
, wdev_address(wdev
)))
682 /* Transmit the Action frame as requested by user space */
683 return rdev_mgmt_tx(rdev
, wdev
, chan
, offchan
,
684 wait
, buf
, len
, no_cck
, dont_wait_for_ack
,
688 bool cfg80211_rx_mgmt(struct wireless_dev
*wdev
, int freq
, int sig_mbm
,
689 const u8
*buf
, size_t len
, gfp_t gfp
)
691 struct wiphy
*wiphy
= wdev
->wiphy
;
692 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
693 struct cfg80211_mgmt_registration
*reg
;
694 const struct ieee80211_txrx_stypes
*stypes
=
695 &wiphy
->mgmt_stypes
[wdev
->iftype
];
696 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
700 __le16 ftype
= mgmt
->frame_control
&
701 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
704 trace_cfg80211_rx_mgmt(wdev
, freq
, sig_mbm
);
705 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
707 if (!(stypes
->rx
& BIT(stype
))) {
708 trace_cfg80211_return_bool(false);
712 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
713 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
715 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
717 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
718 if (reg
->frame_type
!= ftype
)
721 if (reg
->match_len
> data_len
)
724 if (memcmp(reg
->match
, data
, reg
->match_len
))
729 /* Indicate the received Action frame to user space */
730 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlportid
,
739 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
741 trace_cfg80211_return_bool(result
);
744 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
746 void cfg80211_dfs_channels_update_work(struct work_struct
*work
)
748 struct delayed_work
*delayed_work
;
749 struct cfg80211_registered_device
*rdev
;
750 struct cfg80211_chan_def chandef
;
751 struct ieee80211_supported_band
*sband
;
752 struct ieee80211_channel
*c
;
754 bool check_again
= false;
755 unsigned long timeout
, next_time
= 0;
758 delayed_work
= container_of(work
, struct delayed_work
, work
);
759 rdev
= container_of(delayed_work
, struct cfg80211_registered_device
,
760 dfs_update_channels_wk
);
761 wiphy
= &rdev
->wiphy
;
764 for (bandid
= 0; bandid
< IEEE80211_NUM_BANDS
; bandid
++) {
765 sband
= wiphy
->bands
[bandid
];
769 for (i
= 0; i
< sband
->n_channels
; i
++) {
770 c
= &sband
->channels
[i
];
772 if (c
->dfs_state
!= NL80211_DFS_UNAVAILABLE
)
775 timeout
= c
->dfs_state_entered
+
776 IEEE80211_DFS_MIN_NOP_TIME_MS
;
778 if (time_after_eq(jiffies
, timeout
)) {
779 c
->dfs_state
= NL80211_DFS_USABLE
;
780 cfg80211_chandef_create(&chandef
, c
,
783 nl80211_radar_notify(rdev
, &chandef
,
784 NL80211_RADAR_NOP_FINISHED
,
790 next_time
= timeout
- jiffies
;
792 next_time
= min(next_time
, timeout
- jiffies
);
798 /* reschedule if there are other channels waiting to be cleared again */
800 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
805 void cfg80211_radar_event(struct wiphy
*wiphy
,
806 struct cfg80211_chan_def
*chandef
,
809 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
810 unsigned long timeout
;
812 trace_cfg80211_radar_event(wiphy
, chandef
);
814 /* only set the chandef supplied channel to unavailable, in
815 * case the radar is detected on only one of multiple channels
816 * spanned by the chandef.
818 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_UNAVAILABLE
);
820 timeout
= msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS
);
821 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
824 nl80211_radar_notify(rdev
, chandef
, NL80211_RADAR_DETECTED
, NULL
, gfp
);
826 EXPORT_SYMBOL(cfg80211_radar_event
);
828 void cfg80211_cac_event(struct net_device
*netdev
,
829 enum nl80211_radar_event event
, gfp_t gfp
)
831 struct wireless_dev
*wdev
= netdev
->ieee80211_ptr
;
832 struct wiphy
*wiphy
= wdev
->wiphy
;
833 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
834 struct cfg80211_chan_def chandef
;
835 unsigned long timeout
;
837 trace_cfg80211_cac_event(netdev
, event
);
839 if (WARN_ON(!wdev
->cac_started
))
842 if (WARN_ON(!wdev
->channel
))
845 cfg80211_chandef_create(&chandef
, wdev
->channel
, NL80211_CHAN_NO_HT
);
848 case NL80211_RADAR_CAC_FINISHED
:
849 timeout
= wdev
->cac_start_time
+
850 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS
);
851 WARN_ON(!time_after_eq(jiffies
, timeout
));
852 cfg80211_set_dfs_state(wiphy
, &chandef
, NL80211_DFS_AVAILABLE
);
854 case NL80211_RADAR_CAC_ABORTED
:
860 wdev
->cac_started
= false;
862 nl80211_radar_notify(rdev
, &chandef
, event
, netdev
, gfp
);
864 EXPORT_SYMBOL(cfg80211_cac_event
);