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
= rdev
->ops
->auth(&rdev
->wiphy
, dev
, &req
);
307 cfg80211_put_bss(req
.bss
);
311 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
312 struct net_device
*dev
, struct ieee80211_channel
*chan
,
313 enum nl80211_auth_type auth_type
, const u8
*bssid
,
314 const u8
*ssid
, int ssid_len
,
315 const u8
*ie
, int ie_len
,
316 const u8
*key
, int key_len
, int key_idx
)
320 wdev_lock(dev
->ieee80211_ptr
);
321 err
= __cfg80211_mlme_auth(rdev
, dev
, chan
, auth_type
, bssid
,
322 ssid
, ssid_len
, ie
, ie_len
,
323 key
, key_len
, key_idx
);
324 wdev_unlock(dev
->ieee80211_ptr
);
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 int __cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
347 struct net_device
*dev
,
348 struct ieee80211_channel
*chan
,
349 const u8
*bssid
, const u8
*prev_bssid
,
350 const u8
*ssid
, int ssid_len
,
351 const u8
*ie
, int ie_len
, bool use_mfp
,
352 struct cfg80211_crypto_settings
*crypt
,
353 u32 assoc_flags
, struct ieee80211_ht_cap
*ht_capa
,
354 struct ieee80211_ht_cap
*ht_capa_mask
)
356 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
357 struct cfg80211_assoc_request req
;
359 bool was_connected
= false;
361 ASSERT_WDEV_LOCK(wdev
);
363 memset(&req
, 0, sizeof(req
));
365 if (wdev
->current_bss
&& prev_bssid
&&
366 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, prev_bssid
)) {
368 * Trying to reassociate: Allow this to proceed and let the old
369 * association to be dropped when the new one is completed.
371 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
372 was_connected
= true;
373 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
375 } else if (wdev
->current_bss
)
380 memcpy(&req
.crypto
, crypt
, sizeof(req
.crypto
));
381 req
.use_mfp
= use_mfp
;
382 req
.prev_bssid
= prev_bssid
;
383 req
.flags
= assoc_flags
;
385 memcpy(&req
.ht_capa
, ht_capa
, sizeof(req
.ht_capa
));
387 memcpy(&req
.ht_capa_mask
, ht_capa_mask
,
388 sizeof(req
.ht_capa_mask
));
389 cfg80211_oper_and_ht_capa(&req
.ht_capa_mask
,
390 rdev
->wiphy
.ht_capa_mod_mask
);
392 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
393 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
396 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
400 err
= rdev
->ops
->assoc(&rdev
->wiphy
, dev
, &req
);
404 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
405 cfg80211_put_bss(req
.bss
);
411 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
412 struct net_device
*dev
,
413 struct ieee80211_channel
*chan
,
414 const u8
*bssid
, const u8
*prev_bssid
,
415 const u8
*ssid
, int ssid_len
,
416 const u8
*ie
, int ie_len
, bool use_mfp
,
417 struct cfg80211_crypto_settings
*crypt
,
418 u32 assoc_flags
, struct ieee80211_ht_cap
*ht_capa
,
419 struct ieee80211_ht_cap
*ht_capa_mask
)
421 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
425 err
= __cfg80211_mlme_assoc(rdev
, dev
, chan
, bssid
, prev_bssid
,
426 ssid
, ssid_len
, ie
, ie_len
, use_mfp
, crypt
,
427 assoc_flags
, ht_capa
, ht_capa_mask
);
433 int __cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
434 struct net_device
*dev
, const u8
*bssid
,
435 const u8
*ie
, int ie_len
, u16 reason
,
436 bool local_state_change
)
438 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
439 struct cfg80211_deauth_request req
= {
441 .reason_code
= reason
,
446 ASSERT_WDEV_LOCK(wdev
);
448 if (local_state_change
) {
449 if (wdev
->current_bss
&&
450 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)) {
451 cfg80211_unhold_bss(wdev
->current_bss
);
452 cfg80211_put_bss(&wdev
->current_bss
->pub
);
453 wdev
->current_bss
= NULL
;
459 return rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
);
462 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
463 struct net_device
*dev
, const u8
*bssid
,
464 const u8
*ie
, int ie_len
, u16 reason
,
465 bool local_state_change
)
467 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
471 err
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
478 static int __cfg80211_mlme_disassoc(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
;
484 struct cfg80211_disassoc_request req
;
486 ASSERT_WDEV_LOCK(wdev
);
488 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
491 if (WARN_ON(!wdev
->current_bss
))
494 memset(&req
, 0, sizeof(req
));
495 req
.reason_code
= reason
;
496 req
.local_state_change
= local_state_change
;
499 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
500 req
.bss
= &wdev
->current_bss
->pub
;
504 return rdev
->ops
->disassoc(&rdev
->wiphy
, dev
, &req
);
507 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
508 struct net_device
*dev
, const u8
*bssid
,
509 const u8
*ie
, int ie_len
, u16 reason
,
510 bool local_state_change
)
512 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
516 err
= __cfg80211_mlme_disassoc(rdev
, dev
, bssid
, ie
, ie_len
, reason
,
523 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
524 struct net_device
*dev
)
526 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
527 struct cfg80211_deauth_request req
;
530 ASSERT_WDEV_LOCK(wdev
);
532 if (!rdev
->ops
->deauth
)
535 memset(&req
, 0, sizeof(req
));
536 req
.reason_code
= WLAN_REASON_DEAUTH_LEAVING
;
540 if (!wdev
->current_bss
)
543 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
545 rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
);
547 if (wdev
->current_bss
) {
548 cfg80211_unhold_bss(wdev
->current_bss
);
549 cfg80211_put_bss(&wdev
->current_bss
->pub
);
550 wdev
->current_bss
= NULL
;
554 void cfg80211_ready_on_channel(struct net_device
*dev
, u64 cookie
,
555 struct ieee80211_channel
*chan
,
556 enum nl80211_channel_type channel_type
,
557 unsigned int duration
, gfp_t gfp
)
559 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
560 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
562 nl80211_send_remain_on_channel(rdev
, dev
, cookie
, chan
, channel_type
,
565 EXPORT_SYMBOL(cfg80211_ready_on_channel
);
567 void cfg80211_remain_on_channel_expired(struct net_device
*dev
,
569 struct ieee80211_channel
*chan
,
570 enum nl80211_channel_type channel_type
,
573 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
574 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
576 nl80211_send_remain_on_channel_cancel(rdev
, dev
, cookie
, chan
,
579 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired
);
581 void cfg80211_new_sta(struct net_device
*dev
, const u8
*mac_addr
,
582 struct station_info
*sinfo
, gfp_t gfp
)
584 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
585 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
587 nl80211_send_sta_event(rdev
, dev
, mac_addr
, sinfo
, gfp
);
589 EXPORT_SYMBOL(cfg80211_new_sta
);
591 void cfg80211_del_sta(struct net_device
*dev
, const u8
*mac_addr
, gfp_t gfp
)
593 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
594 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
596 nl80211_send_sta_del_event(rdev
, dev
, mac_addr
, gfp
);
598 EXPORT_SYMBOL(cfg80211_del_sta
);
600 struct cfg80211_mgmt_registration
{
601 struct list_head list
;
612 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_pid
,
613 u16 frame_type
, const u8
*match_data
,
616 struct wiphy
*wiphy
= wdev
->wiphy
;
617 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
618 struct cfg80211_mgmt_registration
*reg
, *nreg
;
622 if (!wdev
->wiphy
->mgmt_stypes
)
625 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
)
628 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
))
631 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
632 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
)))
635 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
639 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
641 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
642 int mlen
= min(match_len
, reg
->match_len
);
644 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
647 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
658 memcpy(nreg
->match
, match_data
, match_len
);
659 nreg
->match_len
= match_len
;
660 nreg
->nlpid
= snd_pid
;
661 nreg
->frame_type
= cpu_to_le16(frame_type
);
662 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
664 if (rdev
->ops
->mgmt_frame_register
)
665 rdev
->ops
->mgmt_frame_register(wiphy
, wdev
->netdev
,
669 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
674 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlpid
)
676 struct wiphy
*wiphy
= wdev
->wiphy
;
677 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
678 struct cfg80211_mgmt_registration
*reg
, *tmp
;
680 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
682 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
683 if (reg
->nlpid
!= nlpid
)
686 if (rdev
->ops
->mgmt_frame_register
) {
687 u16 frame_type
= le16_to_cpu(reg
->frame_type
);
689 rdev
->ops
->mgmt_frame_register(wiphy
, wdev
->netdev
,
693 list_del(®
->list
);
697 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
699 if (nlpid
== wdev
->ap_unexpected_nlpid
)
700 wdev
->ap_unexpected_nlpid
= 0;
703 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
705 struct cfg80211_mgmt_registration
*reg
, *tmp
;
707 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
709 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
710 list_del(®
->list
);
714 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
717 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
718 struct net_device
*dev
,
719 struct ieee80211_channel
*chan
, bool offchan
,
720 enum nl80211_channel_type channel_type
,
721 bool channel_type_valid
, unsigned int wait
,
722 const u8
*buf
, size_t len
, bool no_cck
,
723 bool dont_wait_for_ack
, u64
*cookie
)
725 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
726 const struct ieee80211_mgmt
*mgmt
;
729 if (!wdev
->wiphy
->mgmt_stypes
)
732 if (!rdev
->ops
->mgmt_tx
)
738 mgmt
= (const struct ieee80211_mgmt
*) buf
;
740 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
743 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
744 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
747 if (ieee80211_is_action(mgmt
->frame_control
) &&
748 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
753 switch (wdev
->iftype
) {
754 case NL80211_IFTYPE_ADHOC
:
755 case NL80211_IFTYPE_STATION
:
756 case NL80211_IFTYPE_P2P_CLIENT
:
757 if (!wdev
->current_bss
) {
762 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
769 * check for IBSS DA must be done by driver as
770 * cfg80211 doesn't track the stations
772 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
775 /* for station, check that DA is the AP */
776 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
782 case NL80211_IFTYPE_AP
:
783 case NL80211_IFTYPE_P2P_GO
:
784 case NL80211_IFTYPE_AP_VLAN
:
785 if (!ether_addr_equal(mgmt
->bssid
, dev
->dev_addr
))
788 case NL80211_IFTYPE_MESH_POINT
:
789 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
794 * check for mesh DA must be done by driver as
795 * cfg80211 doesn't track the stations
808 if (!ether_addr_equal(mgmt
->sa
, dev
->dev_addr
))
811 /* Transmit the Action frame as requested by user space */
812 return rdev
->ops
->mgmt_tx(&rdev
->wiphy
, dev
, chan
, offchan
,
813 channel_type
, channel_type_valid
,
814 wait
, buf
, len
, no_cck
, dont_wait_for_ack
,
818 bool cfg80211_rx_mgmt(struct net_device
*dev
, int freq
, int sig_mbm
,
819 const u8
*buf
, size_t len
, gfp_t gfp
)
821 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
822 struct wiphy
*wiphy
= wdev
->wiphy
;
823 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
824 struct cfg80211_mgmt_registration
*reg
;
825 const struct ieee80211_txrx_stypes
*stypes
=
826 &wiphy
->mgmt_stypes
[wdev
->iftype
];
827 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
831 __le16 ftype
= mgmt
->frame_control
&
832 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
835 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
837 if (!(stypes
->rx
& BIT(stype
)))
840 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
841 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
843 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
845 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
846 if (reg
->frame_type
!= ftype
)
849 if (reg
->match_len
> data_len
)
852 if (memcmp(reg
->match
, data
, reg
->match_len
))
857 /* Indicate the received Action frame to user space */
858 if (nl80211_send_mgmt(rdev
, dev
, reg
->nlpid
,
867 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
871 EXPORT_SYMBOL(cfg80211_rx_mgmt
);
873 void cfg80211_mgmt_tx_status(struct net_device
*dev
, u64 cookie
,
874 const u8
*buf
, size_t len
, bool ack
, gfp_t gfp
)
876 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
877 struct wiphy
*wiphy
= wdev
->wiphy
;
878 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
880 /* Indicate TX status of the Action frame to user space */
881 nl80211_send_mgmt_tx_status(rdev
, dev
, cookie
, buf
, len
, ack
, gfp
);
883 EXPORT_SYMBOL(cfg80211_mgmt_tx_status
);
885 void cfg80211_cqm_rssi_notify(struct net_device
*dev
,
886 enum nl80211_cqm_rssi_threshold_event rssi_event
,
889 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
890 struct wiphy
*wiphy
= wdev
->wiphy
;
891 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
893 /* Indicate roaming trigger event to user space */
894 nl80211_send_cqm_rssi_notify(rdev
, dev
, rssi_event
, gfp
);
896 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify
);
898 void cfg80211_cqm_pktloss_notify(struct net_device
*dev
,
899 const u8
*peer
, u32 num_packets
, gfp_t gfp
)
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_pktloss_notify(rdev
, dev
, peer
, num_packets
, gfp
);
908 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify
);
910 void cfg80211_gtk_rekey_notify(struct net_device
*dev
, const u8
*bssid
,
911 const u8
*replay_ctr
, 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 nl80211_gtk_rekey_notify(rdev
, dev
, bssid
, replay_ctr
, gfp
);
919 EXPORT_SYMBOL(cfg80211_gtk_rekey_notify
);
921 void cfg80211_pmksa_candidate_notify(struct net_device
*dev
, int index
,
922 const u8
*bssid
, bool preauth
, gfp_t gfp
)
924 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
925 struct wiphy
*wiphy
= wdev
->wiphy
;
926 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
928 nl80211_pmksa_candidate_notify(rdev
, dev
, index
, bssid
, preauth
, gfp
);
930 EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify
);
932 void cfg80211_ch_switch_notify(struct net_device
*dev
, int freq
,
933 enum nl80211_channel_type type
)
935 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
936 struct wiphy
*wiphy
= wdev
->wiphy
;
937 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
938 struct ieee80211_channel
*chan
;
942 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
943 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
))
946 chan
= rdev_freq_to_chan(rdev
, freq
, type
);
950 wdev
->channel
= chan
;
952 nl80211_ch_switch_notify(rdev
, dev
, freq
, type
, GFP_KERNEL
);
957 EXPORT_SYMBOL(cfg80211_ch_switch_notify
);
959 bool cfg80211_rx_spurious_frame(struct net_device
*dev
,
960 const u8
*addr
, gfp_t gfp
)
962 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
964 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
965 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
))
968 return nl80211_unexpected_frame(dev
, addr
, gfp
);
970 EXPORT_SYMBOL(cfg80211_rx_spurious_frame
);
972 bool cfg80211_rx_unexpected_4addr_frame(struct net_device
*dev
,
973 const u8
*addr
, gfp_t gfp
)
975 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
977 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_AP
&&
978 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
&&
979 wdev
->iftype
!= NL80211_IFTYPE_AP_VLAN
))
982 return nl80211_unexpected_4addr_frame(dev
, addr
, gfp
);
984 EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame
);