cfg80211.c revision 5f68a2b0a890d086e40fc7b55f4a0c32c28bc0d2
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "cfg80211.h"
19#include "debug.h"
20#include "hif-ops.h"
21#include "testmode.h"
22
23static unsigned int ath6kl_p2p;
24
25module_param(ath6kl_p2p, uint, 0644);
26
27#define RATETAB_ENT(_rate, _rateid, _flags) {   \
28	.bitrate    = (_rate),                  \
29	.flags      = (_flags),                 \
30	.hw_value   = (_rateid),                \
31}
32
33#define CHAN2G(_channel, _freq, _flags) {   \
34	.band           = IEEE80211_BAND_2GHZ,  \
35	.hw_value       = (_channel),           \
36	.center_freq    = (_freq),              \
37	.flags          = (_flags),             \
38	.max_antenna_gain   = 0,                \
39	.max_power      = 30,                   \
40}
41
42#define CHAN5G(_channel, _flags) {		    \
43	.band           = IEEE80211_BAND_5GHZ,      \
44	.hw_value       = (_channel),               \
45	.center_freq    = 5000 + (5 * (_channel)),  \
46	.flags          = (_flags),                 \
47	.max_antenna_gain   = 0,                    \
48	.max_power      = 30,                       \
49}
50
51static struct ieee80211_rate ath6kl_rates[] = {
52	RATETAB_ENT(10, 0x1, 0),
53	RATETAB_ENT(20, 0x2, 0),
54	RATETAB_ENT(55, 0x4, 0),
55	RATETAB_ENT(110, 0x8, 0),
56	RATETAB_ENT(60, 0x10, 0),
57	RATETAB_ENT(90, 0x20, 0),
58	RATETAB_ENT(120, 0x40, 0),
59	RATETAB_ENT(180, 0x80, 0),
60	RATETAB_ENT(240, 0x100, 0),
61	RATETAB_ENT(360, 0x200, 0),
62	RATETAB_ENT(480, 0x400, 0),
63	RATETAB_ENT(540, 0x800, 0),
64};
65
66#define ath6kl_a_rates     (ath6kl_rates + 4)
67#define ath6kl_a_rates_size    8
68#define ath6kl_g_rates     (ath6kl_rates + 0)
69#define ath6kl_g_rates_size    12
70
71static struct ieee80211_channel ath6kl_2ghz_channels[] = {
72	CHAN2G(1, 2412, 0),
73	CHAN2G(2, 2417, 0),
74	CHAN2G(3, 2422, 0),
75	CHAN2G(4, 2427, 0),
76	CHAN2G(5, 2432, 0),
77	CHAN2G(6, 2437, 0),
78	CHAN2G(7, 2442, 0),
79	CHAN2G(8, 2447, 0),
80	CHAN2G(9, 2452, 0),
81	CHAN2G(10, 2457, 0),
82	CHAN2G(11, 2462, 0),
83	CHAN2G(12, 2467, 0),
84	CHAN2G(13, 2472, 0),
85	CHAN2G(14, 2484, 0),
86};
87
88static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
89	CHAN5G(34, 0), CHAN5G(36, 0),
90	CHAN5G(38, 0), CHAN5G(40, 0),
91	CHAN5G(42, 0), CHAN5G(44, 0),
92	CHAN5G(46, 0), CHAN5G(48, 0),
93	CHAN5G(52, 0), CHAN5G(56, 0),
94	CHAN5G(60, 0), CHAN5G(64, 0),
95	CHAN5G(100, 0), CHAN5G(104, 0),
96	CHAN5G(108, 0), CHAN5G(112, 0),
97	CHAN5G(116, 0), CHAN5G(120, 0),
98	CHAN5G(124, 0), CHAN5G(128, 0),
99	CHAN5G(132, 0), CHAN5G(136, 0),
100	CHAN5G(140, 0), CHAN5G(149, 0),
101	CHAN5G(153, 0), CHAN5G(157, 0),
102	CHAN5G(161, 0), CHAN5G(165, 0),
103	CHAN5G(184, 0), CHAN5G(188, 0),
104	CHAN5G(192, 0), CHAN5G(196, 0),
105	CHAN5G(200, 0), CHAN5G(204, 0),
106	CHAN5G(208, 0), CHAN5G(212, 0),
107	CHAN5G(216, 0),
108};
109
110static struct ieee80211_supported_band ath6kl_band_2ghz = {
111	.n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
112	.channels = ath6kl_2ghz_channels,
113	.n_bitrates = ath6kl_g_rates_size,
114	.bitrates = ath6kl_g_rates,
115};
116
117static struct ieee80211_supported_band ath6kl_band_5ghz = {
118	.n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
119	.channels = ath6kl_5ghz_a_channels,
120	.n_bitrates = ath6kl_a_rates_size,
121	.bitrates = ath6kl_a_rates,
122};
123
124static int ath6kl_set_wpa_version(struct ath6kl *ar,
125				  enum nl80211_wpa_versions wpa_version)
126{
127	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
128
129	if (!wpa_version) {
130		ar->auth_mode = NONE_AUTH;
131	} else if (wpa_version & NL80211_WPA_VERSION_2) {
132		ar->auth_mode = WPA2_AUTH;
133	} else if (wpa_version & NL80211_WPA_VERSION_1) {
134		ar->auth_mode = WPA_AUTH;
135	} else {
136		ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
137		return -ENOTSUPP;
138	}
139
140	return 0;
141}
142
143static int ath6kl_set_auth_type(struct ath6kl *ar,
144				enum nl80211_auth_type auth_type)
145{
146
147	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
148
149	switch (auth_type) {
150	case NL80211_AUTHTYPE_OPEN_SYSTEM:
151		ar->dot11_auth_mode = OPEN_AUTH;
152		break;
153	case NL80211_AUTHTYPE_SHARED_KEY:
154		ar->dot11_auth_mode = SHARED_AUTH;
155		break;
156	case NL80211_AUTHTYPE_NETWORK_EAP:
157		ar->dot11_auth_mode = LEAP_AUTH;
158		break;
159
160	case NL80211_AUTHTYPE_AUTOMATIC:
161		ar->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
162		break;
163
164	default:
165		ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
166		return -ENOTSUPP;
167	}
168
169	return 0;
170}
171
172static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
173{
174	u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
175	u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len :
176		&ar->grp_crypto_len;
177
178	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
179		   __func__, cipher, ucast);
180
181	switch (cipher) {
182	case 0:
183		/* our own hack to use value 0 as no crypto used */
184		*ar_cipher = NONE_CRYPT;
185		*ar_cipher_len = 0;
186		break;
187	case WLAN_CIPHER_SUITE_WEP40:
188		*ar_cipher = WEP_CRYPT;
189		*ar_cipher_len = 5;
190		break;
191	case WLAN_CIPHER_SUITE_WEP104:
192		*ar_cipher = WEP_CRYPT;
193		*ar_cipher_len = 13;
194		break;
195	case WLAN_CIPHER_SUITE_TKIP:
196		*ar_cipher = TKIP_CRYPT;
197		*ar_cipher_len = 0;
198		break;
199	case WLAN_CIPHER_SUITE_CCMP:
200		*ar_cipher = AES_CRYPT;
201		*ar_cipher_len = 0;
202		break;
203	default:
204		ath6kl_err("cipher 0x%x not supported\n", cipher);
205		return -ENOTSUPP;
206	}
207
208	return 0;
209}
210
211static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
212{
213	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
214
215	if (key_mgmt == WLAN_AKM_SUITE_PSK) {
216		if (ar->auth_mode == WPA_AUTH)
217			ar->auth_mode = WPA_PSK_AUTH;
218		else if (ar->auth_mode == WPA2_AUTH)
219			ar->auth_mode = WPA2_PSK_AUTH;
220	} else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
221		ar->auth_mode = NONE_AUTH;
222	}
223}
224
225static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
226{
227	if (!test_bit(WMI_READY, &ar->flag)) {
228		ath6kl_err("wmi is not ready\n");
229		return false;
230	}
231
232	if (!test_bit(WLAN_ENABLED, &ar->flag)) {
233		ath6kl_err("wlan disabled\n");
234		return false;
235	}
236
237	return true;
238}
239
240static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
241				   struct cfg80211_connect_params *sme)
242{
243	struct ath6kl *ar = ath6kl_priv(dev);
244	int status;
245
246	ar->sme_state = SME_CONNECTING;
247
248	if (!ath6kl_cfg80211_ready(ar))
249		return -EIO;
250
251	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
252		ath6kl_err("destroy in progress\n");
253		return -EBUSY;
254	}
255
256	if (test_bit(SKIP_SCAN, &ar->flag) &&
257	    ((sme->channel && sme->channel->center_freq == 0) ||
258	     (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
259		ath6kl_err("SkipScan: channel or bssid invalid\n");
260		return -EINVAL;
261	}
262
263	if (down_interruptible(&ar->sem)) {
264		ath6kl_err("busy, couldn't get access\n");
265		return -ERESTARTSYS;
266	}
267
268	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
269		ath6kl_err("busy, destroy in progress\n");
270		up(&ar->sem);
271		return -EBUSY;
272	}
273
274	if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
275		/*
276		 * sleep until the command queue drains
277		 */
278		wait_event_interruptible_timeout(ar->event_wq,
279			ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
280			WMI_TIMEOUT);
281		if (signal_pending(current)) {
282			ath6kl_err("cmd queue drain timeout\n");
283			up(&ar->sem);
284			return -EINTR;
285		}
286	}
287
288	if (test_bit(CONNECTED, &ar->flag) &&
289	    ar->ssid_len == sme->ssid_len &&
290	    !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
291		ar->reconnect_flag = true;
292		status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
293						  ar->ch_hint);
294
295		up(&ar->sem);
296		if (status) {
297			ath6kl_err("wmi_reconnect_cmd failed\n");
298			return -EIO;
299		}
300		return 0;
301	} else if (ar->ssid_len == sme->ssid_len &&
302		   !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
303		ath6kl_disconnect(ar);
304	}
305
306	memset(ar->ssid, 0, sizeof(ar->ssid));
307	ar->ssid_len = sme->ssid_len;
308	memcpy(ar->ssid, sme->ssid, sme->ssid_len);
309
310	if (sme->channel)
311		ar->ch_hint = sme->channel->center_freq;
312
313	memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
314	if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
315		memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
316
317	ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
318
319	status = ath6kl_set_auth_type(ar, sme->auth_type);
320	if (status) {
321		up(&ar->sem);
322		return status;
323	}
324
325	if (sme->crypto.n_ciphers_pairwise)
326		ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
327	else
328		ath6kl_set_cipher(ar, 0, true);
329
330	ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
331
332	if (sme->crypto.n_akm_suites)
333		ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
334
335	if ((sme->key_len) &&
336	    (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
337		struct ath6kl_key *key = NULL;
338
339		if (sme->key_idx < WMI_MIN_KEY_INDEX ||
340		    sme->key_idx > WMI_MAX_KEY_INDEX) {
341			ath6kl_err("key index %d out of bounds\n",
342				   sme->key_idx);
343			up(&ar->sem);
344			return -ENOENT;
345		}
346
347		key = &ar->keys[sme->key_idx];
348		key->key_len = sme->key_len;
349		memcpy(key->key, sme->key, key->key_len);
350		key->cipher = ar->prwise_crypto;
351		ar->def_txkey_index = sme->key_idx;
352
353		ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
354				      ar->prwise_crypto,
355				      GROUP_USAGE | TX_USAGE,
356				      key->key_len,
357				      NULL,
358				      key->key, KEY_OP_INIT_VAL, NULL,
359				      NO_SYNC_WMIFLAG);
360	}
361
362	if (!ar->usr_bss_filter) {
363		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
364		if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
365			ath6kl_err("couldn't set bss filtering\n");
366			up(&ar->sem);
367			return -EIO;
368		}
369	}
370
371	ar->nw_type = ar->next_mode;
372
373	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
374		   "%s: connect called with authmode %d dot11 auth %d"
375		   " PW crypto %d PW crypto len %d GRP crypto %d"
376		   " GRP crypto len %d channel hint %u\n",
377		   __func__,
378		   ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
379		   ar->prwise_crypto_len, ar->grp_crypto,
380		   ar->grp_crypto_len, ar->ch_hint);
381
382	ar->reconnect_flag = 0;
383	status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
384					ar->dot11_auth_mode, ar->auth_mode,
385					ar->prwise_crypto,
386					ar->prwise_crypto_len,
387					ar->grp_crypto, ar->grp_crypto_len,
388					ar->ssid_len, ar->ssid,
389					ar->req_bssid, ar->ch_hint,
390					ar->connect_ctrl_flags);
391
392	up(&ar->sem);
393
394	if (status == -EINVAL) {
395		memset(ar->ssid, 0, sizeof(ar->ssid));
396		ar->ssid_len = 0;
397		ath6kl_err("invalid request\n");
398		return -ENOENT;
399	} else if (status) {
400		ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
401		return -EIO;
402	}
403
404	if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
405	    ((ar->auth_mode == WPA_PSK_AUTH)
406	     || (ar->auth_mode == WPA2_PSK_AUTH))) {
407		mod_timer(&ar->disconnect_timer,
408			  jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
409	}
410
411	ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
412	set_bit(CONNECT_PEND, &ar->flag);
413
414	return 0;
415}
416
417static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
418				    struct ieee80211_channel *chan,
419				    const u8 *beacon_ie, size_t beacon_ie_len)
420{
421	struct cfg80211_bss *bss;
422	u8 *ie;
423
424	bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid,
425			       ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
426			       WLAN_CAPABILITY_ESS);
427	if (bss == NULL) {
428		/*
429		 * Since cfg80211 may not yet know about the BSS,
430		 * generate a partial entry until the first BSS info
431		 * event becomes available.
432		 *
433		 * Prepend SSID element since it is not included in the Beacon
434		 * IEs from the target.
435		 */
436		ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL);
437		if (ie == NULL)
438			return -ENOMEM;
439		ie[0] = WLAN_EID_SSID;
440		ie[1] = ar->ssid_len;
441		memcpy(ie + 2, ar->ssid, ar->ssid_len);
442		memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
443		bss = cfg80211_inform_bss(ar->wdev->wiphy, chan,
444					  bssid, 0, WLAN_CAPABILITY_ESS, 100,
445					  ie, 2 + ar->ssid_len + beacon_ie_len,
446					  0, GFP_KERNEL);
447		if (bss)
448			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
449				   "%pM prior to indicating connect/roamed "
450				   "event\n", bssid);
451		kfree(ie);
452	} else
453		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
454			   "entry\n");
455
456	if (bss == NULL)
457		return -ENOMEM;
458
459	cfg80211_put_bss(bss);
460
461	return 0;
462}
463
464void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
465				   u8 *bssid, u16 listen_intvl,
466				   u16 beacon_intvl,
467				   enum network_type nw_type,
468				   u8 beacon_ie_len, u8 assoc_req_len,
469				   u8 assoc_resp_len, u8 *assoc_info)
470{
471	struct ieee80211_channel *chan;
472
473	/* capinfo + listen interval */
474	u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
475
476	/* capinfo + status code +  associd */
477	u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
478
479	u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
480	u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
481	    assoc_resp_ie_offset;
482
483	assoc_req_len -= assoc_req_ie_offset;
484	assoc_resp_len -= assoc_resp_ie_offset;
485
486	/*
487	 * Store Beacon interval here; DTIM period will be available only once
488	 * a Beacon frame from the AP is seen.
489	 */
490	ar->assoc_bss_beacon_int = beacon_intvl;
491	clear_bit(DTIM_PERIOD_AVAIL, &ar->flag);
492
493	if (nw_type & ADHOC_NETWORK) {
494		if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
495			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
496				   "%s: ath6k not in ibss mode\n", __func__);
497			return;
498		}
499	}
500
501	if (nw_type & INFRA_NETWORK) {
502		if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
503		    ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
504			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
505				   "%s: ath6k not in station mode\n", __func__);
506			return;
507		}
508	}
509
510	chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel);
511
512
513	if (nw_type & ADHOC_NETWORK) {
514		cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
515		return;
516	}
517
518	if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info,
519				     beacon_ie_len) < 0) {
520		ath6kl_err("could not add cfg80211 bss entry for "
521			   "connect/roamed notification\n");
522		return;
523	}
524
525	if (ar->sme_state == SME_CONNECTING) {
526		/* inform connect result to cfg80211 */
527		ar->sme_state = SME_CONNECTED;
528		cfg80211_connect_result(ar->net_dev, bssid,
529					assoc_req_ie, assoc_req_len,
530					assoc_resp_ie, assoc_resp_len,
531					WLAN_STATUS_SUCCESS, GFP_KERNEL);
532	} else if (ar->sme_state == SME_CONNECTED) {
533		/* inform roam event to cfg80211 */
534		cfg80211_roamed(ar->net_dev, chan, bssid,
535				assoc_req_ie, assoc_req_len,
536				assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
537	}
538}
539
540static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
541				      struct net_device *dev, u16 reason_code)
542{
543	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
544
545	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
546		   reason_code);
547
548	if (!ath6kl_cfg80211_ready(ar))
549		return -EIO;
550
551	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
552		ath6kl_err("busy, destroy in progress\n");
553		return -EBUSY;
554	}
555
556	if (down_interruptible(&ar->sem)) {
557		ath6kl_err("busy, couldn't get access\n");
558		return -ERESTARTSYS;
559	}
560
561	ar->reconnect_flag = 0;
562	ath6kl_disconnect(ar);
563	memset(ar->ssid, 0, sizeof(ar->ssid));
564	ar->ssid_len = 0;
565
566	if (!test_bit(SKIP_SCAN, &ar->flag))
567		memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
568
569	up(&ar->sem);
570
571	ar->sme_state = SME_DISCONNECTED;
572
573	return 0;
574}
575
576void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
577				      u8 *bssid, u8 assoc_resp_len,
578				      u8 *assoc_info, u16 proto_reason)
579{
580	if (ar->scan_req) {
581		cfg80211_scan_done(ar->scan_req, true);
582		ar->scan_req = NULL;
583	}
584
585	if (ar->nw_type & ADHOC_NETWORK) {
586		if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
587			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
588				   "%s: ath6k not in ibss mode\n", __func__);
589			return;
590		}
591		memset(bssid, 0, ETH_ALEN);
592		cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
593		return;
594	}
595
596	if (ar->nw_type & INFRA_NETWORK) {
597		if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
598		    ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
599			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
600				   "%s: ath6k not in station mode\n", __func__);
601			return;
602		}
603	}
604
605	/*
606	 * Send a disconnect command to target when a disconnect event is
607	 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
608	 * request from host) to make the firmware stop trying to connect even
609	 * after giving disconnect event. There will be one more disconnect
610	 * event for this disconnect command with reason code DISCONNECT_CMD
611	 * which will be notified to cfg80211.
612	 */
613
614	if (reason != DISCONNECT_CMD) {
615		ath6kl_wmi_disconnect_cmd(ar->wmi);
616		return;
617	}
618
619	clear_bit(CONNECT_PEND, &ar->flag);
620
621	if (ar->sme_state == SME_CONNECTING) {
622		cfg80211_connect_result(ar->net_dev,
623				bssid, NULL, 0,
624				NULL, 0,
625				WLAN_STATUS_UNSPECIFIED_FAILURE,
626				GFP_KERNEL);
627	} else if (ar->sme_state == SME_CONNECTED) {
628		cfg80211_disconnected(ar->net_dev, reason,
629				NULL, 0, GFP_KERNEL);
630	}
631
632	ar->sme_state = SME_DISCONNECTED;
633}
634
635static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
636				struct cfg80211_scan_request *request)
637{
638	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
639	s8 n_channels = 0;
640	u16 *channels = NULL;
641	int ret = 0;
642
643	if (!ath6kl_cfg80211_ready(ar))
644		return -EIO;
645
646	if (!ar->usr_bss_filter) {
647		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
648		ret = ath6kl_wmi_bssfilter_cmd(
649			ar->wmi,
650			(test_bit(CONNECTED, &ar->flag) ?
651			 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
652		if (ret) {
653			ath6kl_err("couldn't set bss filtering\n");
654			return ret;
655		}
656	}
657
658	if (request->n_ssids && request->ssids[0].ssid_len) {
659		u8 i;
660
661		if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
662			request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
663
664		for (i = 0; i < request->n_ssids; i++)
665			ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
666						  SPECIFIC_SSID_FLAG,
667						  request->ssids[i].ssid_len,
668						  request->ssids[i].ssid);
669	}
670
671	if (request->ie) {
672		ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
673					       request->ie, request->ie_len);
674		if (ret) {
675			ath6kl_err("failed to set Probe Request appie for "
676				   "scan");
677			return ret;
678		}
679	}
680
681	/*
682	 * Scan only the requested channels if the request specifies a set of
683	 * channels. If the list is longer than the target supports, do not
684	 * configure the list and instead, scan all available channels.
685	 */
686	if (request->n_channels > 0 &&
687	    request->n_channels <= WMI_MAX_CHANNELS) {
688		u8 i;
689
690		n_channels = request->n_channels;
691
692		channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
693		if (channels == NULL) {
694			ath6kl_warn("failed to set scan channels, "
695				    "scan all channels");
696			n_channels = 0;
697		}
698
699		for (i = 0; i < n_channels; i++)
700			channels[i] = request->channels[i]->center_freq;
701	}
702
703	ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
704				       false, 0, 0, n_channels, channels);
705	if (ret)
706		ath6kl_err("wmi_startscan_cmd failed\n");
707	else
708		ar->scan_req = request;
709
710	kfree(channels);
711
712	return ret;
713}
714
715void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
716{
717	int i;
718
719	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
720
721	if (!ar->scan_req)
722		return;
723
724	if ((status == -ECANCELED) || (status == -EBUSY)) {
725		cfg80211_scan_done(ar->scan_req, true);
726		goto out;
727	}
728
729	cfg80211_scan_done(ar->scan_req, false);
730
731	if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
732		for (i = 0; i < ar->scan_req->n_ssids; i++) {
733			ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
734						  DISABLE_SSID_FLAG,
735						  0, NULL);
736		}
737	}
738
739out:
740	ar->scan_req = NULL;
741}
742
743static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
744				   u8 key_index, bool pairwise,
745				   const u8 *mac_addr,
746				   struct key_params *params)
747{
748	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
749	struct ath6kl_key *key = NULL;
750	u8 key_usage;
751	u8 key_type;
752	int status = 0;
753
754	if (!ath6kl_cfg80211_ready(ar))
755		return -EIO;
756
757	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
758		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
759			   "%s: key index %d out of bounds\n", __func__,
760			   key_index);
761		return -ENOENT;
762	}
763
764	key = &ar->keys[key_index];
765	memset(key, 0, sizeof(struct ath6kl_key));
766
767	if (pairwise)
768		key_usage = PAIRWISE_USAGE;
769	else
770		key_usage = GROUP_USAGE;
771
772	if (params) {
773		if (params->key_len > WLAN_MAX_KEY_LEN ||
774		    params->seq_len > sizeof(key->seq))
775			return -EINVAL;
776
777		key->key_len = params->key_len;
778		memcpy(key->key, params->key, key->key_len);
779		key->seq_len = params->seq_len;
780		memcpy(key->seq, params->seq, key->seq_len);
781		key->cipher = params->cipher;
782	}
783
784	switch (key->cipher) {
785	case WLAN_CIPHER_SUITE_WEP40:
786	case WLAN_CIPHER_SUITE_WEP104:
787		key_type = WEP_CRYPT;
788		break;
789
790	case WLAN_CIPHER_SUITE_TKIP:
791		key_type = TKIP_CRYPT;
792		break;
793
794	case WLAN_CIPHER_SUITE_CCMP:
795		key_type = AES_CRYPT;
796		break;
797
798	default:
799		return -ENOTSUPP;
800	}
801
802	if (((ar->auth_mode == WPA_PSK_AUTH)
803	     || (ar->auth_mode == WPA2_PSK_AUTH))
804	    && (key_usage & GROUP_USAGE))
805		del_timer(&ar->disconnect_timer);
806
807	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
808		   "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
809		   __func__, key_index, key->key_len, key_type,
810		   key_usage, key->seq_len);
811
812	ar->def_txkey_index = key_index;
813
814	if (ar->nw_type == AP_NETWORK && !pairwise &&
815	    (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
816		ar->ap_mode_bkey.valid = true;
817		ar->ap_mode_bkey.key_index = key_index;
818		ar->ap_mode_bkey.key_type = key_type;
819		ar->ap_mode_bkey.key_len = key->key_len;
820		memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
821		if (!test_bit(CONNECTED, &ar->flag)) {
822			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
823				   "key configuration until AP mode has been "
824				   "started\n");
825			/*
826			 * The key will be set in ath6kl_connect_ap_mode() once
827			 * the connected event is received from the target.
828			 */
829			return 0;
830		}
831	}
832
833	if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
834	    !test_bit(CONNECTED, &ar->flag)) {
835		/*
836		 * Store the key locally so that it can be re-configured after
837		 * the AP mode has properly started
838		 * (ath6kl_install_statioc_wep_keys).
839		 */
840		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
841			   "until AP mode has been started\n");
842		ar->wep_key_list[key_index].key_len = key->key_len;
843		memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len);
844		return 0;
845	}
846
847	status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
848				       key_type, key_usage, key->key_len,
849				       key->seq, key->key, KEY_OP_INIT_VAL,
850				       (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
851
852	if (status)
853		return -EIO;
854
855	return 0;
856}
857
858static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
859				   u8 key_index, bool pairwise,
860				   const u8 *mac_addr)
861{
862	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
863
864	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
865
866	if (!ath6kl_cfg80211_ready(ar))
867		return -EIO;
868
869	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
870		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
871			   "%s: key index %d out of bounds\n", __func__,
872			   key_index);
873		return -ENOENT;
874	}
875
876	if (!ar->keys[key_index].key_len) {
877		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
878			   "%s: index %d is empty\n", __func__, key_index);
879		return 0;
880	}
881
882	ar->keys[key_index].key_len = 0;
883
884	return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
885}
886
887static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
888				   u8 key_index, bool pairwise,
889				   const u8 *mac_addr, void *cookie,
890				   void (*callback) (void *cookie,
891						     struct key_params *))
892{
893	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
894	struct ath6kl_key *key = NULL;
895	struct key_params params;
896
897	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
898
899	if (!ath6kl_cfg80211_ready(ar))
900		return -EIO;
901
902	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
903		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
904			   "%s: key index %d out of bounds\n", __func__,
905			   key_index);
906		return -ENOENT;
907	}
908
909	key = &ar->keys[key_index];
910	memset(&params, 0, sizeof(params));
911	params.cipher = key->cipher;
912	params.key_len = key->key_len;
913	params.seq_len = key->seq_len;
914	params.seq = key->seq;
915	params.key = key->key;
916
917	callback(cookie, &params);
918
919	return key->key_len ? 0 : -ENOENT;
920}
921
922static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
923					   struct net_device *ndev,
924					   u8 key_index, bool unicast,
925					   bool multicast)
926{
927	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
928	struct ath6kl_key *key = NULL;
929	int status = 0;
930	u8 key_usage;
931	enum crypto_type key_type = NONE_CRYPT;
932
933	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
934
935	if (!ath6kl_cfg80211_ready(ar))
936		return -EIO;
937
938	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
939		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
940			   "%s: key index %d out of bounds\n",
941			   __func__, key_index);
942		return -ENOENT;
943	}
944
945	if (!ar->keys[key_index].key_len) {
946		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
947			   __func__, key_index);
948		return -EINVAL;
949	}
950
951	ar->def_txkey_index = key_index;
952	key = &ar->keys[ar->def_txkey_index];
953	key_usage = GROUP_USAGE;
954	if (ar->prwise_crypto == WEP_CRYPT)
955		key_usage |= TX_USAGE;
956	if (unicast)
957		key_type = ar->prwise_crypto;
958	if (multicast)
959		key_type = ar->grp_crypto;
960
961	if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
962		return 0; /* Delay until AP mode has been started */
963
964	status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
965				       key_type, key_usage,
966				       key->key_len, key->seq, key->key,
967				       KEY_OP_INIT_VAL, NULL,
968				       SYNC_BOTH_WMIFLAG);
969	if (status)
970		return -EIO;
971
972	return 0;
973}
974
975void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
976				       bool ismcast)
977{
978	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
979		   "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
980
981	cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
982				     (ismcast ? NL80211_KEYTYPE_GROUP :
983				      NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
984				     GFP_KERNEL);
985}
986
987static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
988{
989	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
990	int ret;
991
992	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
993		   changed);
994
995	if (!ath6kl_cfg80211_ready(ar))
996		return -EIO;
997
998	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
999		ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1000		if (ret != 0) {
1001			ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1002			return -EIO;
1003		}
1004	}
1005
1006	return 0;
1007}
1008
1009/*
1010 * The type nl80211_tx_power_setting replaces the following
1011 * data type from 2.6.36 onwards
1012*/
1013static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1014				       enum nl80211_tx_power_setting type,
1015				       int dbm)
1016{
1017	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1018	u8 ath6kl_dbm;
1019
1020	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1021		   type, dbm);
1022
1023	if (!ath6kl_cfg80211_ready(ar))
1024		return -EIO;
1025
1026	switch (type) {
1027	case NL80211_TX_POWER_AUTOMATIC:
1028		return 0;
1029	case NL80211_TX_POWER_LIMITED:
1030		ar->tx_pwr = ath6kl_dbm = dbm;
1031		break;
1032	default:
1033		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1034			   __func__, type);
1035		return -EOPNOTSUPP;
1036	}
1037
1038	ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
1039
1040	return 0;
1041}
1042
1043static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1044{
1045	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1046
1047	if (!ath6kl_cfg80211_ready(ar))
1048		return -EIO;
1049
1050	if (test_bit(CONNECTED, &ar->flag)) {
1051		ar->tx_pwr = 0;
1052
1053		if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
1054			ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1055			return -EIO;
1056		}
1057
1058		wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1059						 5 * HZ);
1060
1061		if (signal_pending(current)) {
1062			ath6kl_err("target did not respond\n");
1063			return -EINTR;
1064		}
1065	}
1066
1067	*dbm = ar->tx_pwr;
1068	return 0;
1069}
1070
1071static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1072					  struct net_device *dev,
1073					  bool pmgmt, int timeout)
1074{
1075	struct ath6kl *ar = ath6kl_priv(dev);
1076	struct wmi_power_mode_cmd mode;
1077
1078	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1079		   __func__, pmgmt, timeout);
1080
1081	if (!ath6kl_cfg80211_ready(ar))
1082		return -EIO;
1083
1084	if (pmgmt) {
1085		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1086		mode.pwr_mode = REC_POWER;
1087	} else {
1088		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1089		mode.pwr_mode = MAX_PERF_POWER;
1090	}
1091
1092	if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
1093		ath6kl_err("wmi_powermode_cmd failed\n");
1094		return -EIO;
1095	}
1096
1097	return 0;
1098}
1099
1100static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1101					struct net_device *ndev,
1102					enum nl80211_iftype type, u32 *flags,
1103					struct vif_params *params)
1104{
1105	struct ath6kl *ar = ath6kl_priv(ndev);
1106	struct wireless_dev *wdev = ar->wdev;
1107
1108	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1109
1110	if (!ath6kl_cfg80211_ready(ar))
1111		return -EIO;
1112
1113	switch (type) {
1114	case NL80211_IFTYPE_STATION:
1115		ar->next_mode = INFRA_NETWORK;
1116		break;
1117	case NL80211_IFTYPE_ADHOC:
1118		ar->next_mode = ADHOC_NETWORK;
1119		break;
1120	case NL80211_IFTYPE_AP:
1121		ar->next_mode = AP_NETWORK;
1122		break;
1123	case NL80211_IFTYPE_P2P_CLIENT:
1124		ar->next_mode = INFRA_NETWORK;
1125		break;
1126	case NL80211_IFTYPE_P2P_GO:
1127		ar->next_mode = AP_NETWORK;
1128		break;
1129	default:
1130		ath6kl_err("invalid interface type %u\n", type);
1131		return -EOPNOTSUPP;
1132	}
1133
1134	wdev->iftype = type;
1135
1136	return 0;
1137}
1138
1139static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1140				     struct net_device *dev,
1141				     struct cfg80211_ibss_params *ibss_param)
1142{
1143	struct ath6kl *ar = ath6kl_priv(dev);
1144	int status;
1145
1146	if (!ath6kl_cfg80211_ready(ar))
1147		return -EIO;
1148
1149	ar->ssid_len = ibss_param->ssid_len;
1150	memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
1151
1152	if (ibss_param->channel)
1153		ar->ch_hint = ibss_param->channel->center_freq;
1154
1155	if (ibss_param->channel_fixed) {
1156		/*
1157		 * TODO: channel_fixed: The channel should be fixed, do not
1158		 * search for IBSSs to join on other channels. Target
1159		 * firmware does not support this feature, needs to be
1160		 * updated.
1161		 */
1162		return -EOPNOTSUPP;
1163	}
1164
1165	memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
1166	if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1167		memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
1168
1169	ath6kl_set_wpa_version(ar, 0);
1170
1171	status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1172	if (status)
1173		return status;
1174
1175	if (ibss_param->privacy) {
1176		ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1177		ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1178	} else {
1179		ath6kl_set_cipher(ar, 0, true);
1180		ath6kl_set_cipher(ar, 0, false);
1181	}
1182
1183	ar->nw_type = ar->next_mode;
1184
1185	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1186		   "%s: connect called with authmode %d dot11 auth %d"
1187		   " PW crypto %d PW crypto len %d GRP crypto %d"
1188		   " GRP crypto len %d channel hint %u\n",
1189		   __func__,
1190		   ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
1191		   ar->prwise_crypto_len, ar->grp_crypto,
1192		   ar->grp_crypto_len, ar->ch_hint);
1193
1194	status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
1195					ar->dot11_auth_mode, ar->auth_mode,
1196					ar->prwise_crypto,
1197					ar->prwise_crypto_len,
1198					ar->grp_crypto, ar->grp_crypto_len,
1199					ar->ssid_len, ar->ssid,
1200					ar->req_bssid, ar->ch_hint,
1201					ar->connect_ctrl_flags);
1202	set_bit(CONNECT_PEND, &ar->flag);
1203
1204	return 0;
1205}
1206
1207static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1208				      struct net_device *dev)
1209{
1210	struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
1211
1212	if (!ath6kl_cfg80211_ready(ar))
1213		return -EIO;
1214
1215	ath6kl_disconnect(ar);
1216	memset(ar->ssid, 0, sizeof(ar->ssid));
1217	ar->ssid_len = 0;
1218
1219	return 0;
1220}
1221
1222static const u32 cipher_suites[] = {
1223	WLAN_CIPHER_SUITE_WEP40,
1224	WLAN_CIPHER_SUITE_WEP104,
1225	WLAN_CIPHER_SUITE_TKIP,
1226	WLAN_CIPHER_SUITE_CCMP,
1227};
1228
1229static bool is_rate_legacy(s32 rate)
1230{
1231	static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1232		6000, 9000, 12000, 18000, 24000,
1233		36000, 48000, 54000
1234	};
1235	u8 i;
1236
1237	for (i = 0; i < ARRAY_SIZE(legacy); i++)
1238		if (rate == legacy[i])
1239			return true;
1240
1241	return false;
1242}
1243
1244static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1245{
1246	static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1247		52000, 58500, 65000, 72200
1248	};
1249	u8 i;
1250
1251	for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1252		if (rate == ht20[i]) {
1253			if (i == ARRAY_SIZE(ht20) - 1)
1254				/* last rate uses sgi */
1255				*sgi = true;
1256			else
1257				*sgi = false;
1258
1259			*mcs = i;
1260			return true;
1261		}
1262	}
1263	return false;
1264}
1265
1266static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1267{
1268	static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1269		81000, 108000, 121500, 135000,
1270		150000
1271	};
1272	u8 i;
1273
1274	for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1275		if (rate == ht40[i]) {
1276			if (i == ARRAY_SIZE(ht40) - 1)
1277				/* last rate uses sgi */
1278				*sgi = true;
1279			else
1280				*sgi = false;
1281
1282			*mcs = i;
1283			return true;
1284		}
1285	}
1286
1287	return false;
1288}
1289
1290static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1291			      u8 *mac, struct station_info *sinfo)
1292{
1293	struct ath6kl *ar = ath6kl_priv(dev);
1294	long left;
1295	bool sgi;
1296	s32 rate;
1297	int ret;
1298	u8 mcs;
1299
1300	if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
1301		return -ENOENT;
1302
1303	if (down_interruptible(&ar->sem))
1304		return -EBUSY;
1305
1306	set_bit(STATS_UPDATE_PEND, &ar->flag);
1307
1308	ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
1309
1310	if (ret != 0) {
1311		up(&ar->sem);
1312		return -EIO;
1313	}
1314
1315	left = wait_event_interruptible_timeout(ar->event_wq,
1316						!test_bit(STATS_UPDATE_PEND,
1317							  &ar->flag),
1318						WMI_TIMEOUT);
1319
1320	up(&ar->sem);
1321
1322	if (left == 0)
1323		return -ETIMEDOUT;
1324	else if (left < 0)
1325		return left;
1326
1327	if (ar->target_stats.rx_byte) {
1328		sinfo->rx_bytes = ar->target_stats.rx_byte;
1329		sinfo->filled |= STATION_INFO_RX_BYTES;
1330		sinfo->rx_packets = ar->target_stats.rx_pkt;
1331		sinfo->filled |= STATION_INFO_RX_PACKETS;
1332	}
1333
1334	if (ar->target_stats.tx_byte) {
1335		sinfo->tx_bytes = ar->target_stats.tx_byte;
1336		sinfo->filled |= STATION_INFO_TX_BYTES;
1337		sinfo->tx_packets = ar->target_stats.tx_pkt;
1338		sinfo->filled |= STATION_INFO_TX_PACKETS;
1339	}
1340
1341	sinfo->signal = ar->target_stats.cs_rssi;
1342	sinfo->filled |= STATION_INFO_SIGNAL;
1343
1344	rate = ar->target_stats.tx_ucast_rate;
1345
1346	if (is_rate_legacy(rate)) {
1347		sinfo->txrate.legacy = rate / 100;
1348	} else if (is_rate_ht20(rate, &mcs, &sgi)) {
1349		if (sgi) {
1350			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1351			sinfo->txrate.mcs = mcs - 1;
1352		} else {
1353			sinfo->txrate.mcs = mcs;
1354		}
1355
1356		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1357	} else if (is_rate_ht40(rate, &mcs, &sgi)) {
1358		if (sgi) {
1359			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1360			sinfo->txrate.mcs = mcs - 1;
1361		} else {
1362			sinfo->txrate.mcs = mcs;
1363		}
1364
1365		sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1366		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1367	} else {
1368		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1369			   "invalid rate from stats: %d\n", rate);
1370		ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1371		return 0;
1372	}
1373
1374	sinfo->filled |= STATION_INFO_TX_BITRATE;
1375
1376	if (test_bit(CONNECTED, &ar->flag) &&
1377	    test_bit(DTIM_PERIOD_AVAIL, &ar->flag) &&
1378	    ar->nw_type == INFRA_NETWORK) {
1379		sinfo->filled |= STATION_INFO_BSS_PARAM;
1380		sinfo->bss_param.flags = 0;
1381		sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
1382		sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
1383	}
1384
1385	return 0;
1386}
1387
1388static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1389			    struct cfg80211_pmksa *pmksa)
1390{
1391	struct ath6kl *ar = ath6kl_priv(netdev);
1392	return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1393				       pmksa->pmkid, true);
1394}
1395
1396static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1397			    struct cfg80211_pmksa *pmksa)
1398{
1399	struct ath6kl *ar = ath6kl_priv(netdev);
1400	return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1401				       pmksa->pmkid, false);
1402}
1403
1404static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1405{
1406	struct ath6kl *ar = ath6kl_priv(netdev);
1407	if (test_bit(CONNECTED, &ar->flag))
1408		return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
1409	return 0;
1410}
1411
1412#ifdef CONFIG_PM
1413static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1414				 struct cfg80211_wowlan *wow)
1415{
1416	struct ath6kl *ar = wiphy_priv(wiphy);
1417
1418	return ath6kl_hif_suspend(ar);
1419}
1420#endif
1421
1422static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1423			      struct ieee80211_channel *chan,
1424			      enum nl80211_channel_type channel_type)
1425{
1426	struct ath6kl *ar = ath6kl_priv(dev);
1427
1428	if (!ath6kl_cfg80211_ready(ar))
1429		return -EIO;
1430
1431	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1432		   __func__, chan->center_freq, chan->hw_value);
1433	ar->next_chan = chan->center_freq;
1434
1435	return 0;
1436}
1437
1438static bool ath6kl_is_p2p_ie(const u8 *pos)
1439{
1440	return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1441		pos[2] == 0x50 && pos[3] == 0x6f &&
1442		pos[4] == 0x9a && pos[5] == 0x09;
1443}
1444
1445static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
1446					size_t ies_len)
1447{
1448	const u8 *pos;
1449	u8 *buf = NULL;
1450	size_t len = 0;
1451	int ret;
1452
1453	/*
1454	 * Filter out P2P IE(s) since they will be included depending on
1455	 * the Probe Request frame in ath6kl_send_go_probe_resp().
1456	 */
1457
1458	if (ies && ies_len) {
1459		buf = kmalloc(ies_len, GFP_KERNEL);
1460		if (buf == NULL)
1461			return -ENOMEM;
1462		pos = ies;
1463		while (pos + 1 < ies + ies_len) {
1464			if (pos + 2 + pos[1] > ies + ies_len)
1465				break;
1466			if (!ath6kl_is_p2p_ie(pos)) {
1467				memcpy(buf + len, pos, 2 + pos[1]);
1468				len += 2 + pos[1];
1469			}
1470			pos += 2 + pos[1];
1471		}
1472	}
1473
1474	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
1475				       buf, len);
1476	kfree(buf);
1477	return ret;
1478}
1479
1480static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1481			    struct beacon_parameters *info, bool add)
1482{
1483	struct ath6kl *ar = ath6kl_priv(dev);
1484	struct ieee80211_mgmt *mgmt;
1485	u8 *ies;
1486	int ies_len;
1487	struct wmi_connect_cmd p;
1488	int res;
1489	int i;
1490
1491	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
1492
1493	if (!ath6kl_cfg80211_ready(ar))
1494		return -EIO;
1495
1496	if (ar->next_mode != AP_NETWORK)
1497		return -EOPNOTSUPP;
1498
1499	if (info->beacon_ies) {
1500		res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
1501					       info->beacon_ies,
1502					       info->beacon_ies_len);
1503		if (res)
1504			return res;
1505	}
1506	if (info->proberesp_ies) {
1507		res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
1508						   info->proberesp_ies_len);
1509		if (res)
1510			return res;
1511	}
1512	if (info->assocresp_ies) {
1513		res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
1514					       info->assocresp_ies,
1515					       info->assocresp_ies_len);
1516		if (res)
1517			return res;
1518	}
1519
1520	if (!add)
1521		return 0;
1522
1523	ar->ap_mode_bkey.valid = false;
1524
1525	/* TODO:
1526	 * info->interval
1527	 * info->dtim_period
1528	 */
1529
1530	if (info->head == NULL)
1531		return -EINVAL;
1532	mgmt = (struct ieee80211_mgmt *) info->head;
1533	ies = mgmt->u.beacon.variable;
1534	if (ies > info->head + info->head_len)
1535		return -EINVAL;
1536	ies_len = info->head + info->head_len - ies;
1537
1538	if (info->ssid == NULL)
1539		return -EINVAL;
1540	memcpy(ar->ssid, info->ssid, info->ssid_len);
1541	ar->ssid_len = info->ssid_len;
1542	if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1543		return -EOPNOTSUPP; /* TODO */
1544
1545	ar->dot11_auth_mode = OPEN_AUTH;
1546
1547	memset(&p, 0, sizeof(p));
1548
1549	for (i = 0; i < info->crypto.n_akm_suites; i++) {
1550		switch (info->crypto.akm_suites[i]) {
1551		case WLAN_AKM_SUITE_8021X:
1552			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1553				p.auth_mode |= WPA_AUTH;
1554			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1555				p.auth_mode |= WPA2_AUTH;
1556			break;
1557		case WLAN_AKM_SUITE_PSK:
1558			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1559				p.auth_mode |= WPA_PSK_AUTH;
1560			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1561				p.auth_mode |= WPA2_PSK_AUTH;
1562			break;
1563		}
1564	}
1565	if (p.auth_mode == 0)
1566		p.auth_mode = NONE_AUTH;
1567	ar->auth_mode = p.auth_mode;
1568
1569	for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
1570		switch (info->crypto.ciphers_pairwise[i]) {
1571		case WLAN_CIPHER_SUITE_WEP40:
1572		case WLAN_CIPHER_SUITE_WEP104:
1573			p.prwise_crypto_type |= WEP_CRYPT;
1574			break;
1575		case WLAN_CIPHER_SUITE_TKIP:
1576			p.prwise_crypto_type |= TKIP_CRYPT;
1577			break;
1578		case WLAN_CIPHER_SUITE_CCMP:
1579			p.prwise_crypto_type |= AES_CRYPT;
1580			break;
1581		}
1582	}
1583	if (p.prwise_crypto_type == 0) {
1584		p.prwise_crypto_type = NONE_CRYPT;
1585		ath6kl_set_cipher(ar, 0, true);
1586	} else if (info->crypto.n_ciphers_pairwise == 1)
1587		ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
1588
1589	switch (info->crypto.cipher_group) {
1590	case WLAN_CIPHER_SUITE_WEP40:
1591	case WLAN_CIPHER_SUITE_WEP104:
1592		p.grp_crypto_type = WEP_CRYPT;
1593		break;
1594	case WLAN_CIPHER_SUITE_TKIP:
1595		p.grp_crypto_type = TKIP_CRYPT;
1596		break;
1597	case WLAN_CIPHER_SUITE_CCMP:
1598		p.grp_crypto_type = AES_CRYPT;
1599		break;
1600	default:
1601		p.grp_crypto_type = NONE_CRYPT;
1602		break;
1603	}
1604	ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
1605
1606	p.nw_type = AP_NETWORK;
1607	ar->nw_type = ar->next_mode;
1608
1609	p.ssid_len = ar->ssid_len;
1610	memcpy(p.ssid, ar->ssid, ar->ssid_len);
1611	p.dot11_auth_mode = ar->dot11_auth_mode;
1612	p.ch = cpu_to_le16(ar->next_chan);
1613
1614	res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1615	if (res < 0)
1616		return res;
1617
1618	return 0;
1619}
1620
1621static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
1622			     struct beacon_parameters *info)
1623{
1624	return ath6kl_ap_beacon(wiphy, dev, info, true);
1625}
1626
1627static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
1628			     struct beacon_parameters *info)
1629{
1630	return ath6kl_ap_beacon(wiphy, dev, info, false);
1631}
1632
1633static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
1634{
1635	struct ath6kl *ar = ath6kl_priv(dev);
1636
1637	if (ar->nw_type != AP_NETWORK)
1638		return -EOPNOTSUPP;
1639	if (!test_bit(CONNECTED, &ar->flag))
1640		return -ENOTCONN;
1641
1642	ath6kl_wmi_disconnect_cmd(ar->wmi);
1643	clear_bit(CONNECTED, &ar->flag);
1644
1645	return 0;
1646}
1647
1648static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
1649				 u8 *mac, struct station_parameters *params)
1650{
1651	struct ath6kl *ar = ath6kl_priv(dev);
1652
1653	if (ar->nw_type != AP_NETWORK)
1654		return -EOPNOTSUPP;
1655
1656	/* Use this only for authorizing/unauthorizing a station */
1657	if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1658		return -EOPNOTSUPP;
1659
1660	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
1661		return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
1662					      mac, 0);
1663	return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
1664				      0);
1665}
1666
1667static int ath6kl_remain_on_channel(struct wiphy *wiphy,
1668				    struct net_device *dev,
1669				    struct ieee80211_channel *chan,
1670				    enum nl80211_channel_type channel_type,
1671				    unsigned int duration,
1672				    u64 *cookie)
1673{
1674	struct ath6kl *ar = ath6kl_priv(dev);
1675
1676	/* TODO: if already pending or ongoing remain-on-channel,
1677	 * return -EBUSY */
1678	*cookie = 1; /* only a single pending request is supported */
1679
1680	return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
1681					     duration);
1682}
1683
1684static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
1685					   struct net_device *dev,
1686					   u64 cookie)
1687{
1688	struct ath6kl *ar = ath6kl_priv(dev);
1689
1690	if (cookie != 1)
1691		return -ENOENT;
1692
1693	return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
1694}
1695
1696static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
1697				     size_t len, unsigned int freq)
1698{
1699	const u8 *pos;
1700	u8 *p2p;
1701	int p2p_len;
1702	int ret;
1703	const struct ieee80211_mgmt *mgmt;
1704
1705	mgmt = (const struct ieee80211_mgmt *) buf;
1706
1707	/* Include P2P IE(s) from the frame generated in user space. */
1708
1709	p2p = kmalloc(len, GFP_KERNEL);
1710	if (p2p == NULL)
1711		return -ENOMEM;
1712	p2p_len = 0;
1713
1714	pos = mgmt->u.probe_resp.variable;
1715	while (pos + 1 < buf + len) {
1716		if (pos + 2 + pos[1] > buf + len)
1717			break;
1718		if (ath6kl_is_p2p_ie(pos)) {
1719			memcpy(p2p + p2p_len, pos, 2 + pos[1]);
1720			p2p_len += 2 + pos[1];
1721		}
1722		pos += 2 + pos[1];
1723	}
1724
1725	ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
1726						 p2p, p2p_len);
1727	kfree(p2p);
1728	return ret;
1729}
1730
1731static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1732			  struct ieee80211_channel *chan, bool offchan,
1733			  enum nl80211_channel_type channel_type,
1734			  bool channel_type_valid, unsigned int wait,
1735			  const u8 *buf, size_t len, bool no_cck, u64 *cookie)
1736{
1737	struct ath6kl *ar = ath6kl_priv(dev);
1738	u32 id;
1739	const struct ieee80211_mgmt *mgmt;
1740
1741	mgmt = (const struct ieee80211_mgmt *) buf;
1742	if (buf + len >= mgmt->u.probe_resp.variable &&
1743	    ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
1744	    ieee80211_is_probe_resp(mgmt->frame_control)) {
1745		/*
1746		 * Send Probe Response frame in AP mode using a separate WMI
1747		 * command to allow the target to fill in the generic IEs.
1748		 */
1749		*cookie = 0; /* TX status not supported */
1750		return ath6kl_send_go_probe_resp(ar, buf, len,
1751						 chan->center_freq);
1752	}
1753
1754	id = ar->send_action_id++;
1755	if (id == 0) {
1756		/*
1757		 * 0 is a reserved value in the WMI command and shall not be
1758		 * used for the command.
1759		 */
1760		id = ar->send_action_id++;
1761	}
1762
1763	*cookie = id;
1764	return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
1765					  buf, len);
1766}
1767
1768static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
1769				       struct net_device *dev,
1770				       u16 frame_type, bool reg)
1771{
1772	struct ath6kl *ar = ath6kl_priv(dev);
1773
1774	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
1775		   __func__, frame_type, reg);
1776	if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
1777		/*
1778		 * Note: This notification callback is not allowed to sleep, so
1779		 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
1780		 * hardcode target to report Probe Request frames all the time.
1781		 */
1782		ar->probe_req_report = reg;
1783	}
1784}
1785
1786static const struct ieee80211_txrx_stypes
1787ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1788	[NL80211_IFTYPE_STATION] = {
1789		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1790		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1791		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1792		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1793	},
1794	[NL80211_IFTYPE_P2P_CLIENT] = {
1795		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1796		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1797		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1798		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1799	},
1800	[NL80211_IFTYPE_P2P_GO] = {
1801		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1802		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1803		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1804		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1805	},
1806};
1807
1808static struct cfg80211_ops ath6kl_cfg80211_ops = {
1809	.change_virtual_intf = ath6kl_cfg80211_change_iface,
1810	.scan = ath6kl_cfg80211_scan,
1811	.connect = ath6kl_cfg80211_connect,
1812	.disconnect = ath6kl_cfg80211_disconnect,
1813	.add_key = ath6kl_cfg80211_add_key,
1814	.get_key = ath6kl_cfg80211_get_key,
1815	.del_key = ath6kl_cfg80211_del_key,
1816	.set_default_key = ath6kl_cfg80211_set_default_key,
1817	.set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
1818	.set_tx_power = ath6kl_cfg80211_set_txpower,
1819	.get_tx_power = ath6kl_cfg80211_get_txpower,
1820	.set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
1821	.join_ibss = ath6kl_cfg80211_join_ibss,
1822	.leave_ibss = ath6kl_cfg80211_leave_ibss,
1823	.get_station = ath6kl_get_station,
1824	.set_pmksa = ath6kl_set_pmksa,
1825	.del_pmksa = ath6kl_del_pmksa,
1826	.flush_pmksa = ath6kl_flush_pmksa,
1827	CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
1828#ifdef CONFIG_PM
1829	.suspend = ar6k_cfg80211_suspend,
1830#endif
1831	.set_channel = ath6kl_set_channel,
1832	.add_beacon = ath6kl_add_beacon,
1833	.set_beacon = ath6kl_set_beacon,
1834	.del_beacon = ath6kl_del_beacon,
1835	.change_station = ath6kl_change_station,
1836	.remain_on_channel = ath6kl_remain_on_channel,
1837	.cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
1838	.mgmt_tx = ath6kl_mgmt_tx,
1839	.mgmt_frame_register = ath6kl_mgmt_frame_register,
1840};
1841
1842struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1843{
1844	int ret = 0;
1845	struct wireless_dev *wdev;
1846	struct ath6kl *ar;
1847
1848	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1849	if (!wdev) {
1850		ath6kl_err("couldn't allocate wireless device\n");
1851		return NULL;
1852	}
1853
1854	/* create a new wiphy for use with cfg80211 */
1855	wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
1856	if (!wdev->wiphy) {
1857		ath6kl_err("couldn't allocate wiphy device\n");
1858		kfree(wdev);
1859		return NULL;
1860	}
1861
1862	ar = wiphy_priv(wdev->wiphy);
1863	ar->p2p = !!ath6kl_p2p;
1864
1865	wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
1866
1867	wdev->wiphy->max_remain_on_channel_duration = 5000;
1868
1869	/* set device pointer for wiphy */
1870	set_wiphy_dev(wdev->wiphy, dev);
1871
1872	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1873		BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
1874	if (ar->p2p) {
1875		wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
1876			BIT(NL80211_IFTYPE_P2P_CLIENT);
1877	}
1878	/* max num of ssids that can be probed during scanning */
1879	wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1880	wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
1881	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
1882	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
1883	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1884
1885	wdev->wiphy->cipher_suites = cipher_suites;
1886	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1887
1888	ret = wiphy_register(wdev->wiphy);
1889	if (ret < 0) {
1890		ath6kl_err("couldn't register wiphy device\n");
1891		wiphy_free(wdev->wiphy);
1892		kfree(wdev);
1893		return NULL;
1894	}
1895
1896	return wdev;
1897}
1898
1899void ath6kl_cfg80211_deinit(struct ath6kl *ar)
1900{
1901	struct wireless_dev *wdev = ar->wdev;
1902
1903	if (ar->scan_req) {
1904		cfg80211_scan_done(ar->scan_req, true);
1905		ar->scan_req = NULL;
1906	}
1907
1908	if (!wdev)
1909		return;
1910
1911	wiphy_unregister(wdev->wiphy);
1912	wiphy_free(wdev->wiphy);
1913	kfree(wdev);
1914}
1915