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>
19 void cfg80211_send_rx_auth(struct net_device
*dev
, const u8
*buf
, size_t len
)
21 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
22 struct wiphy
*wiphy
= wdev
->wiphy
;
23 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
27 nl80211_send_rx_auth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
28 cfg80211_sme_rx_auth(dev
, buf
, len
);
32 EXPORT_SYMBOL(cfg80211_send_rx_auth
);
34 void cfg80211_send_rx_assoc(struct net_device
*dev
, struct cfg80211_bss
*bss
,
35 const u8
*buf
, size_t len
)
38 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
39 struct wiphy
*wiphy
= wdev
->wiphy
;
40 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
41 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
42 u8
*ie
= mgmt
->u
.assoc_resp
.variable
;
43 int ieoffs
= offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
47 status_code
= le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
50 * This is a bit of a hack, we don't notify userspace of
51 * a (re-)association reply if we tried to send a reassoc
52 * and got a reject -- we only try again with an assoc
53 * frame instead of reassoc.
55 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
&&
56 cfg80211_sme_failed_reassoc(wdev
)) {
57 cfg80211_put_bss(bss
);
61 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
63 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
) {
64 cfg80211_sme_failed_assoc(wdev
);
66 * do not call connect_result() now because the
67 * sme will schedule work that does it later.
69 cfg80211_put_bss(bss
);
73 if (!wdev
->conn
&& wdev
->sme_state
== CFG80211_SME_IDLE
) {
75 * This is for the userspace SME, the CONNECTING
76 * state will be changed to CONNECTED by
77 * __cfg80211_connect_result() below.
79 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
82 /* this consumes the bss reference */
83 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, ie
, len
- ieoffs
,
85 status_code
== WLAN_STATUS_SUCCESS
, bss
);
89 EXPORT_SYMBOL(cfg80211_send_rx_assoc
);
91 void __cfg80211_send_deauth(struct net_device
*dev
,
92 const u8
*buf
, size_t len
)
94 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
95 struct wiphy
*wiphy
= wdev
->wiphy
;
96 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
97 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
98 const u8
*bssid
= mgmt
->bssid
;
99 bool was_current
= false;
101 ASSERT_WDEV_LOCK(wdev
);
103 if (wdev
->current_bss
&&
104 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
105 cfg80211_unhold_bss(wdev
->current_bss
);
106 cfg80211_put_bss(&wdev
->current_bss
->pub
);
107 wdev
->current_bss
= NULL
;
111 nl80211_send_deauth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
113 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
&& was_current
) {
117 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
119 from_ap
= !ether_addr_equal(mgmt
->sa
, dev
->dev_addr
);
120 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
121 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
) {
122 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
123 WLAN_STATUS_UNSPECIFIED_FAILURE
,
127 EXPORT_SYMBOL(__cfg80211_send_deauth
);
129 void cfg80211_send_deauth(struct net_device
*dev
, const u8
*buf
, size_t len
)
131 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
134 __cfg80211_send_deauth(dev
, buf
, len
);
137 EXPORT_SYMBOL(cfg80211_send_deauth
);
139 void __cfg80211_send_disassoc(struct net_device
*dev
,
140 const u8
*buf
, size_t len
)
142 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
143 struct wiphy
*wiphy
= wdev
->wiphy
;
144 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
145 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
146 const u8
*bssid
= mgmt
->bssid
;
150 ASSERT_WDEV_LOCK(wdev
);
152 nl80211_send_disassoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
154 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
157 if (wdev
->current_bss
&&
158 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
159 cfg80211_sme_disassoc(dev
, wdev
->current_bss
);
160 cfg80211_unhold_bss(wdev
->current_bss
);
161 cfg80211_put_bss(&wdev
->current_bss
->pub
);
162 wdev
->current_bss
= NULL
;
167 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
169 from_ap
= !ether_addr_equal(mgmt
->sa
, dev
->dev_addr
);
170 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
172 EXPORT_SYMBOL(__cfg80211_send_disassoc
);
174 void cfg80211_send_disassoc(struct net_device
*dev
, const u8
*buf
, size_t len
)
176 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
179 __cfg80211_send_disassoc(dev
, buf
, len
);
182 EXPORT_SYMBOL(cfg80211_send_disassoc
);
184 void cfg80211_send_unprot_deauth(struct net_device
*dev
, const u8
*buf
,
187 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
188 struct wiphy
*wiphy
= wdev
->wiphy
;
189 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
191 nl80211_send_unprot_deauth(rdev
, dev
, buf
, len
, GFP_ATOMIC
);
193 EXPORT_SYMBOL(cfg80211_send_unprot_deauth
);
195 void cfg80211_send_unprot_disassoc(struct net_device
*dev
, const u8
*buf
,
198 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
199 struct wiphy
*wiphy
= wdev
->wiphy
;
200 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
202 nl80211_send_unprot_disassoc(rdev
, dev
, buf
, len
, GFP_ATOMIC
);
204 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc
);
206 void cfg80211_send_auth_timeout(struct net_device
*dev
, const u8
*addr
)
208 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
209 struct wiphy
*wiphy
= wdev
->wiphy
;
210 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
214 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
215 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
216 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
217 WLAN_STATUS_UNSPECIFIED_FAILURE
,
222 EXPORT_SYMBOL(cfg80211_send_auth_timeout
);
224 void cfg80211_send_assoc_timeout(struct net_device
*dev
, const u8
*addr
)
226 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
227 struct wiphy
*wiphy
= wdev
->wiphy
;
228 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
232 nl80211_send_assoc_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
233 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
234 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
235 WLAN_STATUS_UNSPECIFIED_FAILURE
,
240 EXPORT_SYMBOL(cfg80211_send_assoc_timeout
);
242 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
243 enum nl80211_key_type key_type
, int key_id
,
244 const u8
*tsc
, gfp_t gfp
)
246 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
247 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
248 #ifdef CONFIG_CFG80211_WEXT
249 union iwreq_data wrqu
;
250 char *buf
= kmalloc(128, gfp
);
253 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
254 "keyid=%d %scast addr=%pM)", key_id
,
255 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
257 memset(&wrqu
, 0, sizeof(wrqu
));
258 wrqu
.data
.length
= strlen(buf
);
259 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
264 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
266 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
268 /* some MLME handling for userspace SME */
269 int __cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
270 struct net_device
*dev
,
271 struct ieee80211_channel
*chan
,
272 enum nl80211_auth_type auth_type
,
274 const u8
*ssid
, int ssid_len
,
275 const u8
*ie
, int ie_len
,
276 const u8
*key
, int key_len
, int key_idx
)
278 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
279 struct cfg80211_auth_request req
;
282 ASSERT_WDEV_LOCK(wdev
);
284 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
285 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 4)
288 if (wdev
->current_bss
&&
289 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
292 memset(&req
, 0, sizeof(req
));
296 req
.auth_type
= auth_type
;
297 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
298 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
300 req
.key_len
= key_len
;
301 req
.key_idx
= key_idx
;
305 err
= cfg80211_can_use_chan(rdev
, wdev
, req
.bss
->channel
,
310 err
= rdev
->ops
->auth(&rdev
->wiphy
, dev
, &req
);
313 cfg80211_put_bss(req
.bss
);
317 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
318 struct net_device
*dev
, struct ieee80211_channel
*chan
,
319 enum nl80211_auth_type auth_type
, const u8
*bssid
,
320 const u8
*ssid
, int ssid_len
,
321 const u8
*ie
, int ie_len
,
322 const u8
*key
, int key_len
, int key_idx
)
326 mutex_lock(&rdev
->devlist_mtx
);
327 wdev_lock(dev
->ieee80211_ptr
);
328 err
= __cfg80211_mlme_auth(rdev
, dev
, chan
, auth_type
, bssid
,
329 ssid
, ssid_len
, ie
, ie_len
,
330 key
, key_len
, key_idx
);
331 wdev_unlock(dev
->ieee80211_ptr
);
332 mutex_unlock(&rdev
->devlist_mtx
);
337 /* Do a logical ht_capa &= ht_capa_mask. */
338 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
339 const struct ieee80211_ht_cap
*ht_capa_mask
)
344 memset(ht_capa
, 0, sizeof(*ht_capa
));
349 p2
= (u8
*)(ht_capa_mask
);
350 for (i
= 0; i
<sizeof(*ht_capa
); i
++)
354 int __cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
355 struct net_device
*dev
,
356 struct ieee80211_channel
*chan
,
357 const u8
*bssid
, const u8
*prev_bssid
,
358 const u8
*ssid
, int ssid_len
,
359 const u8
*ie
, int ie_len
, bool use_mfp
,
360 struct cfg80211_crypto_settings
*crypt
,
361 u32 assoc_flags
, struct ieee80211_ht_cap
*ht_capa
,
362 struct ieee80211_ht_cap
*ht_capa_mask
)
364 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
365 struct cfg80211_assoc_request req
;
367 bool was_connected
= false;
369 ASSERT_WDEV_LOCK(wdev
);
371 memset(&req
, 0, sizeof(req
));
373 if (wdev
->current_bss
&& prev_bssid
&&
374 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, prev_bssid
)) {
376 * Trying to reassociate: Allow this to proceed and let the old
377 * association to be dropped when the new one is completed.
379 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
380 was_connected
= true;
381 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
383 } else if (wdev
->current_bss
)
388 memcpy(&req
.crypto
, crypt
, sizeof(req
.crypto
));
389 req
.use_mfp
= use_mfp
;
390 req
.prev_bssid
= prev_bssid
;
391 req
.flags
= assoc_flags
;
393 memcpy(&req
.ht_capa
, ht_capa
, sizeof(req
.ht_capa
));
395 memcpy(&req
.ht_capa_mask
, ht_capa_mask
,
396 sizeof(req
.ht_capa_mask
));
397 cfg80211_oper_and_ht_capa(&req
.ht_capa_mask
,
398 rdev
->wiphy
.ht_capa_mod_mask
);
400 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
401 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
404 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
408 err
= cfg80211_can_use_chan(rdev
, wdev
, req
.bss
->channel
,
413 err
= rdev
->ops
->assoc(&rdev
->wiphy
, dev
, &req
);
418 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
419 cfg80211_put_bss(req
.bss
);
425 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
426 struct net_device
*dev
,
427 struct ieee80211_channel
*chan
,
428 const u8
*bssid
, const u8
*prev_bssid
,
429 const u8
*ssid
, int ssid_len
,
430 const u8
*ie
, int ie_len
, bool use_mfp
,
431 struct cfg80211_crypto_settings
*crypt
,
432 u32 assoc_flags
, struct ieee80211_ht_cap
*ht_capa
,
433 struct ieee80211_ht_cap
*ht_capa_mask
)
435 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
438 mutex_lock(&rdev
->devlist_mtx
);
440 err
= __cfg80211_mlme_assoc(rdev
, dev
, chan
, bssid
, prev_bssid
,
441 ssid
, ssid_len
, ie
, ie_len
, use_mfp
, crypt
,
442 assoc_flags
, ht_capa
, ht_capa_mask
);
444 mutex_unlock(&rdev
->devlist_mtx
);
449 int __cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
450 struct net_device
*dev
, const u8
*bssid
,
451 const u8
*ie
, int ie_len
, u16 reason
,
452 bool local_state_change
)
454 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
455 struct cfg80211_deauth_request req
= {
457 .reason_code
= reason
,
462 ASSERT_WDEV_LOCK(wdev
);
464 if (local_state_change
) {
465 if (wdev
->current_bss
&&
466 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
467 cfg80211_unhold_bss(wdev
->current_bss
);
468 cfg80211_put_bss(&wdev
->current_bss
->pub
);
469 wdev
->current_bss
= NULL
;
475 return rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
);
478 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
479 struct net_device
*dev
, const u8
*bssid
,
480 const u8
*ie
, int ie_len
, u16 reason
,
481 bool local_state_change
)
483 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
487 err
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
494 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
495 struct net_device
*dev
, const u8
*bssid
,
496 const u8
*ie
, int ie_len
, u16 reason
,
497 bool local_state_change
)
499 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
500 struct cfg80211_disassoc_request req
;
502 ASSERT_WDEV_LOCK(wdev
);
504 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
507 if (WARN_ON(!wdev
->current_bss
))
510 memset(&req
, 0, sizeof(req
));
511 req
.reason_code
= reason
;
512 req
.local_state_change
= local_state_change
;
515 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
516 req
.bss
= &wdev
->current_bss
->pub
;
520 return rdev
->ops
->disassoc(&rdev
->wiphy
, dev
, &req
);
523 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
524 struct net_device
*dev
, const u8
*bssid
,
525 const u8
*ie
, int ie_len
, u16 reason
,
526 bool local_state_change
)
528 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
532 err
= __cfg80211_mlme_disassoc(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
539 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
540 struct net_device
*dev
)
542 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
543 struct cfg80211_deauth_request req
;
546 ASSERT_WDEV_LOCK(wdev
);
548 if (!rdev
->ops
->deauth
)
551 memset(&req
, 0, sizeof(req
));
552 req
.reason_code
= WLAN_REASON_DEAUTH_LEAVING
;
556 if (!wdev
->current_bss
)
559 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
561 rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
);
563 if (wdev
->current_bss
) {
564 cfg80211_unhold_bss(wdev
->current_bss
);
565 cfg80211_put_bss(&wdev
->current_bss
->pub
);
566 wdev
->current_bss
= NULL
;
570 void cfg80211_ready_on_channel(struct wireless_dev
*wdev
, u64 cookie
,
571 struct ieee80211_channel
*chan
,
572 enum nl80211_channel_type channel_type
,
573 unsigned int duration
, gfp_t gfp
)
575 struct wiphy
*wiphy
= wdev
->wiphy
;
576 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
578 nl80211_send_remain_on_channel(rdev
, wdev
, cookie
, chan
, channel_type
,
581 EXPORT_SYMBOL(cfg80211_ready_on_channel
);
583 void cfg80211_remain_on_channel_expired(struct wireless_dev
*wdev
, u64 cookie
,
584 struct ieee80211_channel
*chan
,
585 enum nl80211_channel_type channel_type
,
588 struct wiphy
*wiphy
= wdev
->wiphy
;
589 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
591 nl80211_send_remain_on_channel_cancel(rdev
, wdev
, cookie
, chan
,
594 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired
);
596 void cfg80211_new_sta(struct net_device
*dev
, const u8
*mac_addr
,
597 struct station_info
*sinfo
, gfp_t gfp
)
599 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
600 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
602 nl80211_send_sta_event(rdev
, dev
, mac_addr
, sinfo
, gfp
);
604 EXPORT_SYMBOL(cfg80211_new_sta
);
606 void cfg80211_del_sta(struct net_device
*dev
, const u8
*mac_addr
, gfp_t gfp
)
608 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
609 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
611 nl80211_send_sta_del_event(rdev
, dev
, mac_addr
, gfp
);
613 EXPORT_SYMBOL(cfg80211_del_sta
);
615 struct cfg80211_mgmt_registration
{
616 struct list_head list
;
627 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_pid
,
628 u16 frame_type
, const u8
*match_data
,
631 struct wiphy
*wiphy
= wdev
->wiphy
;
632 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
633 struct cfg80211_mgmt_registration
*reg
, *nreg
;
637 if (!wdev
->wiphy
->mgmt_stypes
)
640 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
643 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
646 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
647 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
650 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
654 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
656 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
657 int mlen
= min(match_len
, reg
->match_len
);
659 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
662 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
673 memcpy(nreg
->match
, match_data
, match_len
);
674 nreg
->match_len
= match_len
;
675 nreg
->nlpid
= snd_pid
;
676 nreg
->frame_type
= cpu_to_le16(frame_type
);
677 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
679 if (rdev
->ops
->mgmt_frame_register
)
680 rdev
->ops
->mgmt_frame_register(wiphy
, wdev
, frame_type
, true);
683 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
688 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlpid
)
690 struct wiphy
*wiphy
= wdev
->wiphy
;
691 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
692 struct cfg80211_mgmt_registration
*reg
, *tmp
;
694 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
696 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
697 if (reg
->nlpid
!= nlpid
)
700 if (rdev
->ops
->mgmt_frame_register
) {
701 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
703 rdev
->ops
->mgmt_frame_register(wiphy
, wdev
,
707 list_del(®
->list
);
711 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
713 if (nlpid
== wdev
->ap_unexpected_nlpid
)
714 wdev
->ap_unexpected_nlpid
= 0;
717 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
719 struct cfg80211_mgmt_registration
*reg
, *tmp
;
721 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
723 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
724 list_del(®
->list
);
728 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
731 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
732 struct wireless_dev
*wdev
,
733 struct ieee80211_channel
*chan
, bool offchan
,
734 enum nl80211_channel_type channel_type
,
735 bool channel_type_valid
, unsigned int wait
,
736 const u8
*buf
, size_t len
, bool no_cck
,
737 bool dont_wait_for_ack
, u64
*cookie
)
739 struct net_device
*dev
= wdev
->netdev
;
740 const struct ieee80211_mgmt
*mgmt
;
743 if (!wdev
->wiphy
->mgmt_stypes
)
746 if (!rdev
->ops
->mgmt_tx
)
752 mgmt
= (const struct ieee80211_mgmt
*) buf
;
754 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
757 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
758 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
761 if (ieee80211_is_action(mgmt
->frame_control
) &&
762 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
767 switch (wdev
->iftype
) {
768 case NL80211_IFTYPE_ADHOC
:
769 case NL80211_IFTYPE_STATION
:
770 case NL80211_IFTYPE_P2P_CLIENT
:
771 if (!wdev
->current_bss
) {
776 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
783 * check for IBSS DA must be done by driver as
784 * cfg80211 doesn't track the stations
786 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
789 /* for station, check that DA is the AP */
790 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
796 case NL80211_IFTYPE_AP
:
797 case NL80211_IFTYPE_P2P_GO
:
798 case NL80211_IFTYPE_AP_VLAN
:
799 if (!ether_addr_equal(mgmt
->bssid
, dev
->dev_addr
))
802 case NL80211_IFTYPE_MESH_POINT
:
803 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
808 * check for mesh DA must be done by driver as
809 * cfg80211 doesn't track the stations
822 if (!ether_addr_equal(mgmt
->sa
, dev
->dev_addr
))
825 /* Transmit the Action frame as requested by user space */
826 return rdev
->ops
->mgmt_tx(&rdev
->wiphy
, wdev
, chan
, offchan
,
827 channel_type
, channel_type_valid
,
828 wait
, buf
, len
, no_cck
, dont_wait_for_ack
,
832 bool cfg80211_rx_mgmt(struct wireless_dev
*wdev
, int freq
, int sig_mbm
,
833 const u8
*buf
, size_t len
, gfp_t gfp
)
835 struct wiphy
*wiphy
= wdev
->wiphy
;
836 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
837 struct cfg80211_mgmt_registration
*reg
;
838 const struct ieee80211_txrx_stypes
*stypes
=
839 &wiphy
->mgmt_stypes
[wdev
->iftype
];
840 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
844 __le16 ftype
= mgmt
->frame_control
&
845 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
848 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
850 if (!(stypes
->rx
& BIT(stype
)))
853 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
854 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
856 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
858 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
859 if (reg
->frame_type
!= ftype
)
862 if (reg
->match_len
> data_len
)
865 if (memcmp(reg
->match
, data
, reg
->match_len
))
870 /* Indicate the received Action frame to user space */
871 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlpid
,
880 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
884 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
886 void cfg80211_mgmt_tx_status(struct wireless_dev
*wdev
, u64 cookie
,
887 const u8
*buf
, size_t len
, bool ack
, gfp_t gfp
)
889 struct wiphy
*wiphy
= wdev
->wiphy
;
890 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
892 /* Indicate TX status of the Action frame to user space */
893 nl80211_send_mgmt_tx_status(rdev
, wdev
, cookie
, buf
, len
, ack
, gfp
);
895 EXPORT_SYMBOL(cfg80211_mgmt_tx_status
);
897 void cfg80211_cqm_rssi_notify(struct net_device
*dev
,
898 enum nl80211_cqm_rssi_threshold_event rssi_event
,
901 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
902 struct wiphy
*wiphy
= wdev
->wiphy
;
903 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
905 /* Indicate roaming trigger event to user space */
906 nl80211_send_cqm_rssi_notify(rdev
, dev
, rssi_event
, gfp
);
908 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify
);
910 void cfg80211_cqm_pktloss_notify(struct net_device
*dev
,
911 const u8
*peer
, u32 num_packets
, gfp_t gfp
)
913 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
914 struct wiphy
*wiphy
= wdev
->wiphy
;
915 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
917 /* Indicate roaming trigger event to user space */
918 nl80211_send_cqm_pktloss_notify(rdev
, dev
, peer
, num_packets
, gfp
);
920 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify
);
922 void cfg80211_gtk_rekey_notify(struct net_device
*dev
, const u8
*bssid
,
923 const u8
*replay_ctr
, gfp_t gfp
)
925 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
926 struct wiphy
*wiphy
= wdev
->wiphy
;
927 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
929 nl80211_gtk_rekey_notify(rdev
, dev
, bssid
, replay_ctr
, gfp
);
931 EXPORT_SYMBOL(cfg80211_gtk_rekey_notify
);
933 void cfg80211_pmksa_candidate_notify(struct net_device
*dev
, int index
,
934 const u8
*bssid
, bool preauth
, gfp_t gfp
)
936 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
937 struct wiphy
*wiphy
= wdev
->wiphy
;
938 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
940 nl80211_pmksa_candidate_notify(rdev
, dev
, index
, bssid
, preauth
, gfp
);
942 EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify
);
944 void cfg80211_ch_switch_notify(struct net_device
*dev
, int freq
,
945 enum nl80211_channel_type type
)
947 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
948 struct wiphy
*wiphy
= wdev
->wiphy
;
949 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
950 struct ieee80211_channel
*chan
;
954 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
955 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
))
958 chan
= rdev_freq_to_chan(rdev
, freq
, type
);
962 wdev
->channel
= chan
;
963 nl80211_ch_switch_notify(rdev
, dev
, freq
, type
, GFP_KERNEL
);
968 EXPORT_SYMBOL(cfg80211_ch_switch_notify
);
970 bool cfg80211_rx_spurious_frame(struct net_device
*dev
,
971 const u8
*addr
, gfp_t gfp
)
973 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
975 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
976 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
))
979 return nl80211_unexpected_frame(dev
, addr
, gfp
);
981 EXPORT_SYMBOL(cfg80211_rx_spurious_frame
);
983 bool cfg80211_rx_unexpected_4addr_frame(struct net_device
*dev
,
984 const u8
*addr
, gfp_t gfp
)
986 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
988 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
989 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
&&
990 wdev
->iftype
!= NL80211_IFTYPE_AP_VLAN
))
993 return nl80211_unexpected_4addr_frame(dev
, addr
, gfp
);
995 EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame
);