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