Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / net / wireless / mlme.c
1 /*
2  * cfg80211 MLME SAP interface
3  *
4  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5  */
6
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/netdevice.h>
10 #include <linux/nl80211.h>
11 #include <linux/slab.h>
12 #include <linux/wireless.h>
13 #include <net/cfg80211.h>
14 #include <net/iw_handler.h>
15 #include "core.h"
16 #include "nl80211.h"
17
18 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
19 {
20         struct wireless_dev *wdev = dev->ieee80211_ptr;
21         struct wiphy *wiphy = wdev->wiphy;
22         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
23
24         wdev_lock(wdev);
25
26         nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
27         cfg80211_sme_rx_auth(dev, buf, len);
28
29         wdev_unlock(wdev);
30 }
31 EXPORT_SYMBOL(cfg80211_send_rx_auth);
32
33 void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
34                             const u8 *buf, size_t len)
35 {
36         u16 status_code;
37         struct wireless_dev *wdev = dev->ieee80211_ptr;
38         struct wiphy *wiphy = wdev->wiphy;
39         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
40         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
41         u8 *ie = mgmt->u.assoc_resp.variable;
42         int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
43
44         wdev_lock(wdev);
45
46         status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
47
48         /*
49          * This is a bit of a hack, we don't notify userspace of
50          * a (re-)association reply if we tried to send a reassoc
51          * and got a reject -- we only try again with an assoc
52          * frame instead of reassoc.
53          */
54         if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
55             cfg80211_sme_failed_reassoc(wdev)) {
56                 cfg80211_put_bss(bss);
57                 goto out;
58         }
59
60         nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
61
62         if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
63                 cfg80211_sme_failed_assoc(wdev);
64                 /*
65                  * do not call connect_result() now because the
66                  * sme will schedule work that does it later.
67                  */
68                 cfg80211_put_bss(bss);
69                 goto out;
70         }
71
72         if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
73                 /*
74                  * This is for the userspace SME, the CONNECTING
75                  * state will be changed to CONNECTED by
76                  * __cfg80211_connect_result() below.
77                  */
78                 wdev->sme_state = CFG80211_SME_CONNECTING;
79         }
80
81         /* this consumes the bss reference */
82         __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
83                                   status_code,
84                                   status_code == WLAN_STATUS_SUCCESS, bss);
85  out:
86         wdev_unlock(wdev);
87 }
88 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
89
90 void __cfg80211_send_deauth(struct net_device *dev,
91                                    const u8 *buf, size_t len)
92 {
93         struct wireless_dev *wdev = dev->ieee80211_ptr;
94         struct wiphy *wiphy = wdev->wiphy;
95         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
96         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
97         const u8 *bssid = mgmt->bssid;
98         bool was_current = false;
99
100         ASSERT_WDEV_LOCK(wdev);
101
102         if (wdev->current_bss &&
103             memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
104                 cfg80211_unhold_bss(wdev->current_bss);
105                 cfg80211_put_bss(&wdev->current_bss->pub);
106                 wdev->current_bss = NULL;
107                 was_current = true;
108         }
109
110         nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
111
112         if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
113                 u16 reason_code;
114                 bool from_ap;
115
116                 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
117
118                 from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
119                 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
120         } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
121                 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
122                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
123                                           false, NULL);
124         }
125 }
126 EXPORT_SYMBOL(__cfg80211_send_deauth);
127
128 void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
129 {
130         struct wireless_dev *wdev = dev->ieee80211_ptr;
131
132         wdev_lock(wdev);
133         __cfg80211_send_deauth(dev, buf, len);
134         wdev_unlock(wdev);
135 }
136 EXPORT_SYMBOL(cfg80211_send_deauth);
137
138 void __cfg80211_send_disassoc(struct net_device *dev,
139                                      const u8 *buf, size_t len)
140 {
141         struct wireless_dev *wdev = dev->ieee80211_ptr;
142         struct wiphy *wiphy = wdev->wiphy;
143         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
144         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
145         const u8 *bssid = mgmt->bssid;
146         u16 reason_code;
147         bool from_ap;
148
149         ASSERT_WDEV_LOCK(wdev);
150
151         nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
152
153         if (wdev->sme_state != CFG80211_SME_CONNECTED)
154                 return;
155
156         if (wdev->current_bss &&
157             memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
158                 cfg80211_sme_disassoc(dev, wdev->current_bss);
159                 cfg80211_unhold_bss(wdev->current_bss);
160                 cfg80211_put_bss(&wdev->current_bss->pub);
161                 wdev->current_bss = NULL;
162         } else
163                 WARN_ON(1);
164
165
166         reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
167
168         from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
169         __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
170 }
171 EXPORT_SYMBOL(__cfg80211_send_disassoc);
172
173 void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
174 {
175         struct wireless_dev *wdev = dev->ieee80211_ptr;
176
177         wdev_lock(wdev);
178         __cfg80211_send_disassoc(dev, buf, len);
179         wdev_unlock(wdev);
180 }
181 EXPORT_SYMBOL(cfg80211_send_disassoc);
182
183 void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
184                                  size_t len)
185 {
186         struct wireless_dev *wdev = dev->ieee80211_ptr;
187         struct wiphy *wiphy = wdev->wiphy;
188         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
189
190         nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
191 }
192 EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
193
194 void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
195                                    size_t len)
196 {
197         struct wireless_dev *wdev = dev->ieee80211_ptr;
198         struct wiphy *wiphy = wdev->wiphy;
199         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
200
201         nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
202 }
203 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
204
205 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
206 {
207         struct wireless_dev *wdev = dev->ieee80211_ptr;
208         struct wiphy *wiphy = wdev->wiphy;
209         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
210
211         wdev_lock(wdev);
212
213         nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
214         if (wdev->sme_state == CFG80211_SME_CONNECTING)
215                 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
216                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
217                                           false, NULL);
218
219         wdev_unlock(wdev);
220 }
221 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
222
223 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
224 {
225         struct wireless_dev *wdev = dev->ieee80211_ptr;
226         struct wiphy *wiphy = wdev->wiphy;
227         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
228
229         wdev_lock(wdev);
230
231         nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
232         if (wdev->sme_state == CFG80211_SME_CONNECTING)
233                 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
234                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
235                                           false, NULL);
236
237         wdev_unlock(wdev);
238 }
239 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
240
241 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
242                                   enum nl80211_key_type key_type, int key_id,
243                                   const u8 *tsc, gfp_t gfp)
244 {
245         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
246         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
247 #ifdef CONFIG_CFG80211_WEXT
248         union iwreq_data wrqu;
249         char *buf = kmalloc(128, gfp);
250
251         if (buf) {
252                 sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
253                         "keyid=%d %scast addr=%pM)", key_id,
254                         key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
255                         addr);
256                 memset(&wrqu, 0, sizeof(wrqu));
257                 wrqu.data.length = strlen(buf);
258                 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
259                 kfree(buf);
260         }
261 #endif
262
263         nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
264 }
265 EXPORT_SYMBOL(cfg80211_michael_mic_failure);
266
267 /* some MLME handling for userspace SME */
268 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
269                          struct net_device *dev,
270                          struct ieee80211_channel *chan,
271                          enum nl80211_auth_type auth_type,
272                          const u8 *bssid,
273                          const u8 *ssid, int ssid_len,
274                          const u8 *ie, int ie_len,
275                          const u8 *key, int key_len, int key_idx)
276 {
277         struct wireless_dev *wdev = dev->ieee80211_ptr;
278         struct cfg80211_auth_request req;
279         int err;
280
281         ASSERT_WDEV_LOCK(wdev);
282
283         if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
284                 if (!key || !key_len || key_idx < 0 || key_idx > 4)
285                         return -EINVAL;
286
287         if (wdev->current_bss &&
288             memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
289                 return -EALREADY;
290
291         memset(&req, 0, sizeof(req));
292
293         req.ie = ie;
294         req.ie_len = ie_len;
295         req.auth_type = auth_type;
296         req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
297                                    WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
298         req.key = key;
299         req.key_len = key_len;
300         req.key_idx = key_idx;
301         if (!req.bss)
302                 return -ENOENT;
303
304         err = rdev->ops->auth(&rdev->wiphy, dev, &req);
305
306         cfg80211_put_bss(req.bss);
307         return err;
308 }
309
310 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
311                        struct net_device *dev, struct ieee80211_channel *chan,
312                        enum nl80211_auth_type auth_type, const u8 *bssid,
313                        const u8 *ssid, int ssid_len,
314                        const u8 *ie, int ie_len,
315                        const u8 *key, int key_len, int key_idx)
316 {
317         int err;
318
319         wdev_lock(dev->ieee80211_ptr);
320         err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
321                                    ssid, ssid_len, ie, ie_len,
322                                    key, key_len, key_idx);
323         wdev_unlock(dev->ieee80211_ptr);
324
325         return err;
326 }
327
328 /*  Do a logical ht_capa &= ht_capa_mask.  */
329 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
330                                const struct ieee80211_ht_cap *ht_capa_mask)
331 {
332         int i;
333         u8 *p1, *p2;
334         if (!ht_capa_mask) {
335                 memset(ht_capa, 0, sizeof(*ht_capa));
336                 return;
337         }
338
339         p1 = (u8*)(ht_capa);
340         p2 = (u8*)(ht_capa_mask);
341         for (i = 0; i<sizeof(*ht_capa); i++)
342                 p1[i] &= p2[i];
343 }
344
345 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
346                           struct net_device *dev,
347                           struct ieee80211_channel *chan,
348                           const u8 *bssid, const u8 *prev_bssid,
349                           const u8 *ssid, int ssid_len,
350                           const u8 *ie, int ie_len, bool use_mfp,
351                           struct cfg80211_crypto_settings *crypt,
352                           u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
353                           struct ieee80211_ht_cap *ht_capa_mask)
354 {
355         struct wireless_dev *wdev = dev->ieee80211_ptr;
356         struct cfg80211_assoc_request req;
357         int err;
358         bool was_connected = false;
359
360         ASSERT_WDEV_LOCK(wdev);
361
362         memset(&req, 0, sizeof(req));
363
364         if (wdev->current_bss && prev_bssid &&
365             memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
366                 /*
367                  * Trying to reassociate: Allow this to proceed and let the old
368                  * association to be dropped when the new one is completed.
369                  */
370                 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
371                         was_connected = true;
372                         wdev->sme_state = CFG80211_SME_CONNECTING;
373                 }
374         } else if (wdev->current_bss)
375                 return -EALREADY;
376
377         req.ie = ie;
378         req.ie_len = ie_len;
379         memcpy(&req.crypto, crypt, sizeof(req.crypto));
380         req.use_mfp = use_mfp;
381         req.prev_bssid = prev_bssid;
382         req.flags = assoc_flags;
383         if (ht_capa)
384                 memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
385         if (ht_capa_mask)
386                 memcpy(&req.ht_capa_mask, ht_capa_mask,
387                        sizeof(req.ht_capa_mask));
388         cfg80211_oper_and_ht_capa(&req.ht_capa_mask,
389                                   rdev->wiphy.ht_capa_mod_mask);
390
391         req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
392                                    WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
393         if (!req.bss) {
394                 if (was_connected)
395                         wdev->sme_state = CFG80211_SME_CONNECTED;
396                 return -ENOENT;
397         }
398
399         err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
400
401         if (err) {
402                 if (was_connected)
403                         wdev->sme_state = CFG80211_SME_CONNECTED;
404                 cfg80211_put_bss(req.bss);
405         }
406
407         return err;
408 }
409
410 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
411                         struct net_device *dev,
412                         struct ieee80211_channel *chan,
413                         const u8 *bssid, const u8 *prev_bssid,
414                         const u8 *ssid, int ssid_len,
415                         const u8 *ie, int ie_len, bool use_mfp,
416                         struct cfg80211_crypto_settings *crypt,
417                         u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
418                         struct ieee80211_ht_cap *ht_capa_mask)
419 {
420         struct wireless_dev *wdev = dev->ieee80211_ptr;
421         int err;
422
423         wdev_lock(wdev);
424         err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
425                                     ssid, ssid_len, ie, ie_len, use_mfp, crypt,
426                                     assoc_flags, ht_capa, ht_capa_mask);
427         wdev_unlock(wdev);
428
429         return err;
430 }
431
432 int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
433                            struct net_device *dev, const u8 *bssid,
434                            const u8 *ie, int ie_len, u16 reason,
435                            bool local_state_change)
436 {
437         struct wireless_dev *wdev = dev->ieee80211_ptr;
438         struct cfg80211_deauth_request req = {
439                 .bssid = bssid,
440                 .reason_code = reason,
441                 .ie = ie,
442                 .ie_len = ie_len,
443         };
444
445         ASSERT_WDEV_LOCK(wdev);
446
447         if (local_state_change) {
448                 if (wdev->current_bss &&
449                     memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
450                         cfg80211_unhold_bss(wdev->current_bss);
451                         cfg80211_put_bss(&wdev->current_bss->pub);
452                         wdev->current_bss = NULL;
453                 }
454
455                 return 0;
456         }
457
458         return rdev->ops->deauth(&rdev->wiphy, dev, &req);
459 }
460
461 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
462                          struct net_device *dev, const u8 *bssid,
463                          const u8 *ie, int ie_len, u16 reason,
464                          bool local_state_change)
465 {
466         struct wireless_dev *wdev = dev->ieee80211_ptr;
467         int err;
468
469         wdev_lock(wdev);
470         err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
471                                      local_state_change);
472         wdev_unlock(wdev);
473
474         return err;
475 }
476
477 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
478                                     struct net_device *dev, const u8 *bssid,
479                                     const u8 *ie, int ie_len, u16 reason,
480                                     bool local_state_change)
481 {
482         struct wireless_dev *wdev = dev->ieee80211_ptr;
483         struct cfg80211_disassoc_request req;
484
485         ASSERT_WDEV_LOCK(wdev);
486
487         if (wdev->sme_state != CFG80211_SME_CONNECTED)
488                 return -ENOTCONN;
489
490         if (WARN_ON(!wdev->current_bss))
491                 return -ENOTCONN;
492
493         memset(&req, 0, sizeof(req));
494         req.reason_code = reason;
495         req.local_state_change = local_state_change;
496         req.ie = ie;
497         req.ie_len = ie_len;
498         if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
499                 req.bss = &wdev->current_bss->pub;
500         else
501                 return -ENOTCONN;
502
503         return rdev->ops->disassoc(&rdev->wiphy, dev, &req);
504 }
505
506 int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
507                            struct net_device *dev, const u8 *bssid,
508                            const u8 *ie, int ie_len, u16 reason,
509                            bool local_state_change)
510 {
511         struct wireless_dev *wdev = dev->ieee80211_ptr;
512         int err;
513
514         wdev_lock(wdev);
515         err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
516                                        local_state_change);
517         wdev_unlock(wdev);
518
519         return err;
520 }
521
522 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
523                         struct net_device *dev)
524 {
525         struct wireless_dev *wdev = dev->ieee80211_ptr;
526         struct cfg80211_deauth_request req;
527         u8 bssid[ETH_ALEN];
528
529         ASSERT_WDEV_LOCK(wdev);
530
531         if (!rdev->ops->deauth)
532                 return;
533
534         memset(&req, 0, sizeof(req));
535         req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
536         req.ie = NULL;
537         req.ie_len = 0;
538
539         if (!wdev->current_bss)
540                 return;
541
542         memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
543         req.bssid = bssid;
544         rdev->ops->deauth(&rdev->wiphy, dev, &req);
545
546         if (wdev->current_bss) {
547                 cfg80211_unhold_bss(wdev->current_bss);
548                 cfg80211_put_bss(&wdev->current_bss->pub);
549                 wdev->current_bss = NULL;
550         }
551 }
552
553 void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
554                                struct ieee80211_channel *chan,
555                                enum nl80211_channel_type channel_type,
556                                unsigned int duration, gfp_t gfp)
557 {
558         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
559         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
560
561         nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type,
562                                        duration, gfp);
563 }
564 EXPORT_SYMBOL(cfg80211_ready_on_channel);
565
566 void cfg80211_remain_on_channel_expired(struct net_device *dev,
567                                         u64 cookie,
568                                         struct ieee80211_channel *chan,
569                                         enum nl80211_channel_type channel_type,
570                                         gfp_t gfp)
571 {
572         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
573         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
574
575         nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan,
576                                               channel_type, gfp);
577 }
578 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
579
580 void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
581                       struct station_info *sinfo, gfp_t gfp)
582 {
583         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
584         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
585
586         nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
587 }
588 EXPORT_SYMBOL(cfg80211_new_sta);
589
590 void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
591 {
592         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
593         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
594
595         nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp);
596 }
597 EXPORT_SYMBOL(cfg80211_del_sta);
598
599 struct cfg80211_mgmt_registration {
600         struct list_head list;
601
602         u32 nlpid;
603
604         int match_len;
605
606         __le16 frame_type;
607
608         u8 match[];
609 };
610
611 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
612                                 u16 frame_type, const u8 *match_data,
613                                 int match_len)
614 {
615         struct wiphy *wiphy = wdev->wiphy;
616         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
617         struct cfg80211_mgmt_registration *reg, *nreg;
618         int err = 0;
619         u16 mgmt_type;
620
621         if (!wdev->wiphy->mgmt_stypes)
622                 return -EOPNOTSUPP;
623
624         if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
625                 return -EINVAL;
626
627         if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
628                 return -EINVAL;
629
630         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
631         if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
632                 return -EINVAL;
633
634         nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
635         if (!nreg)
636                 return -ENOMEM;
637
638         spin_lock_bh(&wdev->mgmt_registrations_lock);
639
640         list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
641                 int mlen = min(match_len, reg->match_len);
642
643                 if (frame_type != le16_to_cpu(reg->frame_type))
644                         continue;
645
646                 if (memcmp(reg->match, match_data, mlen) == 0) {
647                         err = -EALREADY;
648                         break;
649                 }
650         }
651
652         if (err) {
653                 kfree(nreg);
654                 goto out;
655         }
656
657         memcpy(nreg->match, match_data, match_len);
658         nreg->match_len = match_len;
659         nreg->nlpid = snd_pid;
660         nreg->frame_type = cpu_to_le16(frame_type);
661         list_add(&nreg->list, &wdev->mgmt_registrations);
662
663         if (rdev->ops->mgmt_frame_register)
664                 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
665                                                frame_type, true);
666
667  out:
668         spin_unlock_bh(&wdev->mgmt_registrations_lock);
669
670         return err;
671 }
672
673 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
674 {
675         struct wiphy *wiphy = wdev->wiphy;
676         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
677         struct cfg80211_mgmt_registration *reg, *tmp;
678
679         spin_lock_bh(&wdev->mgmt_registrations_lock);
680
681         list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
682                 if (reg->nlpid != nlpid)
683                         continue;
684
685                 if (rdev->ops->mgmt_frame_register) {
686                         u16 frame_type = le16_to_cpu(reg->frame_type);
687
688                         rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
689                                                        frame_type, false);
690                 }
691
692                 list_del(&reg->list);
693                 kfree(reg);
694         }
695
696         spin_unlock_bh(&wdev->mgmt_registrations_lock);
697
698         if (nlpid == wdev->ap_unexpected_nlpid)
699                 wdev->ap_unexpected_nlpid = 0;
700 }
701
702 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
703 {
704         struct cfg80211_mgmt_registration *reg, *tmp;
705
706         spin_lock_bh(&wdev->mgmt_registrations_lock);
707
708         list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
709                 list_del(&reg->list);
710                 kfree(reg);
711         }
712
713         spin_unlock_bh(&wdev->mgmt_registrations_lock);
714 }
715
716 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
717                           struct net_device *dev,
718                           struct ieee80211_channel *chan, bool offchan,
719                           enum nl80211_channel_type channel_type,
720                           bool channel_type_valid, unsigned int wait,
721                           const u8 *buf, size_t len, bool no_cck,
722                           bool dont_wait_for_ack, u64 *cookie)
723 {
724         struct wireless_dev *wdev = dev->ieee80211_ptr;
725         const struct ieee80211_mgmt *mgmt;
726         u16 stype;
727
728         if (!wdev->wiphy->mgmt_stypes)
729                 return -EOPNOTSUPP;
730
731         if (!rdev->ops->mgmt_tx)
732                 return -EOPNOTSUPP;
733
734         if (len < 24 + 1)
735                 return -EINVAL;
736
737         mgmt = (const struct ieee80211_mgmt *) buf;
738
739         if (!ieee80211_is_mgmt(mgmt->frame_control))
740                 return -EINVAL;
741
742         stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
743         if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
744                 return -EINVAL;
745
746         if (ieee80211_is_action(mgmt->frame_control) &&
747             mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
748                 int err = 0;
749
750                 wdev_lock(wdev);
751
752                 switch (wdev->iftype) {
753                 case NL80211_IFTYPE_ADHOC:
754                 case NL80211_IFTYPE_STATION:
755                 case NL80211_IFTYPE_P2P_CLIENT:
756                         if (!wdev->current_bss) {
757                                 err = -ENOTCONN;
758                                 break;
759                         }
760
761                         if (memcmp(wdev->current_bss->pub.bssid,
762                                    mgmt->bssid, ETH_ALEN)) {
763                                 err = -ENOTCONN;
764                                 break;
765                         }
766
767                         /*
768                          * check for IBSS DA must be done by driver as
769                          * cfg80211 doesn't track the stations
770                          */
771                         if (wdev->iftype == NL80211_IFTYPE_ADHOC)
772                                 break;
773
774                         /* for station, check that DA is the AP */
775                         if (memcmp(wdev->current_bss->pub.bssid,
776                                    mgmt->da, ETH_ALEN)) {
777                                 err = -ENOTCONN;
778                                 break;
779                         }
780                         break;
781                 case NL80211_IFTYPE_AP:
782                 case NL80211_IFTYPE_P2P_GO:
783                 case NL80211_IFTYPE_AP_VLAN:
784                         if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
785                                 err = -EINVAL;
786                         break;
787                 case NL80211_IFTYPE_MESH_POINT:
788                         if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) {
789                                 err = -EINVAL;
790                                 break;
791                         }
792                         /*
793                          * check for mesh DA must be done by driver as
794                          * cfg80211 doesn't track the stations
795                          */
796                         break;
797                 default:
798                         err = -EOPNOTSUPP;
799                         break;
800                 }
801                 wdev_unlock(wdev);
802
803                 if (err)
804                         return err;
805         }
806
807         if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
808                 return -EINVAL;
809
810         /* Transmit the Action frame as requested by user space */
811         return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
812                                   channel_type, channel_type_valid,
813                                   wait, buf, len, no_cck, dont_wait_for_ack,
814                                   cookie);
815 }
816
817 bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm,
818                       const u8 *buf, size_t len, gfp_t gfp)
819 {
820         struct wireless_dev *wdev = dev->ieee80211_ptr;
821         struct wiphy *wiphy = wdev->wiphy;
822         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
823         struct cfg80211_mgmt_registration *reg;
824         const struct ieee80211_txrx_stypes *stypes =
825                 &wiphy->mgmt_stypes[wdev->iftype];
826         struct ieee80211_mgmt *mgmt = (void *)buf;
827         const u8 *data;
828         int data_len;
829         bool result = false;
830         __le16 ftype = mgmt->frame_control &
831                 cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
832         u16 stype;
833
834         stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
835
836         if (!(stypes->rx & BIT(stype)))
837                 return false;
838
839         data = buf + ieee80211_hdrlen(mgmt->frame_control);
840         data_len = len - ieee80211_hdrlen(mgmt->frame_control);
841
842         spin_lock_bh(&wdev->mgmt_registrations_lock);
843
844         list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
845                 if (reg->frame_type != ftype)
846                         continue;
847
848                 if (reg->match_len > data_len)
849                         continue;
850
851                 if (memcmp(reg->match, data, reg->match_len))
852                         continue;
853
854                 /* found match! */
855
856                 /* Indicate the received Action frame to user space */
857                 if (nl80211_send_mgmt(rdev, dev, reg->nlpid,
858                                       freq, sig_mbm,
859                                       buf, len, gfp))
860                         continue;
861
862                 result = true;
863                 break;
864         }
865
866         spin_unlock_bh(&wdev->mgmt_registrations_lock);
867
868         return result;
869 }
870 EXPORT_SYMBOL(cfg80211_rx_mgmt);
871
872 void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie,
873                              const u8 *buf, size_t len, bool ack, gfp_t gfp)
874 {
875         struct wireless_dev *wdev = dev->ieee80211_ptr;
876         struct wiphy *wiphy = wdev->wiphy;
877         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
878
879         /* Indicate TX status of the Action frame to user space */
880         nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
881 }
882 EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
883
884 void cfg80211_cqm_rssi_notify(struct net_device *dev,
885                               enum nl80211_cqm_rssi_threshold_event rssi_event,
886                               gfp_t gfp)
887 {
888         struct wireless_dev *wdev = dev->ieee80211_ptr;
889         struct wiphy *wiphy = wdev->wiphy;
890         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
891
892         /* Indicate roaming trigger event to user space */
893         nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
894 }
895 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
896
897 void cfg80211_cqm_pktloss_notify(struct net_device *dev,
898                                  const u8 *peer, u32 num_packets, gfp_t gfp)
899 {
900         struct wireless_dev *wdev = dev->ieee80211_ptr;
901         struct wiphy *wiphy = wdev->wiphy;
902         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
903
904         /* Indicate roaming trigger event to user space */
905         nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
906 }
907 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
908
909 void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
910                                const u8 *replay_ctr, gfp_t gfp)
911 {
912         struct wireless_dev *wdev = dev->ieee80211_ptr;
913         struct wiphy *wiphy = wdev->wiphy;
914         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
915
916         nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
917 }
918 EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
919
920 void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
921                                      const u8 *bssid, bool preauth, gfp_t gfp)
922 {
923         struct wireless_dev *wdev = dev->ieee80211_ptr;
924         struct wiphy *wiphy = wdev->wiphy;
925         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
926
927         nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
928 }
929 EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
930
931 bool cfg80211_rx_spurious_frame(struct net_device *dev,
932                                 const u8 *addr, gfp_t gfp)
933 {
934         struct wireless_dev *wdev = dev->ieee80211_ptr;
935
936         if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
937                     wdev->iftype != NL80211_IFTYPE_P2P_GO))
938                 return false;
939
940         return nl80211_unexpected_frame(dev, addr, gfp);
941 }
942 EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
943
944 bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
945                                         const u8 *addr, gfp_t gfp)
946 {
947         struct wireless_dev *wdev = dev->ieee80211_ptr;
948
949         if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
950                     wdev->iftype != NL80211_IFTYPE_P2P_GO &&
951                     wdev->iftype != NL80211_IFTYPE_AP_VLAN))
952                 return false;
953
954         return nl80211_unexpected_4addr_frame(dev, addr, gfp);
955 }
956 EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);