2 * cfg80211 MLME SAP interface
4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2015 Intel Deutschland GmbH
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/etherdevice.h>
11 #include <linux/netdevice.h>
12 #include <linux/nl80211.h>
13 #include <linux/slab.h>
14 #include <linux/wireless.h>
15 #include <net/cfg80211.h>
16 #include <net/iw_handler.h>
22 void cfg80211_rx_assoc_resp(struct net_device
*dev
, struct cfg80211_bss
*bss
,
23 const u8
*buf
, size_t len
, int uapsd_queues
)
25 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
26 struct wiphy
*wiphy
= wdev
->wiphy
;
27 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(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
);
31 u16 status_code
= le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
33 trace_cfg80211_send_rx_assoc(dev
, bss
);
36 * This is a bit of a hack, we don't notify userspace of
37 * a (re-)association reply if we tried to send a reassoc
38 * and got a reject -- we only try again with an assoc
39 * frame instead of reassoc.
41 if (cfg80211_sme_rx_assoc_resp(wdev
, status_code
)) {
42 cfg80211_unhold_bss(bss_from_pub(bss
));
43 cfg80211_put_bss(wiphy
, bss
);
47 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
, uapsd_queues
);
48 /* update current_bss etc., consumes the bss reference */
49 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, ie
, len
- ieoffs
,
51 status_code
== WLAN_STATUS_SUCCESS
, bss
,
52 NL80211_TIMEOUT_UNSPECIFIED
);
54 EXPORT_SYMBOL(cfg80211_rx_assoc_resp
);
56 static void cfg80211_process_auth(struct wireless_dev
*wdev
,
57 const u8
*buf
, size_t len
)
59 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
61 nl80211_send_rx_auth(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
62 cfg80211_sme_rx_auth(wdev
, buf
, len
);
65 static void cfg80211_process_deauth(struct wireless_dev
*wdev
,
66 const u8
*buf
, size_t len
)
68 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
69 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
70 const u8
*bssid
= mgmt
->bssid
;
71 u16 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
72 bool from_ap
= !ether_addr_equal(mgmt
->sa
, wdev
->netdev
->dev_addr
);
74 nl80211_send_deauth(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
76 if (!wdev
->current_bss
||
77 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
80 __cfg80211_disconnected(wdev
->netdev
, NULL
, 0, reason_code
, from_ap
);
81 cfg80211_sme_deauth(wdev
);
84 static void cfg80211_process_disassoc(struct wireless_dev
*wdev
,
85 const u8
*buf
, size_t len
)
87 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
88 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
89 const u8
*bssid
= mgmt
->bssid
;
90 u16 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
91 bool from_ap
= !ether_addr_equal(mgmt
->sa
, wdev
->netdev
->dev_addr
);
93 nl80211_send_disassoc(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
95 if (WARN_ON(!wdev
->current_bss
||
96 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
99 __cfg80211_disconnected(wdev
->netdev
, NULL
, 0, reason_code
, from_ap
);
100 cfg80211_sme_disassoc(wdev
);
103 void cfg80211_rx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
105 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
106 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
108 ASSERT_WDEV_LOCK(wdev
);
110 trace_cfg80211_rx_mlme_mgmt(dev
, buf
, len
);
112 if (WARN_ON(len
< 2))
115 if (ieee80211_is_auth(mgmt
->frame_control
))
116 cfg80211_process_auth(wdev
, buf
, len
);
117 else if (ieee80211_is_deauth(mgmt
->frame_control
))
118 cfg80211_process_deauth(wdev
, buf
, len
);
119 else if (ieee80211_is_disassoc(mgmt
->frame_control
))
120 cfg80211_process_disassoc(wdev
, buf
, len
);
122 EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt
);
124 void cfg80211_auth_timeout(struct net_device
*dev
, const u8
*addr
)
126 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
127 struct wiphy
*wiphy
= wdev
->wiphy
;
128 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
130 trace_cfg80211_send_auth_timeout(dev
, addr
);
132 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
133 cfg80211_sme_auth_timeout(wdev
);
135 EXPORT_SYMBOL(cfg80211_auth_timeout
);
137 void cfg80211_assoc_timeout(struct net_device
*dev
, struct cfg80211_bss
*bss
)
139 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
140 struct wiphy
*wiphy
= wdev
->wiphy
;
141 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
143 trace_cfg80211_send_assoc_timeout(dev
, bss
->bssid
);
145 nl80211_send_assoc_timeout(rdev
, dev
, bss
->bssid
, GFP_KERNEL
);
146 cfg80211_sme_assoc_timeout(wdev
);
148 cfg80211_unhold_bss(bss_from_pub(bss
));
149 cfg80211_put_bss(wiphy
, bss
);
151 EXPORT_SYMBOL(cfg80211_assoc_timeout
);
153 void cfg80211_abandon_assoc(struct net_device
*dev
, struct cfg80211_bss
*bss
)
155 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
156 struct wiphy
*wiphy
= wdev
->wiphy
;
158 cfg80211_sme_abandon_assoc(wdev
);
160 cfg80211_unhold_bss(bss_from_pub(bss
));
161 cfg80211_put_bss(wiphy
, bss
);
163 EXPORT_SYMBOL(cfg80211_abandon_assoc
);
165 void cfg80211_tx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
167 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
168 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
170 ASSERT_WDEV_LOCK(wdev
);
172 trace_cfg80211_tx_mlme_mgmt(dev
, buf
, len
);
174 if (WARN_ON(len
< 2))
177 if (ieee80211_is_deauth(mgmt
->frame_control
))
178 cfg80211_process_deauth(wdev
, buf
, len
);
180 cfg80211_process_disassoc(wdev
, buf
, len
);
182 EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt
);
184 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
185 enum nl80211_key_type key_type
, int key_id
,
186 const u8
*tsc
, gfp_t gfp
)
188 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
189 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
190 #ifdef CONFIG_CFG80211_WEXT
191 union iwreq_data wrqu
;
192 char *buf
= kmalloc(128, gfp
);
195 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
196 "keyid=%d %scast addr=%pM)", key_id
,
197 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
199 memset(&wrqu
, 0, sizeof(wrqu
));
200 wrqu
.data
.length
= strlen(buf
);
201 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
206 trace_cfg80211_michael_mic_failure(dev
, addr
, key_type
, key_id
, tsc
);
207 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
209 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
211 /* some MLME handling for userspace SME */
212 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
213 struct net_device
*dev
,
214 struct ieee80211_channel
*chan
,
215 enum nl80211_auth_type auth_type
,
217 const u8
*ssid
, int ssid_len
,
218 const u8
*ie
, int ie_len
,
219 const u8
*key
, int key_len
, int key_idx
,
220 const u8
*auth_data
, int auth_data_len
)
222 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
223 struct cfg80211_auth_request req
= {
226 .auth_data
= auth_data
,
227 .auth_data_len
= auth_data_len
,
228 .auth_type
= auth_type
,
235 ASSERT_WDEV_LOCK(wdev
);
237 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
238 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 3)
241 if (wdev
->current_bss
&&
242 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
245 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
246 IEEE80211_BSS_TYPE_ESS
,
247 IEEE80211_PRIVACY_ANY
);
251 err
= rdev_auth(rdev
, dev
, &req
);
253 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
257 /* Do a logical ht_capa &= ht_capa_mask. */
258 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
259 const struct ieee80211_ht_cap
*ht_capa_mask
)
264 memset(ht_capa
, 0, sizeof(*ht_capa
));
269 p2
= (u8
*)(ht_capa_mask
);
270 for (i
= 0; i
<sizeof(*ht_capa
); i
++)
274 /* Do a logical ht_capa &= ht_capa_mask. */
275 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap
*vht_capa
,
276 const struct ieee80211_vht_cap
*vht_capa_mask
)
280 if (!vht_capa_mask
) {
281 memset(vht_capa
, 0, sizeof(*vht_capa
));
285 p1
= (u8
*)(vht_capa
);
286 p2
= (u8
*)(vht_capa_mask
);
287 for (i
= 0; i
< sizeof(*vht_capa
); i
++)
291 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
292 struct net_device
*dev
,
293 struct ieee80211_channel
*chan
,
295 const u8
*ssid
, int ssid_len
,
296 struct cfg80211_assoc_request
*req
)
298 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
301 ASSERT_WDEV_LOCK(wdev
);
303 if (wdev
->current_bss
&&
304 (!req
->prev_bssid
|| !ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
308 cfg80211_oper_and_ht_capa(&req
->ht_capa_mask
,
309 rdev
->wiphy
.ht_capa_mod_mask
);
310 cfg80211_oper_and_vht_capa(&req
->vht_capa_mask
,
311 rdev
->wiphy
.vht_capa_mod_mask
);
313 req
->bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
314 IEEE80211_BSS_TYPE_ESS
,
315 IEEE80211_PRIVACY_ANY
);
319 err
= rdev_assoc(rdev
, dev
, req
);
321 cfg80211_hold_bss(bss_from_pub(req
->bss
));
323 cfg80211_put_bss(&rdev
->wiphy
, req
->bss
);
328 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
329 struct net_device
*dev
, const u8
*bssid
,
330 const u8
*ie
, int ie_len
, u16 reason
,
331 bool local_state_change
)
333 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
334 struct cfg80211_deauth_request req
= {
336 .reason_code
= reason
,
339 .local_state_change
= local_state_change
,
342 ASSERT_WDEV_LOCK(wdev
);
344 if (local_state_change
&&
345 (!wdev
->current_bss
||
346 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
349 if (ether_addr_equal(wdev
->disconnect_bssid
, bssid
) ||
350 (wdev
->current_bss
&&
351 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
352 wdev
->conn_owner_nlportid
= 0;
354 return rdev_deauth(rdev
, dev
, &req
);
357 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
358 struct net_device
*dev
, const u8
*bssid
,
359 const u8
*ie
, int ie_len
, u16 reason
,
360 bool local_state_change
)
362 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
363 struct cfg80211_disassoc_request req
= {
364 .reason_code
= reason
,
365 .local_state_change
= local_state_change
,
371 ASSERT_WDEV_LOCK(wdev
);
373 if (!wdev
->current_bss
)
376 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
377 req
.bss
= &wdev
->current_bss
->pub
;
381 err
= rdev_disassoc(rdev
, dev
, &req
);
385 /* driver should have reported the disassoc */
386 WARN_ON(wdev
->current_bss
);
390 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
391 struct net_device
*dev
)
393 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
396 ASSERT_WDEV_LOCK(wdev
);
398 if (!rdev
->ops
->deauth
)
401 if (!wdev
->current_bss
)
404 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
405 cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
406 WLAN_REASON_DEAUTH_LEAVING
, false);
409 struct cfg80211_mgmt_registration
{
410 struct list_head list
;
411 struct wireless_dev
*wdev
;
423 cfg80211_process_mlme_unregistrations(struct cfg80211_registered_device
*rdev
)
425 struct cfg80211_mgmt_registration
*reg
;
429 spin_lock_bh(&rdev
->mlme_unreg_lock
);
430 while ((reg
= list_first_entry_or_null(&rdev
->mlme_unreg
,
431 struct cfg80211_mgmt_registration
,
433 list_del(®
->list
);
434 spin_unlock_bh(&rdev
->mlme_unreg_lock
);
436 if (rdev
->ops
->mgmt_frame_register
) {
437 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
439 rdev_mgmt_frame_register(rdev
, reg
->wdev
,
445 spin_lock_bh(&rdev
->mlme_unreg_lock
);
447 spin_unlock_bh(&rdev
->mlme_unreg_lock
);
450 void cfg80211_mlme_unreg_wk(struct work_struct
*wk
)
452 struct cfg80211_registered_device
*rdev
;
454 rdev
= container_of(wk
, struct cfg80211_registered_device
,
458 cfg80211_process_mlme_unregistrations(rdev
);
462 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_portid
,
463 u16 frame_type
, const u8
*match_data
,
466 struct wiphy
*wiphy
= wdev
->wiphy
;
467 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
468 struct cfg80211_mgmt_registration
*reg
, *nreg
;
472 if (!wdev
->wiphy
->mgmt_stypes
)
475 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
478 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
481 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
482 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
485 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
489 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
491 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
492 int mlen
= min(match_len
, reg
->match_len
);
494 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
497 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
508 memcpy(nreg
->match
, match_data
, match_len
);
509 nreg
->match_len
= match_len
;
510 nreg
->nlportid
= snd_portid
;
511 nreg
->frame_type
= cpu_to_le16(frame_type
);
513 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
514 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
516 /* process all unregistrations to avoid driver confusion */
517 cfg80211_process_mlme_unregistrations(rdev
);
519 if (rdev
->ops
->mgmt_frame_register
)
520 rdev_mgmt_frame_register(rdev
, wdev
, frame_type
, true);
525 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
530 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlportid
)
532 struct wiphy
*wiphy
= wdev
->wiphy
;
533 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
534 struct cfg80211_mgmt_registration
*reg
, *tmp
;
536 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
538 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
539 if (reg
->nlportid
!= nlportid
)
542 list_del(®
->list
);
543 spin_lock(&rdev
->mlme_unreg_lock
);
544 list_add_tail(®
->list
, &rdev
->mlme_unreg
);
545 spin_unlock(&rdev
->mlme_unreg_lock
);
547 schedule_work(&rdev
->mlme_unreg_wk
);
550 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
552 if (nlportid
&& rdev
->crit_proto_nlportid
== nlportid
) {
553 rdev
->crit_proto_nlportid
= 0;
554 rdev_crit_proto_stop(rdev
, wdev
);
557 if (nlportid
== wdev
->ap_unexpected_nlportid
)
558 wdev
->ap_unexpected_nlportid
= 0;
561 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
563 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
565 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
566 spin_lock(&rdev
->mlme_unreg_lock
);
567 list_splice_tail_init(&wdev
->mgmt_registrations
, &rdev
->mlme_unreg
);
568 spin_unlock(&rdev
->mlme_unreg_lock
);
569 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
571 cfg80211_process_mlme_unregistrations(rdev
);
574 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
575 struct wireless_dev
*wdev
,
576 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
578 const struct ieee80211_mgmt
*mgmt
;
581 if (!wdev
->wiphy
->mgmt_stypes
)
584 if (!rdev
->ops
->mgmt_tx
)
587 if (params
->len
< 24 + 1)
590 mgmt
= (const struct ieee80211_mgmt
*)params
->buf
;
592 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
595 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
596 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
599 if (ieee80211_is_action(mgmt
->frame_control
) &&
600 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
605 switch (wdev
->iftype
) {
606 case NL80211_IFTYPE_ADHOC
:
607 case NL80211_IFTYPE_STATION
:
608 case NL80211_IFTYPE_P2P_CLIENT
:
609 if (!wdev
->current_bss
) {
614 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
621 * check for IBSS DA must be done by driver as
622 * cfg80211 doesn't track the stations
624 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
627 /* for station, check that DA is the AP */
628 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
634 case NL80211_IFTYPE_AP
:
635 case NL80211_IFTYPE_P2P_GO
:
636 case NL80211_IFTYPE_AP_VLAN
:
637 if (!ether_addr_equal(mgmt
->bssid
, wdev_address(wdev
)))
640 case NL80211_IFTYPE_MESH_POINT
:
641 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
646 * check for mesh DA must be done by driver as
647 * cfg80211 doesn't track the stations
650 case NL80211_IFTYPE_P2P_DEVICE
:
652 * fall through, P2P device only supports
653 * public action frames
655 case NL80211_IFTYPE_NAN
:
666 if (!ether_addr_equal(mgmt
->sa
, wdev_address(wdev
))) {
667 /* Allow random TA to be used with Public Action frames if the
668 * driver has indicated support for this. Otherwise, only allow
669 * the local address to be used.
671 if (!ieee80211_is_action(mgmt
->frame_control
) ||
672 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
)
674 if (!wdev
->current_bss
&&
675 !wiphy_ext_feature_isset(
677 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA
))
679 if (wdev
->current_bss
&&
680 !wiphy_ext_feature_isset(
682 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED
))
686 /* Transmit the Action frame as requested by user space */
687 return rdev_mgmt_tx(rdev
, wdev
, params
, cookie
);
690 bool cfg80211_rx_mgmt(struct wireless_dev
*wdev
, int freq
, int sig_mbm
,
691 const u8
*buf
, size_t len
, u32 flags
)
693 struct wiphy
*wiphy
= wdev
->wiphy
;
694 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
695 struct cfg80211_mgmt_registration
*reg
;
696 const struct ieee80211_txrx_stypes
*stypes
=
697 &wiphy
->mgmt_stypes
[wdev
->iftype
];
698 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
702 __le16 ftype
= mgmt
->frame_control
&
703 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
706 trace_cfg80211_rx_mgmt(wdev
, freq
, sig_mbm
);
707 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
709 if (!(stypes
->rx
& BIT(stype
))) {
710 trace_cfg80211_return_bool(false);
714 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
715 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
717 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
719 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
720 if (reg
->frame_type
!= ftype
)
723 if (reg
->match_len
> data_len
)
726 if (memcmp(reg
->match
, data
, reg
->match_len
))
731 /* Indicate the received Action frame to user space */
732 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlportid
,
734 buf
, len
, flags
, GFP_ATOMIC
))
741 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
743 trace_cfg80211_return_bool(result
);
746 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
748 void cfg80211_dfs_channels_update_work(struct work_struct
*work
)
750 struct delayed_work
*delayed_work
= to_delayed_work(work
);
751 struct cfg80211_registered_device
*rdev
;
752 struct cfg80211_chan_def chandef
;
753 struct ieee80211_supported_band
*sband
;
754 struct ieee80211_channel
*c
;
756 bool check_again
= false;
757 unsigned long timeout
, next_time
= 0;
760 rdev
= container_of(delayed_work
, struct cfg80211_registered_device
,
761 dfs_update_channels_wk
);
762 wiphy
= &rdev
->wiphy
;
765 for (bandid
= 0; bandid
< NUM_NL80211_BANDS
; bandid
++) {
766 sband
= wiphy
->bands
[bandid
];
770 for (i
= 0; i
< sband
->n_channels
; i
++) {
771 c
= &sband
->channels
[i
];
773 if (c
->dfs_state
!= NL80211_DFS_UNAVAILABLE
)
776 timeout
= c
->dfs_state_entered
+ msecs_to_jiffies(
777 IEEE80211_DFS_MIN_NOP_TIME_MS
);
779 if (time_after_eq(jiffies
, timeout
)) {
780 c
->dfs_state
= NL80211_DFS_USABLE
;
781 c
->dfs_state_entered
= jiffies
;
783 cfg80211_chandef_create(&chandef
, c
,
786 nl80211_radar_notify(rdev
, &chandef
,
787 NL80211_RADAR_NOP_FINISHED
,
793 next_time
= timeout
- jiffies
;
795 next_time
= min(next_time
, timeout
- jiffies
);
801 /* reschedule if there are other channels waiting to be cleared again */
803 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
808 void cfg80211_radar_event(struct wiphy
*wiphy
,
809 struct cfg80211_chan_def
*chandef
,
812 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
813 unsigned long timeout
;
815 trace_cfg80211_radar_event(wiphy
, chandef
);
817 /* only set the chandef supplied channel to unavailable, in
818 * case the radar is detected on only one of multiple channels
819 * spanned by the chandef.
821 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_UNAVAILABLE
);
823 timeout
= msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS
);
824 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
827 nl80211_radar_notify(rdev
, chandef
, NL80211_RADAR_DETECTED
, NULL
, gfp
);
829 EXPORT_SYMBOL(cfg80211_radar_event
);
831 void cfg80211_cac_event(struct net_device
*netdev
,
832 const struct cfg80211_chan_def
*chandef
,
833 enum nl80211_radar_event event
, gfp_t gfp
)
835 struct wireless_dev
*wdev
= netdev
->ieee80211_ptr
;
836 struct wiphy
*wiphy
= wdev
->wiphy
;
837 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
838 unsigned long timeout
;
840 trace_cfg80211_cac_event(netdev
, event
);
842 if (WARN_ON(!wdev
->cac_started
))
845 if (WARN_ON(!wdev
->chandef
.chan
))
849 case NL80211_RADAR_CAC_FINISHED
:
850 timeout
= wdev
->cac_start_time
+
851 msecs_to_jiffies(wdev
->cac_time_ms
);
852 WARN_ON(!time_after_eq(jiffies
, timeout
));
853 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_AVAILABLE
);
855 case NL80211_RADAR_CAC_ABORTED
:
861 wdev
->cac_started
= false;
863 nl80211_radar_notify(rdev
, chandef
, event
, netdev
, gfp
);
865 EXPORT_SYMBOL(cfg80211_cac_event
);