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, 0);
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,unsigned int link_id)2970 static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev,
2971 			  unsigned int link_id)
2972 {
2973 	struct ath6kl *ar = ath6kl_priv(dev);
2974 	struct ath6kl_vif *vif = netdev_priv(dev);
2975 
2976 	if (vif->nw_type != AP_NETWORK)
2977 		return -EOPNOTSUPP;
2978 	if (!test_bit(CONNECTED, &vif->flags))
2979 		return -ENOTCONN;
2980 
2981 	ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2982 	clear_bit(CONNECTED, &vif->flags);
2983 	netif_carrier_off(vif->ndev);
2984 
2985 	/* Restore ht setting in firmware */
2986 	return ath6kl_restore_htcap(vif);
2987 }
2988 
2989 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2990 
ath6kl_del_station(struct wiphy * wiphy,struct net_device * dev,struct station_del_parameters * params)2991 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2992 			      struct station_del_parameters *params)
2993 {
2994 	struct ath6kl *ar = ath6kl_priv(dev);
2995 	struct ath6kl_vif *vif = netdev_priv(dev);
2996 	const u8 *addr = params->mac ? params->mac : bcast_addr;
2997 
2998 	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2999 				      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
3000 }
3001 
ath6kl_change_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_parameters * params)3002 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3003 				 const u8 *mac,
3004 				 struct station_parameters *params)
3005 {
3006 	struct ath6kl *ar = ath6kl_priv(dev);
3007 	struct ath6kl_vif *vif = netdev_priv(dev);
3008 	int err;
3009 
3010 	if (vif->nw_type != AP_NETWORK)
3011 		return -EOPNOTSUPP;
3012 
3013 	err = cfg80211_check_station_change(wiphy, params,
3014 					    CFG80211_STA_AP_MLME_CLIENT);
3015 	if (err)
3016 		return err;
3017 
3018 	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3019 		return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3020 					      WMI_AP_MLME_AUTHORIZE, mac, 0);
3021 	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3022 				      WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3023 }
3024 
ath6kl_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,struct ieee80211_channel * chan,unsigned int duration,u64 * cookie)3025 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3026 				    struct wireless_dev *wdev,
3027 				    struct ieee80211_channel *chan,
3028 				    unsigned int duration,
3029 				    u64 *cookie)
3030 {
3031 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3032 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3033 	u32 id;
3034 
3035 	/* TODO: if already pending or ongoing remain-on-channel,
3036 	 * return -EBUSY */
3037 	id = ++vif->last_roc_id;
3038 	if (id == 0) {
3039 		/* Do not use 0 as the cookie value */
3040 		id = ++vif->last_roc_id;
3041 	}
3042 	*cookie = id;
3043 
3044 	return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3045 					     chan->center_freq, duration);
3046 }
3047 
ath6kl_cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)3048 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3049 					   struct wireless_dev *wdev,
3050 					   u64 cookie)
3051 {
3052 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3053 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3054 
3055 	if (cookie != vif->last_roc_id)
3056 		return -ENOENT;
3057 	vif->last_cancel_roc_id = cookie;
3058 
3059 	return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3060 }
3061 
ath6kl_send_go_probe_resp(struct ath6kl_vif * vif,const u8 * buf,size_t len,unsigned int freq)3062 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3063 				     const u8 *buf, size_t len,
3064 				     unsigned int freq)
3065 {
3066 	struct ath6kl *ar = vif->ar;
3067 	const u8 *pos;
3068 	u8 *p2p;
3069 	int p2p_len;
3070 	int ret;
3071 	const struct ieee80211_mgmt *mgmt;
3072 
3073 	mgmt = (const struct ieee80211_mgmt *) buf;
3074 
3075 	/* Include P2P IE(s) from the frame generated in user space. */
3076 
3077 	p2p = kmalloc(len, GFP_KERNEL);
3078 	if (p2p == NULL)
3079 		return -ENOMEM;
3080 	p2p_len = 0;
3081 
3082 	pos = mgmt->u.probe_resp.variable;
3083 	while (pos + 1 < buf + len) {
3084 		if (pos + 2 + pos[1] > buf + len)
3085 			break;
3086 		if (ath6kl_is_p2p_ie(pos)) {
3087 			memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3088 			p2p_len += 2 + pos[1];
3089 		}
3090 		pos += 2 + pos[1];
3091 	}
3092 
3093 	ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3094 						 mgmt->da, p2p, p2p_len);
3095 	kfree(p2p);
3096 	return ret;
3097 }
3098 
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)3099 static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3100 				     u32 id,
3101 				     u32 freq,
3102 				     u32 wait,
3103 				     const u8 *buf,
3104 				     size_t len,
3105 				     bool *more_data,
3106 				     bool no_cck)
3107 {
3108 	struct ieee80211_mgmt *mgmt;
3109 	struct ath6kl_sta *conn;
3110 	bool is_psq_empty = false;
3111 	struct ath6kl_mgmt_buff *mgmt_buf;
3112 	size_t mgmt_buf_size;
3113 	struct ath6kl *ar = vif->ar;
3114 
3115 	mgmt = (struct ieee80211_mgmt *) buf;
3116 	if (is_multicast_ether_addr(mgmt->da))
3117 		return false;
3118 
3119 	conn = ath6kl_find_sta(vif, mgmt->da);
3120 	if (!conn)
3121 		return false;
3122 
3123 	if (conn->sta_flags & STA_PS_SLEEP) {
3124 		if (!(conn->sta_flags & STA_PS_POLLED)) {
3125 			/* Queue the frames if the STA is sleeping */
3126 			mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3127 			mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3128 			if (!mgmt_buf)
3129 				return false;
3130 
3131 			INIT_LIST_HEAD(&mgmt_buf->list);
3132 			mgmt_buf->id = id;
3133 			mgmt_buf->freq = freq;
3134 			mgmt_buf->wait = wait;
3135 			mgmt_buf->len = len;
3136 			mgmt_buf->no_cck = no_cck;
3137 			memcpy(mgmt_buf->buf, buf, len);
3138 			spin_lock_bh(&conn->psq_lock);
3139 			is_psq_empty = skb_queue_empty(&conn->psq) &&
3140 					(conn->mgmt_psq_len == 0);
3141 			list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3142 			conn->mgmt_psq_len++;
3143 			spin_unlock_bh(&conn->psq_lock);
3144 
3145 			/*
3146 			 * If this is the first pkt getting queued
3147 			 * for this STA, update the PVB for this
3148 			 * STA.
3149 			 */
3150 			if (is_psq_empty)
3151 				ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3152 						       conn->aid, 1);
3153 			return true;
3154 		}
3155 
3156 		/*
3157 		 * This tx is because of a PsPoll.
3158 		 * Determine if MoreData bit has to be set.
3159 		 */
3160 		spin_lock_bh(&conn->psq_lock);
3161 		if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3162 			*more_data = true;
3163 		spin_unlock_bh(&conn->psq_lock);
3164 	}
3165 
3166 	return false;
3167 }
3168 
3169 /* Check if SSID length is greater than DIRECT- */
ath6kl_is_p2p_go_ssid(const u8 * buf,size_t len)3170 static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3171 {
3172 	const struct ieee80211_mgmt *mgmt;
3173 	mgmt = (const struct ieee80211_mgmt *) buf;
3174 
3175 	/* variable[1] contains the SSID tag length */
3176 	if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3177 	    (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3178 		return true;
3179 	}
3180 
3181 	return false;
3182 }
3183 
ath6kl_mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_mgmt_tx_params * params,u64 * cookie)3184 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3185 			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3186 {
3187 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3188 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3189 	struct ieee80211_channel *chan = params->chan;
3190 	const u8 *buf = params->buf;
3191 	size_t len = params->len;
3192 	unsigned int wait = params->wait;
3193 	bool no_cck = params->no_cck;
3194 	u32 id, freq;
3195 	const struct ieee80211_mgmt *mgmt;
3196 	bool more_data, queued;
3197 
3198 	/* default to the current channel, but use the one specified as argument
3199 	 * if any
3200 	 */
3201 	freq = vif->ch_hint;
3202 	if (chan)
3203 		freq = chan->center_freq;
3204 
3205 	/* never send freq zero to the firmware */
3206 	if (WARN_ON(freq == 0))
3207 		return -EINVAL;
3208 
3209 	mgmt = (const struct ieee80211_mgmt *) buf;
3210 	if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3211 	    ieee80211_is_probe_resp(mgmt->frame_control) &&
3212 	    ath6kl_is_p2p_go_ssid(buf, len)) {
3213 		/*
3214 		 * Send Probe Response frame in GO mode using a separate WMI
3215 		 * command to allow the target to fill in the generic IEs.
3216 		 */
3217 		*cookie = 0; /* TX status not supported */
3218 		return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3219 	}
3220 
3221 	id = vif->send_action_id++;
3222 	if (id == 0) {
3223 		/*
3224 		 * 0 is a reserved value in the WMI command and shall not be
3225 		 * used for the command.
3226 		 */
3227 		id = vif->send_action_id++;
3228 	}
3229 
3230 	*cookie = id;
3231 
3232 	/* AP mode Power saving processing */
3233 	if (vif->nw_type == AP_NETWORK) {
3234 		queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3235 						  &more_data, no_cck);
3236 		if (queued)
3237 			return 0;
3238 	}
3239 
3240 	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3241 					wait, buf, len, no_cck);
3242 }
3243 
ath6kl_get_antenna(struct wiphy * wiphy,u32 * tx_ant,u32 * rx_ant)3244 static int ath6kl_get_antenna(struct wiphy *wiphy,
3245 			      u32 *tx_ant, u32 *rx_ant)
3246 {
3247 	struct ath6kl *ar = wiphy_priv(wiphy);
3248 	*tx_ant = ar->hw.tx_ant;
3249 	*rx_ant = ar->hw.rx_ant;
3250 	return 0;
3251 }
3252 
ath6kl_update_mgmt_frame_registrations(struct wiphy * wiphy,struct wireless_dev * wdev,struct mgmt_frame_regs * upd)3253 static void ath6kl_update_mgmt_frame_registrations(struct wiphy *wiphy,
3254 						   struct wireless_dev *wdev,
3255 						   struct mgmt_frame_regs *upd)
3256 {
3257 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3258 
3259 	/*
3260 	 * FIXME: send WMI_PROBE_REQ_REPORT_CMD here instead of hardcoding
3261 	 *	  the reporting in the target all the time, this callback
3262 	 *	  *is* allowed to sleep after all.
3263 	 */
3264 	vif->probe_req_report =
3265 		upd->interface_stypes & BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
3266 }
3267 
ath6kl_cfg80211_sscan_start(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_sched_scan_request * request)3268 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3269 			struct net_device *dev,
3270 			struct cfg80211_sched_scan_request *request)
3271 {
3272 	struct ath6kl *ar = ath6kl_priv(dev);
3273 	struct ath6kl_vif *vif = netdev_priv(dev);
3274 	u16 interval;
3275 	int ret, rssi_thold;
3276 	int n_match_sets = request->n_match_sets;
3277 
3278 	/*
3279 	 * If there's a matchset w/o an SSID, then assume it's just for
3280 	 * the RSSI (nothing else is currently supported) and ignore it.
3281 	 * The device only supports a global RSSI filter that we set below.
3282 	 */
3283 	if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3284 		n_match_sets = 0;
3285 
3286 	if (ar->state != ATH6KL_STATE_ON)
3287 		return -EIO;
3288 
3289 	if (vif->sme_state != SME_DISCONNECTED)
3290 		return -EBUSY;
3291 
3292 	ath6kl_cfg80211_scan_complete_event(vif, true);
3293 
3294 	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3295 				      request->n_ssids,
3296 				      request->match_sets,
3297 				      n_match_sets);
3298 	if (ret < 0)
3299 		return ret;
3300 
3301 	if (!n_match_sets) {
3302 		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3303 					       ALL_BSS_FILTER, 0);
3304 		if (ret < 0)
3305 			return ret;
3306 	} else {
3307 		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3308 					       MATCHED_SSID_FILTER, 0);
3309 		if (ret < 0)
3310 			return ret;
3311 	}
3312 
3313 	if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3314 		     ar->fw_capabilities)) {
3315 		if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3316 			rssi_thold = 0;
3317 		else if (request->min_rssi_thold < -127)
3318 			rssi_thold = -127;
3319 		else
3320 			rssi_thold = request->min_rssi_thold;
3321 
3322 		ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3323 						     rssi_thold);
3324 		if (ret) {
3325 			ath6kl_err("failed to set RSSI threshold for scan\n");
3326 			return ret;
3327 		}
3328 	}
3329 
3330 	/* fw uses seconds, also make sure that it's >0 */
3331 	interval = max_t(u16, 1, request->scan_plans[0].interval);
3332 
3333 	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3334 				  interval, interval,
3335 				  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3336 
3337 	/* this also clears IE in fw if it's not set */
3338 	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3339 				       WMI_FRAME_PROBE_REQ,
3340 				       request->ie, request->ie_len);
3341 	if (ret) {
3342 		ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3343 			    ret);
3344 		return ret;
3345 	}
3346 
3347 	ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3348 	if (ret)
3349 		return ret;
3350 
3351 	set_bit(SCHED_SCANNING, &vif->flags);
3352 
3353 	return 0;
3354 }
3355 
ath6kl_cfg80211_sscan_stop(struct wiphy * wiphy,struct net_device * dev,u64 reqid)3356 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3357 				      struct net_device *dev, u64 reqid)
3358 {
3359 	struct ath6kl_vif *vif = netdev_priv(dev);
3360 	bool stopped;
3361 
3362 	stopped = __ath6kl_cfg80211_sscan_stop(vif);
3363 
3364 	if (!stopped)
3365 		return -EIO;
3366 
3367 	return 0;
3368 }
3369 
ath6kl_cfg80211_set_bitrate(struct wiphy * wiphy,struct net_device * dev,unsigned int link_id,const u8 * addr,const struct cfg80211_bitrate_mask * mask)3370 static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3371 				       struct net_device *dev,
3372 				       unsigned int link_id,
3373 				       const u8 *addr,
3374 				       const struct cfg80211_bitrate_mask *mask)
3375 {
3376 	struct ath6kl *ar = ath6kl_priv(dev);
3377 	struct ath6kl_vif *vif = netdev_priv(dev);
3378 
3379 	return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3380 					   mask);
3381 }
3382 
ath6kl_cfg80211_set_txe_config(struct wiphy * wiphy,struct net_device * dev,u32 rate,u32 pkts,u32 intvl)3383 static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3384 					  struct net_device *dev,
3385 					  u32 rate, u32 pkts, u32 intvl)
3386 {
3387 	struct ath6kl *ar = ath6kl_priv(dev);
3388 	struct ath6kl_vif *vif = netdev_priv(dev);
3389 
3390 	if (vif->nw_type != INFRA_NETWORK ||
3391 	    !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3392 		return -EOPNOTSUPP;
3393 
3394 	if (vif->sme_state != SME_CONNECTED)
3395 		return -ENOTCONN;
3396 
3397 	/* save this since the firmware won't report the interval */
3398 	vif->txe_intvl = intvl;
3399 
3400 	return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3401 					 rate, pkts, intvl);
3402 }
3403 
3404 static const struct ieee80211_txrx_stypes
3405 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3406 	[NL80211_IFTYPE_STATION] = {
3407 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3408 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3409 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3410 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3411 	},
3412 	[NL80211_IFTYPE_AP] = {
3413 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3414 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3415 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3416 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3417 	},
3418 	[NL80211_IFTYPE_P2P_CLIENT] = {
3419 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3420 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3421 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3422 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3423 	},
3424 	[NL80211_IFTYPE_P2P_GO] = {
3425 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3426 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3427 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3428 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3429 	},
3430 };
3431 
3432 static struct cfg80211_ops ath6kl_cfg80211_ops = {
3433 	.add_virtual_intf = ath6kl_cfg80211_add_iface,
3434 	.del_virtual_intf = ath6kl_cfg80211_del_iface,
3435 	.change_virtual_intf = ath6kl_cfg80211_change_iface,
3436 	.scan = ath6kl_cfg80211_scan,
3437 	.connect = ath6kl_cfg80211_connect,
3438 	.disconnect = ath6kl_cfg80211_disconnect,
3439 	.add_key = ath6kl_cfg80211_add_key,
3440 	.get_key = ath6kl_cfg80211_get_key,
3441 	.del_key = ath6kl_cfg80211_del_key,
3442 	.set_default_key = ath6kl_cfg80211_set_default_key,
3443 	.set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3444 	.set_tx_power = ath6kl_cfg80211_set_txpower,
3445 	.get_tx_power = ath6kl_cfg80211_get_txpower,
3446 	.set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3447 	.join_ibss = ath6kl_cfg80211_join_ibss,
3448 	.leave_ibss = ath6kl_cfg80211_leave_ibss,
3449 	.get_station = ath6kl_get_station,
3450 	.set_pmksa = ath6kl_set_pmksa,
3451 	.del_pmksa = ath6kl_del_pmksa,
3452 	.flush_pmksa = ath6kl_flush_pmksa,
3453 	CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3454 #ifdef CONFIG_PM
3455 	.suspend = __ath6kl_cfg80211_suspend,
3456 	.resume = __ath6kl_cfg80211_resume,
3457 #endif
3458 	.start_ap = ath6kl_start_ap,
3459 	.change_beacon = ath6kl_change_beacon,
3460 	.stop_ap = ath6kl_stop_ap,
3461 	.del_station = ath6kl_del_station,
3462 	.change_station = ath6kl_change_station,
3463 	.remain_on_channel = ath6kl_remain_on_channel,
3464 	.cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3465 	.mgmt_tx = ath6kl_mgmt_tx,
3466 	.update_mgmt_frame_registrations =
3467 		ath6kl_update_mgmt_frame_registrations,
3468 	.get_antenna = ath6kl_get_antenna,
3469 	.sched_scan_start = ath6kl_cfg80211_sscan_start,
3470 	.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3471 	.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3472 	.set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3473 };
3474 
ath6kl_cfg80211_stop(struct ath6kl_vif * vif)3475 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3476 {
3477 	ath6kl_cfg80211_sscan_disable(vif);
3478 
3479 	switch (vif->sme_state) {
3480 	case SME_DISCONNECTED:
3481 		break;
3482 	case SME_CONNECTING:
3483 		cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3484 					NULL, 0,
3485 					WLAN_STATUS_UNSPECIFIED_FAILURE,
3486 					GFP_KERNEL);
3487 		break;
3488 	case SME_CONNECTED:
3489 		cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3490 		break;
3491 	}
3492 
3493 	if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3494 	    (test_bit(CONNECTED, &vif->flags) ||
3495 	    test_bit(CONNECT_PEND, &vif->flags)))
3496 		ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3497 
3498 	vif->sme_state = SME_DISCONNECTED;
3499 	clear_bit(CONNECTED, &vif->flags);
3500 	clear_bit(CONNECT_PEND, &vif->flags);
3501 
3502 	/* Stop netdev queues, needed during recovery */
3503 	netif_stop_queue(vif->ndev);
3504 	netif_carrier_off(vif->ndev);
3505 
3506 	/* disable scanning */
3507 	if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3508 	    ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3509 				      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3510 		ath6kl_warn("failed to disable scan during stop\n");
3511 
3512 	ath6kl_cfg80211_scan_complete_event(vif, true);
3513 }
3514 
ath6kl_cfg80211_stop_all(struct ath6kl * ar)3515 void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3516 {
3517 	struct ath6kl_vif *vif;
3518 
3519 	vif = ath6kl_vif_first(ar);
3520 	if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3521 		/* save the current power mode before enabling power save */
3522 		ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3523 
3524 		if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3525 			ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3526 		return;
3527 	}
3528 
3529 	/*
3530 	 * FIXME: we should take ar->list_lock to protect changes in the
3531 	 * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3532 	 * sleeps.
3533 	 */
3534 	list_for_each_entry(vif, &ar->vif_list, list)
3535 		ath6kl_cfg80211_stop(vif);
3536 }
3537 
ath6kl_cfg80211_reg_notify(struct wiphy * wiphy,struct regulatory_request * request)3538 static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3539 				       struct regulatory_request *request)
3540 {
3541 	struct ath6kl *ar = wiphy_priv(wiphy);
3542 	u32 rates[NUM_NL80211_BANDS];
3543 	int ret, i;
3544 
3545 	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3546 		   "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3547 		   request->alpha2[0], request->alpha2[1],
3548 		   request->intersect ? " intersect" : "",
3549 		   request->processed ? " processed" : "",
3550 		   request->initiator, request->user_reg_hint_type);
3551 
3552 	if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3553 		return;
3554 
3555 	ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3556 	if (ret) {
3557 		ath6kl_err("failed to set regdomain: %d\n", ret);
3558 		return;
3559 	}
3560 
3561 	/*
3562 	 * Firmware will apply the regdomain change only after a scan is
3563 	 * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3564 	 * changed.
3565 	 */
3566 
3567 	for (i = 0; i < NUM_NL80211_BANDS; i++)
3568 		if (wiphy->bands[i])
3569 			rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3570 
3571 
3572 	ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3573 				       false, 0, ATH6KL_FG_SCAN_INTERVAL,
3574 				       0, NULL, false, rates);
3575 	if (ret) {
3576 		ath6kl_err("failed to start scan for a regdomain change: %d\n",
3577 			   ret);
3578 		return;
3579 	}
3580 }
3581 
ath6kl_cfg80211_vif_init(struct ath6kl_vif * vif)3582 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3583 {
3584 	vif->aggr_cntxt = aggr_init(vif);
3585 	if (!vif->aggr_cntxt) {
3586 		ath6kl_err("failed to initialize aggr\n");
3587 		return -ENOMEM;
3588 	}
3589 
3590 	timer_setup(&vif->disconnect_timer, disconnect_timer_handler, 0);
3591 	timer_setup(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer, 0);
3592 
3593 	set_bit(WMM_ENABLED, &vif->flags);
3594 	spin_lock_init(&vif->if_lock);
3595 
3596 	INIT_LIST_HEAD(&vif->mc_filter);
3597 
3598 	return 0;
3599 }
3600 
ath6kl_cfg80211_vif_stop(struct ath6kl_vif * vif,bool wmi_ready)3601 void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3602 {
3603 	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3604 	bool discon_issued;
3605 
3606 	netif_stop_queue(vif->ndev);
3607 
3608 	clear_bit(WLAN_ENABLED, &vif->flags);
3609 
3610 	if (wmi_ready) {
3611 		discon_issued = test_bit(CONNECTED, &vif->flags) ||
3612 				test_bit(CONNECT_PEND, &vif->flags);
3613 		ath6kl_disconnect(vif);
3614 		del_timer(&vif->disconnect_timer);
3615 
3616 		if (discon_issued)
3617 			ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3618 						(vif->nw_type & AP_NETWORK) ?
3619 						bcast_mac : vif->bssid,
3620 						0, NULL, 0);
3621 	}
3622 
3623 	if (vif->scan_req) {
3624 		struct cfg80211_scan_info info = {
3625 			.aborted = true,
3626 		};
3627 
3628 		cfg80211_scan_done(vif->scan_req, &info);
3629 		vif->scan_req = NULL;
3630 	}
3631 
3632 	/* need to clean up enhanced bmiss detection fw state */
3633 	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3634 }
3635 
ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif * vif)3636 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3637 {
3638 	struct ath6kl *ar = vif->ar;
3639 	struct ath6kl_mc_filter *mc_filter, *tmp;
3640 
3641 	aggr_module_destroy(vif->aggr_cntxt);
3642 
3643 	ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3644 
3645 	if (vif->nw_type == ADHOC_NETWORK)
3646 		ar->ibss_if_active = false;
3647 
3648 	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3649 		list_del(&mc_filter->list);
3650 		kfree(mc_filter);
3651 	}
3652 
3653 	cfg80211_unregister_netdevice(vif->ndev);
3654 
3655 	ar->num_vif--;
3656 }
3657 
3658 static const char ath6kl_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
3659 	/* Common stats names used by many drivers. */
3660 	"tx_pkts_nic", "tx_bytes_nic", "rx_pkts_nic", "rx_bytes_nic",
3661 
3662 	/* TX stats. */
3663 	"d_tx_ucast_pkts", "d_tx_bcast_pkts",
3664 	"d_tx_ucast_bytes", "d_tx_bcast_bytes",
3665 	"d_tx_rts_ok", "d_tx_error", "d_tx_fail",
3666 	"d_tx_retry", "d_tx_multi_retry", "d_tx_rts_fail",
3667 	"d_tx_tkip_counter_measures",
3668 
3669 	/* RX Stats. */
3670 	"d_rx_ucast_pkts", "d_rx_ucast_rate", "d_rx_bcast_pkts",
3671 	"d_rx_ucast_bytes", "d_rx_bcast_bytes", "d_rx_frag_pkt",
3672 	"d_rx_error", "d_rx_crc_err", "d_rx_keycache_miss",
3673 	"d_rx_decrypt_crc_err", "d_rx_duplicate_frames",
3674 	"d_rx_mic_err", "d_rx_tkip_format_err", "d_rx_ccmp_format_err",
3675 	"d_rx_ccmp_replay_err",
3676 
3677 	/* Misc stats. */
3678 	"d_beacon_miss", "d_num_connects", "d_num_disconnects",
3679 	"d_beacon_avg_rssi", "d_arp_received", "d_arp_matched",
3680 	"d_arp_replied"
3681 };
3682 
3683 #define ATH6KL_STATS_LEN	ARRAY_SIZE(ath6kl_gstrings_sta_stats)
3684 
ath6kl_get_sset_count(struct net_device * dev,int sset)3685 static int ath6kl_get_sset_count(struct net_device *dev, int sset)
3686 {
3687 	int rv = 0;
3688 
3689 	if (sset == ETH_SS_STATS)
3690 		rv += ATH6KL_STATS_LEN;
3691 
3692 	if (rv == 0)
3693 		return -EOPNOTSUPP;
3694 	return rv;
3695 }
3696 
ath6kl_get_stats(struct net_device * dev,struct ethtool_stats * stats,u64 * data)3697 static void ath6kl_get_stats(struct net_device *dev,
3698 			    struct ethtool_stats *stats,
3699 			    u64 *data)
3700 {
3701 	struct ath6kl_vif *vif = netdev_priv(dev);
3702 	struct ath6kl *ar = vif->ar;
3703 	int i = 0;
3704 	struct target_stats *tgt_stats;
3705 
3706 	memset(data, 0, sizeof(u64) * ATH6KL_STATS_LEN);
3707 
3708 	ath6kl_read_tgt_stats(ar, vif);
3709 
3710 	tgt_stats = &vif->target_stats;
3711 
3712 	data[i++] = tgt_stats->tx_ucast_pkt + tgt_stats->tx_bcast_pkt;
3713 	data[i++] = tgt_stats->tx_ucast_byte + tgt_stats->tx_bcast_byte;
3714 	data[i++] = tgt_stats->rx_ucast_pkt + tgt_stats->rx_bcast_pkt;
3715 	data[i++] = tgt_stats->rx_ucast_byte + tgt_stats->rx_bcast_byte;
3716 
3717 	data[i++] = tgt_stats->tx_ucast_pkt;
3718 	data[i++] = tgt_stats->tx_bcast_pkt;
3719 	data[i++] = tgt_stats->tx_ucast_byte;
3720 	data[i++] = tgt_stats->tx_bcast_byte;
3721 	data[i++] = tgt_stats->tx_rts_success_cnt;
3722 	data[i++] = tgt_stats->tx_err;
3723 	data[i++] = tgt_stats->tx_fail_cnt;
3724 	data[i++] = tgt_stats->tx_retry_cnt;
3725 	data[i++] = tgt_stats->tx_mult_retry_cnt;
3726 	data[i++] = tgt_stats->tx_rts_fail_cnt;
3727 	data[i++] = tgt_stats->tkip_cnter_measures_invoked;
3728 
3729 	data[i++] = tgt_stats->rx_ucast_pkt;
3730 	data[i++] = tgt_stats->rx_ucast_rate;
3731 	data[i++] = tgt_stats->rx_bcast_pkt;
3732 	data[i++] = tgt_stats->rx_ucast_byte;
3733 	data[i++] = tgt_stats->rx_bcast_byte;
3734 	data[i++] = tgt_stats->rx_frgment_pkt;
3735 	data[i++] = tgt_stats->rx_err;
3736 	data[i++] = tgt_stats->rx_crc_err;
3737 	data[i++] = tgt_stats->rx_key_cache_miss;
3738 	data[i++] = tgt_stats->rx_decrypt_err;
3739 	data[i++] = tgt_stats->rx_dupl_frame;
3740 	data[i++] = tgt_stats->tkip_local_mic_fail;
3741 	data[i++] = tgt_stats->tkip_fmt_err;
3742 	data[i++] = tgt_stats->ccmp_fmt_err;
3743 	data[i++] = tgt_stats->ccmp_replays;
3744 
3745 	data[i++] = tgt_stats->cs_bmiss_cnt;
3746 	data[i++] = tgt_stats->cs_connect_cnt;
3747 	data[i++] = tgt_stats->cs_discon_cnt;
3748 	data[i++] = tgt_stats->cs_ave_beacon_rssi;
3749 	data[i++] = tgt_stats->arp_received;
3750 	data[i++] = tgt_stats->arp_matched;
3751 	data[i++] = tgt_stats->arp_replied;
3752 
3753 	if (i !=  ATH6KL_STATS_LEN) {
3754 		WARN_ON_ONCE(1);
3755 		ath6kl_err("ethtool stats error, i: %d  STATS_LEN: %d\n",
3756 			   i, (int)ATH6KL_STATS_LEN);
3757 	}
3758 }
3759 
3760 /* These stats are per NIC, not really per vdev, so we just ignore dev. */
ath6kl_get_strings(struct net_device * dev,u32 sset,u8 * data)3761 static void ath6kl_get_strings(struct net_device *dev, u32 sset, u8 *data)
3762 {
3763 	int sz_sta_stats = 0;
3764 
3765 	if (sset == ETH_SS_STATS) {
3766 		sz_sta_stats = sizeof(ath6kl_gstrings_sta_stats);
3767 		memcpy(data, ath6kl_gstrings_sta_stats, sz_sta_stats);
3768 	}
3769 }
3770 
3771 static const struct ethtool_ops ath6kl_ethtool_ops = {
3772 	.get_drvinfo = cfg80211_get_drvinfo,
3773 	.get_link = ethtool_op_get_link,
3774 	.get_strings = ath6kl_get_strings,
3775 	.get_ethtool_stats = ath6kl_get_stats,
3776 	.get_sset_count = ath6kl_get_sset_count,
3777 };
3778 
ath6kl_interface_add(struct ath6kl * ar,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u8 fw_vif_idx,u8 nw_type)3779 struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3780 					  unsigned char name_assign_type,
3781 					  enum nl80211_iftype type,
3782 					  u8 fw_vif_idx, u8 nw_type)
3783 {
3784 	struct net_device *ndev;
3785 	struct ath6kl_vif *vif;
3786 	u8 addr[ETH_ALEN];
3787 
3788 	ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3789 	if (!ndev)
3790 		return NULL;
3791 
3792 	vif = netdev_priv(ndev);
3793 	ndev->ieee80211_ptr = &vif->wdev;
3794 	vif->wdev.wiphy = ar->wiphy;
3795 	vif->ar = ar;
3796 	vif->ndev = ndev;
3797 	SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3798 	vif->wdev.netdev = ndev;
3799 	vif->wdev.iftype = type;
3800 	vif->fw_vif_idx = fw_vif_idx;
3801 	vif->nw_type = nw_type;
3802 	vif->next_mode = nw_type;
3803 	vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3804 	vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3805 	vif->bg_scan_period = 0;
3806 	vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3807 	vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3808 
3809 	ether_addr_copy(addr, ar->mac_addr);
3810 	if (fw_vif_idx != 0) {
3811 		addr[0] = (addr[0] ^ (1 << fw_vif_idx)) | 0x2;
3812 		if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3813 			     ar->fw_capabilities))
3814 			addr[4] ^= 0x80;
3815 	}
3816 	eth_hw_addr_set(ndev, addr);
3817 
3818 	init_netdev(ndev);
3819 
3820 	ath6kl_init_control_info(vif);
3821 
3822 	if (ath6kl_cfg80211_vif_init(vif))
3823 		goto err;
3824 
3825 	netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3826 
3827 	if (cfg80211_register_netdevice(ndev))
3828 		goto err;
3829 
3830 	ar->avail_idx_map &= ~BIT(fw_vif_idx);
3831 	vif->sme_state = SME_DISCONNECTED;
3832 	set_bit(WLAN_ENABLED, &vif->flags);
3833 	ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3834 
3835 	if (type == NL80211_IFTYPE_ADHOC)
3836 		ar->ibss_if_active = true;
3837 
3838 	spin_lock_bh(&ar->list_lock);
3839 	list_add_tail(&vif->list, &ar->vif_list);
3840 	spin_unlock_bh(&ar->list_lock);
3841 
3842 	return &vif->wdev;
3843 
3844 err:
3845 	aggr_module_destroy(vif->aggr_cntxt);
3846 	free_netdev(ndev);
3847 	return NULL;
3848 }
3849 
3850 #ifdef CONFIG_PM
3851 static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3852 	.flags = WIPHY_WOWLAN_MAGIC_PKT |
3853 		 WIPHY_WOWLAN_DISCONNECT |
3854 		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3855 		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3856 		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3857 		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
3858 	.n_patterns = WOW_MAX_FILTERS_PER_LIST,
3859 	.pattern_min_len = 1,
3860 	.pattern_max_len = WOW_PATTERN_SIZE,
3861 };
3862 #endif
3863 
ath6kl_cfg80211_init(struct ath6kl * ar)3864 int ath6kl_cfg80211_init(struct ath6kl *ar)
3865 {
3866 	struct wiphy *wiphy = ar->wiphy;
3867 	bool band_2gig = false, band_5gig = false, ht = false;
3868 	int ret;
3869 
3870 	wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3871 
3872 	wiphy->max_remain_on_channel_duration = 5000;
3873 
3874 	/* set device pointer for wiphy */
3875 	set_wiphy_dev(wiphy, ar->dev);
3876 
3877 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3878 				 BIT(NL80211_IFTYPE_ADHOC) |
3879 				 BIT(NL80211_IFTYPE_AP);
3880 	if (ar->p2p) {
3881 		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3882 					  BIT(NL80211_IFTYPE_P2P_CLIENT);
3883 	}
3884 
3885 	if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3886 	    test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3887 		wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3888 		ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3889 	}
3890 
3891 	/* max num of ssids that can be probed during scanning */
3892 	wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3893 
3894 	/* max num of ssids that can be matched after scan */
3895 	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3896 		     ar->fw_capabilities))
3897 		wiphy->max_match_sets = MAX_PROBED_SSIDS;
3898 
3899 	wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3900 	switch (ar->hw.cap) {
3901 	case WMI_11AN_CAP:
3902 		ht = true;
3903 		fallthrough;
3904 	case WMI_11A_CAP:
3905 		band_5gig = true;
3906 		break;
3907 	case WMI_11GN_CAP:
3908 		ht = true;
3909 		fallthrough;
3910 	case WMI_11G_CAP:
3911 		band_2gig = true;
3912 		break;
3913 	case WMI_11AGN_CAP:
3914 		ht = true;
3915 		fallthrough;
3916 	case WMI_11AG_CAP:
3917 		band_2gig = true;
3918 		band_5gig = true;
3919 		break;
3920 	default:
3921 		ath6kl_err("invalid phy capability!\n");
3922 		return -EINVAL;
3923 	}
3924 
3925 	/*
3926 	 * Even if the fw has HT support, advertise HT cap only when
3927 	 * the firmware has support to override RSN capability, otherwise
3928 	 * 4-way handshake would fail.
3929 	 */
3930 	if (!(ht &&
3931 	      test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3932 		       ar->fw_capabilities))) {
3933 		ath6kl_band_2ghz.ht_cap.cap = 0;
3934 		ath6kl_band_2ghz.ht_cap.ht_supported = false;
3935 		ath6kl_band_5ghz.ht_cap.cap = 0;
3936 		ath6kl_band_5ghz.ht_cap.ht_supported = false;
3937 
3938 		if (ht)
3939 			ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3940 	}
3941 
3942 	if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3943 		     ar->fw_capabilities)) {
3944 		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3945 		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3946 		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3947 		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3948 		ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3949 		ar->hw.rx_ant = 0x3;
3950 	} else {
3951 		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3952 		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3953 		ar->hw.tx_ant = 1;
3954 		ar->hw.rx_ant = 1;
3955 	}
3956 
3957 	wiphy->available_antennas_tx = ar->hw.tx_ant;
3958 	wiphy->available_antennas_rx = ar->hw.rx_ant;
3959 
3960 	if (band_2gig)
3961 		wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3962 	if (band_5gig)
3963 		wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3964 
3965 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3966 
3967 	wiphy->cipher_suites = cipher_suites;
3968 	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3969 
3970 #ifdef CONFIG_PM
3971 	wiphy->wowlan = &ath6kl_wowlan_support;
3972 #endif
3973 
3974 	wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3975 
3976 	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3977 			    WIPHY_FLAG_HAVE_AP_SME |
3978 			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3979 			    WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3980 
3981 	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3982 		ar->wiphy->max_sched_scan_reqs = 1;
3983 
3984 	if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3985 		     ar->fw_capabilities))
3986 		ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3987 
3988 	ar->wiphy->probe_resp_offload =
3989 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3990 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3991 		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3992 
3993 	ret = wiphy_register(wiphy);
3994 	if (ret < 0) {
3995 		ath6kl_err("couldn't register wiphy device\n");
3996 		return ret;
3997 	}
3998 
3999 	ar->wiphy_registered = true;
4000 
4001 	return 0;
4002 }
4003 
ath6kl_cfg80211_cleanup(struct ath6kl * ar)4004 void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4005 {
4006 	wiphy_unregister(ar->wiphy);
4007 
4008 	ar->wiphy_registered = false;
4009 }
4010 
ath6kl_cfg80211_create(void)4011 struct ath6kl *ath6kl_cfg80211_create(void)
4012 {
4013 	struct ath6kl *ar;
4014 	struct wiphy *wiphy;
4015 
4016 	/* create a new wiphy for use with cfg80211 */
4017 	wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4018 
4019 	if (!wiphy) {
4020 		ath6kl_err("couldn't allocate wiphy device\n");
4021 		return NULL;
4022 	}
4023 
4024 	ar = wiphy_priv(wiphy);
4025 	ar->wiphy = wiphy;
4026 
4027 	return ar;
4028 }
4029 
4030 /* Note: ar variable must not be accessed after calling this! */
ath6kl_cfg80211_destroy(struct ath6kl * ar)4031 void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4032 {
4033 	int i;
4034 
4035 	for (i = 0; i < AP_MAX_NUM_STA; i++)
4036 		kfree(ar->sta_list[i].aggr_conn);
4037 
4038 	wiphy_free(ar->wiphy);
4039 }
4040 
4041