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/netdevice.h>
10 #include <linux/nl80211.h>
11 #include <linux/wireless.h>
12 #include <net/cfg80211.h>
13 #include <net/iw_handler.h>
17 void cfg80211_send_rx_auth(struct net_device
*dev
, const u8
*buf
, size_t len
)
19 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
20 struct wiphy
*wiphy
= wdev
->wiphy
;
21 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
22 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
23 u8
*bssid
= mgmt
->bssid
;
25 u16 status
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
30 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
31 if (wdev
->authtry_bsses
[i
] &&
32 memcmp(wdev
->authtry_bsses
[i
]->pub
.bssid
, bssid
,
34 if (status
== WLAN_STATUS_SUCCESS
) {
35 wdev
->auth_bsses
[i
] = wdev
->authtry_bsses
[i
];
37 cfg80211_unhold_bss(wdev
->authtry_bsses
[i
]);
38 cfg80211_put_bss(&wdev
->authtry_bsses
[i
]->pub
);
40 wdev
->authtry_bsses
[i
] = NULL
;
48 nl80211_send_rx_auth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
49 cfg80211_sme_rx_auth(dev
, buf
, len
);
53 EXPORT_SYMBOL(cfg80211_send_rx_auth
);
55 void cfg80211_send_rx_assoc(struct net_device
*dev
, const u8
*buf
, size_t len
)
58 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
59 struct wiphy
*wiphy
= wdev
->wiphy
;
60 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
61 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
62 u8
*ie
= mgmt
->u
.assoc_resp
.variable
;
63 int i
, ieoffs
= offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
64 struct cfg80211_internal_bss
*bss
= NULL
;
68 status_code
= le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
71 * This is a bit of a hack, we don't notify userspace of
72 * a (re-)association reply if we tried to send a reassoc
73 * and got a reject -- we only try again with an assoc
74 * frame instead of reassoc.
76 if (status_code
!= WLAN_STATUS_SUCCESS
&& wdev
->conn
&&
77 cfg80211_sme_failed_reassoc(wdev
))
80 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
82 if (status_code
== WLAN_STATUS_SUCCESS
) {
83 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
84 if (!wdev
->auth_bsses
[i
])
86 if (memcmp(wdev
->auth_bsses
[i
]->pub
.bssid
, mgmt
->bssid
,
88 bss
= wdev
->auth_bsses
[i
];
89 wdev
->auth_bsses
[i
] = NULL
;
90 /* additional reference to drop hold */
91 cfg80211_ref_bss(bss
);
97 } else if (wdev
->conn
) {
98 cfg80211_sme_failed_assoc(wdev
);
100 * do not call connect_result() now because the
101 * sme will schedule work that does it later.
106 if (!wdev
->conn
&& wdev
->sme_state
== CFG80211_SME_IDLE
) {
108 * This is for the userspace SME, the CONNECTING
109 * state will be changed to CONNECTED by
110 * __cfg80211_connect_result() below.
112 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
115 /* this consumes one bss reference (unless bss is NULL) */
116 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, ie
, len
- ieoffs
,
118 status_code
== WLAN_STATUS_SUCCESS
,
119 bss
? &bss
->pub
: NULL
);
120 /* drop hold now, and also reference acquired above */
122 cfg80211_unhold_bss(bss
);
123 cfg80211_put_bss(&bss
->pub
);
129 EXPORT_SYMBOL(cfg80211_send_rx_assoc
);
131 void __cfg80211_send_deauth(struct net_device
*dev
,
132 const u8
*buf
, size_t len
)
134 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
135 struct wiphy
*wiphy
= wdev
->wiphy
;
136 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
137 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
138 const u8
*bssid
= mgmt
->bssid
;
142 ASSERT_WDEV_LOCK(wdev
);
144 if (wdev
->current_bss
&&
145 memcmp(wdev
->current_bss
->pub
.bssid
, bssid
, ETH_ALEN
) == 0) {
146 cfg80211_unhold_bss(wdev
->current_bss
);
147 cfg80211_put_bss(&wdev
->current_bss
->pub
);
148 wdev
->current_bss
= NULL
;
150 } else for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
151 if (wdev
->auth_bsses
[i
] &&
152 memcmp(wdev
->auth_bsses
[i
]->pub
.bssid
, bssid
, ETH_ALEN
) == 0) {
153 cfg80211_unhold_bss(wdev
->auth_bsses
[i
]);
154 cfg80211_put_bss(&wdev
->auth_bsses
[i
]->pub
);
155 wdev
->auth_bsses
[i
] = NULL
;
159 if (wdev
->authtry_bsses
[i
] &&
160 memcmp(wdev
->authtry_bsses
[i
]->pub
.bssid
, bssid
, ETH_ALEN
) == 0) {
161 cfg80211_unhold_bss(wdev
->authtry_bsses
[i
]);
162 cfg80211_put_bss(&wdev
->authtry_bsses
[i
]->pub
);
163 wdev
->authtry_bsses
[i
] = NULL
;
172 nl80211_send_deauth(rdev
, dev
, buf
, len
, GFP_KERNEL
);
174 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
178 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
180 from_ap
= memcmp(mgmt
->sa
, dev
->dev_addr
, ETH_ALEN
) != 0;
181 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
182 } else if (wdev
->sme_state
== CFG80211_SME_CONNECTING
) {
183 __cfg80211_connect_result(dev
, mgmt
->bssid
, NULL
, 0, NULL
, 0,
184 WLAN_STATUS_UNSPECIFIED_FAILURE
,
188 EXPORT_SYMBOL(__cfg80211_send_deauth
);
190 void cfg80211_send_deauth(struct net_device
*dev
, const u8
*buf
, size_t len
)
192 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
195 __cfg80211_send_deauth(dev
, buf
, len
);
198 EXPORT_SYMBOL(cfg80211_send_deauth
);
200 void __cfg80211_send_disassoc(struct net_device
*dev
,
201 const u8
*buf
, size_t len
)
203 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
204 struct wiphy
*wiphy
= wdev
->wiphy
;
205 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
206 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
207 const u8
*bssid
= mgmt
->bssid
;
213 ASSERT_WDEV_LOCK(wdev
);
215 nl80211_send_disassoc(rdev
, dev
, buf
, len
, GFP_KERNEL
);
217 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
220 if (wdev
->current_bss
&&
221 memcmp(wdev
->current_bss
->pub
.bssid
, bssid
, ETH_ALEN
) == 0) {
222 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
223 if (wdev
->authtry_bsses
[i
] || wdev
->auth_bsses
[i
])
225 wdev
->auth_bsses
[i
] = wdev
->current_bss
;
226 wdev
->current_bss
= NULL
;
228 cfg80211_sme_disassoc(dev
, i
);
236 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
238 from_ap
= memcmp(mgmt
->sa
, dev
->dev_addr
, ETH_ALEN
) != 0;
239 __cfg80211_disconnected(dev
, NULL
, 0, reason_code
, from_ap
);
241 EXPORT_SYMBOL(__cfg80211_send_disassoc
);
243 void cfg80211_send_disassoc(struct net_device
*dev
, const u8
*buf
, size_t len
)
245 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
248 __cfg80211_send_disassoc(dev
, buf
, len
);
251 EXPORT_SYMBOL(cfg80211_send_disassoc
);
253 static void __cfg80211_auth_remove(struct wireless_dev
*wdev
, const u8
*addr
)
258 ASSERT_WDEV_LOCK(wdev
);
260 for (i
= 0; addr
&& i
< MAX_AUTH_BSSES
; i
++) {
261 if (wdev
->authtry_bsses
[i
] &&
262 memcmp(wdev
->authtry_bsses
[i
]->pub
.bssid
,
263 addr
, ETH_ALEN
) == 0) {
264 cfg80211_unhold_bss(wdev
->authtry_bsses
[i
]);
265 cfg80211_put_bss(&wdev
->authtry_bsses
[i
]->pub
);
266 wdev
->authtry_bsses
[i
] = NULL
;
275 void __cfg80211_auth_canceled(struct net_device
*dev
, const u8
*addr
)
277 __cfg80211_auth_remove(dev
->ieee80211_ptr
, addr
);
279 EXPORT_SYMBOL(__cfg80211_auth_canceled
);
281 void cfg80211_send_auth_timeout(struct net_device
*dev
, const u8
*addr
)
283 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
284 struct wiphy
*wiphy
= wdev
->wiphy
;
285 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
289 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
290 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
291 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
292 WLAN_STATUS_UNSPECIFIED_FAILURE
,
295 __cfg80211_auth_remove(wdev
, addr
);
299 EXPORT_SYMBOL(cfg80211_send_auth_timeout
);
301 void cfg80211_send_assoc_timeout(struct net_device
*dev
, const u8
*addr
)
303 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
304 struct wiphy
*wiphy
= wdev
->wiphy
;
305 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
311 nl80211_send_assoc_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
312 if (wdev
->sme_state
== CFG80211_SME_CONNECTING
)
313 __cfg80211_connect_result(dev
, addr
, NULL
, 0, NULL
, 0,
314 WLAN_STATUS_UNSPECIFIED_FAILURE
,
317 for (i
= 0; addr
&& i
< MAX_AUTH_BSSES
; i
++) {
318 if (wdev
->auth_bsses
[i
] &&
319 memcmp(wdev
->auth_bsses
[i
]->pub
.bssid
,
320 addr
, ETH_ALEN
) == 0) {
321 cfg80211_unhold_bss(wdev
->auth_bsses
[i
]);
322 cfg80211_put_bss(&wdev
->auth_bsses
[i
]->pub
);
323 wdev
->auth_bsses
[i
] = NULL
;
333 EXPORT_SYMBOL(cfg80211_send_assoc_timeout
);
335 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
336 enum nl80211_key_type key_type
, int key_id
,
337 const u8
*tsc
, gfp_t gfp
)
339 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
340 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
341 #ifdef CONFIG_CFG80211_WEXT
342 union iwreq_data wrqu
;
343 char *buf
= kmalloc(128, gfp
);
346 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
347 "keyid=%d %scast addr=%pM)", key_id
,
348 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
350 memset(&wrqu
, 0, sizeof(wrqu
));
351 wrqu
.data
.length
= strlen(buf
);
352 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
357 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
359 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
361 /* some MLME handling for userspace SME */
362 int __cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
363 struct net_device
*dev
,
364 struct ieee80211_channel
*chan
,
365 enum nl80211_auth_type auth_type
,
367 const u8
*ssid
, int ssid_len
,
368 const u8
*ie
, int ie_len
,
369 const u8
*key
, int key_len
, int key_idx
)
371 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
372 struct cfg80211_auth_request req
;
373 struct cfg80211_internal_bss
*bss
;
374 int i
, err
, slot
= -1, nfree
= 0;
376 ASSERT_WDEV_LOCK(wdev
);
378 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
379 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 4)
382 if (wdev
->current_bss
&&
383 memcmp(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
) == 0)
386 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
387 if (wdev
->authtry_bsses
[i
] &&
388 memcmp(bssid
, wdev
->authtry_bsses
[i
]->pub
.bssid
,
391 if (wdev
->auth_bsses
[i
] &&
392 memcmp(bssid
, wdev
->auth_bsses
[i
]->pub
.bssid
,
397 memset(&req
, 0, sizeof(req
));
401 req
.auth_type
= auth_type
;
402 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
403 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
405 req
.key_len
= key_len
;
406 req
.key_idx
= key_idx
;
410 bss
= bss_from_pub(req
.bss
);
412 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
413 if (!wdev
->auth_bsses
[i
] && !wdev
->authtry_bsses
[i
]) {
419 /* we need one free slot for disassoc and one for this auth */
425 wdev
->authtry_bsses
[slot
] = bss
;
426 cfg80211_hold_bss(bss
);
428 err
= rdev
->ops
->auth(&rdev
->wiphy
, dev
, &req
);
430 wdev
->authtry_bsses
[slot
] = NULL
;
431 cfg80211_unhold_bss(bss
);
436 cfg80211_put_bss(req
.bss
);
440 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
441 struct net_device
*dev
, struct ieee80211_channel
*chan
,
442 enum nl80211_auth_type auth_type
, const u8
*bssid
,
443 const u8
*ssid
, int ssid_len
,
444 const u8
*ie
, int ie_len
,
445 const u8
*key
, int key_len
, int key_idx
)
449 wdev_lock(dev
->ieee80211_ptr
);
450 err
= __cfg80211_mlme_auth(rdev
, dev
, chan
, auth_type
, bssid
,
451 ssid
, ssid_len
, ie
, ie_len
,
452 key
, key_len
, key_idx
);
453 wdev_unlock(dev
->ieee80211_ptr
);
458 int __cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
459 struct net_device
*dev
,
460 struct ieee80211_channel
*chan
,
461 const u8
*bssid
, const u8
*prev_bssid
,
462 const u8
*ssid
, int ssid_len
,
463 const u8
*ie
, int ie_len
, bool use_mfp
,
464 struct cfg80211_crypto_settings
*crypt
)
466 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
467 struct cfg80211_assoc_request req
;
468 struct cfg80211_internal_bss
*bss
;
469 int i
, err
, slot
= -1;
470 bool was_connected
= false;
472 ASSERT_WDEV_LOCK(wdev
);
474 memset(&req
, 0, sizeof(req
));
476 if (wdev
->current_bss
&& prev_bssid
&&
477 memcmp(wdev
->current_bss
->pub
.bssid
, prev_bssid
, ETH_ALEN
) == 0) {
479 * Trying to reassociate: Allow this to proceed and let the old
480 * association to be dropped when the new one is completed.
482 if (wdev
->sme_state
== CFG80211_SME_CONNECTED
) {
483 was_connected
= true;
484 wdev
->sme_state
= CFG80211_SME_CONNECTING
;
486 } else if (wdev
->current_bss
)
491 memcpy(&req
.crypto
, crypt
, sizeof(req
.crypto
));
492 req
.use_mfp
= use_mfp
;
493 req
.prev_bssid
= prev_bssid
;
494 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
495 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
498 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
502 bss
= bss_from_pub(req
.bss
);
504 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
505 if (bss
== wdev
->auth_bsses
[i
]) {
516 err
= rdev
->ops
->assoc(&rdev
->wiphy
, dev
, &req
);
518 if (err
&& was_connected
)
519 wdev
->sme_state
= CFG80211_SME_CONNECTED
;
520 /* still a reference in wdev->auth_bsses[slot] */
521 cfg80211_put_bss(req
.bss
);
525 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
526 struct net_device
*dev
,
527 struct ieee80211_channel
*chan
,
528 const u8
*bssid
, const u8
*prev_bssid
,
529 const u8
*ssid
, int ssid_len
,
530 const u8
*ie
, int ie_len
, bool use_mfp
,
531 struct cfg80211_crypto_settings
*crypt
)
533 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
537 err
= __cfg80211_mlme_assoc(rdev
, dev
, chan
, bssid
, prev_bssid
,
538 ssid
, ssid_len
, ie
, ie_len
, use_mfp
, crypt
);
544 int __cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
545 struct net_device
*dev
, const u8
*bssid
,
546 const u8
*ie
, int ie_len
, u16 reason
)
548 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
549 struct cfg80211_deauth_request req
;
552 ASSERT_WDEV_LOCK(wdev
);
554 memset(&req
, 0, sizeof(req
));
555 req
.reason_code
= reason
;
558 if (wdev
->current_bss
&&
559 memcmp(wdev
->current_bss
->pub
.bssid
, bssid
, ETH_ALEN
) == 0) {
560 req
.bss
= &wdev
->current_bss
->pub
;
561 } else for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
562 if (wdev
->auth_bsses
[i
] &&
563 memcmp(bssid
, wdev
->auth_bsses
[i
]->pub
.bssid
, ETH_ALEN
) == 0) {
564 req
.bss
= &wdev
->auth_bsses
[i
]->pub
;
567 if (wdev
->authtry_bsses
[i
] &&
568 memcmp(bssid
, wdev
->authtry_bsses
[i
]->pub
.bssid
, ETH_ALEN
) == 0) {
569 req
.bss
= &wdev
->authtry_bsses
[i
]->pub
;
577 return rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
, wdev
);
580 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
581 struct net_device
*dev
, const u8
*bssid
,
582 const u8
*ie
, int ie_len
, u16 reason
)
584 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
588 err
= __cfg80211_mlme_deauth(rdev
, dev
, bssid
, ie
, ie_len
, reason
);
594 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
595 struct net_device
*dev
, const u8
*bssid
,
596 const u8
*ie
, int ie_len
, u16 reason
)
598 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
599 struct cfg80211_disassoc_request req
;
601 ASSERT_WDEV_LOCK(wdev
);
603 if (wdev
->sme_state
!= CFG80211_SME_CONNECTED
)
606 if (WARN_ON(!wdev
->current_bss
))
609 memset(&req
, 0, sizeof(req
));
610 req
.reason_code
= reason
;
613 if (memcmp(wdev
->current_bss
->pub
.bssid
, bssid
, ETH_ALEN
) == 0)
614 req
.bss
= &wdev
->current_bss
->pub
;
618 return rdev
->ops
->disassoc(&rdev
->wiphy
, dev
, &req
, wdev
);
621 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
622 struct net_device
*dev
, const u8
*bssid
,
623 const u8
*ie
, int ie_len
, u16 reason
)
625 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
629 err
= __cfg80211_mlme_disassoc(rdev
, dev
, bssid
, ie
, ie_len
, reason
);
635 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
636 struct net_device
*dev
)
638 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
639 struct cfg80211_deauth_request req
;
642 ASSERT_WDEV_LOCK(wdev
);
644 if (!rdev
->ops
->deauth
)
647 memset(&req
, 0, sizeof(req
));
648 req
.reason_code
= WLAN_REASON_DEAUTH_LEAVING
;
652 if (wdev
->current_bss
) {
653 req
.bss
= &wdev
->current_bss
->pub
;
654 rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
, wdev
);
655 if (wdev
->current_bss
) {
656 cfg80211_unhold_bss(wdev
->current_bss
);
657 cfg80211_put_bss(&wdev
->current_bss
->pub
);
658 wdev
->current_bss
= NULL
;
662 for (i
= 0; i
< MAX_AUTH_BSSES
; i
++) {
663 if (wdev
->auth_bsses
[i
]) {
664 req
.bss
= &wdev
->auth_bsses
[i
]->pub
;
665 rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
, wdev
);
666 if (wdev
->auth_bsses
[i
]) {
667 cfg80211_unhold_bss(wdev
->auth_bsses
[i
]);
668 cfg80211_put_bss(&wdev
->auth_bsses
[i
]->pub
);
669 wdev
->auth_bsses
[i
] = NULL
;
672 if (wdev
->authtry_bsses
[i
]) {
673 req
.bss
= &wdev
->authtry_bsses
[i
]->pub
;
674 rdev
->ops
->deauth(&rdev
->wiphy
, dev
, &req
, wdev
);
675 if (wdev
->authtry_bsses
[i
]) {
676 cfg80211_unhold_bss(wdev
->authtry_bsses
[i
]);
677 cfg80211_put_bss(&wdev
->authtry_bsses
[i
]->pub
);
678 wdev
->authtry_bsses
[i
] = NULL
;
684 void cfg80211_ready_on_channel(struct net_device
*dev
, u64 cookie
,
685 struct ieee80211_channel
*chan
,
686 enum nl80211_channel_type channel_type
,
687 unsigned int duration
, gfp_t gfp
)
689 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
690 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
692 nl80211_send_remain_on_channel(rdev
, dev
, cookie
, chan
, channel_type
,
695 EXPORT_SYMBOL(cfg80211_ready_on_channel
);
697 void cfg80211_remain_on_channel_expired(struct net_device
*dev
,
699 struct ieee80211_channel
*chan
,
700 enum nl80211_channel_type channel_type
,
703 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
704 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
706 nl80211_send_remain_on_channel_cancel(rdev
, dev
, cookie
, chan
,
709 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired
);
711 void cfg80211_new_sta(struct net_device
*dev
, const u8
*mac_addr
,
712 struct station_info
*sinfo
, gfp_t gfp
)
714 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
715 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wiphy
);
717 nl80211_send_sta_event(rdev
, dev
, mac_addr
, sinfo
, gfp
);
719 EXPORT_SYMBOL(cfg80211_new_sta
);