• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2004-2011 Atheros Communications Inc.
3  * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 
20 #include <linux/moduleparam.h>
21 #include <linux/inetdevice.h>
22 #include <linux/export.h>
23 
24 #include "core.h"
25 #include "cfg80211.h"
26 #include "debug.h"
27 #include "hif-ops.h"
28 #include "testmode.h"
29 
30 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
31 	.bitrate    = (_rate),                  \
32 	.flags      = (_flags),                 \
33 	.hw_value   = (_rateid),                \
34 }
35 
36 #define CHAN2G(_channel, _freq, _flags) {   \
37 	.band           = NL80211_BAND_2GHZ,  \
38 	.hw_value       = (_channel),           \
39 	.center_freq    = (_freq),              \
40 	.flags          = (_flags),             \
41 	.max_antenna_gain   = 0,                \
42 	.max_power      = 30,                   \
43 }
44 
45 #define CHAN5G(_channel, _flags) {		    \
46 	.band           = NL80211_BAND_5GHZ,      \
47 	.hw_value       = (_channel),               \
48 	.center_freq    = 5000 + (5 * (_channel)),  \
49 	.flags          = (_flags),                 \
50 	.max_antenna_gain   = 0,                    \
51 	.max_power      = 30,                       \
52 }
53 
54 #define DEFAULT_BG_SCAN_PERIOD 60
55 
56 struct ath6kl_cfg80211_match_probe_ssid {
57 	struct cfg80211_ssid ssid;
58 	u8 flag;
59 };
60 
61 static struct ieee80211_rate ath6kl_rates[] = {
62 	RATETAB_ENT(10, 0x1, 0),
63 	RATETAB_ENT(20, 0x2, 0),
64 	RATETAB_ENT(55, 0x4, 0),
65 	RATETAB_ENT(110, 0x8, 0),
66 	RATETAB_ENT(60, 0x10, 0),
67 	RATETAB_ENT(90, 0x20, 0),
68 	RATETAB_ENT(120, 0x40, 0),
69 	RATETAB_ENT(180, 0x80, 0),
70 	RATETAB_ENT(240, 0x100, 0),
71 	RATETAB_ENT(360, 0x200, 0),
72 	RATETAB_ENT(480, 0x400, 0),
73 	RATETAB_ENT(540, 0x800, 0),
74 };
75 
76 #define ath6kl_a_rates     (ath6kl_rates + 4)
77 #define ath6kl_a_rates_size    8
78 #define ath6kl_g_rates     (ath6kl_rates + 0)
79 #define ath6kl_g_rates_size    12
80 
81 #define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
82 #define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
83 			IEEE80211_HT_CAP_SGI_20		 | \
84 			IEEE80211_HT_CAP_SGI_40)
85 
86 static struct ieee80211_channel ath6kl_2ghz_channels[] = {
87 	CHAN2G(1, 2412, 0),
88 	CHAN2G(2, 2417, 0),
89 	CHAN2G(3, 2422, 0),
90 	CHAN2G(4, 2427, 0),
91 	CHAN2G(5, 2432, 0),
92 	CHAN2G(6, 2437, 0),
93 	CHAN2G(7, 2442, 0),
94 	CHAN2G(8, 2447, 0),
95 	CHAN2G(9, 2452, 0),
96 	CHAN2G(10, 2457, 0),
97 	CHAN2G(11, 2462, 0),
98 	CHAN2G(12, 2467, 0),
99 	CHAN2G(13, 2472, 0),
100 	CHAN2G(14, 2484, 0),
101 };
102 
103 static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
104 	CHAN5G(34, 0), CHAN5G(36, 0),
105 	CHAN5G(38, 0), CHAN5G(40, 0),
106 	CHAN5G(42, 0), CHAN5G(44, 0),
107 	CHAN5G(46, 0), CHAN5G(48, 0),
108 	CHAN5G(52, 0), CHAN5G(56, 0),
109 	CHAN5G(60, 0), CHAN5G(64, 0),
110 	CHAN5G(100, 0), CHAN5G(104, 0),
111 	CHAN5G(108, 0), CHAN5G(112, 0),
112 	CHAN5G(116, 0), CHAN5G(120, 0),
113 	CHAN5G(124, 0), CHAN5G(128, 0),
114 	CHAN5G(132, 0), CHAN5G(136, 0),
115 	CHAN5G(140, 0), CHAN5G(149, 0),
116 	CHAN5G(153, 0), CHAN5G(157, 0),
117 	CHAN5G(161, 0), CHAN5G(165, 0),
118 	CHAN5G(184, 0), CHAN5G(188, 0),
119 	CHAN5G(192, 0), CHAN5G(196, 0),
120 	CHAN5G(200, 0), CHAN5G(204, 0),
121 	CHAN5G(208, 0), CHAN5G(212, 0),
122 	CHAN5G(216, 0),
123 };
124 
125 static struct ieee80211_supported_band ath6kl_band_2ghz = {
126 	.n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
127 	.channels = ath6kl_2ghz_channels,
128 	.n_bitrates = ath6kl_g_rates_size,
129 	.bitrates = ath6kl_g_rates,
130 	.ht_cap.cap = ath6kl_g_htcap,
131 	.ht_cap.ht_supported = true,
132 };
133 
134 static struct ieee80211_supported_band ath6kl_band_5ghz = {
135 	.n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
136 	.channels = ath6kl_5ghz_a_channels,
137 	.n_bitrates = ath6kl_a_rates_size,
138 	.bitrates = ath6kl_a_rates,
139 	.ht_cap.cap = ath6kl_a_htcap,
140 	.ht_cap.ht_supported = true,
141 };
142 
143 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
144 
145 /* returns true if scheduled scan was stopped */
__ath6kl_cfg80211_sscan_stop(struct ath6kl_vif * vif)146 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
147 {
148 	struct ath6kl *ar = vif->ar;
149 
150 	if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
151 		return false;
152 
153 	del_timer_sync(&vif->sched_scan_timer);
154 
155 	if (ar->state == ATH6KL_STATE_RECOVERY)
156 		return true;
157 
158 	ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
159 
160 	return true;
161 }
162 
ath6kl_cfg80211_sscan_disable(struct ath6kl_vif * vif)163 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
164 {
165 	struct ath6kl *ar = vif->ar;
166 	bool stopped;
167 
168 	stopped = __ath6kl_cfg80211_sscan_stop(vif);
169 
170 	if (!stopped)
171 		return;
172 
173 	cfg80211_sched_scan_stopped(ar->wiphy);
174 }
175 
ath6kl_set_wpa_version(struct ath6kl_vif * vif,enum nl80211_wpa_versions wpa_version)176 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
177 				  enum nl80211_wpa_versions wpa_version)
178 {
179 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
180 
181 	if (!wpa_version) {
182 		vif->auth_mode = NONE_AUTH;
183 	} else if (wpa_version & NL80211_WPA_VERSION_2) {
184 		vif->auth_mode = WPA2_AUTH;
185 	} else if (wpa_version & NL80211_WPA_VERSION_1) {
186 		vif->auth_mode = WPA_AUTH;
187 	} else {
188 		ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
189 		return -ENOTSUPP;
190 	}
191 
192 	return 0;
193 }
194 
ath6kl_set_auth_type(struct ath6kl_vif * vif,enum nl80211_auth_type auth_type)195 static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
196 				enum nl80211_auth_type auth_type)
197 {
198 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
199 
200 	switch (auth_type) {
201 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
202 		vif->dot11_auth_mode = OPEN_AUTH;
203 		break;
204 	case NL80211_AUTHTYPE_SHARED_KEY:
205 		vif->dot11_auth_mode = SHARED_AUTH;
206 		break;
207 	case NL80211_AUTHTYPE_NETWORK_EAP:
208 		vif->dot11_auth_mode = LEAP_AUTH;
209 		break;
210 
211 	case NL80211_AUTHTYPE_AUTOMATIC:
212 		vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
213 		break;
214 
215 	default:
216 		ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
217 		return -ENOTSUPP;
218 	}
219 
220 	return 0;
221 }
222 
ath6kl_set_cipher(struct ath6kl_vif * vif,u32 cipher,bool ucast)223 static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
224 {
225 	u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
226 	u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
227 		&vif->grp_crypto_len;
228 
229 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
230 		   __func__, cipher, ucast);
231 
232 	switch (cipher) {
233 	case 0:
234 		/* our own hack to use value 0 as no crypto used */
235 		*ar_cipher = NONE_CRYPT;
236 		*ar_cipher_len = 0;
237 		break;
238 	case WLAN_CIPHER_SUITE_WEP40:
239 		*ar_cipher = WEP_CRYPT;
240 		*ar_cipher_len = 5;
241 		break;
242 	case WLAN_CIPHER_SUITE_WEP104:
243 		*ar_cipher = WEP_CRYPT;
244 		*ar_cipher_len = 13;
245 		break;
246 	case WLAN_CIPHER_SUITE_TKIP:
247 		*ar_cipher = TKIP_CRYPT;
248 		*ar_cipher_len = 0;
249 		break;
250 	case WLAN_CIPHER_SUITE_CCMP:
251 		*ar_cipher = AES_CRYPT;
252 		*ar_cipher_len = 0;
253 		break;
254 	case WLAN_CIPHER_SUITE_SMS4:
255 		*ar_cipher = WAPI_CRYPT;
256 		*ar_cipher_len = 0;
257 		break;
258 	default:
259 		ath6kl_err("cipher 0x%x not supported\n", cipher);
260 		return -ENOTSUPP;
261 	}
262 
263 	return 0;
264 }
265 
ath6kl_set_key_mgmt(struct ath6kl_vif * vif,u32 key_mgmt)266 static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
267 {
268 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
269 
270 	if (key_mgmt == WLAN_AKM_SUITE_PSK) {
271 		if (vif->auth_mode == WPA_AUTH)
272 			vif->auth_mode = WPA_PSK_AUTH;
273 		else if (vif->auth_mode == WPA2_AUTH)
274 			vif->auth_mode = WPA2_PSK_AUTH;
275 	} else if (key_mgmt == 0x00409600) {
276 		if (vif->auth_mode == WPA_AUTH)
277 			vif->auth_mode = WPA_AUTH_CCKM;
278 		else if (vif->auth_mode == WPA2_AUTH)
279 			vif->auth_mode = WPA2_AUTH_CCKM;
280 	} else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
281 		vif->auth_mode = NONE_AUTH;
282 	}
283 }
284 
ath6kl_cfg80211_ready(struct ath6kl_vif * vif)285 static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
286 {
287 	struct ath6kl *ar = vif->ar;
288 
289 	if (!test_bit(WMI_READY, &ar->flag)) {
290 		ath6kl_err("wmi is not ready\n");
291 		return false;
292 	}
293 
294 	if (!test_bit(WLAN_ENABLED, &vif->flags)) {
295 		ath6kl_err("wlan disabled\n");
296 		return false;
297 	}
298 
299 	return true;
300 }
301 
ath6kl_is_wpa_ie(const u8 * pos)302 static bool ath6kl_is_wpa_ie(const u8 *pos)
303 {
304 	return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
305 		pos[2] == 0x00 && pos[3] == 0x50 &&
306 		pos[4] == 0xf2 && pos[5] == 0x01;
307 }
308 
ath6kl_is_rsn_ie(const u8 * pos)309 static bool ath6kl_is_rsn_ie(const u8 *pos)
310 {
311 	return pos[0] == WLAN_EID_RSN;
312 }
313 
ath6kl_is_wps_ie(const u8 * pos)314 static bool ath6kl_is_wps_ie(const u8 *pos)
315 {
316 	return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
317 		pos[1] >= 4 &&
318 		pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
319 		pos[5] == 0x04);
320 }
321 
ath6kl_set_assoc_req_ies(struct ath6kl_vif * vif,const u8 * ies,size_t ies_len)322 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
323 				    size_t ies_len)
324 {
325 	struct ath6kl *ar = vif->ar;
326 	const u8 *pos;
327 	u8 *buf = NULL;
328 	size_t len = 0;
329 	int ret;
330 
331 	/*
332 	 * Clear previously set flag
333 	 */
334 
335 	ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
336 
337 	/*
338 	 * Filter out RSN/WPA IE(s)
339 	 */
340 
341 	if (ies && ies_len) {
342 		buf = kmalloc(ies_len, GFP_KERNEL);
343 		if (buf == NULL)
344 			return -ENOMEM;
345 		pos = ies;
346 
347 		while (pos + 1 < ies + ies_len) {
348 			if (pos + 2 + pos[1] > ies + ies_len)
349 				break;
350 			if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
351 				memcpy(buf + len, pos, 2 + pos[1]);
352 				len += 2 + pos[1];
353 			}
354 
355 			if (ath6kl_is_wps_ie(pos))
356 				ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
357 
358 			pos += 2 + pos[1];
359 		}
360 	}
361 
362 	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
363 				       WMI_FRAME_ASSOC_REQ, buf, len);
364 	kfree(buf);
365 	return ret;
366 }
367 
ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type,u8 * nw_type)368 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
369 {
370 	switch (type) {
371 	case NL80211_IFTYPE_STATION:
372 	case NL80211_IFTYPE_P2P_CLIENT:
373 		*nw_type = INFRA_NETWORK;
374 		break;
375 	case NL80211_IFTYPE_ADHOC:
376 		*nw_type = ADHOC_NETWORK;
377 		break;
378 	case NL80211_IFTYPE_AP:
379 	case NL80211_IFTYPE_P2P_GO:
380 		*nw_type = AP_NETWORK;
381 		break;
382 	default:
383 		ath6kl_err("invalid interface type %u\n", type);
384 		return -ENOTSUPP;
385 	}
386 
387 	return 0;
388 }
389 
ath6kl_is_valid_iftype(struct ath6kl * ar,enum nl80211_iftype type,u8 * if_idx,u8 * nw_type)390 static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
391 				   u8 *if_idx, u8 *nw_type)
392 {
393 	int i;
394 
395 	if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
396 		return false;
397 
398 	if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
399 				   ar->num_vif))
400 		return false;
401 
402 	if (type == NL80211_IFTYPE_STATION ||
403 	    type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
404 		for (i = 0; i < ar->vif_max; i++) {
405 			if ((ar->avail_idx_map) & BIT(i)) {
406 				*if_idx = i;
407 				return true;
408 			}
409 		}
410 	}
411 
412 	if (type == NL80211_IFTYPE_P2P_CLIENT ||
413 	    type == NL80211_IFTYPE_P2P_GO) {
414 		for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
415 			if ((ar->avail_idx_map) & BIT(i)) {
416 				*if_idx = i;
417 				return true;
418 			}
419 		}
420 	}
421 
422 	return false;
423 }
424 
ath6kl_is_tx_pending(struct ath6kl * ar)425 static bool ath6kl_is_tx_pending(struct ath6kl *ar)
426 {
427 	return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
428 }
429 
ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif * vif,bool enable)430 static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
431 					      bool enable)
432 {
433 	int err;
434 
435 	if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
436 		return;
437 
438 	if (vif->nw_type != INFRA_NETWORK)
439 		return;
440 
441 	if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
442 		      vif->ar->fw_capabilities))
443 		return;
444 
445 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
446 		   enable ? "enable" : "disable");
447 
448 	err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
449 					       vif->fw_vif_idx, enable);
450 	if (err)
451 		ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
452 			   enable ? "enable" : "disable", err);
453 }
454 
ath6kl_cfg80211_connect(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_connect_params * sme)455 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
456 				   struct cfg80211_connect_params *sme)
457 {
458 	struct ath6kl *ar = ath6kl_priv(dev);
459 	struct ath6kl_vif *vif = netdev_priv(dev);
460 	int status;
461 	u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
462 	u16 interval;
463 
464 	ath6kl_cfg80211_sscan_disable(vif);
465 
466 	vif->sme_state = SME_CONNECTING;
467 
468 	if (!ath6kl_cfg80211_ready(vif))
469 		return -EIO;
470 
471 	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
472 		ath6kl_err("destroy in progress\n");
473 		return -EBUSY;
474 	}
475 
476 	if (test_bit(SKIP_SCAN, &ar->flag) &&
477 	    ((sme->channel && sme->channel->center_freq == 0) ||
478 	     (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
479 		ath6kl_err("SkipScan: channel or bssid invalid\n");
480 		return -EINVAL;
481 	}
482 
483 	if (down_interruptible(&ar->sem)) {
484 		ath6kl_err("busy, couldn't get access\n");
485 		return -ERESTARTSYS;
486 	}
487 
488 	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
489 		ath6kl_err("busy, destroy in progress\n");
490 		up(&ar->sem);
491 		return -EBUSY;
492 	}
493 
494 	if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
495 		/*
496 		 * sleep until the command queue drains
497 		 */
498 		wait_event_interruptible_timeout(ar->event_wq,
499 						 ath6kl_is_tx_pending(ar),
500 						 WMI_TIMEOUT);
501 		if (signal_pending(current)) {
502 			ath6kl_err("cmd queue drain timeout\n");
503 			up(&ar->sem);
504 			return -EINTR;
505 		}
506 	}
507 
508 	status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
509 	if (status) {
510 		up(&ar->sem);
511 		return status;
512 	}
513 
514 	if (sme->ie == NULL || sme->ie_len == 0)
515 		ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
516 
517 	if (test_bit(CONNECTED, &vif->flags) &&
518 	    vif->ssid_len == sme->ssid_len &&
519 	    !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
520 		vif->reconnect_flag = true;
521 		status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
522 						  vif->req_bssid,
523 						  vif->ch_hint);
524 
525 		up(&ar->sem);
526 		if (status) {
527 			ath6kl_err("wmi_reconnect_cmd failed\n");
528 			return -EIO;
529 		}
530 		return 0;
531 	} else if (vif->ssid_len == sme->ssid_len &&
532 		   !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
533 		ath6kl_disconnect(vif);
534 	}
535 
536 	memset(vif->ssid, 0, sizeof(vif->ssid));
537 	vif->ssid_len = sme->ssid_len;
538 	memcpy(vif->ssid, sme->ssid, sme->ssid_len);
539 
540 	if (sme->channel)
541 		vif->ch_hint = sme->channel->center_freq;
542 
543 	memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
544 	if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
545 		memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
546 
547 	ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
548 
549 	status = ath6kl_set_auth_type(vif, sme->auth_type);
550 	if (status) {
551 		up(&ar->sem);
552 		return status;
553 	}
554 
555 	if (sme->crypto.n_ciphers_pairwise)
556 		ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
557 	else
558 		ath6kl_set_cipher(vif, 0, true);
559 
560 	ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
561 
562 	if (sme->crypto.n_akm_suites)
563 		ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
564 
565 	if ((sme->key_len) &&
566 	    (vif->auth_mode == NONE_AUTH) &&
567 	    (vif->prwise_crypto == WEP_CRYPT)) {
568 		struct ath6kl_key *key = NULL;
569 
570 		if (sme->key_idx > WMI_MAX_KEY_INDEX) {
571 			ath6kl_err("key index %d out of bounds\n",
572 				   sme->key_idx);
573 			up(&ar->sem);
574 			return -ENOENT;
575 		}
576 
577 		key = &vif->keys[sme->key_idx];
578 		key->key_len = sme->key_len;
579 		memcpy(key->key, sme->key, key->key_len);
580 		key->cipher = vif->prwise_crypto;
581 		vif->def_txkey_index = sme->key_idx;
582 
583 		ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
584 				      vif->prwise_crypto,
585 				      GROUP_USAGE | TX_USAGE,
586 				      key->key_len,
587 				      NULL, 0,
588 				      key->key, KEY_OP_INIT_VAL, NULL,
589 				      NO_SYNC_WMIFLAG);
590 	}
591 
592 	if (!ar->usr_bss_filter) {
593 		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
594 		if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
595 					     ALL_BSS_FILTER, 0) != 0) {
596 			ath6kl_err("couldn't set bss filtering\n");
597 			up(&ar->sem);
598 			return -EIO;
599 		}
600 	}
601 
602 	vif->nw_type = vif->next_mode;
603 
604 	/* enable enhanced bmiss detection if applicable */
605 	ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
606 
607 	if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
608 		nw_subtype = SUBTYPE_P2PCLIENT;
609 
610 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
611 		   "%s: connect called with authmode %d dot11 auth %d"
612 		   " PW crypto %d PW crypto len %d GRP crypto %d"
613 		   " GRP crypto len %d channel hint %u\n",
614 		   __func__,
615 		   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
616 		   vif->prwise_crypto_len, vif->grp_crypto,
617 		   vif->grp_crypto_len, vif->ch_hint);
618 
619 	vif->reconnect_flag = 0;
620 
621 	if (vif->nw_type == INFRA_NETWORK) {
622 		interval = max_t(u16, vif->listen_intvl_t,
623 				 ATH6KL_MAX_WOW_LISTEN_INTL);
624 		status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
625 						       interval,
626 						       0);
627 		if (status) {
628 			ath6kl_err("couldn't set listen intervel\n");
629 			up(&ar->sem);
630 			return status;
631 		}
632 	}
633 
634 	status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
635 					vif->dot11_auth_mode, vif->auth_mode,
636 					vif->prwise_crypto,
637 					vif->prwise_crypto_len,
638 					vif->grp_crypto, vif->grp_crypto_len,
639 					vif->ssid_len, vif->ssid,
640 					vif->req_bssid, vif->ch_hint,
641 					ar->connect_ctrl_flags, nw_subtype);
642 
643 	if (sme->bg_scan_period == 0) {
644 		/* disable background scan if period is 0 */
645 		sme->bg_scan_period = 0xffff;
646 	} else if (sme->bg_scan_period == -1) {
647 		/* configure default value if not specified */
648 		sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
649 	}
650 
651 	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
652 				  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
653 
654 	up(&ar->sem);
655 
656 	if (status == -EINVAL) {
657 		memset(vif->ssid, 0, sizeof(vif->ssid));
658 		vif->ssid_len = 0;
659 		ath6kl_err("invalid request\n");
660 		return -ENOENT;
661 	} else if (status) {
662 		ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
663 		return -EIO;
664 	}
665 
666 	if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
667 	    ((vif->auth_mode == WPA_PSK_AUTH) ||
668 	     (vif->auth_mode == WPA2_PSK_AUTH))) {
669 		mod_timer(&vif->disconnect_timer,
670 			  jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
671 	}
672 
673 	ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
674 	set_bit(CONNECT_PEND, &vif->flags);
675 
676 	return 0;
677 }
678 
679 static struct cfg80211_bss *
ath6kl_add_bss_if_needed(struct ath6kl_vif * vif,enum network_type nw_type,const u8 * bssid,struct ieee80211_channel * chan,const u8 * beacon_ie,size_t beacon_ie_len)680 ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
681 			 enum network_type nw_type,
682 			 const u8 *bssid,
683 			 struct ieee80211_channel *chan,
684 			 const u8 *beacon_ie,
685 			 size_t beacon_ie_len)
686 {
687 	struct ath6kl *ar = vif->ar;
688 	struct cfg80211_bss *bss;
689 	u16 cap_val;
690 	enum ieee80211_bss_type bss_type;
691 	u8 *ie;
692 
693 	if (nw_type & ADHOC_NETWORK) {
694 		cap_val = WLAN_CAPABILITY_IBSS;
695 		bss_type = IEEE80211_BSS_TYPE_IBSS;
696 	} else {
697 		cap_val = WLAN_CAPABILITY_ESS;
698 		bss_type = IEEE80211_BSS_TYPE_ESS;
699 	}
700 
701 	bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
702 			       vif->ssid, vif->ssid_len,
703 			       bss_type, IEEE80211_PRIVACY_ANY);
704 	if (bss == NULL) {
705 		/*
706 		 * Since cfg80211 may not yet know about the BSS,
707 		 * generate a partial entry until the first BSS info
708 		 * event becomes available.
709 		 *
710 		 * Prepend SSID element since it is not included in the Beacon
711 		 * IEs from the target.
712 		 */
713 		ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
714 		if (ie == NULL)
715 			return NULL;
716 		ie[0] = WLAN_EID_SSID;
717 		ie[1] = vif->ssid_len;
718 		memcpy(ie + 2, vif->ssid, vif->ssid_len);
719 		memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
720 		bss = cfg80211_inform_bss(ar->wiphy, chan,
721 					  CFG80211_BSS_FTYPE_UNKNOWN,
722 					  bssid, 0, cap_val, 100,
723 					  ie, 2 + vif->ssid_len + beacon_ie_len,
724 					  0, GFP_KERNEL);
725 		if (bss)
726 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
727 				   "added bss %pM to cfg80211\n", bssid);
728 		kfree(ie);
729 	} else {
730 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
731 	}
732 
733 	return bss;
734 }
735 
ath6kl_cfg80211_connect_event(struct ath6kl_vif * vif,u16 channel,u8 * bssid,u16 listen_intvl,u16 beacon_intvl,enum network_type nw_type,u8 beacon_ie_len,u8 assoc_req_len,u8 assoc_resp_len,u8 * assoc_info)736 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
737 				   u8 *bssid, u16 listen_intvl,
738 				   u16 beacon_intvl,
739 				   enum network_type nw_type,
740 				   u8 beacon_ie_len, u8 assoc_req_len,
741 				   u8 assoc_resp_len, u8 *assoc_info)
742 {
743 	struct ieee80211_channel *chan;
744 	struct ath6kl *ar = vif->ar;
745 	struct cfg80211_bss *bss;
746 
747 	/* capinfo + listen interval */
748 	u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
749 
750 	/* capinfo + status code +  associd */
751 	u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
752 
753 	u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
754 	u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
755 	    assoc_resp_ie_offset;
756 
757 	assoc_req_len -= assoc_req_ie_offset;
758 	assoc_resp_len -= assoc_resp_ie_offset;
759 
760 	/*
761 	 * Store Beacon interval here; DTIM period will be available only once
762 	 * a Beacon frame from the AP is seen.
763 	 */
764 	vif->assoc_bss_beacon_int = beacon_intvl;
765 	clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
766 
767 	if (nw_type & ADHOC_NETWORK) {
768 		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
769 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
770 				   "%s: ath6k not in ibss mode\n", __func__);
771 			return;
772 		}
773 	}
774 
775 	if (nw_type & INFRA_NETWORK) {
776 		if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
777 		    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
778 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
779 				   "%s: ath6k not in station mode\n", __func__);
780 			return;
781 		}
782 	}
783 
784 	chan = ieee80211_get_channel(ar->wiphy, (int) channel);
785 
786 	bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
787 				       assoc_info, beacon_ie_len);
788 	if (!bss) {
789 		ath6kl_err("could not add cfg80211 bss entry\n");
790 		return;
791 	}
792 
793 	if (nw_type & ADHOC_NETWORK) {
794 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
795 			   nw_type & ADHOC_CREATOR ? "creator" : "joiner");
796 		cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
797 		cfg80211_put_bss(ar->wiphy, bss);
798 		return;
799 	}
800 
801 	if (vif->sme_state == SME_CONNECTING) {
802 		/* inform connect result to cfg80211 */
803 		vif->sme_state = SME_CONNECTED;
804 		cfg80211_connect_result(vif->ndev, bssid,
805 					assoc_req_ie, assoc_req_len,
806 					assoc_resp_ie, assoc_resp_len,
807 					WLAN_STATUS_SUCCESS, GFP_KERNEL);
808 		cfg80211_put_bss(ar->wiphy, bss);
809 	} else if (vif->sme_state == SME_CONNECTED) {
810 		/* inform roam event to cfg80211 */
811 		cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
812 				    assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
813 	}
814 }
815 
ath6kl_cfg80211_disconnect(struct wiphy * wiphy,struct net_device * dev,u16 reason_code)816 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
817 				      struct net_device *dev, u16 reason_code)
818 {
819 	struct ath6kl *ar = ath6kl_priv(dev);
820 	struct ath6kl_vif *vif = netdev_priv(dev);
821 
822 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
823 		   reason_code);
824 
825 	ath6kl_cfg80211_sscan_disable(vif);
826 
827 	if (!ath6kl_cfg80211_ready(vif))
828 		return -EIO;
829 
830 	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
831 		ath6kl_err("busy, destroy in progress\n");
832 		return -EBUSY;
833 	}
834 
835 	if (down_interruptible(&ar->sem)) {
836 		ath6kl_err("busy, couldn't get access\n");
837 		return -ERESTARTSYS;
838 	}
839 
840 	vif->reconnect_flag = 0;
841 	ath6kl_disconnect(vif);
842 	memset(vif->ssid, 0, sizeof(vif->ssid));
843 	vif->ssid_len = 0;
844 
845 	if (!test_bit(SKIP_SCAN, &ar->flag))
846 		memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
847 
848 	up(&ar->sem);
849 
850 	return 0;
851 }
852 
ath6kl_cfg80211_disconnect_event(struct ath6kl_vif * vif,u8 reason,u8 * bssid,u8 assoc_resp_len,u8 * assoc_info,u16 proto_reason)853 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
854 				      u8 *bssid, u8 assoc_resp_len,
855 				      u8 *assoc_info, u16 proto_reason)
856 {
857 	struct ath6kl *ar = vif->ar;
858 
859 	if (vif->scan_req) {
860 		struct cfg80211_scan_info info = {
861 			.aborted = true,
862 		};
863 
864 		cfg80211_scan_done(vif->scan_req, &info);
865 		vif->scan_req = NULL;
866 	}
867 
868 	if (vif->nw_type & ADHOC_NETWORK) {
869 		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
870 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
871 				   "%s: ath6k not in ibss mode\n", __func__);
872 		return;
873 	}
874 
875 	if (vif->nw_type & INFRA_NETWORK) {
876 		if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
877 		    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
878 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
879 				   "%s: ath6k not in station mode\n", __func__);
880 			return;
881 		}
882 	}
883 
884 	clear_bit(CONNECT_PEND, &vif->flags);
885 
886 	if (vif->sme_state == SME_CONNECTING) {
887 		cfg80211_connect_result(vif->ndev,
888 					bssid, NULL, 0,
889 					NULL, 0,
890 					WLAN_STATUS_UNSPECIFIED_FAILURE,
891 					GFP_KERNEL);
892 	} else if (vif->sme_state == SME_CONNECTED) {
893 		cfg80211_disconnected(vif->ndev, proto_reason,
894 				      NULL, 0, false, GFP_KERNEL);
895 	}
896 
897 	vif->sme_state = SME_DISCONNECTED;
898 
899 	/*
900 	 * Send a disconnect command to target when a disconnect event is
901 	 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
902 	 * request from host) to make the firmware stop trying to connect even
903 	 * after giving disconnect event. There will be one more disconnect
904 	 * event for this disconnect command with reason code DISCONNECT_CMD
905 	 * which won't be notified to cfg80211.
906 	 */
907 	if (reason != DISCONNECT_CMD)
908 		ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
909 }
910 
ath6kl_set_probed_ssids(struct ath6kl * ar,struct ath6kl_vif * vif,struct cfg80211_ssid * ssids,int n_ssids,struct cfg80211_match_set * match_set,int n_match_ssid)911 static int ath6kl_set_probed_ssids(struct ath6kl *ar,
912 				   struct ath6kl_vif *vif,
913 				   struct cfg80211_ssid *ssids, int n_ssids,
914 				   struct cfg80211_match_set *match_set,
915 				   int n_match_ssid)
916 {
917 	u8 i, j, index_to_add, ssid_found = false;
918 	struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
919 
920 	memset(ssid_list, 0, sizeof(ssid_list));
921 
922 	if (n_ssids > MAX_PROBED_SSIDS ||
923 	    n_match_ssid > MAX_PROBED_SSIDS)
924 		return -EINVAL;
925 
926 	for (i = 0; i < n_ssids; i++) {
927 		memcpy(ssid_list[i].ssid.ssid,
928 		       ssids[i].ssid,
929 		       ssids[i].ssid_len);
930 		ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
931 
932 		if (ssids[i].ssid_len)
933 			ssid_list[i].flag = SPECIFIC_SSID_FLAG;
934 		else
935 			ssid_list[i].flag = ANY_SSID_FLAG;
936 
937 		if (n_match_ssid == 0)
938 			ssid_list[i].flag |= MATCH_SSID_FLAG;
939 	}
940 
941 	index_to_add = i;
942 
943 	for (i = 0; i < n_match_ssid; i++) {
944 		ssid_found = false;
945 
946 		for (j = 0; j < n_ssids; j++) {
947 			if ((match_set[i].ssid.ssid_len ==
948 			     ssid_list[j].ssid.ssid_len) &&
949 			    (!memcmp(ssid_list[j].ssid.ssid,
950 				     match_set[i].ssid.ssid,
951 				     match_set[i].ssid.ssid_len))) {
952 				ssid_list[j].flag |= MATCH_SSID_FLAG;
953 				ssid_found = true;
954 				break;
955 			}
956 		}
957 
958 		if (ssid_found)
959 			continue;
960 
961 		if (index_to_add >= MAX_PROBED_SSIDS)
962 			continue;
963 
964 		ssid_list[index_to_add].ssid.ssid_len =
965 			match_set[i].ssid.ssid_len;
966 		memcpy(ssid_list[index_to_add].ssid.ssid,
967 		       match_set[i].ssid.ssid,
968 		       match_set[i].ssid.ssid_len);
969 		ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
970 		index_to_add++;
971 	}
972 
973 	for (i = 0; i < index_to_add; i++) {
974 		ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
975 					  ssid_list[i].flag,
976 					  ssid_list[i].ssid.ssid_len,
977 					  ssid_list[i].ssid.ssid);
978 	}
979 
980 	/* Make sure no old entries are left behind */
981 	for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
982 		ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
983 					  DISABLE_SSID_FLAG, 0, NULL);
984 	}
985 
986 	return 0;
987 }
988 
ath6kl_cfg80211_scan(struct wiphy * wiphy,struct cfg80211_scan_request * request)989 static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
990 				struct cfg80211_scan_request *request)
991 {
992 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
993 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
994 	s8 n_channels = 0;
995 	u16 *channels = NULL;
996 	int ret = 0;
997 	u32 force_fg_scan = 0;
998 
999 	if (!ath6kl_cfg80211_ready(vif))
1000 		return -EIO;
1001 
1002 	ath6kl_cfg80211_sscan_disable(vif);
1003 
1004 	if (!ar->usr_bss_filter) {
1005 		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1006 		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
1007 					       ALL_BSS_FILTER, 0);
1008 		if (ret) {
1009 			ath6kl_err("couldn't set bss filtering\n");
1010 			return ret;
1011 		}
1012 	}
1013 
1014 	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
1015 				      request->n_ssids, NULL, 0);
1016 	if (ret < 0)
1017 		return ret;
1018 
1019 	/* this also clears IE in fw if it's not set */
1020 	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1021 				       WMI_FRAME_PROBE_REQ,
1022 				       request->ie, request->ie_len);
1023 	if (ret) {
1024 		ath6kl_err("failed to set Probe Request appie for scan\n");
1025 		return ret;
1026 	}
1027 
1028 	/*
1029 	 * Scan only the requested channels if the request specifies a set of
1030 	 * channels. If the list is longer than the target supports, do not
1031 	 * configure the list and instead, scan all available channels.
1032 	 */
1033 	if (request->n_channels > 0 &&
1034 	    request->n_channels <= WMI_MAX_CHANNELS) {
1035 		u8 i;
1036 
1037 		n_channels = request->n_channels;
1038 
1039 		channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
1040 		if (channels == NULL) {
1041 			ath6kl_warn("failed to set scan channels, scan all channels");
1042 			n_channels = 0;
1043 		}
1044 
1045 		for (i = 0; i < n_channels; i++)
1046 			channels[i] = request->channels[i]->center_freq;
1047 	}
1048 
1049 	if (test_bit(CONNECTED, &vif->flags))
1050 		force_fg_scan = 1;
1051 
1052 	vif->scan_req = request;
1053 
1054 	ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1055 				       WMI_LONG_SCAN, force_fg_scan,
1056 				       false, 0,
1057 				       ATH6KL_FG_SCAN_INTERVAL,
1058 				       n_channels, channels,
1059 				       request->no_cck,
1060 				       request->rates);
1061 	if (ret) {
1062 		ath6kl_err("failed to start scan: %d\n", ret);
1063 		vif->scan_req = NULL;
1064 	}
1065 
1066 	kfree(channels);
1067 
1068 	return ret;
1069 }
1070 
ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif * vif,bool aborted)1071 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1072 {
1073 	struct ath6kl *ar = vif->ar;
1074 	struct cfg80211_scan_info info = {
1075 		.aborted = aborted,
1076 	};
1077 	int i;
1078 
1079 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1080 		   aborted ? " aborted" : "");
1081 
1082 	if (!vif->scan_req)
1083 		return;
1084 
1085 	if (aborted)
1086 		goto out;
1087 
1088 	if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1089 		for (i = 0; i < vif->scan_req->n_ssids; i++) {
1090 			ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1091 						  i + 1, DISABLE_SSID_FLAG,
1092 						  0, NULL);
1093 		}
1094 	}
1095 
1096 out:
1097 	cfg80211_scan_done(vif->scan_req, &info);
1098 	vif->scan_req = NULL;
1099 }
1100 
ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif * vif,int freq,enum wmi_phy_mode mode)1101 void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1102 				      enum wmi_phy_mode mode)
1103 {
1104 	struct cfg80211_chan_def chandef;
1105 
1106 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1107 		   "channel switch notify nw_type %d freq %d mode %d\n",
1108 		   vif->nw_type, freq, mode);
1109 
1110 	cfg80211_chandef_create(&chandef,
1111 				ieee80211_get_channel(vif->ar->wiphy, freq),
1112 				(mode == WMI_11G_HT20 &&
1113 				 ath6kl_band_2ghz.ht_cap.ht_supported) ?
1114 					NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1115 
1116 	mutex_lock(&vif->wdev.mtx);
1117 	cfg80211_ch_switch_notify(vif->ndev, &chandef);
1118 	mutex_unlock(&vif->wdev.mtx);
1119 }
1120 
ath6kl_cfg80211_add_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool pairwise,const u8 * mac_addr,struct key_params * params)1121 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1122 				   u8 key_index, bool pairwise,
1123 				   const u8 *mac_addr,
1124 				   struct key_params *params)
1125 {
1126 	struct ath6kl *ar = ath6kl_priv(ndev);
1127 	struct ath6kl_vif *vif = netdev_priv(ndev);
1128 	struct ath6kl_key *key = NULL;
1129 	int seq_len;
1130 	u8 key_usage;
1131 	u8 key_type;
1132 
1133 	if (!ath6kl_cfg80211_ready(vif))
1134 		return -EIO;
1135 
1136 	if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1137 		if (params->key_len != WMI_KRK_LEN)
1138 			return -EINVAL;
1139 		return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1140 					      params->key);
1141 	}
1142 
1143 	if (key_index > WMI_MAX_KEY_INDEX) {
1144 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1145 			   "%s: key index %d out of bounds\n", __func__,
1146 			   key_index);
1147 		return -ENOENT;
1148 	}
1149 
1150 	key = &vif->keys[key_index];
1151 	memset(key, 0, sizeof(struct ath6kl_key));
1152 
1153 	if (pairwise)
1154 		key_usage = PAIRWISE_USAGE;
1155 	else
1156 		key_usage = GROUP_USAGE;
1157 
1158 	seq_len = params->seq_len;
1159 	if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1160 	    seq_len > ATH6KL_KEY_SEQ_LEN) {
1161 		/* Only first half of the WPI PN is configured */
1162 		seq_len = ATH6KL_KEY_SEQ_LEN;
1163 	}
1164 	if (params->key_len > WLAN_MAX_KEY_LEN ||
1165 	    seq_len > sizeof(key->seq))
1166 		return -EINVAL;
1167 
1168 	key->key_len = params->key_len;
1169 	memcpy(key->key, params->key, key->key_len);
1170 	key->seq_len = seq_len;
1171 	memcpy(key->seq, params->seq, key->seq_len);
1172 	key->cipher = params->cipher;
1173 
1174 	switch (key->cipher) {
1175 	case WLAN_CIPHER_SUITE_WEP40:
1176 	case WLAN_CIPHER_SUITE_WEP104:
1177 		key_type = WEP_CRYPT;
1178 		break;
1179 
1180 	case WLAN_CIPHER_SUITE_TKIP:
1181 		key_type = TKIP_CRYPT;
1182 		break;
1183 
1184 	case WLAN_CIPHER_SUITE_CCMP:
1185 		key_type = AES_CRYPT;
1186 		break;
1187 	case WLAN_CIPHER_SUITE_SMS4:
1188 		key_type = WAPI_CRYPT;
1189 		break;
1190 
1191 	default:
1192 		return -ENOTSUPP;
1193 	}
1194 
1195 	if (((vif->auth_mode == WPA_PSK_AUTH) ||
1196 	     (vif->auth_mode == WPA2_PSK_AUTH)) &&
1197 	    (key_usage & GROUP_USAGE))
1198 		del_timer(&vif->disconnect_timer);
1199 
1200 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1201 		   "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1202 		   __func__, key_index, key->key_len, key_type,
1203 		   key_usage, key->seq_len);
1204 
1205 	if (vif->nw_type == AP_NETWORK && !pairwise &&
1206 	    (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1207 	     key_type == WAPI_CRYPT)) {
1208 		ar->ap_mode_bkey.valid = true;
1209 		ar->ap_mode_bkey.key_index = key_index;
1210 		ar->ap_mode_bkey.key_type = key_type;
1211 		ar->ap_mode_bkey.key_len = key->key_len;
1212 		memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1213 		if (!test_bit(CONNECTED, &vif->flags)) {
1214 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1215 				   "Delay initial group key configuration until AP mode has been started\n");
1216 			/*
1217 			 * The key will be set in ath6kl_connect_ap_mode() once
1218 			 * the connected event is received from the target.
1219 			 */
1220 			return 0;
1221 		}
1222 	}
1223 
1224 	if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1225 	    !test_bit(CONNECTED, &vif->flags)) {
1226 		/*
1227 		 * Store the key locally so that it can be re-configured after
1228 		 * the AP mode has properly started
1229 		 * (ath6kl_install_statioc_wep_keys).
1230 		 */
1231 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1232 			   "Delay WEP key configuration until AP mode has been started\n");
1233 		vif->wep_key_list[key_index].key_len = key->key_len;
1234 		memcpy(vif->wep_key_list[key_index].key, key->key,
1235 		       key->key_len);
1236 		return 0;
1237 	}
1238 
1239 	return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1240 				     key_type, key_usage, key->key_len,
1241 				     key->seq, key->seq_len, key->key,
1242 				     KEY_OP_INIT_VAL,
1243 				     (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1244 }
1245 
ath6kl_cfg80211_del_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool pairwise,const u8 * mac_addr)1246 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1247 				   u8 key_index, bool pairwise,
1248 				   const u8 *mac_addr)
1249 {
1250 	struct ath6kl *ar = ath6kl_priv(ndev);
1251 	struct ath6kl_vif *vif = netdev_priv(ndev);
1252 
1253 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1254 
1255 	if (!ath6kl_cfg80211_ready(vif))
1256 		return -EIO;
1257 
1258 	if (key_index > WMI_MAX_KEY_INDEX) {
1259 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1260 			   "%s: key index %d out of bounds\n", __func__,
1261 			   key_index);
1262 		return -ENOENT;
1263 	}
1264 
1265 	if (!vif->keys[key_index].key_len) {
1266 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1267 			   "%s: index %d is empty\n", __func__, key_index);
1268 		return 0;
1269 	}
1270 
1271 	vif->keys[key_index].key_len = 0;
1272 
1273 	return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1274 }
1275 
ath6kl_cfg80211_get_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool pairwise,const u8 * mac_addr,void * cookie,void (* callback)(void * cookie,struct key_params *))1276 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1277 				   u8 key_index, bool pairwise,
1278 				   const u8 *mac_addr, void *cookie,
1279 				   void (*callback) (void *cookie,
1280 						     struct key_params *))
1281 {
1282 	struct ath6kl_vif *vif = netdev_priv(ndev);
1283 	struct ath6kl_key *key = NULL;
1284 	struct key_params params;
1285 
1286 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1287 
1288 	if (!ath6kl_cfg80211_ready(vif))
1289 		return -EIO;
1290 
1291 	if (key_index > WMI_MAX_KEY_INDEX) {
1292 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1293 			   "%s: key index %d out of bounds\n", __func__,
1294 			   key_index);
1295 		return -ENOENT;
1296 	}
1297 
1298 	key = &vif->keys[key_index];
1299 	memset(&params, 0, sizeof(params));
1300 	params.cipher = key->cipher;
1301 	params.key_len = key->key_len;
1302 	params.seq_len = key->seq_len;
1303 	params.seq = key->seq;
1304 	params.key = key->key;
1305 
1306 	callback(cookie, &params);
1307 
1308 	return key->key_len ? 0 : -ENOENT;
1309 }
1310 
ath6kl_cfg80211_set_default_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool unicast,bool multicast)1311 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1312 					   struct net_device *ndev,
1313 					   u8 key_index, bool unicast,
1314 					   bool multicast)
1315 {
1316 	struct ath6kl *ar = ath6kl_priv(ndev);
1317 	struct ath6kl_vif *vif = netdev_priv(ndev);
1318 	struct ath6kl_key *key = NULL;
1319 	u8 key_usage;
1320 	enum crypto_type key_type = NONE_CRYPT;
1321 
1322 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1323 
1324 	if (!ath6kl_cfg80211_ready(vif))
1325 		return -EIO;
1326 
1327 	if (key_index > WMI_MAX_KEY_INDEX) {
1328 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1329 			   "%s: key index %d out of bounds\n",
1330 			   __func__, key_index);
1331 		return -ENOENT;
1332 	}
1333 
1334 	if (!vif->keys[key_index].key_len) {
1335 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1336 			   __func__, key_index);
1337 		return -EINVAL;
1338 	}
1339 
1340 	vif->def_txkey_index = key_index;
1341 	key = &vif->keys[vif->def_txkey_index];
1342 	key_usage = GROUP_USAGE;
1343 	if (vif->prwise_crypto == WEP_CRYPT)
1344 		key_usage |= TX_USAGE;
1345 	if (unicast)
1346 		key_type = vif->prwise_crypto;
1347 	if (multicast)
1348 		key_type = vif->grp_crypto;
1349 
1350 	if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1351 		return 0; /* Delay until AP mode has been started */
1352 
1353 	return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1354 				     vif->def_txkey_index,
1355 				     key_type, key_usage,
1356 				     key->key_len, key->seq, key->seq_len,
1357 				     key->key,
1358 				     KEY_OP_INIT_VAL, NULL,
1359 				     SYNC_BOTH_WMIFLAG);
1360 }
1361 
ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif * vif,u8 keyid,bool ismcast)1362 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1363 				       bool ismcast)
1364 {
1365 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1366 		   "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1367 
1368 	cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1369 				     (ismcast ? NL80211_KEYTYPE_GROUP :
1370 				      NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1371 				     GFP_KERNEL);
1372 }
1373 
ath6kl_cfg80211_set_wiphy_params(struct wiphy * wiphy,u32 changed)1374 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1375 {
1376 	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1377 	struct ath6kl_vif *vif;
1378 	int ret;
1379 
1380 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1381 		   changed);
1382 
1383 	vif = ath6kl_vif_first(ar);
1384 	if (!vif)
1385 		return -EIO;
1386 
1387 	if (!ath6kl_cfg80211_ready(vif))
1388 		return -EIO;
1389 
1390 	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1391 		ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1392 		if (ret != 0) {
1393 			ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1394 			return -EIO;
1395 		}
1396 	}
1397 
1398 	return 0;
1399 }
1400 
ath6kl_cfg80211_set_txpower(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_tx_power_setting type,int mbm)1401 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1402 				       struct wireless_dev *wdev,
1403 				       enum nl80211_tx_power_setting type,
1404 				       int mbm)
1405 {
1406 	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1407 	struct ath6kl_vif *vif;
1408 	int dbm = MBM_TO_DBM(mbm);
1409 
1410 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1411 		   type, dbm);
1412 
1413 	vif = ath6kl_vif_first(ar);
1414 	if (!vif)
1415 		return -EIO;
1416 
1417 	if (!ath6kl_cfg80211_ready(vif))
1418 		return -EIO;
1419 
1420 	switch (type) {
1421 	case NL80211_TX_POWER_AUTOMATIC:
1422 		return 0;
1423 	case NL80211_TX_POWER_LIMITED:
1424 		ar->tx_pwr = dbm;
1425 		break;
1426 	default:
1427 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1428 			   __func__, type);
1429 		return -EOPNOTSUPP;
1430 	}
1431 
1432 	ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
1433 
1434 	return 0;
1435 }
1436 
ath6kl_cfg80211_get_txpower(struct wiphy * wiphy,struct wireless_dev * wdev,int * dbm)1437 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1438 				       struct wireless_dev *wdev,
1439 				       int *dbm)
1440 {
1441 	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1442 	struct ath6kl_vif *vif;
1443 
1444 	vif = ath6kl_vif_first(ar);
1445 	if (!vif)
1446 		return -EIO;
1447 
1448 	if (!ath6kl_cfg80211_ready(vif))
1449 		return -EIO;
1450 
1451 	if (test_bit(CONNECTED, &vif->flags)) {
1452 		ar->tx_pwr = 255;
1453 
1454 		if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1455 			ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1456 			return -EIO;
1457 		}
1458 
1459 		wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 255,
1460 						 5 * HZ);
1461 
1462 		if (signal_pending(current)) {
1463 			ath6kl_err("target did not respond\n");
1464 			return -EINTR;
1465 		}
1466 	}
1467 
1468 	*dbm = ar->tx_pwr;
1469 	return 0;
1470 }
1471 
ath6kl_cfg80211_set_power_mgmt(struct wiphy * wiphy,struct net_device * dev,bool pmgmt,int timeout)1472 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1473 					  struct net_device *dev,
1474 					  bool pmgmt, int timeout)
1475 {
1476 	struct ath6kl *ar = ath6kl_priv(dev);
1477 	struct wmi_power_mode_cmd mode;
1478 	struct ath6kl_vif *vif = netdev_priv(dev);
1479 
1480 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1481 		   __func__, pmgmt, timeout);
1482 
1483 	if (!ath6kl_cfg80211_ready(vif))
1484 		return -EIO;
1485 
1486 	if (pmgmt) {
1487 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1488 		mode.pwr_mode = REC_POWER;
1489 	} else {
1490 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1491 		mode.pwr_mode = MAX_PERF_POWER;
1492 	}
1493 
1494 	if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1495 				     mode.pwr_mode) != 0) {
1496 		ath6kl_err("wmi_powermode_cmd failed\n");
1497 		return -EIO;
1498 	}
1499 
1500 	return 0;
1501 }
1502 
ath6kl_cfg80211_add_iface(struct wiphy * wiphy,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u32 * flags,struct vif_params * params)1503 static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1504 						      const char *name,
1505 						      unsigned char name_assign_type,
1506 						      enum nl80211_iftype type,
1507 						      u32 *flags,
1508 						      struct vif_params *params)
1509 {
1510 	struct ath6kl *ar = wiphy_priv(wiphy);
1511 	struct wireless_dev *wdev;
1512 	u8 if_idx, nw_type;
1513 
1514 	if (ar->num_vif == ar->vif_max) {
1515 		ath6kl_err("Reached maximum number of supported vif\n");
1516 		return ERR_PTR(-EINVAL);
1517 	}
1518 
1519 	if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1520 		ath6kl_err("Not a supported interface type\n");
1521 		return ERR_PTR(-EINVAL);
1522 	}
1523 
1524 	wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type);
1525 	if (!wdev)
1526 		return ERR_PTR(-ENOMEM);
1527 
1528 	ar->num_vif++;
1529 
1530 	return wdev;
1531 }
1532 
ath6kl_cfg80211_del_iface(struct wiphy * wiphy,struct wireless_dev * wdev)1533 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1534 				     struct wireless_dev *wdev)
1535 {
1536 	struct ath6kl *ar = wiphy_priv(wiphy);
1537 	struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
1538 
1539 	spin_lock_bh(&ar->list_lock);
1540 	list_del(&vif->list);
1541 	spin_unlock_bh(&ar->list_lock);
1542 
1543 	ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1544 
1545 	rtnl_lock();
1546 	ath6kl_cfg80211_vif_cleanup(vif);
1547 	rtnl_unlock();
1548 
1549 	return 0;
1550 }
1551 
ath6kl_cfg80211_change_iface(struct wiphy * wiphy,struct net_device * ndev,enum nl80211_iftype type,u32 * flags,struct vif_params * params)1552 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1553 					struct net_device *ndev,
1554 					enum nl80211_iftype type, u32 *flags,
1555 					struct vif_params *params)
1556 {
1557 	struct ath6kl_vif *vif = netdev_priv(ndev);
1558 	int i;
1559 
1560 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1561 
1562 	/*
1563 	 * Don't bring up p2p on an interface which is not initialized
1564 	 * for p2p operation where fw does not have capability to switch
1565 	 * dynamically between non-p2p and p2p type interface.
1566 	 */
1567 	if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1568 		      vif->ar->fw_capabilities) &&
1569 	    (type == NL80211_IFTYPE_P2P_CLIENT ||
1570 	     type == NL80211_IFTYPE_P2P_GO)) {
1571 		if (vif->ar->vif_max == 1) {
1572 			if (vif->fw_vif_idx != 0)
1573 				return -EINVAL;
1574 			else
1575 				goto set_iface_type;
1576 		}
1577 
1578 		for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1579 			if (i == vif->fw_vif_idx)
1580 				break;
1581 		}
1582 
1583 		if (i == vif->ar->vif_max) {
1584 			ath6kl_err("Invalid interface to bring up P2P\n");
1585 			return -EINVAL;
1586 		}
1587 	}
1588 
1589 	/* need to clean up enhanced bmiss detection fw state */
1590 	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1591 
1592 set_iface_type:
1593 	switch (type) {
1594 	case NL80211_IFTYPE_STATION:
1595 	case NL80211_IFTYPE_P2P_CLIENT:
1596 		vif->next_mode = INFRA_NETWORK;
1597 		break;
1598 	case NL80211_IFTYPE_ADHOC:
1599 		vif->next_mode = ADHOC_NETWORK;
1600 		break;
1601 	case NL80211_IFTYPE_AP:
1602 	case NL80211_IFTYPE_P2P_GO:
1603 		vif->next_mode = AP_NETWORK;
1604 		break;
1605 	default:
1606 		ath6kl_err("invalid interface type %u\n", type);
1607 		return -EOPNOTSUPP;
1608 	}
1609 
1610 	vif->wdev.iftype = type;
1611 
1612 	return 0;
1613 }
1614 
ath6kl_cfg80211_join_ibss(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_ibss_params * ibss_param)1615 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1616 				     struct net_device *dev,
1617 				     struct cfg80211_ibss_params *ibss_param)
1618 {
1619 	struct ath6kl *ar = ath6kl_priv(dev);
1620 	struct ath6kl_vif *vif = netdev_priv(dev);
1621 	int status;
1622 
1623 	if (!ath6kl_cfg80211_ready(vif))
1624 		return -EIO;
1625 
1626 	vif->ssid_len = ibss_param->ssid_len;
1627 	memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1628 
1629 	if (ibss_param->chandef.chan)
1630 		vif->ch_hint = ibss_param->chandef.chan->center_freq;
1631 
1632 	if (ibss_param->channel_fixed) {
1633 		/*
1634 		 * TODO: channel_fixed: The channel should be fixed, do not
1635 		 * search for IBSSs to join on other channels. Target
1636 		 * firmware does not support this feature, needs to be
1637 		 * updated.
1638 		 */
1639 		return -EOPNOTSUPP;
1640 	}
1641 
1642 	memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1643 	if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1644 		memcpy(vif->req_bssid, ibss_param->bssid,
1645 		       sizeof(vif->req_bssid));
1646 
1647 	ath6kl_set_wpa_version(vif, 0);
1648 
1649 	status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1650 	if (status)
1651 		return status;
1652 
1653 	if (ibss_param->privacy) {
1654 		ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1655 		ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1656 	} else {
1657 		ath6kl_set_cipher(vif, 0, true);
1658 		ath6kl_set_cipher(vif, 0, false);
1659 	}
1660 
1661 	vif->nw_type = vif->next_mode;
1662 
1663 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1664 		   "%s: connect called with authmode %d dot11 auth %d"
1665 		   " PW crypto %d PW crypto len %d GRP crypto %d"
1666 		   " GRP crypto len %d channel hint %u\n",
1667 		   __func__,
1668 		   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1669 		   vif->prwise_crypto_len, vif->grp_crypto,
1670 		   vif->grp_crypto_len, vif->ch_hint);
1671 
1672 	status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1673 					vif->dot11_auth_mode, vif->auth_mode,
1674 					vif->prwise_crypto,
1675 					vif->prwise_crypto_len,
1676 					vif->grp_crypto, vif->grp_crypto_len,
1677 					vif->ssid_len, vif->ssid,
1678 					vif->req_bssid, vif->ch_hint,
1679 					ar->connect_ctrl_flags, SUBTYPE_NONE);
1680 	set_bit(CONNECT_PEND, &vif->flags);
1681 
1682 	return 0;
1683 }
1684 
ath6kl_cfg80211_leave_ibss(struct wiphy * wiphy,struct net_device * dev)1685 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1686 				      struct net_device *dev)
1687 {
1688 	struct ath6kl_vif *vif = netdev_priv(dev);
1689 
1690 	if (!ath6kl_cfg80211_ready(vif))
1691 		return -EIO;
1692 
1693 	ath6kl_disconnect(vif);
1694 	memset(vif->ssid, 0, sizeof(vif->ssid));
1695 	vif->ssid_len = 0;
1696 
1697 	return 0;
1698 }
1699 
1700 static const u32 cipher_suites[] = {
1701 	WLAN_CIPHER_SUITE_WEP40,
1702 	WLAN_CIPHER_SUITE_WEP104,
1703 	WLAN_CIPHER_SUITE_TKIP,
1704 	WLAN_CIPHER_SUITE_CCMP,
1705 	CCKM_KRK_CIPHER_SUITE,
1706 	WLAN_CIPHER_SUITE_SMS4,
1707 };
1708 
is_rate_legacy(s32 rate)1709 static bool is_rate_legacy(s32 rate)
1710 {
1711 	static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1712 		6000, 9000, 12000, 18000, 24000,
1713 		36000, 48000, 54000
1714 	};
1715 	u8 i;
1716 
1717 	for (i = 0; i < ARRAY_SIZE(legacy); i++)
1718 		if (rate == legacy[i])
1719 			return true;
1720 
1721 	return false;
1722 }
1723 
is_rate_ht20(s32 rate,u8 * mcs,bool * sgi)1724 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1725 {
1726 	static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1727 		52000, 58500, 65000, 72200
1728 	};
1729 	u8 i;
1730 
1731 	for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1732 		if (rate == ht20[i]) {
1733 			if (i == ARRAY_SIZE(ht20) - 1)
1734 				/* last rate uses sgi */
1735 				*sgi = true;
1736 			else
1737 				*sgi = false;
1738 
1739 			*mcs = i;
1740 			return true;
1741 		}
1742 	}
1743 	return false;
1744 }
1745 
is_rate_ht40(s32 rate,u8 * mcs,bool * sgi)1746 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1747 {
1748 	static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1749 		81000, 108000, 121500, 135000,
1750 		150000
1751 	};
1752 	u8 i;
1753 
1754 	for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1755 		if (rate == ht40[i]) {
1756 			if (i == ARRAY_SIZE(ht40) - 1)
1757 				/* last rate uses sgi */
1758 				*sgi = true;
1759 			else
1760 				*sgi = false;
1761 
1762 			*mcs = i;
1763 			return true;
1764 		}
1765 	}
1766 
1767 	return false;
1768 }
1769 
ath6kl_get_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_info * sinfo)1770 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1771 			      const u8 *mac, struct station_info *sinfo)
1772 {
1773 	struct ath6kl *ar = ath6kl_priv(dev);
1774 	struct ath6kl_vif *vif = netdev_priv(dev);
1775 	long left;
1776 	bool sgi;
1777 	s32 rate;
1778 	int ret;
1779 	u8 mcs;
1780 
1781 	if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1782 		return -ENOENT;
1783 
1784 	if (down_interruptible(&ar->sem))
1785 		return -EBUSY;
1786 
1787 	set_bit(STATS_UPDATE_PEND, &vif->flags);
1788 
1789 	ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1790 
1791 	if (ret != 0) {
1792 		up(&ar->sem);
1793 		return -EIO;
1794 	}
1795 
1796 	left = wait_event_interruptible_timeout(ar->event_wq,
1797 						!test_bit(STATS_UPDATE_PEND,
1798 							  &vif->flags),
1799 						WMI_TIMEOUT);
1800 
1801 	up(&ar->sem);
1802 
1803 	if (left == 0)
1804 		return -ETIMEDOUT;
1805 	else if (left < 0)
1806 		return left;
1807 
1808 	if (vif->target_stats.rx_byte) {
1809 		sinfo->rx_bytes = vif->target_stats.rx_byte;
1810 		sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64);
1811 		sinfo->rx_packets = vif->target_stats.rx_pkt;
1812 		sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
1813 	}
1814 
1815 	if (vif->target_stats.tx_byte) {
1816 		sinfo->tx_bytes = vif->target_stats.tx_byte;
1817 		sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64);
1818 		sinfo->tx_packets = vif->target_stats.tx_pkt;
1819 		sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
1820 	}
1821 
1822 	sinfo->signal = vif->target_stats.cs_rssi;
1823 	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1824 
1825 	rate = vif->target_stats.tx_ucast_rate;
1826 
1827 	if (is_rate_legacy(rate)) {
1828 		sinfo->txrate.legacy = rate / 100;
1829 	} else if (is_rate_ht20(rate, &mcs, &sgi)) {
1830 		if (sgi) {
1831 			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1832 			sinfo->txrate.mcs = mcs - 1;
1833 		} else {
1834 			sinfo->txrate.mcs = mcs;
1835 		}
1836 
1837 		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1838 		sinfo->txrate.bw = RATE_INFO_BW_20;
1839 	} else if (is_rate_ht40(rate, &mcs, &sgi)) {
1840 		if (sgi) {
1841 			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1842 			sinfo->txrate.mcs = mcs - 1;
1843 		} else {
1844 			sinfo->txrate.mcs = mcs;
1845 		}
1846 
1847 		sinfo->txrate.bw = RATE_INFO_BW_40;
1848 		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1849 	} else {
1850 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1851 			   "invalid rate from stats: %d\n", rate);
1852 		ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1853 		return 0;
1854 	}
1855 
1856 	sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
1857 
1858 	if (test_bit(CONNECTED, &vif->flags) &&
1859 	    test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1860 	    vif->nw_type == INFRA_NETWORK) {
1861 		sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
1862 		sinfo->bss_param.flags = 0;
1863 		sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1864 		sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1865 	}
1866 
1867 	return 0;
1868 }
1869 
ath6kl_set_pmksa(struct wiphy * wiphy,struct net_device * netdev,struct cfg80211_pmksa * pmksa)1870 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1871 			    struct cfg80211_pmksa *pmksa)
1872 {
1873 	struct ath6kl *ar = ath6kl_priv(netdev);
1874 	struct ath6kl_vif *vif = netdev_priv(netdev);
1875 
1876 	return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1877 				       pmksa->pmkid, true);
1878 }
1879 
ath6kl_del_pmksa(struct wiphy * wiphy,struct net_device * netdev,struct cfg80211_pmksa * pmksa)1880 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1881 			    struct cfg80211_pmksa *pmksa)
1882 {
1883 	struct ath6kl *ar = ath6kl_priv(netdev);
1884 	struct ath6kl_vif *vif = netdev_priv(netdev);
1885 
1886 	return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1887 				       pmksa->pmkid, false);
1888 }
1889 
ath6kl_flush_pmksa(struct wiphy * wiphy,struct net_device * netdev)1890 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1891 {
1892 	struct ath6kl *ar = ath6kl_priv(netdev);
1893 	struct ath6kl_vif *vif = netdev_priv(netdev);
1894 
1895 	if (test_bit(CONNECTED, &vif->flags))
1896 		return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1897 					       vif->bssid, NULL, false);
1898 	return 0;
1899 }
1900 
ath6kl_wow_usr(struct ath6kl * ar,struct ath6kl_vif * vif,struct cfg80211_wowlan * wow,u32 * filter)1901 static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1902 			  struct cfg80211_wowlan *wow, u32 *filter)
1903 {
1904 	int ret, pos;
1905 	u8 mask[WOW_PATTERN_SIZE];
1906 	u16 i;
1907 
1908 	/* Configure the patterns that we received from the user. */
1909 	for (i = 0; i < wow->n_patterns; i++) {
1910 		/*
1911 		 * Convert given nl80211 specific mask value to equivalent
1912 		 * driver specific mask value and send it to the chip along
1913 		 * with patterns. For example, If the mask value defined in
1914 		 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1915 		 * then equivalent driver specific mask value is
1916 		 * "0xFF 0x00 0xFF 0x00".
1917 		 */
1918 		memset(&mask, 0, sizeof(mask));
1919 		for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1920 			if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1921 				mask[pos] = 0xFF;
1922 		}
1923 		/*
1924 		 * Note: Pattern's offset is not passed as part of wowlan
1925 		 * parameter from CFG layer. So it's always passed as ZERO
1926 		 * to the firmware. It means, given WOW patterns are always
1927 		 * matched from the first byte of received pkt in the firmware.
1928 		 */
1929 		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1930 				vif->fw_vif_idx, WOW_LIST_ID,
1931 				wow->patterns[i].pattern_len,
1932 				0 /* pattern offset */,
1933 				wow->patterns[i].pattern, mask);
1934 		if (ret)
1935 			return ret;
1936 	}
1937 
1938 	if (wow->disconnect)
1939 		*filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1940 
1941 	if (wow->magic_pkt)
1942 		*filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1943 
1944 	if (wow->gtk_rekey_failure)
1945 		*filter |= WOW_FILTER_OPTION_GTK_ERROR;
1946 
1947 	if (wow->eap_identity_req)
1948 		*filter |= WOW_FILTER_OPTION_EAP_REQ;
1949 
1950 	if (wow->four_way_handshake)
1951 		*filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1952 
1953 	return 0;
1954 }
1955 
ath6kl_wow_ap(struct ath6kl * ar,struct ath6kl_vif * vif)1956 static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1957 {
1958 	static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1959 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1961 		0x00, 0x08 };
1962 	static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1963 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1964 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1965 		0x00, 0x7f };
1966 	u8 unicst_offset = 0;
1967 	static const u8 arp_pattern[] = { 0x08, 0x06 };
1968 	static const u8 arp_mask[] = { 0xff, 0xff };
1969 	u8 arp_offset = 20;
1970 	static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1971 	static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1972 	u8 discvr_offset = 38;
1973 	static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1974 		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1975 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1976 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1977 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1978 		0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1979 	static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1980 		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1981 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1982 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1983 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1984 		0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1985 	u8 dhcp_offset = 0;
1986 	int ret;
1987 
1988 	/* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1989 	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1990 			vif->fw_vif_idx, WOW_LIST_ID,
1991 			sizeof(unicst_pattern), unicst_offset,
1992 			unicst_pattern, unicst_mask);
1993 	if (ret) {
1994 		ath6kl_err("failed to add WOW unicast IP pattern\n");
1995 		return ret;
1996 	}
1997 
1998 	/* Setup all ARP pkt pattern */
1999 	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2000 			vif->fw_vif_idx, WOW_LIST_ID,
2001 			sizeof(arp_pattern), arp_offset,
2002 			arp_pattern, arp_mask);
2003 	if (ret) {
2004 		ath6kl_err("failed to add WOW ARP pattern\n");
2005 		return ret;
2006 	}
2007 
2008 	/*
2009 	 * Setup multicast pattern for mDNS 224.0.0.251,
2010 	 * SSDP 239.255.255.250 and LLMNR  224.0.0.252
2011 	 */
2012 	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2013 			vif->fw_vif_idx, WOW_LIST_ID,
2014 			sizeof(discvr_pattern), discvr_offset,
2015 			discvr_pattern, discvr_mask);
2016 	if (ret) {
2017 		ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2018 		return ret;
2019 	}
2020 
2021 	/* Setup all DHCP broadcast pkt pattern */
2022 	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2023 			vif->fw_vif_idx, WOW_LIST_ID,
2024 			sizeof(dhcp_pattern), dhcp_offset,
2025 			dhcp_pattern, dhcp_mask);
2026 	if (ret) {
2027 		ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
2028 		return ret;
2029 	}
2030 
2031 	return 0;
2032 }
2033 
ath6kl_wow_sta(struct ath6kl * ar,struct ath6kl_vif * vif)2034 static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2035 {
2036 	struct net_device *ndev = vif->ndev;
2037 	static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2038 	static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2039 	u8 discvr_offset = 38;
2040 	u8 mac_mask[ETH_ALEN];
2041 	int ret;
2042 
2043 	/* Setup unicast pkt pattern */
2044 	eth_broadcast_addr(mac_mask);
2045 	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2046 				vif->fw_vif_idx, WOW_LIST_ID,
2047 				ETH_ALEN, 0, ndev->dev_addr,
2048 				mac_mask);
2049 	if (ret) {
2050 		ath6kl_err("failed to add WOW unicast pattern\n");
2051 		return ret;
2052 	}
2053 
2054 	/*
2055 	 * Setup multicast pattern for mDNS 224.0.0.251,
2056 	 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2057 	 */
2058 	if ((ndev->flags & IFF_ALLMULTI) ||
2059 	    (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2060 		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2061 				vif->fw_vif_idx, WOW_LIST_ID,
2062 				sizeof(discvr_pattern), discvr_offset,
2063 				discvr_pattern, discvr_mask);
2064 		if (ret) {
2065 			ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2066 			return ret;
2067 		}
2068 	}
2069 
2070 	return 0;
2071 }
2072 
is_hsleep_mode_procsed(struct ath6kl_vif * vif)2073 static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2074 {
2075 	return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2076 }
2077 
is_ctrl_ep_empty(struct ath6kl * ar)2078 static bool is_ctrl_ep_empty(struct ath6kl *ar)
2079 {
2080 	return !ar->tx_pending[ar->ctrl_ep];
2081 }
2082 
ath6kl_cfg80211_host_sleep(struct ath6kl * ar,struct ath6kl_vif * vif)2083 static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2084 {
2085 	int ret, left;
2086 
2087 	clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2088 
2089 	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2090 						 ATH6KL_HOST_MODE_ASLEEP);
2091 	if (ret)
2092 		return ret;
2093 
2094 	left = wait_event_interruptible_timeout(ar->event_wq,
2095 						is_hsleep_mode_procsed(vif),
2096 						WMI_TIMEOUT);
2097 	if (left == 0) {
2098 		ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2099 		ret = -ETIMEDOUT;
2100 	} else if (left < 0) {
2101 		ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2102 			    left);
2103 		ret = left;
2104 	}
2105 
2106 	if (ar->tx_pending[ar->ctrl_ep]) {
2107 		left = wait_event_interruptible_timeout(ar->event_wq,
2108 							is_ctrl_ep_empty(ar),
2109 							WMI_TIMEOUT);
2110 		if (left == 0) {
2111 			ath6kl_warn("clear wmi ctrl data timeout\n");
2112 			ret = -ETIMEDOUT;
2113 		} else if (left < 0) {
2114 			ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2115 			ret = left;
2116 		}
2117 	}
2118 
2119 	return ret;
2120 }
2121 
ath6kl_wow_suspend_vif(struct ath6kl_vif * vif,struct cfg80211_wowlan * wow,u32 * filter)2122 static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2123 				  struct cfg80211_wowlan *wow, u32 *filter)
2124 {
2125 	struct ath6kl *ar = vif->ar;
2126 	struct in_device *in_dev;
2127 	struct in_ifaddr *ifa;
2128 	int ret;
2129 	u16 i, bmiss_time;
2130 	__be32 ips[MAX_IP_ADDRS];
2131 	u8 index = 0;
2132 
2133 	if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2134 	    test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2135 		     ar->fw_capabilities)) {
2136 		ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2137 						vif->fw_vif_idx, false);
2138 		if (ret)
2139 			return ret;
2140 	}
2141 
2142 	/* Clear existing WOW patterns */
2143 	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2144 		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2145 					       WOW_LIST_ID, i);
2146 
2147 	/*
2148 	 * Skip the default WOW pattern configuration
2149 	 * if the driver receives any WOW patterns from
2150 	 * the user.
2151 	 */
2152 	if (wow)
2153 		ret = ath6kl_wow_usr(ar, vif, wow, filter);
2154 	else if (vif->nw_type == AP_NETWORK)
2155 		ret = ath6kl_wow_ap(ar, vif);
2156 	else
2157 		ret = ath6kl_wow_sta(ar, vif);
2158 
2159 	if (ret)
2160 		return ret;
2161 
2162 	netif_stop_queue(vif->ndev);
2163 
2164 	if (vif->nw_type != AP_NETWORK) {
2165 		ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2166 						    ATH6KL_MAX_WOW_LISTEN_INTL,
2167 						    0);
2168 		if (ret)
2169 			return ret;
2170 
2171 		/* Set listen interval x 15 times as bmiss time */
2172 		bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2173 		if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2174 			bmiss_time = ATH6KL_MAX_BMISS_TIME;
2175 
2176 		ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2177 					       bmiss_time, 0);
2178 		if (ret)
2179 			return ret;
2180 
2181 		ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2182 						0xFFFF, 0, 0xFFFF, 0, 0, 0,
2183 						0, 0, 0, 0);
2184 		if (ret)
2185 			return ret;
2186 	}
2187 
2188 	/* Setup own IP addr for ARP agent. */
2189 	in_dev = __in_dev_get_rtnl(vif->ndev);
2190 	if (!in_dev)
2191 		return 0;
2192 
2193 	ifa = in_dev->ifa_list;
2194 	memset(&ips, 0, sizeof(ips));
2195 
2196 	/* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2197 	while (index < MAX_IP_ADDRS && ifa) {
2198 		ips[index] = ifa->ifa_local;
2199 		ifa = ifa->ifa_next;
2200 		index++;
2201 	}
2202 
2203 	if (ifa) {
2204 		ath6kl_err("total IP addr count is exceeding fw limit\n");
2205 		return -EINVAL;
2206 	}
2207 
2208 	ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2209 	if (ret) {
2210 		ath6kl_err("fail to setup ip for arp agent\n");
2211 		return ret;
2212 	}
2213 
2214 	return ret;
2215 }
2216 
ath6kl_wow_suspend(struct ath6kl * ar,struct cfg80211_wowlan * wow)2217 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2218 {
2219 	struct ath6kl_vif *first_vif, *vif;
2220 	int ret = 0;
2221 	u32 filter = 0;
2222 	bool connected = false;
2223 
2224 	/* enter / leave wow suspend on first vif always */
2225 	first_vif = ath6kl_vif_first(ar);
2226 	if (WARN_ON(!first_vif) ||
2227 	    !ath6kl_cfg80211_ready(first_vif))
2228 		return -EIO;
2229 
2230 	if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2231 		return -EINVAL;
2232 
2233 	/* install filters for each connected vif */
2234 	spin_lock_bh(&ar->list_lock);
2235 	list_for_each_entry(vif, &ar->vif_list, list) {
2236 		if (!test_bit(CONNECTED, &vif->flags) ||
2237 		    !ath6kl_cfg80211_ready(vif))
2238 			continue;
2239 		connected = true;
2240 
2241 		ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2242 		if (ret)
2243 			break;
2244 	}
2245 	spin_unlock_bh(&ar->list_lock);
2246 
2247 	if (!connected)
2248 		return -ENOTCONN;
2249 	else if (ret)
2250 		return ret;
2251 
2252 	ar->state = ATH6KL_STATE_SUSPENDING;
2253 
2254 	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2255 					  ATH6KL_WOW_MODE_ENABLE,
2256 					  filter,
2257 					  WOW_HOST_REQ_DELAY);
2258 	if (ret)
2259 		return ret;
2260 
2261 	return ath6kl_cfg80211_host_sleep(ar, first_vif);
2262 }
2263 
ath6kl_wow_resume_vif(struct ath6kl_vif * vif)2264 static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2265 {
2266 	struct ath6kl *ar = vif->ar;
2267 	int ret;
2268 
2269 	if (vif->nw_type != AP_NETWORK) {
2270 		ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2271 						0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2272 		if (ret)
2273 			return ret;
2274 
2275 		ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2276 						    vif->listen_intvl_t, 0);
2277 		if (ret)
2278 			return ret;
2279 
2280 		ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2281 					       vif->bmiss_time_t, 0);
2282 		if (ret)
2283 			return ret;
2284 	}
2285 
2286 	if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2287 	    test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2288 		     ar->fw_capabilities)) {
2289 		ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2290 						  vif->fw_vif_idx, true);
2291 		if (ret)
2292 			return ret;
2293 	}
2294 
2295 	netif_wake_queue(vif->ndev);
2296 
2297 	return 0;
2298 }
2299 
ath6kl_wow_resume(struct ath6kl * ar)2300 static int ath6kl_wow_resume(struct ath6kl *ar)
2301 {
2302 	struct ath6kl_vif *vif;
2303 	int ret;
2304 
2305 	vif = ath6kl_vif_first(ar);
2306 	if (WARN_ON(!vif) ||
2307 	    !ath6kl_cfg80211_ready(vif))
2308 		return -EIO;
2309 
2310 	ar->state = ATH6KL_STATE_RESUMING;
2311 
2312 	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2313 						 ATH6KL_HOST_MODE_AWAKE);
2314 	if (ret) {
2315 		ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2316 			    ret);
2317 		goto cleanup;
2318 	}
2319 
2320 	spin_lock_bh(&ar->list_lock);
2321 	list_for_each_entry(vif, &ar->vif_list, list) {
2322 		if (!test_bit(CONNECTED, &vif->flags) ||
2323 		    !ath6kl_cfg80211_ready(vif))
2324 			continue;
2325 		ret = ath6kl_wow_resume_vif(vif);
2326 		if (ret)
2327 			break;
2328 	}
2329 	spin_unlock_bh(&ar->list_lock);
2330 
2331 	if (ret)
2332 		goto cleanup;
2333 
2334 	ar->state = ATH6KL_STATE_ON;
2335 	return 0;
2336 
2337 cleanup:
2338 	ar->state = ATH6KL_STATE_WOW;
2339 	return ret;
2340 }
2341 
ath6kl_cfg80211_deepsleep_suspend(struct ath6kl * ar)2342 static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2343 {
2344 	struct ath6kl_vif *vif;
2345 	int ret;
2346 
2347 	vif = ath6kl_vif_first(ar);
2348 	if (!vif)
2349 		return -EIO;
2350 
2351 	if (!test_bit(WMI_READY, &ar->flag)) {
2352 		ath6kl_err("deepsleep failed as wmi is not ready\n");
2353 		return -EIO;
2354 	}
2355 
2356 	ath6kl_cfg80211_stop_all(ar);
2357 
2358 	/* Save the current power mode before enabling power save */
2359 	ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2360 
2361 	ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2362 	if (ret)
2363 		return ret;
2364 
2365 	/* Disable WOW mode */
2366 	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2367 					  ATH6KL_WOW_MODE_DISABLE,
2368 					  0, 0);
2369 	if (ret)
2370 		return ret;
2371 
2372 	/* Flush all non control pkts in TX path */
2373 	ath6kl_tx_data_cleanup(ar);
2374 
2375 	ret = ath6kl_cfg80211_host_sleep(ar, vif);
2376 	if (ret)
2377 		return ret;
2378 
2379 	return 0;
2380 }
2381 
ath6kl_cfg80211_deepsleep_resume(struct ath6kl * ar)2382 static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2383 {
2384 	struct ath6kl_vif *vif;
2385 	int ret;
2386 
2387 	vif = ath6kl_vif_first(ar);
2388 
2389 	if (!vif)
2390 		return -EIO;
2391 
2392 	if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2393 		ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2394 					       ar->wmi->saved_pwr_mode);
2395 		if (ret)
2396 			return ret;
2397 	}
2398 
2399 	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2400 						 ATH6KL_HOST_MODE_AWAKE);
2401 	if (ret)
2402 		return ret;
2403 
2404 	ar->state = ATH6KL_STATE_ON;
2405 
2406 	/* Reset scan parameter to default values */
2407 	ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2408 					0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2409 	if (ret)
2410 		return ret;
2411 
2412 	return 0;
2413 }
2414 
ath6kl_cfg80211_suspend(struct ath6kl * ar,enum ath6kl_cfg_suspend_mode mode,struct cfg80211_wowlan * wow)2415 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2416 			    enum ath6kl_cfg_suspend_mode mode,
2417 			    struct cfg80211_wowlan *wow)
2418 {
2419 	struct ath6kl_vif *vif;
2420 	enum ath6kl_state prev_state;
2421 	int ret;
2422 
2423 	switch (mode) {
2424 	case ATH6KL_CFG_SUSPEND_WOW:
2425 
2426 		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2427 
2428 		/* Flush all non control pkts in TX path */
2429 		ath6kl_tx_data_cleanup(ar);
2430 
2431 		prev_state = ar->state;
2432 
2433 		ret = ath6kl_wow_suspend(ar, wow);
2434 		if (ret) {
2435 			ar->state = prev_state;
2436 			return ret;
2437 		}
2438 
2439 		ar->state = ATH6KL_STATE_WOW;
2440 		break;
2441 
2442 	case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2443 
2444 		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2445 
2446 		ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2447 		if (ret) {
2448 			ath6kl_err("deepsleep suspend failed: %d\n", ret);
2449 			return ret;
2450 		}
2451 
2452 		ar->state = ATH6KL_STATE_DEEPSLEEP;
2453 
2454 		break;
2455 
2456 	case ATH6KL_CFG_SUSPEND_CUTPOWER:
2457 
2458 		ath6kl_cfg80211_stop_all(ar);
2459 
2460 		if (ar->state == ATH6KL_STATE_OFF) {
2461 			ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2462 				   "suspend hw off, no action for cutpower\n");
2463 			break;
2464 		}
2465 
2466 		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2467 
2468 		ret = ath6kl_init_hw_stop(ar);
2469 		if (ret) {
2470 			ath6kl_warn("failed to stop hw during suspend: %d\n",
2471 				    ret);
2472 		}
2473 
2474 		ar->state = ATH6KL_STATE_CUTPOWER;
2475 
2476 		break;
2477 
2478 	default:
2479 		break;
2480 	}
2481 
2482 	list_for_each_entry(vif, &ar->vif_list, list)
2483 		ath6kl_cfg80211_scan_complete_event(vif, true);
2484 
2485 	return 0;
2486 }
2487 EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2488 
ath6kl_cfg80211_resume(struct ath6kl * ar)2489 int ath6kl_cfg80211_resume(struct ath6kl *ar)
2490 {
2491 	int ret;
2492 
2493 	switch (ar->state) {
2494 	case  ATH6KL_STATE_WOW:
2495 		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2496 
2497 		ret = ath6kl_wow_resume(ar);
2498 		if (ret) {
2499 			ath6kl_warn("wow mode resume failed: %d\n", ret);
2500 			return ret;
2501 		}
2502 
2503 		break;
2504 
2505 	case ATH6KL_STATE_DEEPSLEEP:
2506 		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2507 
2508 		ret = ath6kl_cfg80211_deepsleep_resume(ar);
2509 		if (ret) {
2510 			ath6kl_warn("deep sleep resume failed: %d\n", ret);
2511 			return ret;
2512 		}
2513 		break;
2514 
2515 	case ATH6KL_STATE_CUTPOWER:
2516 		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2517 
2518 		ret = ath6kl_init_hw_start(ar);
2519 		if (ret) {
2520 			ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2521 			return ret;
2522 		}
2523 		break;
2524 
2525 	default:
2526 		break;
2527 	}
2528 
2529 	return 0;
2530 }
2531 EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2532 
2533 #ifdef CONFIG_PM
2534 
2535 /* hif layer decides what suspend mode to use */
__ath6kl_cfg80211_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wow)2536 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2537 				 struct cfg80211_wowlan *wow)
2538 {
2539 	struct ath6kl *ar = wiphy_priv(wiphy);
2540 
2541 	ath6kl_recovery_suspend(ar);
2542 
2543 	return ath6kl_hif_suspend(ar, wow);
2544 }
2545 
__ath6kl_cfg80211_resume(struct wiphy * wiphy)2546 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2547 {
2548 	struct ath6kl *ar = wiphy_priv(wiphy);
2549 	int err;
2550 
2551 	err = ath6kl_hif_resume(ar);
2552 	if (err)
2553 		return err;
2554 
2555 	ath6kl_recovery_resume(ar);
2556 
2557 	return 0;
2558 }
2559 
2560 /*
2561  * FIXME: WOW suspend mode is selected if the host sdio controller supports
2562  * both sdio irq wake up and keep power. The target pulls sdio data line to
2563  * wake up the host when WOW pattern matches. This causes sdio irq handler
2564  * is being called in the host side which internally hits ath6kl's RX path.
2565  *
2566  * Since sdio interrupt is not disabled, RX path executes even before
2567  * the host executes the actual resume operation from PM module.
2568  *
2569  * In the current scenario, WOW resume should happen before start processing
2570  * any data from the target. So It's required to perform WOW resume in RX path.
2571  * Ideally we should perform WOW resume only in the actual platform
2572  * resume path. This area needs bit rework to avoid WOW resume in RX path.
2573  *
2574  * ath6kl_check_wow_status() is called from ath6kl_rx().
2575  */
ath6kl_check_wow_status(struct ath6kl * ar)2576 void ath6kl_check_wow_status(struct ath6kl *ar)
2577 {
2578 	if (ar->state == ATH6KL_STATE_SUSPENDING)
2579 		return;
2580 
2581 	if (ar->state == ATH6KL_STATE_WOW)
2582 		ath6kl_cfg80211_resume(ar);
2583 }
2584 
2585 #else
2586 
ath6kl_check_wow_status(struct ath6kl * ar)2587 void ath6kl_check_wow_status(struct ath6kl *ar)
2588 {
2589 }
2590 #endif
2591 
ath6kl_set_htcap(struct ath6kl_vif * vif,enum nl80211_band band,bool ht_enable)2592 static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum nl80211_band band,
2593 			    bool ht_enable)
2594 {
2595 	struct ath6kl_htcap *htcap = &vif->htcap[band];
2596 
2597 	if (htcap->ht_enable == ht_enable)
2598 		return 0;
2599 
2600 	if (ht_enable) {
2601 		/* Set default ht capabilities */
2602 		htcap->ht_enable = true;
2603 		htcap->cap_info = (band == NL80211_BAND_2GHZ) ?
2604 				   ath6kl_g_htcap : ath6kl_a_htcap;
2605 		htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2606 	} else /* Disable ht */
2607 		memset(htcap, 0, sizeof(*htcap));
2608 
2609 	return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2610 					band, htcap);
2611 }
2612 
ath6kl_restore_htcap(struct ath6kl_vif * vif)2613 static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2614 {
2615 	struct wiphy *wiphy = vif->ar->wiphy;
2616 	int band, ret = 0;
2617 
2618 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
2619 		if (!wiphy->bands[band])
2620 			continue;
2621 
2622 		ret = ath6kl_set_htcap(vif, band,
2623 				wiphy->bands[band]->ht_cap.ht_supported);
2624 		if (ret)
2625 			return ret;
2626 	}
2627 
2628 	return ret;
2629 }
2630 
ath6kl_is_p2p_ie(const u8 * pos)2631 static bool ath6kl_is_p2p_ie(const u8 *pos)
2632 {
2633 	return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2634 		pos[2] == 0x50 && pos[3] == 0x6f &&
2635 		pos[4] == 0x9a && pos[5] == 0x09;
2636 }
2637 
ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif * vif,const u8 * ies,size_t ies_len)2638 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2639 					const u8 *ies, size_t ies_len)
2640 {
2641 	struct ath6kl *ar = vif->ar;
2642 	const u8 *pos;
2643 	u8 *buf = NULL;
2644 	size_t len = 0;
2645 	int ret;
2646 
2647 	/*
2648 	 * Filter out P2P IE(s) since they will be included depending on
2649 	 * the Probe Request frame in ath6kl_send_go_probe_resp().
2650 	 */
2651 
2652 	if (ies && ies_len) {
2653 		buf = kmalloc(ies_len, GFP_KERNEL);
2654 		if (buf == NULL)
2655 			return -ENOMEM;
2656 		pos = ies;
2657 		while (pos + 1 < ies + ies_len) {
2658 			if (pos + 2 + pos[1] > ies + ies_len)
2659 				break;
2660 			if (!ath6kl_is_p2p_ie(pos)) {
2661 				memcpy(buf + len, pos, 2 + pos[1]);
2662 				len += 2 + pos[1];
2663 			}
2664 			pos += 2 + pos[1];
2665 		}
2666 	}
2667 
2668 	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2669 				       WMI_FRAME_PROBE_RESP, buf, len);
2670 	kfree(buf);
2671 	return ret;
2672 }
2673 
ath6kl_set_ies(struct ath6kl_vif * vif,struct cfg80211_beacon_data * info)2674 static int ath6kl_set_ies(struct ath6kl_vif *vif,
2675 			  struct cfg80211_beacon_data *info)
2676 {
2677 	struct ath6kl *ar = vif->ar;
2678 	int res;
2679 
2680 	/* this also clears IE in fw if it's not set */
2681 	res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2682 				       WMI_FRAME_BEACON,
2683 				       info->beacon_ies,
2684 				       info->beacon_ies_len);
2685 	if (res)
2686 		return res;
2687 
2688 	/* this also clears IE in fw if it's not set */
2689 	res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2690 					   info->proberesp_ies_len);
2691 	if (res)
2692 		return res;
2693 
2694 	/* this also clears IE in fw if it's not set */
2695 	res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2696 				       WMI_FRAME_ASSOC_RESP,
2697 				       info->assocresp_ies,
2698 				       info->assocresp_ies_len);
2699 	if (res)
2700 		return res;
2701 
2702 	return 0;
2703 }
2704 
ath6kl_get_rsn_capab(struct cfg80211_beacon_data * beacon,u8 * rsn_capab)2705 static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2706 				u8 *rsn_capab)
2707 {
2708 	const u8 *rsn_ie;
2709 	size_t rsn_ie_len;
2710 	u16 cnt;
2711 
2712 	if (!beacon->tail)
2713 		return -EINVAL;
2714 
2715 	rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2716 	if (!rsn_ie)
2717 		return -EINVAL;
2718 
2719 	rsn_ie_len = *(rsn_ie + 1);
2720 	/* skip element id and length */
2721 	rsn_ie += 2;
2722 
2723 	/* skip version */
2724 	if (rsn_ie_len < 2)
2725 		return -EINVAL;
2726 	rsn_ie +=  2;
2727 	rsn_ie_len -= 2;
2728 
2729 	/* skip group cipher suite */
2730 	if (rsn_ie_len < 4)
2731 		return 0;
2732 	rsn_ie +=  4;
2733 	rsn_ie_len -= 4;
2734 
2735 	/* skip pairwise cipher suite */
2736 	if (rsn_ie_len < 2)
2737 		return 0;
2738 	cnt = get_unaligned_le16(rsn_ie);
2739 	rsn_ie += (2 + cnt * 4);
2740 	rsn_ie_len -= (2 + cnt * 4);
2741 
2742 	/* skip akm suite */
2743 	if (rsn_ie_len < 2)
2744 		return 0;
2745 	cnt = get_unaligned_le16(rsn_ie);
2746 	rsn_ie += (2 + cnt * 4);
2747 	rsn_ie_len -= (2 + cnt * 4);
2748 
2749 	if (rsn_ie_len < 2)
2750 		return 0;
2751 
2752 	memcpy(rsn_capab, rsn_ie, 2);
2753 
2754 	return 0;
2755 }
2756 
ath6kl_start_ap(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_ap_settings * info)2757 static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2758 			   struct cfg80211_ap_settings *info)
2759 {
2760 	struct ath6kl *ar = ath6kl_priv(dev);
2761 	struct ath6kl_vif *vif = netdev_priv(dev);
2762 	struct ieee80211_mgmt *mgmt;
2763 	bool hidden = false;
2764 	u8 *ies;
2765 	int ies_len;
2766 	struct wmi_connect_cmd p;
2767 	int res;
2768 	int i, ret;
2769 	u16 rsn_capab = 0;
2770 	int inactivity_timeout = 0;
2771 
2772 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2773 
2774 	if (!ath6kl_cfg80211_ready(vif))
2775 		return -EIO;
2776 
2777 	if (vif->next_mode != AP_NETWORK)
2778 		return -EOPNOTSUPP;
2779 
2780 	res = ath6kl_set_ies(vif, &info->beacon);
2781 
2782 	ar->ap_mode_bkey.valid = false;
2783 
2784 	ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2785 						 info->beacon_interval);
2786 
2787 	if (ret)
2788 		ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2789 
2790 	ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2791 					 info->dtim_period);
2792 
2793 	/* ignore error, just print a warning and continue normally */
2794 	if (ret)
2795 		ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2796 
2797 	if (info->beacon.head == NULL)
2798 		return -EINVAL;
2799 	mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2800 	ies = mgmt->u.beacon.variable;
2801 	if (ies > info->beacon.head + info->beacon.head_len)
2802 		return -EINVAL;
2803 	ies_len = info->beacon.head + info->beacon.head_len - ies;
2804 
2805 	if (info->ssid == NULL)
2806 		return -EINVAL;
2807 	memcpy(vif->ssid, info->ssid, info->ssid_len);
2808 	vif->ssid_len = info->ssid_len;
2809 	if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2810 		hidden = true;
2811 
2812 	res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2813 	if (res)
2814 		return res;
2815 
2816 	ret = ath6kl_set_auth_type(vif, info->auth_type);
2817 	if (ret)
2818 		return ret;
2819 
2820 	memset(&p, 0, sizeof(p));
2821 
2822 	for (i = 0; i < info->crypto.n_akm_suites; i++) {
2823 		switch (info->crypto.akm_suites[i]) {
2824 		case WLAN_AKM_SUITE_8021X:
2825 			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2826 				p.auth_mode |= WPA_AUTH;
2827 			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2828 				p.auth_mode |= WPA2_AUTH;
2829 			break;
2830 		case WLAN_AKM_SUITE_PSK:
2831 			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2832 				p.auth_mode |= WPA_PSK_AUTH;
2833 			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2834 				p.auth_mode |= WPA2_PSK_AUTH;
2835 			break;
2836 		}
2837 	}
2838 	if (p.auth_mode == 0)
2839 		p.auth_mode = NONE_AUTH;
2840 	vif->auth_mode = p.auth_mode;
2841 
2842 	for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2843 		switch (info->crypto.ciphers_pairwise[i]) {
2844 		case WLAN_CIPHER_SUITE_WEP40:
2845 		case WLAN_CIPHER_SUITE_WEP104:
2846 			p.prwise_crypto_type |= WEP_CRYPT;
2847 			break;
2848 		case WLAN_CIPHER_SUITE_TKIP:
2849 			p.prwise_crypto_type |= TKIP_CRYPT;
2850 			break;
2851 		case WLAN_CIPHER_SUITE_CCMP:
2852 			p.prwise_crypto_type |= AES_CRYPT;
2853 			break;
2854 		case WLAN_CIPHER_SUITE_SMS4:
2855 			p.prwise_crypto_type |= WAPI_CRYPT;
2856 			break;
2857 		}
2858 	}
2859 	if (p.prwise_crypto_type == 0) {
2860 		p.prwise_crypto_type = NONE_CRYPT;
2861 		ath6kl_set_cipher(vif, 0, true);
2862 	} else if (info->crypto.n_ciphers_pairwise == 1) {
2863 		ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2864 	}
2865 
2866 	switch (info->crypto.cipher_group) {
2867 	case WLAN_CIPHER_SUITE_WEP40:
2868 	case WLAN_CIPHER_SUITE_WEP104:
2869 		p.grp_crypto_type = WEP_CRYPT;
2870 		break;
2871 	case WLAN_CIPHER_SUITE_TKIP:
2872 		p.grp_crypto_type = TKIP_CRYPT;
2873 		break;
2874 	case WLAN_CIPHER_SUITE_CCMP:
2875 		p.grp_crypto_type = AES_CRYPT;
2876 		break;
2877 	case WLAN_CIPHER_SUITE_SMS4:
2878 		p.grp_crypto_type = WAPI_CRYPT;
2879 		break;
2880 	default:
2881 		p.grp_crypto_type = NONE_CRYPT;
2882 		break;
2883 	}
2884 	ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2885 
2886 	p.nw_type = AP_NETWORK;
2887 	vif->nw_type = vif->next_mode;
2888 
2889 	p.ssid_len = vif->ssid_len;
2890 	memcpy(p.ssid, vif->ssid, vif->ssid_len);
2891 	p.dot11_auth_mode = vif->dot11_auth_mode;
2892 	p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2893 
2894 	/* Enable uAPSD support by default */
2895 	res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2896 	if (res < 0)
2897 		return res;
2898 
2899 	if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2900 		p.nw_subtype = SUBTYPE_P2PGO;
2901 	} else {
2902 		/*
2903 		 * Due to firmware limitation, it is not possible to
2904 		 * do P2P mgmt operations in AP mode
2905 		 */
2906 		p.nw_subtype = SUBTYPE_NONE;
2907 	}
2908 
2909 	if (info->inactivity_timeout) {
2910 		inactivity_timeout = info->inactivity_timeout;
2911 
2912 		if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2913 			     ar->fw_capabilities))
2914 			inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2915 							  60);
2916 
2917 		res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2918 						  inactivity_timeout);
2919 		if (res < 0)
2920 			return res;
2921 	}
2922 
2923 	if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2924 			     cfg80211_get_chandef_type(&info->chandef)
2925 					!= NL80211_CHAN_NO_HT))
2926 		return -EIO;
2927 
2928 	/*
2929 	 * Get the PTKSA replay counter in the RSN IE. Supplicant
2930 	 * will use the RSN IE in M3 message and firmware has to
2931 	 * advertise the same in beacon/probe response. Send
2932 	 * the complete RSN IE capability field to firmware
2933 	 */
2934 	if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2935 	    test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2936 		     ar->fw_capabilities)) {
2937 		res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2938 					    WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2939 					    (const u8 *) &rsn_capab,
2940 					    sizeof(rsn_capab));
2941 		vif->rsn_capab = rsn_capab;
2942 		if (res < 0)
2943 			return res;
2944 	}
2945 
2946 	memcpy(&vif->profile, &p, sizeof(p));
2947 	res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2948 	if (res < 0)
2949 		return res;
2950 
2951 	return 0;
2952 }
2953 
ath6kl_change_beacon(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_beacon_data * beacon)2954 static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2955 				struct cfg80211_beacon_data *beacon)
2956 {
2957 	struct ath6kl_vif *vif = netdev_priv(dev);
2958 
2959 	if (!ath6kl_cfg80211_ready(vif))
2960 		return -EIO;
2961 
2962 	if (vif->next_mode != AP_NETWORK)
2963 		return -EOPNOTSUPP;
2964 
2965 	return ath6kl_set_ies(vif, beacon);
2966 }
2967 
ath6kl_stop_ap(struct wiphy * wiphy,struct net_device * dev)2968 static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2969 {
2970 	struct ath6kl *ar = ath6kl_priv(dev);
2971 	struct ath6kl_vif *vif = netdev_priv(dev);
2972 
2973 	if (vif->nw_type != AP_NETWORK)
2974 		return -EOPNOTSUPP;
2975 	if (!test_bit(CONNECTED, &vif->flags))
2976 		return -ENOTCONN;
2977 
2978 	ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2979 	clear_bit(CONNECTED, &vif->flags);
2980 	netif_carrier_off(vif->ndev);
2981 
2982 	/* Restore ht setting in firmware */
2983 	return ath6kl_restore_htcap(vif);
2984 }
2985 
2986 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2987 
ath6kl_del_station(struct wiphy * wiphy,struct net_device * dev,struct station_del_parameters * params)2988 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2989 			      struct station_del_parameters *params)
2990 {
2991 	struct ath6kl *ar = ath6kl_priv(dev);
2992 	struct ath6kl_vif *vif = netdev_priv(dev);
2993 	const u8 *addr = params->mac ? params->mac : bcast_addr;
2994 
2995 	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2996 				      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2997 }
2998 
ath6kl_change_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_parameters * params)2999 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3000 				 const u8 *mac,
3001 				 struct station_parameters *params)
3002 {
3003 	struct ath6kl *ar = ath6kl_priv(dev);
3004 	struct ath6kl_vif *vif = netdev_priv(dev);
3005 	int err;
3006 
3007 	if (vif->nw_type != AP_NETWORK)
3008 		return -EOPNOTSUPP;
3009 
3010 	err = cfg80211_check_station_change(wiphy, params,
3011 					    CFG80211_STA_AP_MLME_CLIENT);
3012 	if (err)
3013 		return err;
3014 
3015 	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3016 		return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3017 					      WMI_AP_MLME_AUTHORIZE, mac, 0);
3018 	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3019 				      WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3020 }
3021 
ath6kl_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,struct ieee80211_channel * chan,unsigned int duration,u64 * cookie)3022 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3023 				    struct wireless_dev *wdev,
3024 				    struct ieee80211_channel *chan,
3025 				    unsigned int duration,
3026 				    u64 *cookie)
3027 {
3028 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3029 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3030 	u32 id;
3031 
3032 	/* TODO: if already pending or ongoing remain-on-channel,
3033 	 * return -EBUSY */
3034 	id = ++vif->last_roc_id;
3035 	if (id == 0) {
3036 		/* Do not use 0 as the cookie value */
3037 		id = ++vif->last_roc_id;
3038 	}
3039 	*cookie = id;
3040 
3041 	return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3042 					     chan->center_freq, duration);
3043 }
3044 
ath6kl_cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)3045 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3046 					   struct wireless_dev *wdev,
3047 					   u64 cookie)
3048 {
3049 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3050 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3051 
3052 	if (cookie != vif->last_roc_id)
3053 		return -ENOENT;
3054 	vif->last_cancel_roc_id = cookie;
3055 
3056 	return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3057 }
3058 
ath6kl_send_go_probe_resp(struct ath6kl_vif * vif,const u8 * buf,size_t len,unsigned int freq)3059 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3060 				     const u8 *buf, size_t len,
3061 				     unsigned int freq)
3062 {
3063 	struct ath6kl *ar = vif->ar;
3064 	const u8 *pos;
3065 	u8 *p2p;
3066 	int p2p_len;
3067 	int ret;
3068 	const struct ieee80211_mgmt *mgmt;
3069 
3070 	mgmt = (const struct ieee80211_mgmt *) buf;
3071 
3072 	/* Include P2P IE(s) from the frame generated in user space. */
3073 
3074 	p2p = kmalloc(len, GFP_KERNEL);
3075 	if (p2p == NULL)
3076 		return -ENOMEM;
3077 	p2p_len = 0;
3078 
3079 	pos = mgmt->u.probe_resp.variable;
3080 	while (pos + 1 < buf + len) {
3081 		if (pos + 2 + pos[1] > buf + len)
3082 			break;
3083 		if (ath6kl_is_p2p_ie(pos)) {
3084 			memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3085 			p2p_len += 2 + pos[1];
3086 		}
3087 		pos += 2 + pos[1];
3088 	}
3089 
3090 	ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3091 						 mgmt->da, p2p, p2p_len);
3092 	kfree(p2p);
3093 	return ret;
3094 }
3095 
ath6kl_mgmt_powersave_ap(struct ath6kl_vif * vif,u32 id,u32 freq,u32 wait,const u8 * buf,size_t len,bool * more_data,bool no_cck)3096 static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3097 				     u32 id,
3098 				     u32 freq,
3099 				     u32 wait,
3100 				     const u8 *buf,
3101 				     size_t len,
3102 				     bool *more_data,
3103 				     bool no_cck)
3104 {
3105 	struct ieee80211_mgmt *mgmt;
3106 	struct ath6kl_sta *conn;
3107 	bool is_psq_empty = false;
3108 	struct ath6kl_mgmt_buff *mgmt_buf;
3109 	size_t mgmt_buf_size;
3110 	struct ath6kl *ar = vif->ar;
3111 
3112 	mgmt = (struct ieee80211_mgmt *) buf;
3113 	if (is_multicast_ether_addr(mgmt->da))
3114 		return false;
3115 
3116 	conn = ath6kl_find_sta(vif, mgmt->da);
3117 	if (!conn)
3118 		return false;
3119 
3120 	if (conn->sta_flags & STA_PS_SLEEP) {
3121 		if (!(conn->sta_flags & STA_PS_POLLED)) {
3122 			/* Queue the frames if the STA is sleeping */
3123 			mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3124 			mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3125 			if (!mgmt_buf)
3126 				return false;
3127 
3128 			INIT_LIST_HEAD(&mgmt_buf->list);
3129 			mgmt_buf->id = id;
3130 			mgmt_buf->freq = freq;
3131 			mgmt_buf->wait = wait;
3132 			mgmt_buf->len = len;
3133 			mgmt_buf->no_cck = no_cck;
3134 			memcpy(mgmt_buf->buf, buf, len);
3135 			spin_lock_bh(&conn->psq_lock);
3136 			is_psq_empty = skb_queue_empty(&conn->psq) &&
3137 					(conn->mgmt_psq_len == 0);
3138 			list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3139 			conn->mgmt_psq_len++;
3140 			spin_unlock_bh(&conn->psq_lock);
3141 
3142 			/*
3143 			 * If this is the first pkt getting queued
3144 			 * for this STA, update the PVB for this
3145 			 * STA.
3146 			 */
3147 			if (is_psq_empty)
3148 				ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3149 						       conn->aid, 1);
3150 			return true;
3151 		}
3152 
3153 		/*
3154 		 * This tx is because of a PsPoll.
3155 		 * Determine if MoreData bit has to be set.
3156 		 */
3157 		spin_lock_bh(&conn->psq_lock);
3158 		if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3159 			*more_data = true;
3160 		spin_unlock_bh(&conn->psq_lock);
3161 	}
3162 
3163 	return false;
3164 }
3165 
3166 /* Check if SSID length is greater than DIRECT- */
ath6kl_is_p2p_go_ssid(const u8 * buf,size_t len)3167 static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3168 {
3169 	const struct ieee80211_mgmt *mgmt;
3170 	mgmt = (const struct ieee80211_mgmt *) buf;
3171 
3172 	/* variable[1] contains the SSID tag length */
3173 	if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3174 	    (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3175 		return true;
3176 	}
3177 
3178 	return false;
3179 }
3180 
ath6kl_mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_mgmt_tx_params * params,u64 * cookie)3181 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3182 			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3183 {
3184 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3185 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3186 	struct ieee80211_channel *chan = params->chan;
3187 	const u8 *buf = params->buf;
3188 	size_t len = params->len;
3189 	unsigned int wait = params->wait;
3190 	bool no_cck = params->no_cck;
3191 	u32 id, freq;
3192 	const struct ieee80211_mgmt *mgmt;
3193 	bool more_data, queued;
3194 
3195 	/* default to the current channel, but use the one specified as argument
3196 	 * if any
3197 	 */
3198 	freq = vif->ch_hint;
3199 	if (chan)
3200 		freq = chan->center_freq;
3201 
3202 	/* never send freq zero to the firmware */
3203 	if (WARN_ON(freq == 0))
3204 		return -EINVAL;
3205 
3206 	mgmt = (const struct ieee80211_mgmt *) buf;
3207 	if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3208 	    ieee80211_is_probe_resp(mgmt->frame_control) &&
3209 	    ath6kl_is_p2p_go_ssid(buf, len)) {
3210 		/*
3211 		 * Send Probe Response frame in GO mode using a separate WMI
3212 		 * command to allow the target to fill in the generic IEs.
3213 		 */
3214 		*cookie = 0; /* TX status not supported */
3215 		return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3216 	}
3217 
3218 	id = vif->send_action_id++;
3219 	if (id == 0) {
3220 		/*
3221 		 * 0 is a reserved value in the WMI command and shall not be
3222 		 * used for the command.
3223 		 */
3224 		id = vif->send_action_id++;
3225 	}
3226 
3227 	*cookie = id;
3228 
3229 	/* AP mode Power saving processing */
3230 	if (vif->nw_type == AP_NETWORK) {
3231 		queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3232 						  &more_data, no_cck);
3233 		if (queued)
3234 			return 0;
3235 	}
3236 
3237 	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3238 					wait, buf, len, no_cck);
3239 }
3240 
ath6kl_get_antenna(struct wiphy * wiphy,u32 * tx_ant,u32 * rx_ant)3241 static int ath6kl_get_antenna(struct wiphy *wiphy,
3242 			      u32 *tx_ant, u32 *rx_ant)
3243 {
3244 	struct ath6kl *ar = wiphy_priv(wiphy);
3245 	*tx_ant = ar->hw.tx_ant;
3246 	*rx_ant = ar->hw.rx_ant;
3247 	return 0;
3248 }
3249 
ath6kl_mgmt_frame_register(struct wiphy * wiphy,struct wireless_dev * wdev,u16 frame_type,bool reg)3250 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
3251 				       struct wireless_dev *wdev,
3252 				       u16 frame_type, bool reg)
3253 {
3254 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3255 
3256 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
3257 		   __func__, frame_type, reg);
3258 	if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
3259 		/*
3260 		 * Note: This notification callback is not allowed to sleep, so
3261 		 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
3262 		 * hardcode target to report Probe Request frames all the time.
3263 		 */
3264 		vif->probe_req_report = reg;
3265 	}
3266 }
3267 
ath6kl_cfg80211_sscan_start(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_sched_scan_request * request)3268 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3269 			struct net_device *dev,
3270 			struct cfg80211_sched_scan_request *request)
3271 {
3272 	struct ath6kl *ar = ath6kl_priv(dev);
3273 	struct ath6kl_vif *vif = netdev_priv(dev);
3274 	u16 interval;
3275 	int ret, rssi_thold;
3276 	int n_match_sets = request->n_match_sets;
3277 
3278 	/*
3279 	 * If there's a matchset w/o an SSID, then assume it's just for
3280 	 * the RSSI (nothing else is currently supported) and ignore it.
3281 	 * The device only supports a global RSSI filter that we set below.
3282 	 */
3283 	if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3284 		n_match_sets = 0;
3285 
3286 	if (ar->state != ATH6KL_STATE_ON)
3287 		return -EIO;
3288 
3289 	if (vif->sme_state != SME_DISCONNECTED)
3290 		return -EBUSY;
3291 
3292 	ath6kl_cfg80211_scan_complete_event(vif, true);
3293 
3294 	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3295 				      request->n_ssids,
3296 				      request->match_sets,
3297 				      n_match_sets);
3298 	if (ret < 0)
3299 		return ret;
3300 
3301 	if (!n_match_sets) {
3302 		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3303 					       ALL_BSS_FILTER, 0);
3304 		if (ret < 0)
3305 			return ret;
3306 	} else {
3307 		 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3308 						MATCHED_SSID_FILTER, 0);
3309 		if (ret < 0)
3310 			return ret;
3311 	}
3312 
3313 	if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3314 		     ar->fw_capabilities)) {
3315 		if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3316 			rssi_thold = 0;
3317 		else if (request->min_rssi_thold < -127)
3318 			rssi_thold = -127;
3319 		else
3320 			rssi_thold = request->min_rssi_thold;
3321 
3322 		ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3323 						     rssi_thold);
3324 		if (ret) {
3325 			ath6kl_err("failed to set RSSI threshold for scan\n");
3326 			return ret;
3327 		}
3328 	}
3329 
3330 	/* fw uses seconds, also make sure that it's >0 */
3331 	interval = max_t(u16, 1, request->scan_plans[0].interval);
3332 
3333 	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3334 				  interval, interval,
3335 				  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3336 
3337 	/* this also clears IE in fw if it's not set */
3338 	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3339 				       WMI_FRAME_PROBE_REQ,
3340 				       request->ie, request->ie_len);
3341 	if (ret) {
3342 		ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3343 			    ret);
3344 		return ret;
3345 	}
3346 
3347 	ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3348 	if (ret)
3349 		return ret;
3350 
3351 	set_bit(SCHED_SCANNING, &vif->flags);
3352 
3353 	return 0;
3354 }
3355 
ath6kl_cfg80211_sscan_stop(struct wiphy * wiphy,struct net_device * dev)3356 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3357 				      struct net_device *dev)
3358 {
3359 	struct ath6kl_vif *vif = netdev_priv(dev);
3360 	bool stopped;
3361 
3362 	stopped = __ath6kl_cfg80211_sscan_stop(vif);
3363 
3364 	if (!stopped)
3365 		return -EIO;
3366 
3367 	return 0;
3368 }
3369 
ath6kl_cfg80211_set_bitrate(struct wiphy * wiphy,struct net_device * dev,const u8 * addr,const struct cfg80211_bitrate_mask * mask)3370 static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3371 				       struct net_device *dev,
3372 				       const u8 *addr,
3373 				       const struct cfg80211_bitrate_mask *mask)
3374 {
3375 	struct ath6kl *ar = ath6kl_priv(dev);
3376 	struct ath6kl_vif *vif = netdev_priv(dev);
3377 
3378 	return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3379 					   mask);
3380 }
3381 
ath6kl_cfg80211_set_txe_config(struct wiphy * wiphy,struct net_device * dev,u32 rate,u32 pkts,u32 intvl)3382 static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3383 					  struct net_device *dev,
3384 					  u32 rate, u32 pkts, u32 intvl)
3385 {
3386 	struct ath6kl *ar = ath6kl_priv(dev);
3387 	struct ath6kl_vif *vif = netdev_priv(dev);
3388 
3389 	if (vif->nw_type != INFRA_NETWORK ||
3390 	    !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3391 		return -EOPNOTSUPP;
3392 
3393 	if (vif->sme_state != SME_CONNECTED)
3394 		return -ENOTCONN;
3395 
3396 	/* save this since the firmware won't report the interval */
3397 	vif->txe_intvl = intvl;
3398 
3399 	return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3400 					 rate, pkts, intvl);
3401 }
3402 
3403 static const struct ieee80211_txrx_stypes
3404 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3405 	[NL80211_IFTYPE_STATION] = {
3406 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3407 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3408 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3409 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3410 	},
3411 	[NL80211_IFTYPE_AP] = {
3412 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3413 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3414 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3415 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3416 	},
3417 	[NL80211_IFTYPE_P2P_CLIENT] = {
3418 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3419 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3420 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3421 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3422 	},
3423 	[NL80211_IFTYPE_P2P_GO] = {
3424 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3425 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3426 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3427 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3428 	},
3429 };
3430 
3431 static struct cfg80211_ops ath6kl_cfg80211_ops = {
3432 	.add_virtual_intf = ath6kl_cfg80211_add_iface,
3433 	.del_virtual_intf = ath6kl_cfg80211_del_iface,
3434 	.change_virtual_intf = ath6kl_cfg80211_change_iface,
3435 	.scan = ath6kl_cfg80211_scan,
3436 	.connect = ath6kl_cfg80211_connect,
3437 	.disconnect = ath6kl_cfg80211_disconnect,
3438 	.add_key = ath6kl_cfg80211_add_key,
3439 	.get_key = ath6kl_cfg80211_get_key,
3440 	.del_key = ath6kl_cfg80211_del_key,
3441 	.set_default_key = ath6kl_cfg80211_set_default_key,
3442 	.set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3443 	.set_tx_power = ath6kl_cfg80211_set_txpower,
3444 	.get_tx_power = ath6kl_cfg80211_get_txpower,
3445 	.set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3446 	.join_ibss = ath6kl_cfg80211_join_ibss,
3447 	.leave_ibss = ath6kl_cfg80211_leave_ibss,
3448 	.get_station = ath6kl_get_station,
3449 	.set_pmksa = ath6kl_set_pmksa,
3450 	.del_pmksa = ath6kl_del_pmksa,
3451 	.flush_pmksa = ath6kl_flush_pmksa,
3452 	CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3453 #ifdef CONFIG_PM
3454 	.suspend = __ath6kl_cfg80211_suspend,
3455 	.resume = __ath6kl_cfg80211_resume,
3456 #endif
3457 	.start_ap = ath6kl_start_ap,
3458 	.change_beacon = ath6kl_change_beacon,
3459 	.stop_ap = ath6kl_stop_ap,
3460 	.del_station = ath6kl_del_station,
3461 	.change_station = ath6kl_change_station,
3462 	.remain_on_channel = ath6kl_remain_on_channel,
3463 	.cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3464 	.mgmt_tx = ath6kl_mgmt_tx,
3465 	.mgmt_frame_register = ath6kl_mgmt_frame_register,
3466 	.get_antenna = ath6kl_get_antenna,
3467 	.sched_scan_start = ath6kl_cfg80211_sscan_start,
3468 	.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3469 	.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3470 	.set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3471 };
3472 
ath6kl_cfg80211_stop(struct ath6kl_vif * vif)3473 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3474 {
3475 	ath6kl_cfg80211_sscan_disable(vif);
3476 
3477 	switch (vif->sme_state) {
3478 	case SME_DISCONNECTED:
3479 		break;
3480 	case SME_CONNECTING:
3481 		cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3482 					NULL, 0,
3483 					WLAN_STATUS_UNSPECIFIED_FAILURE,
3484 					GFP_KERNEL);
3485 		break;
3486 	case SME_CONNECTED:
3487 		cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3488 		break;
3489 	}
3490 
3491 	if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3492 	    (test_bit(CONNECTED, &vif->flags) ||
3493 	    test_bit(CONNECT_PEND, &vif->flags)))
3494 		ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3495 
3496 	vif->sme_state = SME_DISCONNECTED;
3497 	clear_bit(CONNECTED, &vif->flags);
3498 	clear_bit(CONNECT_PEND, &vif->flags);
3499 
3500 	/* Stop netdev queues, needed during recovery */
3501 	netif_stop_queue(vif->ndev);
3502 	netif_carrier_off(vif->ndev);
3503 
3504 	/* disable scanning */
3505 	if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3506 	    ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3507 				      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3508 		ath6kl_warn("failed to disable scan during stop\n");
3509 
3510 	ath6kl_cfg80211_scan_complete_event(vif, true);
3511 }
3512 
ath6kl_cfg80211_stop_all(struct ath6kl * ar)3513 void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3514 {
3515 	struct ath6kl_vif *vif;
3516 
3517 	vif = ath6kl_vif_first(ar);
3518 	if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3519 		/* save the current power mode before enabling power save */
3520 		ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3521 
3522 		if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3523 			ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3524 		return;
3525 	}
3526 
3527 	/*
3528 	 * FIXME: we should take ar->list_lock to protect changes in the
3529 	 * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3530 	 * sleeps.
3531 	 */
3532 	list_for_each_entry(vif, &ar->vif_list, list)
3533 		ath6kl_cfg80211_stop(vif);
3534 }
3535 
ath6kl_cfg80211_reg_notify(struct wiphy * wiphy,struct regulatory_request * request)3536 static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3537 				       struct regulatory_request *request)
3538 {
3539 	struct ath6kl *ar = wiphy_priv(wiphy);
3540 	u32 rates[NUM_NL80211_BANDS];
3541 	int ret, i;
3542 
3543 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3544 		   "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3545 		   request->alpha2[0], request->alpha2[1],
3546 		   request->intersect ? " intersect" : "",
3547 		   request->processed ? " processed" : "",
3548 		   request->initiator, request->user_reg_hint_type);
3549 
3550 	if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3551 		return;
3552 
3553 	ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3554 	if (ret) {
3555 		ath6kl_err("failed to set regdomain: %d\n", ret);
3556 		return;
3557 	}
3558 
3559 	/*
3560 	 * Firmware will apply the regdomain change only after a scan is
3561 	 * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3562 	 * changed.
3563 	 */
3564 
3565 	for (i = 0; i < NUM_NL80211_BANDS; i++)
3566 		if (wiphy->bands[i])
3567 			rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3568 
3569 
3570 	ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3571 				       false, 0, ATH6KL_FG_SCAN_INTERVAL,
3572 				       0, NULL, false, rates);
3573 	if (ret) {
3574 		ath6kl_err("failed to start scan for a regdomain change: %d\n",
3575 			   ret);
3576 		return;
3577 	}
3578 }
3579 
ath6kl_cfg80211_vif_init(struct ath6kl_vif * vif)3580 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3581 {
3582 	vif->aggr_cntxt = aggr_init(vif);
3583 	if (!vif->aggr_cntxt) {
3584 		ath6kl_err("failed to initialize aggr\n");
3585 		return -ENOMEM;
3586 	}
3587 
3588 	setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
3589 		    (unsigned long) vif->ndev);
3590 	setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
3591 		    (unsigned long) vif);
3592 
3593 	set_bit(WMM_ENABLED, &vif->flags);
3594 	spin_lock_init(&vif->if_lock);
3595 
3596 	INIT_LIST_HEAD(&vif->mc_filter);
3597 
3598 	return 0;
3599 }
3600 
ath6kl_cfg80211_vif_stop(struct ath6kl_vif * vif,bool wmi_ready)3601 void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3602 {
3603 	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3604 	bool discon_issued;
3605 
3606 	netif_stop_queue(vif->ndev);
3607 
3608 	clear_bit(WLAN_ENABLED, &vif->flags);
3609 
3610 	if (wmi_ready) {
3611 		discon_issued = test_bit(CONNECTED, &vif->flags) ||
3612 				test_bit(CONNECT_PEND, &vif->flags);
3613 		ath6kl_disconnect(vif);
3614 		del_timer(&vif->disconnect_timer);
3615 
3616 		if (discon_issued)
3617 			ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3618 						(vif->nw_type & AP_NETWORK) ?
3619 						bcast_mac : vif->bssid,
3620 						0, NULL, 0);
3621 	}
3622 
3623 	if (vif->scan_req) {
3624 		struct cfg80211_scan_info info = {
3625 			.aborted = true,
3626 		};
3627 
3628 		cfg80211_scan_done(vif->scan_req, &info);
3629 		vif->scan_req = NULL;
3630 	}
3631 
3632 	/* need to clean up enhanced bmiss detection fw state */
3633 	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3634 }
3635 
ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif * vif)3636 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3637 {
3638 	struct ath6kl *ar = vif->ar;
3639 	struct ath6kl_mc_filter *mc_filter, *tmp;
3640 
3641 	aggr_module_destroy(vif->aggr_cntxt);
3642 
3643 	ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3644 
3645 	if (vif->nw_type == ADHOC_NETWORK)
3646 		ar->ibss_if_active = false;
3647 
3648 	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3649 		list_del(&mc_filter->list);
3650 		kfree(mc_filter);
3651 	}
3652 
3653 	unregister_netdevice(vif->ndev);
3654 
3655 	ar->num_vif--;
3656 }
3657 
3658 static const char ath6kl_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
3659 	/* Common stats names used by many drivers. */
3660 	"tx_pkts_nic", "tx_bytes_nic", "rx_pkts_nic", "rx_bytes_nic",
3661 
3662 	/* TX stats. */
3663 	"d_tx_ucast_pkts", "d_tx_bcast_pkts",
3664 	"d_tx_ucast_bytes", "d_tx_bcast_bytes",
3665 	"d_tx_rts_ok", "d_tx_error", "d_tx_fail",
3666 	"d_tx_retry", "d_tx_multi_retry", "d_tx_rts_fail",
3667 	"d_tx_tkip_counter_measures",
3668 
3669 	/* RX Stats. */
3670 	"d_rx_ucast_pkts", "d_rx_ucast_rate", "d_rx_bcast_pkts",
3671 	"d_rx_ucast_bytes", "d_rx_bcast_bytes", "d_rx_frag_pkt",
3672 	"d_rx_error", "d_rx_crc_err", "d_rx_keycache_miss",
3673 	"d_rx_decrypt_crc_err", "d_rx_duplicate_frames",
3674 	"d_rx_mic_err", "d_rx_tkip_format_err", "d_rx_ccmp_format_err",
3675 	"d_rx_ccmp_replay_err",
3676 
3677 	/* Misc stats. */
3678 	"d_beacon_miss", "d_num_connects", "d_num_disconnects",
3679 	"d_beacon_avg_rssi", "d_arp_received", "d_arp_matched",
3680 	"d_arp_replied"
3681 };
3682 
3683 #define ATH6KL_STATS_LEN	ARRAY_SIZE(ath6kl_gstrings_sta_stats)
3684 
ath6kl_get_sset_count(struct net_device * dev,int sset)3685 static int ath6kl_get_sset_count(struct net_device *dev, int sset)
3686 {
3687 	int rv = 0;
3688 
3689 	if (sset == ETH_SS_STATS)
3690 		rv += ATH6KL_STATS_LEN;
3691 
3692 	if (rv == 0)
3693 		return -EOPNOTSUPP;
3694 	return rv;
3695 }
3696 
ath6kl_get_stats(struct net_device * dev,struct ethtool_stats * stats,u64 * data)3697 static void ath6kl_get_stats(struct net_device *dev,
3698 			    struct ethtool_stats *stats,
3699 			    u64 *data)
3700 {
3701 	struct ath6kl_vif *vif = netdev_priv(dev);
3702 	struct ath6kl *ar = vif->ar;
3703 	int i = 0;
3704 	struct target_stats *tgt_stats;
3705 
3706 	memset(data, 0, sizeof(u64) * ATH6KL_STATS_LEN);
3707 
3708 	ath6kl_read_tgt_stats(ar, vif);
3709 
3710 	tgt_stats = &vif->target_stats;
3711 
3712 	data[i++] = tgt_stats->tx_ucast_pkt + tgt_stats->tx_bcast_pkt;
3713 	data[i++] = tgt_stats->tx_ucast_byte + tgt_stats->tx_bcast_byte;
3714 	data[i++] = tgt_stats->rx_ucast_pkt + tgt_stats->rx_bcast_pkt;
3715 	data[i++] = tgt_stats->rx_ucast_byte + tgt_stats->rx_bcast_byte;
3716 
3717 	data[i++] = tgt_stats->tx_ucast_pkt;
3718 	data[i++] = tgt_stats->tx_bcast_pkt;
3719 	data[i++] = tgt_stats->tx_ucast_byte;
3720 	data[i++] = tgt_stats->tx_bcast_byte;
3721 	data[i++] = tgt_stats->tx_rts_success_cnt;
3722 	data[i++] = tgt_stats->tx_err;
3723 	data[i++] = tgt_stats->tx_fail_cnt;
3724 	data[i++] = tgt_stats->tx_retry_cnt;
3725 	data[i++] = tgt_stats->tx_mult_retry_cnt;
3726 	data[i++] = tgt_stats->tx_rts_fail_cnt;
3727 	data[i++] = tgt_stats->tkip_cnter_measures_invoked;
3728 
3729 	data[i++] = tgt_stats->rx_ucast_pkt;
3730 	data[i++] = tgt_stats->rx_ucast_rate;
3731 	data[i++] = tgt_stats->rx_bcast_pkt;
3732 	data[i++] = tgt_stats->rx_ucast_byte;
3733 	data[i++] = tgt_stats->rx_bcast_byte;
3734 	data[i++] = tgt_stats->rx_frgment_pkt;
3735 	data[i++] = tgt_stats->rx_err;
3736 	data[i++] = tgt_stats->rx_crc_err;
3737 	data[i++] = tgt_stats->rx_key_cache_miss;
3738 	data[i++] = tgt_stats->rx_decrypt_err;
3739 	data[i++] = tgt_stats->rx_dupl_frame;
3740 	data[i++] = tgt_stats->tkip_local_mic_fail;
3741 	data[i++] = tgt_stats->tkip_fmt_err;
3742 	data[i++] = tgt_stats->ccmp_fmt_err;
3743 	data[i++] = tgt_stats->ccmp_replays;
3744 
3745 	data[i++] = tgt_stats->cs_bmiss_cnt;
3746 	data[i++] = tgt_stats->cs_connect_cnt;
3747 	data[i++] = tgt_stats->cs_discon_cnt;
3748 	data[i++] = tgt_stats->cs_ave_beacon_rssi;
3749 	data[i++] = tgt_stats->arp_received;
3750 	data[i++] = tgt_stats->arp_matched;
3751 	data[i++] = tgt_stats->arp_replied;
3752 
3753 	if (i !=  ATH6KL_STATS_LEN) {
3754 		WARN_ON_ONCE(1);
3755 		ath6kl_err("ethtool stats error, i: %d  STATS_LEN: %d\n",
3756 			   i, (int)ATH6KL_STATS_LEN);
3757 	}
3758 }
3759 
3760 /* These stats are per NIC, not really per vdev, so we just ignore dev. */
ath6kl_get_strings(struct net_device * dev,u32 sset,u8 * data)3761 static void ath6kl_get_strings(struct net_device *dev, u32 sset, u8 *data)
3762 {
3763 	int sz_sta_stats = 0;
3764 
3765 	if (sset == ETH_SS_STATS) {
3766 		sz_sta_stats = sizeof(ath6kl_gstrings_sta_stats);
3767 		memcpy(data, ath6kl_gstrings_sta_stats, sz_sta_stats);
3768 	}
3769 }
3770 
3771 static const struct ethtool_ops ath6kl_ethtool_ops = {
3772 	.get_drvinfo = cfg80211_get_drvinfo,
3773 	.get_link = ethtool_op_get_link,
3774 	.get_strings = ath6kl_get_strings,
3775 	.get_ethtool_stats = ath6kl_get_stats,
3776 	.get_sset_count = ath6kl_get_sset_count,
3777 };
3778 
ath6kl_interface_add(struct ath6kl * ar,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u8 fw_vif_idx,u8 nw_type)3779 struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3780 					  unsigned char name_assign_type,
3781 					  enum nl80211_iftype type,
3782 					  u8 fw_vif_idx, u8 nw_type)
3783 {
3784 	struct net_device *ndev;
3785 	struct ath6kl_vif *vif;
3786 
3787 	ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3788 	if (!ndev)
3789 		return NULL;
3790 
3791 	vif = netdev_priv(ndev);
3792 	ndev->ieee80211_ptr = &vif->wdev;
3793 	vif->wdev.wiphy = ar->wiphy;
3794 	vif->ar = ar;
3795 	vif->ndev = ndev;
3796 	SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3797 	vif->wdev.netdev = ndev;
3798 	vif->wdev.iftype = type;
3799 	vif->fw_vif_idx = fw_vif_idx;
3800 	vif->nw_type = nw_type;
3801 	vif->next_mode = nw_type;
3802 	vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3803 	vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3804 	vif->bg_scan_period = 0;
3805 	vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3806 	vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3807 
3808 	memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3809 	if (fw_vif_idx != 0) {
3810 		ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3811 				     0x2;
3812 		if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3813 			     ar->fw_capabilities))
3814 			ndev->dev_addr[4] ^= 0x80;
3815 	}
3816 
3817 	init_netdev(ndev);
3818 
3819 	ath6kl_init_control_info(vif);
3820 
3821 	if (ath6kl_cfg80211_vif_init(vif))
3822 		goto err;
3823 
3824 	netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3825 
3826 	if (register_netdevice(ndev))
3827 		goto err;
3828 
3829 	ar->avail_idx_map &= ~BIT(fw_vif_idx);
3830 	vif->sme_state = SME_DISCONNECTED;
3831 	set_bit(WLAN_ENABLED, &vif->flags);
3832 	ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3833 
3834 	if (type == NL80211_IFTYPE_ADHOC)
3835 		ar->ibss_if_active = true;
3836 
3837 	spin_lock_bh(&ar->list_lock);
3838 	list_add_tail(&vif->list, &ar->vif_list);
3839 	spin_unlock_bh(&ar->list_lock);
3840 
3841 	return &vif->wdev;
3842 
3843 err:
3844 	aggr_module_destroy(vif->aggr_cntxt);
3845 	free_netdev(ndev);
3846 	return NULL;
3847 }
3848 
3849 #ifdef CONFIG_PM
3850 static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3851 	.flags = WIPHY_WOWLAN_MAGIC_PKT |
3852 		 WIPHY_WOWLAN_DISCONNECT |
3853 		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3854 		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3855 		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3856 		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
3857 	.n_patterns = WOW_MAX_FILTERS_PER_LIST,
3858 	.pattern_min_len = 1,
3859 	.pattern_max_len = WOW_PATTERN_SIZE,
3860 };
3861 #endif
3862 
ath6kl_cfg80211_init(struct ath6kl * ar)3863 int ath6kl_cfg80211_init(struct ath6kl *ar)
3864 {
3865 	struct wiphy *wiphy = ar->wiphy;
3866 	bool band_2gig = false, band_5gig = false, ht = false;
3867 	int ret;
3868 
3869 	wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3870 
3871 	wiphy->max_remain_on_channel_duration = 5000;
3872 
3873 	/* set device pointer for wiphy */
3874 	set_wiphy_dev(wiphy, ar->dev);
3875 
3876 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3877 				 BIT(NL80211_IFTYPE_ADHOC) |
3878 				 BIT(NL80211_IFTYPE_AP);
3879 	if (ar->p2p) {
3880 		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3881 					  BIT(NL80211_IFTYPE_P2P_CLIENT);
3882 	}
3883 
3884 	if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3885 	    test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3886 		wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3887 		ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3888 	}
3889 
3890 	/* max num of ssids that can be probed during scanning */
3891 	wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3892 
3893 	/* max num of ssids that can be matched after scan */
3894 	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3895 		     ar->fw_capabilities))
3896 		wiphy->max_match_sets = MAX_PROBED_SSIDS;
3897 
3898 	wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3899 	switch (ar->hw.cap) {
3900 	case WMI_11AN_CAP:
3901 		ht = true;
3902 	case WMI_11A_CAP:
3903 		band_5gig = true;
3904 		break;
3905 	case WMI_11GN_CAP:
3906 		ht = true;
3907 	case WMI_11G_CAP:
3908 		band_2gig = true;
3909 		break;
3910 	case WMI_11AGN_CAP:
3911 		ht = true;
3912 	case WMI_11AG_CAP:
3913 		band_2gig = true;
3914 		band_5gig = true;
3915 		break;
3916 	default:
3917 		ath6kl_err("invalid phy capability!\n");
3918 		return -EINVAL;
3919 	}
3920 
3921 	/*
3922 	 * Even if the fw has HT support, advertise HT cap only when
3923 	 * the firmware has support to override RSN capability, otherwise
3924 	 * 4-way handshake would fail.
3925 	 */
3926 	if (!(ht &&
3927 	      test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3928 		       ar->fw_capabilities))) {
3929 		ath6kl_band_2ghz.ht_cap.cap = 0;
3930 		ath6kl_band_2ghz.ht_cap.ht_supported = false;
3931 		ath6kl_band_5ghz.ht_cap.cap = 0;
3932 		ath6kl_band_5ghz.ht_cap.ht_supported = false;
3933 
3934 		if (ht)
3935 			ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3936 	}
3937 
3938 	if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3939 		     ar->fw_capabilities)) {
3940 		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3941 		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3942 		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3943 		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3944 		ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3945 		ar->hw.rx_ant = 0x3;
3946 	} else {
3947 		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3948 		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3949 		ar->hw.tx_ant = 1;
3950 		ar->hw.rx_ant = 1;
3951 	}
3952 
3953 	wiphy->available_antennas_tx = ar->hw.tx_ant;
3954 	wiphy->available_antennas_rx = ar->hw.rx_ant;
3955 
3956 	if (band_2gig)
3957 		wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3958 	if (band_5gig)
3959 		wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3960 
3961 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3962 
3963 	wiphy->cipher_suites = cipher_suites;
3964 	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3965 
3966 #ifdef CONFIG_PM
3967 	wiphy->wowlan = &ath6kl_wowlan_support;
3968 #endif
3969 
3970 	wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3971 
3972 	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3973 			    WIPHY_FLAG_HAVE_AP_SME |
3974 			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3975 			    WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3976 
3977 	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3978 		ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3979 
3980 	if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3981 		     ar->fw_capabilities))
3982 		ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3983 
3984 	ar->wiphy->probe_resp_offload =
3985 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3986 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3987 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3988 
3989 	ret = wiphy_register(wiphy);
3990 	if (ret < 0) {
3991 		ath6kl_err("couldn't register wiphy device\n");
3992 		return ret;
3993 	}
3994 
3995 	ar->wiphy_registered = true;
3996 
3997 	return 0;
3998 }
3999 
ath6kl_cfg80211_cleanup(struct ath6kl * ar)4000 void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4001 {
4002 	wiphy_unregister(ar->wiphy);
4003 
4004 	ar->wiphy_registered = false;
4005 }
4006 
ath6kl_cfg80211_create(void)4007 struct ath6kl *ath6kl_cfg80211_create(void)
4008 {
4009 	struct ath6kl *ar;
4010 	struct wiphy *wiphy;
4011 
4012 	/* create a new wiphy for use with cfg80211 */
4013 	wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4014 
4015 	if (!wiphy) {
4016 		ath6kl_err("couldn't allocate wiphy device\n");
4017 		return NULL;
4018 	}
4019 
4020 	ar = wiphy_priv(wiphy);
4021 	ar->wiphy = wiphy;
4022 
4023 	return ar;
4024 }
4025 
4026 /* Note: ar variable must not be accessed after calling this! */
ath6kl_cfg80211_destroy(struct ath6kl * ar)4027 void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4028 {
4029 	int i;
4030 
4031 	for (i = 0; i < AP_MAX_NUM_STA; i++)
4032 		kfree(ar->sta_list[i].aggr_conn);
4033 
4034 	wiphy_free(ar->wiphy);
4035 }
4036 
4037