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