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
21void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
22			    const u8 *buf, size_t len, int uapsd_queues)
23{
24	struct wireless_dev *wdev = dev->ieee80211_ptr;
25	struct wiphy *wiphy = wdev->wiphy;
26	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
27	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
28	u8 *ie = mgmt->u.assoc_resp.variable;
29	int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
30	u16 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
31
32	trace_cfg80211_send_rx_assoc(dev, bss);
33
34	/*
35	 * This is a bit of a hack, we don't notify userspace of
36	 * a (re-)association reply if we tried to send a reassoc
37	 * and got a reject -- we only try again with an assoc
38	 * frame instead of reassoc.
39	 */
40	if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
41		cfg80211_unhold_bss(bss_from_pub(bss));
42		cfg80211_put_bss(wiphy, bss);
43		return;
44	}
45
46	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);
47	/* update current_bss etc., consumes the bss reference */
48	__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
49				  status_code,
50				  status_code == WLAN_STATUS_SUCCESS, bss);
51}
52EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
53
54static void cfg80211_process_auth(struct wireless_dev *wdev,
55				  const u8 *buf, size_t len)
56{
57	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
58
59	nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
60	cfg80211_sme_rx_auth(wdev, buf, len);
61}
62
63static void cfg80211_process_deauth(struct wireless_dev *wdev,
64				    const u8 *buf, size_t len)
65{
66	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
67	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
68	const u8 *bssid = mgmt->bssid;
69	u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
70	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
71
72	nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
73
74	if (!wdev->current_bss ||
75	    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
76		return;
77
78	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
79	cfg80211_sme_deauth(wdev);
80}
81
82static void cfg80211_process_disassoc(struct wireless_dev *wdev,
83				      const u8 *buf, size_t len)
84{
85	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
86	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
87	const u8 *bssid = mgmt->bssid;
88	u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
89	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
90
91	nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
92
93	if (WARN_ON(!wdev->current_bss ||
94		    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
95		return;
96
97	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
98	cfg80211_sme_disassoc(wdev);
99}
100
101void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
102{
103	struct wireless_dev *wdev = dev->ieee80211_ptr;
104	struct ieee80211_mgmt *mgmt = (void *)buf;
105
106	ASSERT_WDEV_LOCK(wdev);
107
108	trace_cfg80211_rx_mlme_mgmt(dev, buf, len);
109
110	if (WARN_ON(len < 2))
111		return;
112
113	if (ieee80211_is_auth(mgmt->frame_control))
114		cfg80211_process_auth(wdev, buf, len);
115	else if (ieee80211_is_deauth(mgmt->frame_control))
116		cfg80211_process_deauth(wdev, buf, len);
117	else if (ieee80211_is_disassoc(mgmt->frame_control))
118		cfg80211_process_disassoc(wdev, buf, len);
119}
120EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
121
122void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
123{
124	struct wireless_dev *wdev = dev->ieee80211_ptr;
125	struct wiphy *wiphy = wdev->wiphy;
126	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
127
128	trace_cfg80211_send_auth_timeout(dev, addr);
129
130	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
131	cfg80211_sme_auth_timeout(wdev);
132}
133EXPORT_SYMBOL(cfg80211_auth_timeout);
134
135void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
136{
137	struct wireless_dev *wdev = dev->ieee80211_ptr;
138	struct wiphy *wiphy = wdev->wiphy;
139	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
140
141	trace_cfg80211_send_assoc_timeout(dev, bss->bssid);
142
143	nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
144	cfg80211_sme_assoc_timeout(wdev);
145
146	cfg80211_unhold_bss(bss_from_pub(bss));
147	cfg80211_put_bss(wiphy, bss);
148}
149EXPORT_SYMBOL(cfg80211_assoc_timeout);
150
151void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
152{
153	struct wireless_dev *wdev = dev->ieee80211_ptr;
154	struct ieee80211_mgmt *mgmt = (void *)buf;
155
156	ASSERT_WDEV_LOCK(wdev);
157
158	trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
159
160	if (WARN_ON(len < 2))
161		return;
162
163	if (ieee80211_is_deauth(mgmt->frame_control))
164		cfg80211_process_deauth(wdev, buf, len);
165	else
166		cfg80211_process_disassoc(wdev, buf, len);
167}
168EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
169
170void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
171				  enum nl80211_key_type key_type, int key_id,
172				  const u8 *tsc, gfp_t gfp)
173{
174	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
175	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
176#ifdef CONFIG_CFG80211_WEXT
177	union iwreq_data wrqu;
178	char *buf = kmalloc(128, gfp);
179
180	if (buf) {
181		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
182			"keyid=%d %scast addr=%pM)", key_id,
183			key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
184			addr);
185		memset(&wrqu, 0, sizeof(wrqu));
186		wrqu.data.length = strlen(buf);
187		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
188		kfree(buf);
189	}
190#endif
191
192	trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
193	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
194}
195EXPORT_SYMBOL(cfg80211_michael_mic_failure);
196
197/* some MLME handling for userspace SME */
198int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
199		       struct net_device *dev,
200		       struct ieee80211_channel *chan,
201		       enum nl80211_auth_type auth_type,
202		       const u8 *bssid,
203		       const u8 *ssid, int ssid_len,
204		       const u8 *ie, int ie_len,
205		       const u8 *key, int key_len, int key_idx,
206		       const u8 *sae_data, int sae_data_len)
207{
208	struct wireless_dev *wdev = dev->ieee80211_ptr;
209	struct cfg80211_auth_request req = {
210		.ie = ie,
211		.ie_len = ie_len,
212		.sae_data = sae_data,
213		.sae_data_len = sae_data_len,
214		.auth_type = auth_type,
215		.key = key,
216		.key_len = key_len,
217		.key_idx = key_idx,
218	};
219	int err;
220
221	ASSERT_WDEV_LOCK(wdev);
222
223	if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
224		if (!key || !key_len || key_idx < 0 || key_idx > 4)
225			return -EINVAL;
226
227	if (wdev->current_bss &&
228	    ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
229		return -EALREADY;
230
231	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
232				   IEEE80211_BSS_TYPE_ESS,
233				   IEEE80211_PRIVACY_ANY);
234	if (!req.bss)
235		return -ENOENT;
236
237	err = rdev_auth(rdev, dev, &req);
238
239	cfg80211_put_bss(&rdev->wiphy, req.bss);
240	return err;
241}
242
243/*  Do a logical ht_capa &= ht_capa_mask.  */
244void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
245			       const struct ieee80211_ht_cap *ht_capa_mask)
246{
247	int i;
248	u8 *p1, *p2;
249	if (!ht_capa_mask) {
250		memset(ht_capa, 0, sizeof(*ht_capa));
251		return;
252	}
253
254	p1 = (u8*)(ht_capa);
255	p2 = (u8*)(ht_capa_mask);
256	for (i = 0; i<sizeof(*ht_capa); i++)
257		p1[i] &= p2[i];
258}
259
260/*  Do a logical ht_capa &= ht_capa_mask.  */
261void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
262				const struct ieee80211_vht_cap *vht_capa_mask)
263{
264	int i;
265	u8 *p1, *p2;
266	if (!vht_capa_mask) {
267		memset(vht_capa, 0, sizeof(*vht_capa));
268		return;
269	}
270
271	p1 = (u8*)(vht_capa);
272	p2 = (u8*)(vht_capa_mask);
273	for (i = 0; i < sizeof(*vht_capa); i++)
274		p1[i] &= p2[i];
275}
276
277int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
278			struct net_device *dev,
279			struct ieee80211_channel *chan,
280			const u8 *bssid,
281			const u8 *ssid, int ssid_len,
282			struct cfg80211_assoc_request *req)
283{
284	struct wireless_dev *wdev = dev->ieee80211_ptr;
285	int err;
286
287	ASSERT_WDEV_LOCK(wdev);
288
289	if (wdev->current_bss &&
290	    (!req->prev_bssid || !ether_addr_equal(wdev->current_bss->pub.bssid,
291						   req->prev_bssid)))
292		return -EALREADY;
293
294	cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
295				  rdev->wiphy.ht_capa_mod_mask);
296	cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
297				   rdev->wiphy.vht_capa_mod_mask);
298
299	req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
300				    IEEE80211_BSS_TYPE_ESS,
301				    IEEE80211_PRIVACY_ANY);
302	if (!req->bss)
303		return -ENOENT;
304
305	err = rdev_assoc(rdev, dev, req);
306	if (!err)
307		cfg80211_hold_bss(bss_from_pub(req->bss));
308	else
309		cfg80211_put_bss(&rdev->wiphy, req->bss);
310
311	return err;
312}
313
314int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
315			 struct net_device *dev, const u8 *bssid,
316			 const u8 *ie, int ie_len, u16 reason,
317			 bool local_state_change)
318{
319	struct wireless_dev *wdev = dev->ieee80211_ptr;
320	struct cfg80211_deauth_request req = {
321		.bssid = bssid,
322		.reason_code = reason,
323		.ie = ie,
324		.ie_len = ie_len,
325		.local_state_change = local_state_change,
326	};
327
328	ASSERT_WDEV_LOCK(wdev);
329
330	if (local_state_change &&
331	    (!wdev->current_bss ||
332	     !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
333		return 0;
334
335	return rdev_deauth(rdev, dev, &req);
336}
337
338int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
339			   struct net_device *dev, const u8 *bssid,
340			   const u8 *ie, int ie_len, u16 reason,
341			   bool local_state_change)
342{
343	struct wireless_dev *wdev = dev->ieee80211_ptr;
344	struct cfg80211_disassoc_request req = {
345		.reason_code = reason,
346		.local_state_change = local_state_change,
347		.ie = ie,
348		.ie_len = ie_len,
349	};
350	int err;
351
352	ASSERT_WDEV_LOCK(wdev);
353
354	if (!wdev->current_bss)
355		return -ENOTCONN;
356
357	if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
358		req.bss = &wdev->current_bss->pub;
359	else
360		return -ENOTCONN;
361
362	err = rdev_disassoc(rdev, dev, &req);
363	if (err)
364		return err;
365
366	/* driver should have reported the disassoc */
367	WARN_ON(wdev->current_bss);
368	return 0;
369}
370
371void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
372			struct net_device *dev)
373{
374	struct wireless_dev *wdev = dev->ieee80211_ptr;
375	u8 bssid[ETH_ALEN];
376
377	ASSERT_WDEV_LOCK(wdev);
378
379	if (!rdev->ops->deauth)
380		return;
381
382	if (!wdev->current_bss)
383		return;
384
385	memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
386	cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
387			     WLAN_REASON_DEAUTH_LEAVING, false);
388}
389
390struct cfg80211_mgmt_registration {
391	struct list_head list;
392
393	u32 nlportid;
394
395	int match_len;
396
397	__le16 frame_type;
398
399	u8 match[];
400};
401
402int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
403				u16 frame_type, const u8 *match_data,
404				int match_len)
405{
406	struct wiphy *wiphy = wdev->wiphy;
407	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
408	struct cfg80211_mgmt_registration *reg, *nreg;
409	int err = 0;
410	u16 mgmt_type;
411
412	if (!wdev->wiphy->mgmt_stypes)
413		return -EOPNOTSUPP;
414
415	if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
416		return -EINVAL;
417
418	if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
419		return -EINVAL;
420
421	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
422	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
423		return -EINVAL;
424
425	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
426	if (!nreg)
427		return -ENOMEM;
428
429	spin_lock_bh(&wdev->mgmt_registrations_lock);
430
431	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
432		int mlen = min(match_len, reg->match_len);
433
434		if (frame_type != le16_to_cpu(reg->frame_type))
435			continue;
436
437		if (memcmp(reg->match, match_data, mlen) == 0) {
438			err = -EALREADY;
439			break;
440		}
441	}
442
443	if (err) {
444		kfree(nreg);
445		goto out;
446	}
447
448	memcpy(nreg->match, match_data, match_len);
449	nreg->match_len = match_len;
450	nreg->nlportid = snd_portid;
451	nreg->frame_type = cpu_to_le16(frame_type);
452	list_add(&nreg->list, &wdev->mgmt_registrations);
453
454	if (rdev->ops->mgmt_frame_register)
455		rdev_mgmt_frame_register(rdev, wdev, frame_type, true);
456
457 out:
458	spin_unlock_bh(&wdev->mgmt_registrations_lock);
459
460	return err;
461}
462
463void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
464{
465	struct wiphy *wiphy = wdev->wiphy;
466	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
467	struct cfg80211_mgmt_registration *reg, *tmp;
468
469	spin_lock_bh(&wdev->mgmt_registrations_lock);
470
471	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
472		if (reg->nlportid != nlportid)
473			continue;
474
475		if (rdev->ops->mgmt_frame_register) {
476			u16 frame_type = le16_to_cpu(reg->frame_type);
477
478			rdev_mgmt_frame_register(rdev, wdev,
479						 frame_type, false);
480		}
481
482		list_del(&reg->list);
483		kfree(reg);
484	}
485
486	spin_unlock_bh(&wdev->mgmt_registrations_lock);
487
488	if (nlportid && rdev->crit_proto_nlportid == nlportid) {
489		rdev->crit_proto_nlportid = 0;
490		rdev_crit_proto_stop(rdev, wdev);
491	}
492
493	if (nlportid == wdev->ap_unexpected_nlportid)
494		wdev->ap_unexpected_nlportid = 0;
495}
496
497void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
498{
499	struct cfg80211_mgmt_registration *reg, *tmp;
500
501	spin_lock_bh(&wdev->mgmt_registrations_lock);
502
503	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
504		list_del(&reg->list);
505		kfree(reg);
506	}
507
508	spin_unlock_bh(&wdev->mgmt_registrations_lock);
509}
510
511int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
512			  struct wireless_dev *wdev,
513			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
514{
515	const struct ieee80211_mgmt *mgmt;
516	u16 stype;
517
518	if (!wdev->wiphy->mgmt_stypes)
519		return -EOPNOTSUPP;
520
521	if (!rdev->ops->mgmt_tx)
522		return -EOPNOTSUPP;
523
524	if (params->len < 24 + 1)
525		return -EINVAL;
526
527	mgmt = (const struct ieee80211_mgmt *)params->buf;
528
529	if (!ieee80211_is_mgmt(mgmt->frame_control))
530		return -EINVAL;
531
532	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
533	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
534		return -EINVAL;
535
536	if (ieee80211_is_action(mgmt->frame_control) &&
537	    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
538		int err = 0;
539
540		wdev_lock(wdev);
541
542		switch (wdev->iftype) {
543		case NL80211_IFTYPE_ADHOC:
544		case NL80211_IFTYPE_STATION:
545		case NL80211_IFTYPE_P2P_CLIENT:
546			if (!wdev->current_bss) {
547				err = -ENOTCONN;
548				break;
549			}
550
551			if (!ether_addr_equal(wdev->current_bss->pub.bssid,
552					      mgmt->bssid)) {
553				err = -ENOTCONN;
554				break;
555			}
556
557			/*
558			 * check for IBSS DA must be done by driver as
559			 * cfg80211 doesn't track the stations
560			 */
561			if (wdev->iftype == NL80211_IFTYPE_ADHOC)
562				break;
563
564			/* for station, check that DA is the AP */
565			if (!ether_addr_equal(wdev->current_bss->pub.bssid,
566					      mgmt->da)) {
567				err = -ENOTCONN;
568				break;
569			}
570			break;
571		case NL80211_IFTYPE_AP:
572		case NL80211_IFTYPE_P2P_GO:
573		case NL80211_IFTYPE_AP_VLAN:
574			if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)))
575				err = -EINVAL;
576			break;
577		case NL80211_IFTYPE_MESH_POINT:
578			if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
579				err = -EINVAL;
580				break;
581			}
582			/*
583			 * check for mesh DA must be done by driver as
584			 * cfg80211 doesn't track the stations
585			 */
586			break;
587		case NL80211_IFTYPE_P2P_DEVICE:
588			/*
589			 * fall through, P2P device only supports
590			 * public action frames
591			 */
592		default:
593			err = -EOPNOTSUPP;
594			break;
595		}
596		wdev_unlock(wdev);
597
598		if (err)
599			return err;
600	}
601
602	if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
603		return -EINVAL;
604
605	/* Transmit the Action frame as requested by user space */
606	return rdev_mgmt_tx(rdev, wdev, params, cookie);
607}
608
609bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
610		      const u8 *buf, size_t len, u32 flags)
611{
612	struct wiphy *wiphy = wdev->wiphy;
613	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
614	struct cfg80211_mgmt_registration *reg;
615	const struct ieee80211_txrx_stypes *stypes =
616		&wiphy->mgmt_stypes[wdev->iftype];
617	struct ieee80211_mgmt *mgmt = (void *)buf;
618	const u8 *data;
619	int data_len;
620	bool result = false;
621	__le16 ftype = mgmt->frame_control &
622		cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
623	u16 stype;
624
625	trace_cfg80211_rx_mgmt(wdev, freq, sig_mbm);
626	stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
627
628	if (!(stypes->rx & BIT(stype))) {
629		trace_cfg80211_return_bool(false);
630		return false;
631	}
632
633	data = buf + ieee80211_hdrlen(mgmt->frame_control);
634	data_len = len - ieee80211_hdrlen(mgmt->frame_control);
635
636	spin_lock_bh(&wdev->mgmt_registrations_lock);
637
638	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
639		if (reg->frame_type != ftype)
640			continue;
641
642		if (reg->match_len > data_len)
643			continue;
644
645		if (memcmp(reg->match, data, reg->match_len))
646			continue;
647
648		/* found match! */
649
650		/* Indicate the received Action frame to user space */
651		if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
652				      freq, sig_mbm,
653				      buf, len, flags, GFP_ATOMIC))
654			continue;
655
656		result = true;
657		break;
658	}
659
660	spin_unlock_bh(&wdev->mgmt_registrations_lock);
661
662	trace_cfg80211_return_bool(result);
663	return result;
664}
665EXPORT_SYMBOL(cfg80211_rx_mgmt);
666
667void cfg80211_dfs_channels_update_work(struct work_struct *work)
668{
669	struct delayed_work *delayed_work;
670	struct cfg80211_registered_device *rdev;
671	struct cfg80211_chan_def chandef;
672	struct ieee80211_supported_band *sband;
673	struct ieee80211_channel *c;
674	struct wiphy *wiphy;
675	bool check_again = false;
676	unsigned long timeout, next_time = 0;
677	int bandid, i;
678
679	delayed_work = container_of(work, struct delayed_work, work);
680	rdev = container_of(delayed_work, struct cfg80211_registered_device,
681			    dfs_update_channels_wk);
682	wiphy = &rdev->wiphy;
683
684	rtnl_lock();
685	for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
686		sband = wiphy->bands[bandid];
687		if (!sband)
688			continue;
689
690		for (i = 0; i < sband->n_channels; i++) {
691			c = &sband->channels[i];
692
693			if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
694				continue;
695
696			timeout = c->dfs_state_entered + msecs_to_jiffies(
697					IEEE80211_DFS_MIN_NOP_TIME_MS);
698
699			if (time_after_eq(jiffies, timeout)) {
700				c->dfs_state = NL80211_DFS_USABLE;
701				c->dfs_state_entered = jiffies;
702
703				cfg80211_chandef_create(&chandef, c,
704							NL80211_CHAN_NO_HT);
705
706				nl80211_radar_notify(rdev, &chandef,
707						     NL80211_RADAR_NOP_FINISHED,
708						     NULL, GFP_ATOMIC);
709				continue;
710			}
711
712			if (!check_again)
713				next_time = timeout - jiffies;
714			else
715				next_time = min(next_time, timeout - jiffies);
716			check_again = true;
717		}
718	}
719	rtnl_unlock();
720
721	/* reschedule if there are other channels waiting to be cleared again */
722	if (check_again)
723		queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
724				   next_time);
725}
726
727
728void cfg80211_radar_event(struct wiphy *wiphy,
729			  struct cfg80211_chan_def *chandef,
730			  gfp_t gfp)
731{
732	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
733	unsigned long timeout;
734
735	trace_cfg80211_radar_event(wiphy, chandef);
736
737	/* only set the chandef supplied channel to unavailable, in
738	 * case the radar is detected on only one of multiple channels
739	 * spanned by the chandef.
740	 */
741	cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
742
743	timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
744	queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
745			   timeout);
746
747	nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
748}
749EXPORT_SYMBOL(cfg80211_radar_event);
750
751void cfg80211_cac_event(struct net_device *netdev,
752			const struct cfg80211_chan_def *chandef,
753			enum nl80211_radar_event event, gfp_t gfp)
754{
755	struct wireless_dev *wdev = netdev->ieee80211_ptr;
756	struct wiphy *wiphy = wdev->wiphy;
757	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
758	unsigned long timeout;
759
760	trace_cfg80211_cac_event(netdev, event);
761
762	if (WARN_ON(!wdev->cac_started))
763		return;
764
765	if (WARN_ON(!wdev->chandef.chan))
766		return;
767
768	switch (event) {
769	case NL80211_RADAR_CAC_FINISHED:
770		timeout = wdev->cac_start_time +
771			  msecs_to_jiffies(wdev->cac_time_ms);
772		WARN_ON(!time_after_eq(jiffies, timeout));
773		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
774		break;
775	case NL80211_RADAR_CAC_ABORTED:
776		break;
777	default:
778		WARN_ON(1);
779		return;
780	}
781	wdev->cac_started = false;
782
783	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
784}
785EXPORT_SYMBOL(cfg80211_cac_event);
786