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