1 // SPDX-License-Identifier: GPL-2.0
3 * cfg80211 MLME SAP interface
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6 * Copyright (c) 2015 Intel Deutschland GmbH
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/etherdevice.h>
12 #include <linux/netdevice.h>
13 #include <linux/nl80211.h>
14 #include <linux/slab.h>
15 #include <linux/wireless.h>
16 #include <net/cfg80211.h>
17 #include <net/iw_handler.h>
23 void cfg80211_rx_assoc_resp(struct net_device
*dev
, struct cfg80211_bss
*bss
,
24 const u8
*buf
, size_t len
, int uapsd_queues
,
25 const u8
*req_ies
, size_t req_ies_len
)
27 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
28 struct wiphy
*wiphy
= wdev
->wiphy
;
29 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
30 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
31 struct cfg80211_connect_resp_params cr
;
33 memset(&cr
, 0, sizeof(cr
));
34 cr
.status
= (int)le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
35 cr
.bssid
= mgmt
->bssid
;
38 cr
.req_ie_len
= req_ies_len
;
39 cr
.resp_ie
= mgmt
->u
.assoc_resp
.variable
;
41 len
- offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
42 cr
.timeout_reason
= NL80211_TIMEOUT_UNSPECIFIED
;
44 trace_cfg80211_send_rx_assoc(dev
, bss
);
47 * This is a bit of a hack, we don't notify userspace of
48 * a (re-)association reply if we tried to send a reassoc
49 * and got a reject -- we only try again with an assoc
50 * frame instead of reassoc.
52 if (cfg80211_sme_rx_assoc_resp(wdev
, cr
.status
)) {
53 cfg80211_unhold_bss(bss_from_pub(bss
));
54 cfg80211_put_bss(wiphy
, bss
);
58 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
, uapsd_queues
,
59 req_ies
, req_ies_len
);
60 /* update current_bss etc., consumes the bss reference */
61 __cfg80211_connect_result(dev
, &cr
, cr
.status
== WLAN_STATUS_SUCCESS
);
63 EXPORT_SYMBOL(cfg80211_rx_assoc_resp
);
65 static void cfg80211_process_auth(struct wireless_dev
*wdev
,
66 const u8
*buf
, size_t len
)
68 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
70 nl80211_send_rx_auth(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
71 cfg80211_sme_rx_auth(wdev
, buf
, len
);
74 static void cfg80211_process_deauth(struct wireless_dev
*wdev
,
75 const u8
*buf
, size_t len
)
77 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
78 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
79 const u8
*bssid
= mgmt
->bssid
;
80 u16 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
81 bool from_ap
= !ether_addr_equal(mgmt
->sa
, wdev
->netdev
->dev_addr
);
83 nl80211_send_deauth(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
85 if (!wdev
->current_bss
||
86 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
89 __cfg80211_disconnected(wdev
->netdev
, NULL
, 0, reason_code
, from_ap
);
90 cfg80211_sme_deauth(wdev
);
93 static void cfg80211_process_disassoc(struct wireless_dev
*wdev
,
94 const u8
*buf
, size_t len
)
96 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
97 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
98 const u8
*bssid
= mgmt
->bssid
;
99 u16 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
100 bool from_ap
= !ether_addr_equal(mgmt
->sa
, wdev
->netdev
->dev_addr
);
102 nl80211_send_disassoc(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
104 if (WARN_ON(!wdev
->current_bss
||
105 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
108 __cfg80211_disconnected(wdev
->netdev
, NULL
, 0, reason_code
, from_ap
);
109 cfg80211_sme_disassoc(wdev
);
112 void cfg80211_rx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
114 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
115 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
117 ASSERT_WDEV_LOCK(wdev
);
119 trace_cfg80211_rx_mlme_mgmt(dev
, buf
, len
);
121 if (WARN_ON(len
< 2))
124 if (ieee80211_is_auth(mgmt
->frame_control
))
125 cfg80211_process_auth(wdev
, buf
, len
);
126 else if (ieee80211_is_deauth(mgmt
->frame_control
))
127 cfg80211_process_deauth(wdev
, buf
, len
);
128 else if (ieee80211_is_disassoc(mgmt
->frame_control
))
129 cfg80211_process_disassoc(wdev
, buf
, len
);
131 EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt
);
133 void cfg80211_auth_timeout(struct net_device
*dev
, const u8
*addr
)
135 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
136 struct wiphy
*wiphy
= wdev
->wiphy
;
137 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
139 trace_cfg80211_send_auth_timeout(dev
, addr
);
141 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
142 cfg80211_sme_auth_timeout(wdev
);
144 EXPORT_SYMBOL(cfg80211_auth_timeout
);
146 void cfg80211_assoc_timeout(struct net_device
*dev
, struct cfg80211_bss
*bss
)
148 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
149 struct wiphy
*wiphy
= wdev
->wiphy
;
150 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
152 trace_cfg80211_send_assoc_timeout(dev
, bss
->bssid
);
154 nl80211_send_assoc_timeout(rdev
, dev
, bss
->bssid
, GFP_KERNEL
);
155 cfg80211_sme_assoc_timeout(wdev
);
157 cfg80211_unhold_bss(bss_from_pub(bss
));
158 cfg80211_put_bss(wiphy
, bss
);
160 EXPORT_SYMBOL(cfg80211_assoc_timeout
);
162 void cfg80211_abandon_assoc(struct net_device
*dev
, struct cfg80211_bss
*bss
)
164 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
165 struct wiphy
*wiphy
= wdev
->wiphy
;
167 cfg80211_sme_abandon_assoc(wdev
);
169 cfg80211_unhold_bss(bss_from_pub(bss
));
170 cfg80211_put_bss(wiphy
, bss
);
172 EXPORT_SYMBOL(cfg80211_abandon_assoc
);
174 void cfg80211_tx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
176 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
177 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
179 ASSERT_WDEV_LOCK(wdev
);
181 trace_cfg80211_tx_mlme_mgmt(dev
, buf
, len
);
183 if (WARN_ON(len
< 2))
186 if (ieee80211_is_deauth(mgmt
->frame_control
))
187 cfg80211_process_deauth(wdev
, buf
, len
);
189 cfg80211_process_disassoc(wdev
, buf
, len
);
191 EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt
);
193 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
194 enum nl80211_key_type key_type
, int key_id
,
195 const u8
*tsc
, gfp_t gfp
)
197 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
198 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
199 #ifdef CONFIG_CFG80211_WEXT
200 union iwreq_data wrqu
;
201 char *buf
= kmalloc(128, gfp
);
204 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
205 "keyid=%d %scast addr=%pM)", key_id
,
206 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
208 memset(&wrqu
, 0, sizeof(wrqu
));
209 wrqu
.data
.length
= strlen(buf
);
210 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
215 trace_cfg80211_michael_mic_failure(dev
, addr
, key_type
, key_id
, tsc
);
216 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
218 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
220 /* some MLME handling for userspace SME */
221 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
222 struct net_device
*dev
,
223 struct ieee80211_channel
*chan
,
224 enum nl80211_auth_type auth_type
,
226 const u8
*ssid
, int ssid_len
,
227 const u8
*ie
, int ie_len
,
228 const u8
*key
, int key_len
, int key_idx
,
229 const u8
*auth_data
, int auth_data_len
)
231 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
232 struct cfg80211_auth_request req
= {
235 .auth_data
= auth_data
,
236 .auth_data_len
= auth_data_len
,
237 .auth_type
= auth_type
,
244 ASSERT_WDEV_LOCK(wdev
);
246 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
247 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 3)
250 if (wdev
->current_bss
&&
251 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
254 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
255 IEEE80211_BSS_TYPE_ESS
,
256 IEEE80211_PRIVACY_ANY
);
260 err
= rdev_auth(rdev
, dev
, &req
);
262 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
266 /* Do a logical ht_capa &= ht_capa_mask. */
267 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
268 const struct ieee80211_ht_cap
*ht_capa_mask
)
273 memset(ht_capa
, 0, sizeof(*ht_capa
));
278 p2
= (u8
*)(ht_capa_mask
);
279 for (i
= 0; i
< sizeof(*ht_capa
); i
++)
283 /* Do a logical vht_capa &= vht_capa_mask. */
284 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap
*vht_capa
,
285 const struct ieee80211_vht_cap
*vht_capa_mask
)
289 if (!vht_capa_mask
) {
290 memset(vht_capa
, 0, sizeof(*vht_capa
));
294 p1
= (u8
*)(vht_capa
);
295 p2
= (u8
*)(vht_capa_mask
);
296 for (i
= 0; i
< sizeof(*vht_capa
); i
++)
300 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
301 struct net_device
*dev
,
302 struct ieee80211_channel
*chan
,
304 const u8
*ssid
, int ssid_len
,
305 struct cfg80211_assoc_request
*req
)
307 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
310 ASSERT_WDEV_LOCK(wdev
);
312 if (wdev
->current_bss
&&
313 (!req
->prev_bssid
|| !ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
317 cfg80211_oper_and_ht_capa(&req
->ht_capa_mask
,
318 rdev
->wiphy
.ht_capa_mod_mask
);
319 cfg80211_oper_and_vht_capa(&req
->vht_capa_mask
,
320 rdev
->wiphy
.vht_capa_mod_mask
);
322 req
->bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
323 IEEE80211_BSS_TYPE_ESS
,
324 IEEE80211_PRIVACY_ANY
);
328 err
= rdev_assoc(rdev
, dev
, req
);
330 cfg80211_hold_bss(bss_from_pub(req
->bss
));
332 cfg80211_put_bss(&rdev
->wiphy
, req
->bss
);
337 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
338 struct net_device
*dev
, const u8
*bssid
,
339 const u8
*ie
, int ie_len
, u16 reason
,
340 bool local_state_change
)
342 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
343 struct cfg80211_deauth_request req
= {
345 .reason_code
= reason
,
348 .local_state_change
= local_state_change
,
351 ASSERT_WDEV_LOCK(wdev
);
353 if (local_state_change
&&
354 (!wdev
->current_bss
||
355 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
358 if (ether_addr_equal(wdev
->disconnect_bssid
, bssid
) ||
359 (wdev
->current_bss
&&
360 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
361 wdev
->conn_owner_nlportid
= 0;
363 return rdev_deauth(rdev
, dev
, &req
);
366 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
367 struct net_device
*dev
, const u8
*bssid
,
368 const u8
*ie
, int ie_len
, u16 reason
,
369 bool local_state_change
)
371 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
372 struct cfg80211_disassoc_request req
= {
373 .reason_code
= reason
,
374 .local_state_change
= local_state_change
,
380 ASSERT_WDEV_LOCK(wdev
);
382 if (!wdev
->current_bss
)
385 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
386 req
.bss
= &wdev
->current_bss
->pub
;
390 err
= rdev_disassoc(rdev
, dev
, &req
);
394 /* driver should have reported the disassoc */
395 WARN_ON(wdev
->current_bss
);
399 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
400 struct net_device
*dev
)
402 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
405 ASSERT_WDEV_LOCK(wdev
);
407 if (!rdev
->ops
->deauth
)
410 if (!wdev
->current_bss
)
413 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
414 cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
415 WLAN_REASON_DEAUTH_LEAVING
, false);
418 struct cfg80211_mgmt_registration
{
419 struct list_head list
;
420 struct wireless_dev
*wdev
;
432 cfg80211_process_mlme_unregistrations(struct cfg80211_registered_device
*rdev
)
434 struct cfg80211_mgmt_registration
*reg
;
438 spin_lock_bh(&rdev
->mlme_unreg_lock
);
439 while ((reg
= list_first_entry_or_null(&rdev
->mlme_unreg
,
440 struct cfg80211_mgmt_registration
,
442 list_del(®
->list
);
443 spin_unlock_bh(&rdev
->mlme_unreg_lock
);
445 if (rdev
->ops
->mgmt_frame_register
) {
446 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
448 rdev_mgmt_frame_register(rdev
, reg
->wdev
,
454 spin_lock_bh(&rdev
->mlme_unreg_lock
);
456 spin_unlock_bh(&rdev
->mlme_unreg_lock
);
459 void cfg80211_mlme_unreg_wk(struct work_struct
*wk
)
461 struct cfg80211_registered_device
*rdev
;
463 rdev
= container_of(wk
, struct cfg80211_registered_device
,
467 cfg80211_process_mlme_unregistrations(rdev
);
471 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_portid
,
472 u16 frame_type
, const u8
*match_data
,
475 struct wiphy
*wiphy
= wdev
->wiphy
;
476 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
477 struct cfg80211_mgmt_registration
*reg
, *nreg
;
481 if (!wdev
->wiphy
->mgmt_stypes
)
484 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
487 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
490 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
491 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
494 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
498 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
500 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
501 int mlen
= min(match_len
, reg
->match_len
);
503 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
506 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
517 memcpy(nreg
->match
, match_data
, match_len
);
518 nreg
->match_len
= match_len
;
519 nreg
->nlportid
= snd_portid
;
520 nreg
->frame_type
= cpu_to_le16(frame_type
);
522 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
523 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
525 /* process all unregistrations to avoid driver confusion */
526 cfg80211_process_mlme_unregistrations(rdev
);
528 if (rdev
->ops
->mgmt_frame_register
)
529 rdev_mgmt_frame_register(rdev
, wdev
, frame_type
, true);
534 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
539 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlportid
)
541 struct wiphy
*wiphy
= wdev
->wiphy
;
542 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
543 struct cfg80211_mgmt_registration
*reg
, *tmp
;
545 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
547 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
548 if (reg
->nlportid
!= nlportid
)
551 list_del(®
->list
);
552 spin_lock(&rdev
->mlme_unreg_lock
);
553 list_add_tail(®
->list
, &rdev
->mlme_unreg
);
554 spin_unlock(&rdev
->mlme_unreg_lock
);
556 schedule_work(&rdev
->mlme_unreg_wk
);
559 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
561 if (nlportid
&& rdev
->crit_proto_nlportid
== nlportid
) {
562 rdev
->crit_proto_nlportid
= 0;
563 rdev_crit_proto_stop(rdev
, wdev
);
566 if (nlportid
== wdev
->ap_unexpected_nlportid
)
567 wdev
->ap_unexpected_nlportid
= 0;
570 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
572 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
574 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
575 spin_lock(&rdev
->mlme_unreg_lock
);
576 list_splice_tail_init(&wdev
->mgmt_registrations
, &rdev
->mlme_unreg
);
577 spin_unlock(&rdev
->mlme_unreg_lock
);
578 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
580 cfg80211_process_mlme_unregistrations(rdev
);
583 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
584 struct wireless_dev
*wdev
,
585 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
587 const struct ieee80211_mgmt
*mgmt
;
590 if (!wdev
->wiphy
->mgmt_stypes
)
593 if (!rdev
->ops
->mgmt_tx
)
596 if (params
->len
< 24 + 1)
599 mgmt
= (const struct ieee80211_mgmt
*)params
->buf
;
601 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
604 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
605 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
608 if (ieee80211_is_action(mgmt
->frame_control
) &&
609 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
614 switch (wdev
->iftype
) {
615 case NL80211_IFTYPE_ADHOC
:
616 case NL80211_IFTYPE_STATION
:
617 case NL80211_IFTYPE_P2P_CLIENT
:
618 if (!wdev
->current_bss
) {
623 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
630 * check for IBSS DA must be done by driver as
631 * cfg80211 doesn't track the stations
633 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
636 /* for station, check that DA is the AP */
637 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
643 case NL80211_IFTYPE_AP
:
644 case NL80211_IFTYPE_P2P_GO
:
645 case NL80211_IFTYPE_AP_VLAN
:
646 if (!ether_addr_equal(mgmt
->bssid
, wdev_address(wdev
)))
649 case NL80211_IFTYPE_MESH_POINT
:
650 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
655 * check for mesh DA must be done by driver as
656 * cfg80211 doesn't track the stations
659 case NL80211_IFTYPE_P2P_DEVICE
:
661 * fall through, P2P device only supports
662 * public action frames
664 case NL80211_IFTYPE_NAN
:
675 if (!ether_addr_equal(mgmt
->sa
, wdev_address(wdev
))) {
676 /* Allow random TA to be used with Public Action frames if the
677 * driver has indicated support for this. Otherwise, only allow
678 * the local address to be used.
680 if (!ieee80211_is_action(mgmt
->frame_control
) ||
681 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
)
683 if (!wdev
->current_bss
&&
684 !wiphy_ext_feature_isset(
686 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA
))
688 if (wdev
->current_bss
&&
689 !wiphy_ext_feature_isset(
691 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED
))
695 /* Transmit the Action frame as requested by user space */
696 return rdev_mgmt_tx(rdev
, wdev
, params
, cookie
);
699 bool cfg80211_rx_mgmt(struct wireless_dev
*wdev
, int freq
, int sig_dbm
,
700 const u8
*buf
, size_t len
, u32 flags
)
702 struct wiphy
*wiphy
= wdev
->wiphy
;
703 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
704 struct cfg80211_mgmt_registration
*reg
;
705 const struct ieee80211_txrx_stypes
*stypes
=
706 &wiphy
->mgmt_stypes
[wdev
->iftype
];
707 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
711 __le16 ftype
= mgmt
->frame_control
&
712 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
715 trace_cfg80211_rx_mgmt(wdev
, freq
, sig_dbm
);
716 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
718 if (!(stypes
->rx
& BIT(stype
))) {
719 trace_cfg80211_return_bool(false);
723 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
724 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
726 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
728 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
729 if (reg
->frame_type
!= ftype
)
732 if (reg
->match_len
> data_len
)
735 if (memcmp(reg
->match
, data
, reg
->match_len
))
740 /* Indicate the received Action frame to user space */
741 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlportid
,
743 buf
, len
, flags
, GFP_ATOMIC
))
750 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
752 trace_cfg80211_return_bool(result
);
755 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
757 void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device
*rdev
)
759 cancel_delayed_work(&rdev
->dfs_update_channels_wk
);
760 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
, 0);
763 void cfg80211_dfs_channels_update_work(struct work_struct
*work
)
765 struct delayed_work
*delayed_work
= to_delayed_work(work
);
766 struct cfg80211_registered_device
*rdev
;
767 struct cfg80211_chan_def chandef
;
768 struct ieee80211_supported_band
*sband
;
769 struct ieee80211_channel
*c
;
771 bool check_again
= false;
772 unsigned long timeout
, next_time
= 0;
773 unsigned long time_dfs_update
;
774 enum nl80211_radar_event radar_event
;
777 rdev
= container_of(delayed_work
, struct cfg80211_registered_device
,
778 dfs_update_channels_wk
);
779 wiphy
= &rdev
->wiphy
;
782 for (bandid
= 0; bandid
< NUM_NL80211_BANDS
; bandid
++) {
783 sband
= wiphy
->bands
[bandid
];
787 for (i
= 0; i
< sband
->n_channels
; i
++) {
788 c
= &sband
->channels
[i
];
790 if (!(c
->flags
& IEEE80211_CHAN_RADAR
))
793 if (c
->dfs_state
!= NL80211_DFS_UNAVAILABLE
&&
794 c
->dfs_state
!= NL80211_DFS_AVAILABLE
)
797 if (c
->dfs_state
== NL80211_DFS_UNAVAILABLE
) {
798 time_dfs_update
= IEEE80211_DFS_MIN_NOP_TIME_MS
;
799 radar_event
= NL80211_RADAR_NOP_FINISHED
;
801 if (regulatory_pre_cac_allowed(wiphy
) ||
802 cfg80211_any_wiphy_oper_chan(wiphy
, c
))
805 time_dfs_update
= REG_PRE_CAC_EXPIRY_GRACE_MS
;
806 radar_event
= NL80211_RADAR_PRE_CAC_EXPIRED
;
809 timeout
= c
->dfs_state_entered
+
810 msecs_to_jiffies(time_dfs_update
);
812 if (time_after_eq(jiffies
, timeout
)) {
813 c
->dfs_state
= NL80211_DFS_USABLE
;
814 c
->dfs_state_entered
= jiffies
;
816 cfg80211_chandef_create(&chandef
, c
,
819 nl80211_radar_notify(rdev
, &chandef
,
823 regulatory_propagate_dfs_state(wiphy
, &chandef
,
830 next_time
= timeout
- jiffies
;
832 next_time
= min(next_time
, timeout
- jiffies
);
838 /* reschedule if there are other channels waiting to be cleared again */
840 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
845 void cfg80211_radar_event(struct wiphy
*wiphy
,
846 struct cfg80211_chan_def
*chandef
,
849 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
851 trace_cfg80211_radar_event(wiphy
, chandef
);
853 /* only set the chandef supplied channel to unavailable, in
854 * case the radar is detected on only one of multiple channels
855 * spanned by the chandef.
857 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_UNAVAILABLE
);
859 cfg80211_sched_dfs_chan_update(rdev
);
861 nl80211_radar_notify(rdev
, chandef
, NL80211_RADAR_DETECTED
, NULL
, gfp
);
863 memcpy(&rdev
->radar_chandef
, chandef
, sizeof(struct cfg80211_chan_def
));
864 queue_work(cfg80211_wq
, &rdev
->propagate_radar_detect_wk
);
866 EXPORT_SYMBOL(cfg80211_radar_event
);
868 void cfg80211_cac_event(struct net_device
*netdev
,
869 const struct cfg80211_chan_def
*chandef
,
870 enum nl80211_radar_event event
, gfp_t gfp
)
872 struct wireless_dev
*wdev
= netdev
->ieee80211_ptr
;
873 struct wiphy
*wiphy
= wdev
->wiphy
;
874 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
875 unsigned long timeout
;
877 trace_cfg80211_cac_event(netdev
, event
);
879 if (WARN_ON(!wdev
->cac_started
&& event
!= NL80211_RADAR_CAC_STARTED
))
882 if (WARN_ON(!wdev
->chandef
.chan
))
886 case NL80211_RADAR_CAC_FINISHED
:
887 timeout
= wdev
->cac_start_time
+
888 msecs_to_jiffies(wdev
->cac_time_ms
);
889 WARN_ON(!time_after_eq(jiffies
, timeout
));
890 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_AVAILABLE
);
891 memcpy(&rdev
->cac_done_chandef
, chandef
,
892 sizeof(struct cfg80211_chan_def
));
893 queue_work(cfg80211_wq
, &rdev
->propagate_cac_done_wk
);
894 cfg80211_sched_dfs_chan_update(rdev
);
896 case NL80211_RADAR_CAC_ABORTED
:
897 wdev
->cac_started
= false;
899 case NL80211_RADAR_CAC_STARTED
:
900 wdev
->cac_started
= true;
907 nl80211_radar_notify(rdev
, chandef
, event
, netdev
, gfp
);
909 EXPORT_SYMBOL(cfg80211_cac_event
);