1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18 
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 
21 #include <linux/kernel.h>
22 #include <linux/if_arp.h>
23 #include <linux/sched.h>
24 #include <linux/kthread.h>
25 #include <linux/netdevice.h>
26 #include <linux/bitops.h>
27 #include <linux/etherdevice.h>
28 #include <linux/ieee80211.h>
29 #include <linux/uaccess.h>
30 #include <net/cfg80211.h>
31 
32 #include <brcmu_utils.h>
33 #include <defs.h>
34 #include <brcmu_wifi.h>
35 #include "dhd.h"
36 #include "wl_cfg80211.h"
37 
38 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
39 	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
40 
41 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
42 
43 static u32 brcmf_dbg_level = WL_DBG_ERR;
44 
brcmf_set_drvdata(struct brcmf_cfg80211_dev * dev,void * data)45 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
46 {
47 	dev->driver_data = data;
48 }
49 
brcmf_get_drvdata(struct brcmf_cfg80211_dev * dev)50 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
51 {
52 	void *data = NULL;
53 
54 	if (dev)
55 		data = dev->driver_data;
56 	return data;
57 }
58 
59 static
brcmf_priv_get(struct brcmf_cfg80211_dev * cfg_dev)60 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
61 {
62 	struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
63 	return ci->cfg_priv;
64 }
65 
check_sys_up(struct wiphy * wiphy)66 static bool check_sys_up(struct wiphy *wiphy)
67 {
68 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
69 	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
70 		WL_INFO("device is not ready : status (%d)\n",
71 			(int)cfg_priv->status);
72 		return false;
73 	}
74 	return true;
75 }
76 
77 #define CHAN2G(_channel, _freq, _flags) {			\
78 	.band			= IEEE80211_BAND_2GHZ,		\
79 	.center_freq		= (_freq),			\
80 	.hw_value		= (_channel),			\
81 	.flags			= (_flags),			\
82 	.max_antenna_gain	= 0,				\
83 	.max_power		= 30,				\
84 }
85 
86 #define CHAN5G(_channel, _flags) {				\
87 	.band			= IEEE80211_BAND_5GHZ,		\
88 	.center_freq		= 5000 + (5 * (_channel)),	\
89 	.hw_value		= (_channel),			\
90 	.flags			= (_flags),			\
91 	.max_antenna_gain	= 0,				\
92 	.max_power		= 30,				\
93 }
94 
95 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
96 #define RATETAB_ENT(_rateid, _flags) \
97 	{                                                               \
98 		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
99 		.hw_value       = (_rateid),                            \
100 		.flags          = (_flags),                             \
101 	}
102 
103 static struct ieee80211_rate __wl_rates[] = {
104 	RATETAB_ENT(BRCM_RATE_1M, 0),
105 	RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
106 	RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
107 	RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
108 	RATETAB_ENT(BRCM_RATE_6M, 0),
109 	RATETAB_ENT(BRCM_RATE_9M, 0),
110 	RATETAB_ENT(BRCM_RATE_12M, 0),
111 	RATETAB_ENT(BRCM_RATE_18M, 0),
112 	RATETAB_ENT(BRCM_RATE_24M, 0),
113 	RATETAB_ENT(BRCM_RATE_36M, 0),
114 	RATETAB_ENT(BRCM_RATE_48M, 0),
115 	RATETAB_ENT(BRCM_RATE_54M, 0),
116 };
117 
118 #define wl_a_rates		(__wl_rates + 4)
119 #define wl_a_rates_size	8
120 #define wl_g_rates		(__wl_rates + 0)
121 #define wl_g_rates_size	12
122 
123 static struct ieee80211_channel __wl_2ghz_channels[] = {
124 	CHAN2G(1, 2412, 0),
125 	CHAN2G(2, 2417, 0),
126 	CHAN2G(3, 2422, 0),
127 	CHAN2G(4, 2427, 0),
128 	CHAN2G(5, 2432, 0),
129 	CHAN2G(6, 2437, 0),
130 	CHAN2G(7, 2442, 0),
131 	CHAN2G(8, 2447, 0),
132 	CHAN2G(9, 2452, 0),
133 	CHAN2G(10, 2457, 0),
134 	CHAN2G(11, 2462, 0),
135 	CHAN2G(12, 2467, 0),
136 	CHAN2G(13, 2472, 0),
137 	CHAN2G(14, 2484, 0),
138 };
139 
140 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
141 	CHAN5G(34, 0), CHAN5G(36, 0),
142 	CHAN5G(38, 0), CHAN5G(40, 0),
143 	CHAN5G(42, 0), CHAN5G(44, 0),
144 	CHAN5G(46, 0), CHAN5G(48, 0),
145 	CHAN5G(52, 0), CHAN5G(56, 0),
146 	CHAN5G(60, 0), CHAN5G(64, 0),
147 	CHAN5G(100, 0), CHAN5G(104, 0),
148 	CHAN5G(108, 0), CHAN5G(112, 0),
149 	CHAN5G(116, 0), CHAN5G(120, 0),
150 	CHAN5G(124, 0), CHAN5G(128, 0),
151 	CHAN5G(132, 0), CHAN5G(136, 0),
152 	CHAN5G(140, 0), CHAN5G(149, 0),
153 	CHAN5G(153, 0), CHAN5G(157, 0),
154 	CHAN5G(161, 0), CHAN5G(165, 0),
155 	CHAN5G(184, 0), CHAN5G(188, 0),
156 	CHAN5G(192, 0), CHAN5G(196, 0),
157 	CHAN5G(200, 0), CHAN5G(204, 0),
158 	CHAN5G(208, 0), CHAN5G(212, 0),
159 	CHAN5G(216, 0),
160 };
161 
162 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
163 	CHAN5G(32, 0), CHAN5G(34, 0),
164 	CHAN5G(36, 0), CHAN5G(38, 0),
165 	CHAN5G(40, 0), CHAN5G(42, 0),
166 	CHAN5G(44, 0), CHAN5G(46, 0),
167 	CHAN5G(48, 0), CHAN5G(50, 0),
168 	CHAN5G(52, 0), CHAN5G(54, 0),
169 	CHAN5G(56, 0), CHAN5G(58, 0),
170 	CHAN5G(60, 0), CHAN5G(62, 0),
171 	CHAN5G(64, 0), CHAN5G(66, 0),
172 	CHAN5G(68, 0), CHAN5G(70, 0),
173 	CHAN5G(72, 0), CHAN5G(74, 0),
174 	CHAN5G(76, 0), CHAN5G(78, 0),
175 	CHAN5G(80, 0), CHAN5G(82, 0),
176 	CHAN5G(84, 0), CHAN5G(86, 0),
177 	CHAN5G(88, 0), CHAN5G(90, 0),
178 	CHAN5G(92, 0), CHAN5G(94, 0),
179 	CHAN5G(96, 0), CHAN5G(98, 0),
180 	CHAN5G(100, 0), CHAN5G(102, 0),
181 	CHAN5G(104, 0), CHAN5G(106, 0),
182 	CHAN5G(108, 0), CHAN5G(110, 0),
183 	CHAN5G(112, 0), CHAN5G(114, 0),
184 	CHAN5G(116, 0), CHAN5G(118, 0),
185 	CHAN5G(120, 0), CHAN5G(122, 0),
186 	CHAN5G(124, 0), CHAN5G(126, 0),
187 	CHAN5G(128, 0), CHAN5G(130, 0),
188 	CHAN5G(132, 0), CHAN5G(134, 0),
189 	CHAN5G(136, 0), CHAN5G(138, 0),
190 	CHAN5G(140, 0), CHAN5G(142, 0),
191 	CHAN5G(144, 0), CHAN5G(145, 0),
192 	CHAN5G(146, 0), CHAN5G(147, 0),
193 	CHAN5G(148, 0), CHAN5G(149, 0),
194 	CHAN5G(150, 0), CHAN5G(151, 0),
195 	CHAN5G(152, 0), CHAN5G(153, 0),
196 	CHAN5G(154, 0), CHAN5G(155, 0),
197 	CHAN5G(156, 0), CHAN5G(157, 0),
198 	CHAN5G(158, 0), CHAN5G(159, 0),
199 	CHAN5G(160, 0), CHAN5G(161, 0),
200 	CHAN5G(162, 0), CHAN5G(163, 0),
201 	CHAN5G(164, 0), CHAN5G(165, 0),
202 	CHAN5G(166, 0), CHAN5G(168, 0),
203 	CHAN5G(170, 0), CHAN5G(172, 0),
204 	CHAN5G(174, 0), CHAN5G(176, 0),
205 	CHAN5G(178, 0), CHAN5G(180, 0),
206 	CHAN5G(182, 0), CHAN5G(184, 0),
207 	CHAN5G(186, 0), CHAN5G(188, 0),
208 	CHAN5G(190, 0), CHAN5G(192, 0),
209 	CHAN5G(194, 0), CHAN5G(196, 0),
210 	CHAN5G(198, 0), CHAN5G(200, 0),
211 	CHAN5G(202, 0), CHAN5G(204, 0),
212 	CHAN5G(206, 0), CHAN5G(208, 0),
213 	CHAN5G(210, 0), CHAN5G(212, 0),
214 	CHAN5G(214, 0), CHAN5G(216, 0),
215 	CHAN5G(218, 0), CHAN5G(220, 0),
216 	CHAN5G(222, 0), CHAN5G(224, 0),
217 	CHAN5G(226, 0), CHAN5G(228, 0),
218 };
219 
220 static struct ieee80211_supported_band __wl_band_2ghz = {
221 	.band = IEEE80211_BAND_2GHZ,
222 	.channels = __wl_2ghz_channels,
223 	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
224 	.bitrates = wl_g_rates,
225 	.n_bitrates = wl_g_rates_size,
226 };
227 
228 static struct ieee80211_supported_band __wl_band_5ghz_a = {
229 	.band = IEEE80211_BAND_5GHZ,
230 	.channels = __wl_5ghz_a_channels,
231 	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
232 	.bitrates = wl_a_rates,
233 	.n_bitrates = wl_a_rates_size,
234 };
235 
236 static struct ieee80211_supported_band __wl_band_5ghz_n = {
237 	.band = IEEE80211_BAND_5GHZ,
238 	.channels = __wl_5ghz_n_channels,
239 	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
240 	.bitrates = wl_a_rates,
241 	.n_bitrates = wl_a_rates_size,
242 };
243 
244 static const u32 __wl_cipher_suites[] = {
245 	WLAN_CIPHER_SUITE_WEP40,
246 	WLAN_CIPHER_SUITE_WEP104,
247 	WLAN_CIPHER_SUITE_TKIP,
248 	WLAN_CIPHER_SUITE_CCMP,
249 	WLAN_CIPHER_SUITE_AES_CMAC,
250 };
251 
252 /* tag_ID/length/value_buffer tuple */
253 struct brcmf_tlv {
254 	u8 id;
255 	u8 len;
256 	u8 data[1];
257 };
258 
259 /* Quarter dBm units to mW
260  * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
261  * Table is offset so the last entry is largest mW value that fits in
262  * a u16.
263  */
264 
265 #define QDBM_OFFSET 153		/* Offset for first entry */
266 #define QDBM_TABLE_LEN 40	/* Table size */
267 
268 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
269  * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
270  */
271 #define QDBM_TABLE_LOW_BOUND 6493	/* Low bound */
272 
273 /* Largest mW value that will round down to the last table entry,
274  * QDBM_OFFSET + QDBM_TABLE_LEN-1.
275  * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
276  * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
277  */
278 #define QDBM_TABLE_HIGH_BOUND 64938	/* High bound */
279 
280 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
281 /* qdBm:	+0	+1	+2	+3	+4	+5	+6	+7 */
282 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
283 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
284 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
285 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
286 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
287 };
288 
brcmf_qdbm_to_mw(u8 qdbm)289 static u16 brcmf_qdbm_to_mw(u8 qdbm)
290 {
291 	uint factor = 1;
292 	int idx = qdbm - QDBM_OFFSET;
293 
294 	if (idx >= QDBM_TABLE_LEN)
295 		/* clamp to max u16 mW value */
296 		return 0xFFFF;
297 
298 	/* scale the qdBm index up to the range of the table 0-40
299 	 * where an offset of 40 qdBm equals a factor of 10 mW.
300 	 */
301 	while (idx < 0) {
302 		idx += 40;
303 		factor *= 10;
304 	}
305 
306 	/* return the mW value scaled down to the correct factor of 10,
307 	 * adding in factor/2 to get proper rounding.
308 	 */
309 	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
310 }
311 
brcmf_mw_to_qdbm(u16 mw)312 static u8 brcmf_mw_to_qdbm(u16 mw)
313 {
314 	u8 qdbm;
315 	int offset;
316 	uint mw_uint = mw;
317 	uint boundary;
318 
319 	/* handle boundary case */
320 	if (mw_uint <= 1)
321 		return 0;
322 
323 	offset = QDBM_OFFSET;
324 
325 	/* move mw into the range of the table */
326 	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
327 		mw_uint *= 10;
328 		offset -= 40;
329 	}
330 
331 	for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
332 		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
333 						    nqdBm_to_mW_map[qdbm]) / 2;
334 		if (mw_uint < boundary)
335 			break;
336 	}
337 
338 	qdbm += (u8) offset;
339 
340 	return qdbm;
341 }
342 
343 /* function for reading/writing a single u32 from/to the dongle */
344 static int
brcmf_exec_dcmd_u32(struct net_device * ndev,u32 cmd,u32 * par)345 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
346 {
347 	int err;
348 	__le32 par_le = cpu_to_le32(*par);
349 
350 	err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
351 	*par = le32_to_cpu(par_le);
352 
353 	return err;
354 }
355 
convert_key_from_CPU(struct brcmf_wsec_key * key,struct brcmf_wsec_key_le * key_le)356 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
357 				 struct brcmf_wsec_key_le *key_le)
358 {
359 	key_le->index = cpu_to_le32(key->index);
360 	key_le->len = cpu_to_le32(key->len);
361 	key_le->algo = cpu_to_le32(key->algo);
362 	key_le->flags = cpu_to_le32(key->flags);
363 	key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
364 	key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
365 	key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
366 	memcpy(key_le->data, key->data, sizeof(key->data));
367 	memcpy(key_le->ea, key->ea, sizeof(key->ea));
368 }
369 
send_key_to_dongle(struct net_device * ndev,struct brcmf_wsec_key * key)370 static int send_key_to_dongle(struct net_device *ndev,
371 			      struct brcmf_wsec_key *key)
372 {
373 	int err;
374 	struct brcmf_wsec_key_le key_le;
375 
376 	convert_key_from_CPU(key, &key_le);
377 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
378 	if (err)
379 		WL_ERR("WLC_SET_KEY error (%d)\n", err);
380 	return err;
381 }
382 
383 static s32
brcmf_cfg80211_change_iface(struct wiphy * wiphy,struct net_device * ndev,enum nl80211_iftype type,u32 * flags,struct vif_params * params)384 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
385 			 enum nl80211_iftype type, u32 *flags,
386 			 struct vif_params *params)
387 {
388 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
389 	struct wireless_dev *wdev;
390 	s32 infra = 0;
391 	s32 err = 0;
392 
393 	WL_TRACE("Enter\n");
394 	if (!check_sys_up(wiphy))
395 		return -EIO;
396 
397 	switch (type) {
398 	case NL80211_IFTYPE_MONITOR:
399 	case NL80211_IFTYPE_WDS:
400 		WL_ERR("type (%d) : currently we do not support this type\n",
401 		       type);
402 		return -EOPNOTSUPP;
403 	case NL80211_IFTYPE_ADHOC:
404 		cfg_priv->conf->mode = WL_MODE_IBSS;
405 		infra = 0;
406 		break;
407 	case NL80211_IFTYPE_STATION:
408 		cfg_priv->conf->mode = WL_MODE_BSS;
409 		infra = 1;
410 		break;
411 	default:
412 		err = -EINVAL;
413 		goto done;
414 	}
415 
416 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
417 	if (err) {
418 		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
419 		err = -EAGAIN;
420 	} else {
421 		wdev = ndev->ieee80211_ptr;
422 		wdev->iftype = type;
423 	}
424 
425 	WL_INFO("IF Type = %s\n",
426 		(cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
427 
428 done:
429 	WL_TRACE("Exit\n");
430 
431 	return err;
432 }
433 
brcmf_dev_intvar_set(struct net_device * ndev,s8 * name,s32 val)434 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
435 {
436 	s8 buf[BRCMF_DCMD_SMLEN];
437 	u32 len;
438 	s32 err = 0;
439 	__le32 val_le;
440 
441 	val_le = cpu_to_le32(val);
442 	len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
443 			    sizeof(buf));
444 	BUG_ON(!len);
445 
446 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
447 	if (err)
448 		WL_ERR("error (%d)\n", err);
449 
450 	return err;
451 }
452 
453 static s32
brcmf_dev_intvar_get(struct net_device * ndev,s8 * name,s32 * retval)454 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
455 {
456 	union {
457 		s8 buf[BRCMF_DCMD_SMLEN];
458 		__le32 val;
459 	} var;
460 	u32 len;
461 	u32 data_null;
462 	s32 err = 0;
463 
464 	len =
465 	    brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
466 			sizeof(var.buf));
467 	BUG_ON(!len);
468 	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
469 	if (err)
470 		WL_ERR("error (%d)\n", err);
471 
472 	*retval = le32_to_cpu(var.val);
473 
474 	return err;
475 }
476 
brcmf_set_mpc(struct net_device * ndev,int mpc)477 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
478 {
479 	s32 err = 0;
480 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
481 
482 	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
483 		err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
484 		if (err) {
485 			WL_ERR("fail to set mpc\n");
486 			return;
487 		}
488 		WL_INFO("MPC : %d\n", mpc);
489 	}
490 }
491 
wl_iscan_prep(struct brcmf_scan_params_le * params_le,struct brcmf_ssid * ssid)492 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
493 			  struct brcmf_ssid *ssid)
494 {
495 	memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
496 	params_le->bss_type = DOT11_BSSTYPE_ANY;
497 	params_le->scan_type = 0;
498 	params_le->channel_num = 0;
499 	params_le->nprobes = cpu_to_le32(-1);
500 	params_le->active_time = cpu_to_le32(-1);
501 	params_le->passive_time = cpu_to_le32(-1);
502 	params_le->home_time = cpu_to_le32(-1);
503 	if (ssid && ssid->SSID_len) {
504 		params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
505 		memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
506 	}
507 }
508 
509 static s32
brcmf_dev_iovar_setbuf(struct net_device * ndev,s8 * iovar,void * param,s32 paramlen,void * bufptr,s32 buflen)510 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
511 		    s32 paramlen, void *bufptr, s32 buflen)
512 {
513 	s32 iolen;
514 
515 	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
516 	BUG_ON(!iolen);
517 
518 	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
519 }
520 
521 static s32
brcmf_dev_iovar_getbuf(struct net_device * ndev,s8 * iovar,void * param,s32 paramlen,void * bufptr,s32 buflen)522 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
523 		    s32 paramlen, void *bufptr, s32 buflen)
524 {
525 	s32 iolen;
526 
527 	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
528 	BUG_ON(!iolen);
529 
530 	return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
531 }
532 
533 static s32
brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl * iscan,struct brcmf_ssid * ssid,u16 action)534 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
535 		struct brcmf_ssid *ssid, u16 action)
536 {
537 	s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
538 			  offsetof(struct brcmf_iscan_params_le, params_le);
539 	struct brcmf_iscan_params_le *params;
540 	s32 err = 0;
541 
542 	if (ssid && ssid->SSID_len)
543 		params_size += sizeof(struct brcmf_ssid);
544 	params = kzalloc(params_size, GFP_KERNEL);
545 	if (!params)
546 		return -ENOMEM;
547 	BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
548 
549 	wl_iscan_prep(&params->params_le, ssid);
550 
551 	params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
552 	params->action = cpu_to_le16(action);
553 	params->scan_duration = cpu_to_le16(0);
554 
555 	err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
556 				     iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
557 	if (err) {
558 		if (err == -EBUSY)
559 			WL_INFO("system busy : iscan canceled\n");
560 		else
561 			WL_ERR("error (%d)\n", err);
562 	}
563 
564 	kfree(params);
565 	return err;
566 }
567 
brcmf_do_iscan(struct brcmf_cfg80211_priv * cfg_priv)568 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
569 {
570 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
571 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
572 	struct brcmf_ssid ssid;
573 	__le32 passive_scan;
574 	s32 err = 0;
575 
576 	/* Broadcast scan by default */
577 	memset(&ssid, 0, sizeof(ssid));
578 
579 	iscan->state = WL_ISCAN_STATE_SCANING;
580 
581 	passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
582 	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
583 			&passive_scan, sizeof(passive_scan));
584 	if (err) {
585 		WL_ERR("error (%d)\n", err);
586 		return err;
587 	}
588 	brcmf_set_mpc(ndev, 0);
589 	cfg_priv->iscan_kickstart = true;
590 	err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
591 	if (err) {
592 		brcmf_set_mpc(ndev, 1);
593 		cfg_priv->iscan_kickstart = false;
594 		return err;
595 	}
596 	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
597 	iscan->timer_on = 1;
598 	return err;
599 }
600 
601 static s32
__brcmf_cfg80211_scan(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_scan_request * request,struct cfg80211_ssid * this_ssid)602 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
603 		   struct cfg80211_scan_request *request,
604 		   struct cfg80211_ssid *this_ssid)
605 {
606 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
607 	struct cfg80211_ssid *ssids;
608 	struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
609 	__le32 passive_scan;
610 	bool iscan_req;
611 	bool spec_scan;
612 	s32 err = 0;
613 	u32 SSID_len;
614 
615 	if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
616 		WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
617 		return -EAGAIN;
618 	}
619 	if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
620 		WL_ERR("Scanning being aborted : status (%lu)\n",
621 		       cfg_priv->status);
622 		return -EAGAIN;
623 	}
624 	if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
625 		WL_ERR("Connecting : status (%lu)\n",
626 		       cfg_priv->status);
627 		return -EAGAIN;
628 	}
629 
630 	iscan_req = false;
631 	spec_scan = false;
632 	if (request) {
633 		/* scan bss */
634 		ssids = request->ssids;
635 		if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
636 			iscan_req = true;
637 	} else {
638 		/* scan in ibss */
639 		/* we don't do iscan in ibss */
640 		ssids = this_ssid;
641 	}
642 
643 	cfg_priv->scan_request = request;
644 	set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
645 	if (iscan_req) {
646 		err = brcmf_do_iscan(cfg_priv);
647 		if (!err)
648 			return err;
649 		else
650 			goto scan_out;
651 	} else {
652 		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
653 		       ssids->ssid, ssids->ssid_len);
654 		memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
655 		SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
656 		sr->ssid_le.SSID_len = cpu_to_le32(0);
657 		if (SSID_len) {
658 			memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
659 			sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
660 			spec_scan = true;
661 		} else {
662 			WL_SCAN("Broadcast scan\n");
663 		}
664 
665 		passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
666 		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
667 				&passive_scan, sizeof(passive_scan));
668 		if (err) {
669 			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
670 			goto scan_out;
671 		}
672 		brcmf_set_mpc(ndev, 0);
673 		err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
674 				      sizeof(sr->ssid_le));
675 		if (err) {
676 			if (err == -EBUSY)
677 				WL_INFO("system busy : scan for \"%s\" "
678 					"canceled\n", sr->ssid_le.SSID);
679 			else
680 				WL_ERR("WLC_SCAN error (%d)\n", err);
681 
682 			brcmf_set_mpc(ndev, 1);
683 			goto scan_out;
684 		}
685 	}
686 
687 	return 0;
688 
689 scan_out:
690 	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
691 	cfg_priv->scan_request = NULL;
692 	return err;
693 }
694 
695 static s32
brcmf_cfg80211_scan(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_scan_request * request)696 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
697 		 struct cfg80211_scan_request *request)
698 {
699 	s32 err = 0;
700 
701 	WL_TRACE("Enter\n");
702 
703 	if (!check_sys_up(wiphy))
704 		return -EIO;
705 
706 	err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
707 	if (err)
708 		WL_ERR("scan error (%d)\n", err);
709 
710 	WL_TRACE("Exit\n");
711 	return err;
712 }
713 
brcmf_set_rts(struct net_device * ndev,u32 rts_threshold)714 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
715 {
716 	s32 err = 0;
717 
718 	err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
719 	if (err)
720 		WL_ERR("Error (%d)\n", err);
721 
722 	return err;
723 }
724 
brcmf_set_frag(struct net_device * ndev,u32 frag_threshold)725 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
726 {
727 	s32 err = 0;
728 
729 	err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
730 	if (err)
731 		WL_ERR("Error (%d)\n", err);
732 
733 	return err;
734 }
735 
brcmf_set_retry(struct net_device * ndev,u32 retry,bool l)736 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
737 {
738 	s32 err = 0;
739 	u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
740 
741 	err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
742 	if (err) {
743 		WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
744 		return err;
745 	}
746 	return err;
747 }
748 
brcmf_cfg80211_set_wiphy_params(struct wiphy * wiphy,u32 changed)749 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
750 {
751 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
752 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
753 	s32 err = 0;
754 
755 	WL_TRACE("Enter\n");
756 	if (!check_sys_up(wiphy))
757 		return -EIO;
758 
759 	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
760 	    (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
761 		cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
762 		err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
763 		if (!err)
764 			goto done;
765 	}
766 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
767 	    (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
768 		cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
769 		err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
770 		if (!err)
771 			goto done;
772 	}
773 	if (changed & WIPHY_PARAM_RETRY_LONG
774 	    && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
775 		cfg_priv->conf->retry_long = wiphy->retry_long;
776 		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
777 		if (!err)
778 			goto done;
779 	}
780 	if (changed & WIPHY_PARAM_RETRY_SHORT
781 	    && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
782 		cfg_priv->conf->retry_short = wiphy->retry_short;
783 		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
784 		if (!err)
785 			goto done;
786 	}
787 
788 done:
789 	WL_TRACE("Exit\n");
790 	return err;
791 }
792 
brcmf_read_prof(struct brcmf_cfg80211_priv * cfg_priv,s32 item)793 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
794 {
795 	switch (item) {
796 	case WL_PROF_SEC:
797 		return &cfg_priv->profile->sec;
798 	case WL_PROF_BSSID:
799 		return &cfg_priv->profile->bssid;
800 	case WL_PROF_SSID:
801 		return &cfg_priv->profile->ssid;
802 	}
803 	WL_ERR("invalid item (%d)\n", item);
804 	return NULL;
805 }
806 
807 static s32
brcmf_update_prof(struct brcmf_cfg80211_priv * cfg_priv,const struct brcmf_event_msg * e,void * data,s32 item)808 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
809 		  const struct brcmf_event_msg *e, void *data, s32 item)
810 {
811 	s32 err = 0;
812 	struct brcmf_ssid *ssid;
813 
814 	switch (item) {
815 	case WL_PROF_SSID:
816 		ssid = (struct brcmf_ssid *) data;
817 		memset(cfg_priv->profile->ssid.SSID, 0,
818 		       sizeof(cfg_priv->profile->ssid.SSID));
819 		memcpy(cfg_priv->profile->ssid.SSID,
820 		       ssid->SSID, ssid->SSID_len);
821 		cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
822 		break;
823 	case WL_PROF_BSSID:
824 		if (data)
825 			memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
826 		else
827 			memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
828 		break;
829 	case WL_PROF_SEC:
830 		memcpy(&cfg_priv->profile->sec, data,
831 		       sizeof(cfg_priv->profile->sec));
832 		break;
833 	case WL_PROF_BEACONINT:
834 		cfg_priv->profile->beacon_interval = *(u16 *)data;
835 		break;
836 	case WL_PROF_DTIMPERIOD:
837 		cfg_priv->profile->dtim_period = *(u8 *)data;
838 		break;
839 	default:
840 		WL_ERR("unsupported item (%d)\n", item);
841 		err = -EOPNOTSUPP;
842 		break;
843 	}
844 
845 	return err;
846 }
847 
brcmf_init_prof(struct brcmf_cfg80211_profile * prof)848 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
849 {
850 	memset(prof, 0, sizeof(*prof));
851 }
852 
brcmf_ch_to_chanspec(int ch,struct brcmf_join_params * join_params,size_t * join_params_size)853 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
854 	size_t *join_params_size)
855 {
856 	u16 chanspec = 0;
857 
858 	if (ch != 0) {
859 		if (ch <= CH_MAX_2G_CHANNEL)
860 			chanspec |= WL_CHANSPEC_BAND_2G;
861 		else
862 			chanspec |= WL_CHANSPEC_BAND_5G;
863 
864 		chanspec |= WL_CHANSPEC_BW_20;
865 		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
866 
867 		*join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
868 				     sizeof(u16);
869 
870 		chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
871 		join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
872 		join_params->params_le.chanspec_num = cpu_to_le32(1);
873 
874 		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
875 			"channel %d, chanspec %#X\n",
876 			chanspec, ch, chanspec);
877 	}
878 }
879 
brcmf_link_down(struct brcmf_cfg80211_priv * cfg_priv)880 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
881 {
882 	struct net_device *ndev = NULL;
883 	s32 err = 0;
884 
885 	WL_TRACE("Enter\n");
886 
887 	if (cfg_priv->link_up) {
888 		ndev = cfg_to_ndev(cfg_priv);
889 		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
890 		err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
891 		if (err)
892 			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
893 		cfg_priv->link_up = false;
894 	}
895 	WL_TRACE("Exit\n");
896 }
897 
898 static s32
brcmf_cfg80211_join_ibss(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ibss_params * params)899 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
900 		      struct cfg80211_ibss_params *params)
901 {
902 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
903 	struct brcmf_join_params join_params;
904 	size_t join_params_size = 0;
905 	s32 err = 0;
906 	s32 wsec = 0;
907 	s32 bcnprd;
908 	struct brcmf_ssid ssid;
909 
910 	WL_TRACE("Enter\n");
911 	if (!check_sys_up(wiphy))
912 		return -EIO;
913 
914 	if (params->ssid)
915 		WL_CONN("SSID: %s\n", params->ssid);
916 	else {
917 		WL_CONN("SSID: NULL, Not supported\n");
918 		return -EOPNOTSUPP;
919 	}
920 
921 	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
922 
923 	if (params->bssid)
924 		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
925 		params->bssid[0], params->bssid[1], params->bssid[2],
926 		params->bssid[3], params->bssid[4], params->bssid[5]);
927 	else
928 		WL_CONN("No BSSID specified\n");
929 
930 	if (params->channel)
931 		WL_CONN("channel: %d\n", params->channel->center_freq);
932 	else
933 		WL_CONN("no channel specified\n");
934 
935 	if (params->channel_fixed)
936 		WL_CONN("fixed channel required\n");
937 	else
938 		WL_CONN("no fixed channel required\n");
939 
940 	if (params->ie && params->ie_len)
941 		WL_CONN("ie len: %d\n", params->ie_len);
942 	else
943 		WL_CONN("no ie specified\n");
944 
945 	if (params->beacon_interval)
946 		WL_CONN("beacon interval: %d\n", params->beacon_interval);
947 	else
948 		WL_CONN("no beacon interval specified\n");
949 
950 	if (params->basic_rates)
951 		WL_CONN("basic rates: %08X\n", params->basic_rates);
952 	else
953 		WL_CONN("no basic rates specified\n");
954 
955 	if (params->privacy)
956 		WL_CONN("privacy required\n");
957 	else
958 		WL_CONN("no privacy required\n");
959 
960 	/* Configure Privacy for starter */
961 	if (params->privacy)
962 		wsec |= WEP_ENABLED;
963 
964 	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
965 	if (err) {
966 		WL_ERR("wsec failed (%d)\n", err);
967 		goto done;
968 	}
969 
970 	/* Configure Beacon Interval for starter */
971 	if (params->beacon_interval)
972 		bcnprd = params->beacon_interval;
973 	else
974 		bcnprd = 100;
975 
976 	err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
977 	if (err) {
978 		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
979 		goto done;
980 	}
981 
982 	/* Configure required join parameter */
983 	memset(&join_params, 0, sizeof(struct brcmf_join_params));
984 
985 	/* SSID */
986 	ssid.SSID_len = min_t(u32, params->ssid_len, 32);
987 	memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
988 	memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
989 	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
990 	join_params_size = sizeof(join_params.ssid_le);
991 	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
992 
993 	/* BSSID */
994 	if (params->bssid) {
995 		memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
996 		join_params_size = sizeof(join_params.ssid_le) +
997 				   BRCMF_ASSOC_PARAMS_FIXED_SIZE;
998 	} else {
999 		memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1000 	}
1001 
1002 	brcmf_update_prof(cfg_priv, NULL,
1003 			  &join_params.params_le.bssid, WL_PROF_BSSID);
1004 
1005 	/* Channel */
1006 	if (params->channel) {
1007 		u32 target_channel;
1008 
1009 		cfg_priv->channel =
1010 			ieee80211_frequency_to_channel(
1011 				params->channel->center_freq);
1012 		if (params->channel_fixed) {
1013 			/* adding chanspec */
1014 			brcmf_ch_to_chanspec(cfg_priv->channel,
1015 				&join_params, &join_params_size);
1016 		}
1017 
1018 		/* set channel for starter */
1019 		target_channel = cfg_priv->channel;
1020 		err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1021 					  &target_channel);
1022 		if (err) {
1023 			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1024 			goto done;
1025 		}
1026 	} else
1027 		cfg_priv->channel = 0;
1028 
1029 	cfg_priv->ibss_starter = false;
1030 
1031 
1032 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1033 			   &join_params, join_params_size);
1034 	if (err) {
1035 		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1036 		goto done;
1037 	}
1038 
1039 done:
1040 	if (err)
1041 		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1042 	WL_TRACE("Exit\n");
1043 	return err;
1044 }
1045 
1046 static s32
brcmf_cfg80211_leave_ibss(struct wiphy * wiphy,struct net_device * ndev)1047 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1048 {
1049 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1050 	s32 err = 0;
1051 
1052 	WL_TRACE("Enter\n");
1053 	if (!check_sys_up(wiphy))
1054 		return -EIO;
1055 
1056 	brcmf_link_down(cfg_priv);
1057 
1058 	WL_TRACE("Exit\n");
1059 
1060 	return err;
1061 }
1062 
brcmf_set_wpa_version(struct net_device * ndev,struct cfg80211_connect_params * sme)1063 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1064 				 struct cfg80211_connect_params *sme)
1065 {
1066 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1067 	struct brcmf_cfg80211_security *sec;
1068 	s32 val = 0;
1069 	s32 err = 0;
1070 
1071 	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1072 		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1073 	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1074 		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1075 	else
1076 		val = WPA_AUTH_DISABLED;
1077 	WL_CONN("setting wpa_auth to 0x%0x\n", val);
1078 	err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1079 	if (err) {
1080 		WL_ERR("set wpa_auth failed (%d)\n", err);
1081 		return err;
1082 	}
1083 	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1084 	sec->wpa_versions = sme->crypto.wpa_versions;
1085 	return err;
1086 }
1087 
brcmf_set_auth_type(struct net_device * ndev,struct cfg80211_connect_params * sme)1088 static s32 brcmf_set_auth_type(struct net_device *ndev,
1089 			       struct cfg80211_connect_params *sme)
1090 {
1091 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1092 	struct brcmf_cfg80211_security *sec;
1093 	s32 val = 0;
1094 	s32 err = 0;
1095 
1096 	switch (sme->auth_type) {
1097 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
1098 		val = 0;
1099 		WL_CONN("open system\n");
1100 		break;
1101 	case NL80211_AUTHTYPE_SHARED_KEY:
1102 		val = 1;
1103 		WL_CONN("shared key\n");
1104 		break;
1105 	case NL80211_AUTHTYPE_AUTOMATIC:
1106 		val = 2;
1107 		WL_CONN("automatic\n");
1108 		break;
1109 	case NL80211_AUTHTYPE_NETWORK_EAP:
1110 		WL_CONN("network eap\n");
1111 	default:
1112 		val = 2;
1113 		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1114 		break;
1115 	}
1116 
1117 	err = brcmf_dev_intvar_set(ndev, "auth", val);
1118 	if (err) {
1119 		WL_ERR("set auth failed (%d)\n", err);
1120 		return err;
1121 	}
1122 	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1123 	sec->auth_type = sme->auth_type;
1124 	return err;
1125 }
1126 
1127 static s32
brcmf_set_set_cipher(struct net_device * ndev,struct cfg80211_connect_params * sme)1128 brcmf_set_set_cipher(struct net_device *ndev,
1129 		     struct cfg80211_connect_params *sme)
1130 {
1131 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1132 	struct brcmf_cfg80211_security *sec;
1133 	s32 pval = 0;
1134 	s32 gval = 0;
1135 	s32 err = 0;
1136 
1137 	if (sme->crypto.n_ciphers_pairwise) {
1138 		switch (sme->crypto.ciphers_pairwise[0]) {
1139 		case WLAN_CIPHER_SUITE_WEP40:
1140 		case WLAN_CIPHER_SUITE_WEP104:
1141 			pval = WEP_ENABLED;
1142 			break;
1143 		case WLAN_CIPHER_SUITE_TKIP:
1144 			pval = TKIP_ENABLED;
1145 			break;
1146 		case WLAN_CIPHER_SUITE_CCMP:
1147 			pval = AES_ENABLED;
1148 			break;
1149 		case WLAN_CIPHER_SUITE_AES_CMAC:
1150 			pval = AES_ENABLED;
1151 			break;
1152 		default:
1153 			WL_ERR("invalid cipher pairwise (%d)\n",
1154 			       sme->crypto.ciphers_pairwise[0]);
1155 			return -EINVAL;
1156 		}
1157 	}
1158 	if (sme->crypto.cipher_group) {
1159 		switch (sme->crypto.cipher_group) {
1160 		case WLAN_CIPHER_SUITE_WEP40:
1161 		case WLAN_CIPHER_SUITE_WEP104:
1162 			gval = WEP_ENABLED;
1163 			break;
1164 		case WLAN_CIPHER_SUITE_TKIP:
1165 			gval = TKIP_ENABLED;
1166 			break;
1167 		case WLAN_CIPHER_SUITE_CCMP:
1168 			gval = AES_ENABLED;
1169 			break;
1170 		case WLAN_CIPHER_SUITE_AES_CMAC:
1171 			gval = AES_ENABLED;
1172 			break;
1173 		default:
1174 			WL_ERR("invalid cipher group (%d)\n",
1175 			       sme->crypto.cipher_group);
1176 			return -EINVAL;
1177 		}
1178 	}
1179 
1180 	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1181 	err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1182 	if (err) {
1183 		WL_ERR("error (%d)\n", err);
1184 		return err;
1185 	}
1186 
1187 	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1188 	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1189 	sec->cipher_group = sme->crypto.cipher_group;
1190 
1191 	return err;
1192 }
1193 
1194 static s32
brcmf_set_key_mgmt(struct net_device * ndev,struct cfg80211_connect_params * sme)1195 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1196 {
1197 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1198 	struct brcmf_cfg80211_security *sec;
1199 	s32 val = 0;
1200 	s32 err = 0;
1201 
1202 	if (sme->crypto.n_akm_suites) {
1203 		err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1204 		if (err) {
1205 			WL_ERR("could not get wpa_auth (%d)\n", err);
1206 			return err;
1207 		}
1208 		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1209 			switch (sme->crypto.akm_suites[0]) {
1210 			case WLAN_AKM_SUITE_8021X:
1211 				val = WPA_AUTH_UNSPECIFIED;
1212 				break;
1213 			case WLAN_AKM_SUITE_PSK:
1214 				val = WPA_AUTH_PSK;
1215 				break;
1216 			default:
1217 				WL_ERR("invalid cipher group (%d)\n",
1218 				       sme->crypto.cipher_group);
1219 				return -EINVAL;
1220 			}
1221 		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1222 			switch (sme->crypto.akm_suites[0]) {
1223 			case WLAN_AKM_SUITE_8021X:
1224 				val = WPA2_AUTH_UNSPECIFIED;
1225 				break;
1226 			case WLAN_AKM_SUITE_PSK:
1227 				val = WPA2_AUTH_PSK;
1228 				break;
1229 			default:
1230 				WL_ERR("invalid cipher group (%d)\n",
1231 				       sme->crypto.cipher_group);
1232 				return -EINVAL;
1233 			}
1234 		}
1235 
1236 		WL_CONN("setting wpa_auth to %d\n", val);
1237 		err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1238 		if (err) {
1239 			WL_ERR("could not set wpa_auth (%d)\n", err);
1240 			return err;
1241 		}
1242 	}
1243 	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1244 	sec->wpa_auth = sme->crypto.akm_suites[0];
1245 
1246 	return err;
1247 }
1248 
1249 static s32
brcmf_set_wep_sharedkey(struct net_device * ndev,struct cfg80211_connect_params * sme)1250 brcmf_set_wep_sharedkey(struct net_device *ndev,
1251 		     struct cfg80211_connect_params *sme)
1252 {
1253 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1254 	struct brcmf_cfg80211_security *sec;
1255 	struct brcmf_wsec_key key;
1256 	s32 val;
1257 	s32 err = 0;
1258 
1259 	WL_CONN("key len (%d)\n", sme->key_len);
1260 
1261 	if (sme->key_len == 0)
1262 		return 0;
1263 
1264 	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1265 	WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1266 		sec->wpa_versions, sec->cipher_pairwise);
1267 
1268 	if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1269 		return 0;
1270 
1271 	if (sec->cipher_pairwise &
1272 	    (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1273 		memset(&key, 0, sizeof(key));
1274 		key.len = (u32) sme->key_len;
1275 		key.index = (u32) sme->key_idx;
1276 		if (key.len > sizeof(key.data)) {
1277 			WL_ERR("Too long key length (%u)\n", key.len);
1278 			return -EINVAL;
1279 		}
1280 		memcpy(key.data, sme->key, key.len);
1281 		key.flags = BRCMF_PRIMARY_KEY;
1282 		switch (sec->cipher_pairwise) {
1283 		case WLAN_CIPHER_SUITE_WEP40:
1284 			key.algo = CRYPTO_ALGO_WEP1;
1285 			break;
1286 		case WLAN_CIPHER_SUITE_WEP104:
1287 			key.algo = CRYPTO_ALGO_WEP128;
1288 			break;
1289 		default:
1290 			WL_ERR("Invalid algorithm (%d)\n",
1291 			       sme->crypto.ciphers_pairwise[0]);
1292 			return -EINVAL;
1293 		}
1294 		/* Set the new key/index */
1295 		WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1296 			key.len, key.index, key.algo);
1297 		WL_CONN("key \"%s\"\n", key.data);
1298 		err = send_key_to_dongle(ndev, &key);
1299 		if (err)
1300 			return err;
1301 
1302 		if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1303 			WL_CONN("set auth_type to shared key\n");
1304 			val = 1;	/* shared key */
1305 			err = brcmf_dev_intvar_set(ndev, "auth", val);
1306 			if (err) {
1307 				WL_ERR("set auth failed (%d)\n", err);
1308 				return err;
1309 			}
1310 		}
1311 	}
1312 	return err;
1313 }
1314 
1315 static s32
brcmf_cfg80211_connect(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * sme)1316 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1317 		    struct cfg80211_connect_params *sme)
1318 {
1319 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1320 	struct ieee80211_channel *chan = sme->channel;
1321 	struct brcmf_join_params join_params;
1322 	size_t join_params_size;
1323 	struct brcmf_ssid ssid;
1324 
1325 	s32 err = 0;
1326 
1327 	WL_TRACE("Enter\n");
1328 	if (!check_sys_up(wiphy))
1329 		return -EIO;
1330 
1331 	if (!sme->ssid) {
1332 		WL_ERR("Invalid ssid\n");
1333 		return -EOPNOTSUPP;
1334 	}
1335 
1336 	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1337 
1338 	if (chan) {
1339 		cfg_priv->channel =
1340 			ieee80211_frequency_to_channel(chan->center_freq);
1341 		WL_CONN("channel (%d), center_req (%d)\n",
1342 				cfg_priv->channel, chan->center_freq);
1343 	} else
1344 		cfg_priv->channel = 0;
1345 
1346 	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1347 
1348 	err = brcmf_set_wpa_version(ndev, sme);
1349 	if (err) {
1350 		WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1351 		goto done;
1352 	}
1353 
1354 	err = brcmf_set_auth_type(ndev, sme);
1355 	if (err) {
1356 		WL_ERR("wl_set_auth_type failed (%d)\n", err);
1357 		goto done;
1358 	}
1359 
1360 	err = brcmf_set_set_cipher(ndev, sme);
1361 	if (err) {
1362 		WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1363 		goto done;
1364 	}
1365 
1366 	err = brcmf_set_key_mgmt(ndev, sme);
1367 	if (err) {
1368 		WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1369 		goto done;
1370 	}
1371 
1372 	err = brcmf_set_wep_sharedkey(ndev, sme);
1373 	if (err) {
1374 		WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1375 		goto done;
1376 	}
1377 
1378 	memset(&join_params, 0, sizeof(join_params));
1379 	join_params_size = sizeof(join_params.ssid_le);
1380 
1381 	ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
1382 	memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1383 	memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1384 	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1385 	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1386 
1387 	memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1388 
1389 	if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1390 		WL_CONN("ssid \"%s\", len (%d)\n",
1391 		       ssid.SSID, ssid.SSID_len);
1392 
1393 	brcmf_ch_to_chanspec(cfg_priv->channel,
1394 			     &join_params, &join_params_size);
1395 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1396 			   &join_params, join_params_size);
1397 	if (err)
1398 		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1399 
1400 done:
1401 	if (err)
1402 		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1403 	WL_TRACE("Exit\n");
1404 	return err;
1405 }
1406 
1407 static s32
brcmf_cfg80211_disconnect(struct wiphy * wiphy,struct net_device * ndev,u16 reason_code)1408 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1409 		       u16 reason_code)
1410 {
1411 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1412 	struct brcmf_scb_val_le scbval;
1413 	s32 err = 0;
1414 
1415 	WL_TRACE("Enter. Reason code = %d\n", reason_code);
1416 	if (!check_sys_up(wiphy))
1417 		return -EIO;
1418 
1419 	clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1420 
1421 	memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1422 	scbval.val = cpu_to_le32(reason_code);
1423 	err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1424 			      sizeof(struct brcmf_scb_val_le));
1425 	if (err)
1426 		WL_ERR("error (%d)\n", err);
1427 
1428 	cfg_priv->link_up = false;
1429 
1430 	WL_TRACE("Exit\n");
1431 	return err;
1432 }
1433 
1434 static s32
brcmf_cfg80211_set_tx_power(struct wiphy * wiphy,enum nl80211_tx_power_setting type,s32 mbm)1435 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1436 			    enum nl80211_tx_power_setting type, s32 mbm)
1437 {
1438 
1439 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1440 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
1441 	u16 txpwrmw;
1442 	s32 err = 0;
1443 	s32 disable = 0;
1444 	s32 dbm = MBM_TO_DBM(mbm);
1445 
1446 	WL_TRACE("Enter\n");
1447 	if (!check_sys_up(wiphy))
1448 		return -EIO;
1449 
1450 	switch (type) {
1451 	case NL80211_TX_POWER_AUTOMATIC:
1452 		break;
1453 	case NL80211_TX_POWER_LIMITED:
1454 	case NL80211_TX_POWER_FIXED:
1455 		if (dbm < 0) {
1456 			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1457 			err = -EINVAL;
1458 			goto done;
1459 		}
1460 		break;
1461 	}
1462 	/* Make sure radio is off or on as far as software is concerned */
1463 	disable = WL_RADIO_SW_DISABLE << 16;
1464 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1465 	if (err)
1466 		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1467 
1468 	if (dbm > 0xffff)
1469 		txpwrmw = 0xffff;
1470 	else
1471 		txpwrmw = (u16) dbm;
1472 	err = brcmf_dev_intvar_set(ndev, "qtxpower",
1473 			(s32) (brcmf_mw_to_qdbm(txpwrmw)));
1474 	if (err)
1475 		WL_ERR("qtxpower error (%d)\n", err);
1476 	cfg_priv->conf->tx_power = dbm;
1477 
1478 done:
1479 	WL_TRACE("Exit\n");
1480 	return err;
1481 }
1482 
brcmf_cfg80211_get_tx_power(struct wiphy * wiphy,s32 * dbm)1483 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1484 {
1485 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1486 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
1487 	s32 txpwrdbm;
1488 	u8 result;
1489 	s32 err = 0;
1490 
1491 	WL_TRACE("Enter\n");
1492 	if (!check_sys_up(wiphy))
1493 		return -EIO;
1494 
1495 	err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1496 	if (err) {
1497 		WL_ERR("error (%d)\n", err);
1498 		goto done;
1499 	}
1500 
1501 	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1502 	*dbm = (s32) brcmf_qdbm_to_mw(result);
1503 
1504 done:
1505 	WL_TRACE("Exit\n");
1506 	return err;
1507 }
1508 
1509 static s32
brcmf_cfg80211_config_default_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool unicast,bool multicast)1510 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1511 			       u8 key_idx, bool unicast, bool multicast)
1512 {
1513 	u32 index;
1514 	u32 wsec;
1515 	s32 err = 0;
1516 
1517 	WL_TRACE("Enter\n");
1518 	WL_CONN("key index (%d)\n", key_idx);
1519 	if (!check_sys_up(wiphy))
1520 		return -EIO;
1521 
1522 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1523 	if (err) {
1524 		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1525 		goto done;
1526 	}
1527 
1528 	if (wsec & WEP_ENABLED) {
1529 		/* Just select a new current key */
1530 		index = key_idx;
1531 		err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1532 					  &index);
1533 		if (err)
1534 			WL_ERR("error (%d)\n", err);
1535 	}
1536 done:
1537 	WL_TRACE("Exit\n");
1538 	return err;
1539 }
1540 
1541 static s32
brcmf_add_keyext(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,const u8 * mac_addr,struct key_params * params)1542 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1543 	      u8 key_idx, const u8 *mac_addr, struct key_params *params)
1544 {
1545 	struct brcmf_wsec_key key;
1546 	struct brcmf_wsec_key_le key_le;
1547 	s32 err = 0;
1548 
1549 	memset(&key, 0, sizeof(key));
1550 	key.index = (u32) key_idx;
1551 	/* Instead of bcast for ea address for default wep keys,
1552 		 driver needs it to be Null */
1553 	if (!is_multicast_ether_addr(mac_addr))
1554 		memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1555 	key.len = (u32) params->key_len;
1556 	/* check for key index change */
1557 	if (key.len == 0) {
1558 		/* key delete */
1559 		err = send_key_to_dongle(ndev, &key);
1560 		if (err)
1561 			return err;
1562 	} else {
1563 		if (key.len > sizeof(key.data)) {
1564 			WL_ERR("Invalid key length (%d)\n", key.len);
1565 			return -EINVAL;
1566 		}
1567 
1568 		WL_CONN("Setting the key index %d\n", key.index);
1569 		memcpy(key.data, params->key, key.len);
1570 
1571 		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1572 			u8 keybuf[8];
1573 			memcpy(keybuf, &key.data[24], sizeof(keybuf));
1574 			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1575 			memcpy(&key.data[16], keybuf, sizeof(keybuf));
1576 		}
1577 
1578 		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1579 		if (params->seq && params->seq_len == 6) {
1580 			/* rx iv */
1581 			u8 *ivptr;
1582 			ivptr = (u8 *) params->seq;
1583 			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1584 			    (ivptr[3] << 8) | ivptr[2];
1585 			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1586 			key.iv_initialized = true;
1587 		}
1588 
1589 		switch (params->cipher) {
1590 		case WLAN_CIPHER_SUITE_WEP40:
1591 			key.algo = CRYPTO_ALGO_WEP1;
1592 			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1593 			break;
1594 		case WLAN_CIPHER_SUITE_WEP104:
1595 			key.algo = CRYPTO_ALGO_WEP128;
1596 			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1597 			break;
1598 		case WLAN_CIPHER_SUITE_TKIP:
1599 			key.algo = CRYPTO_ALGO_TKIP;
1600 			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1601 			break;
1602 		case WLAN_CIPHER_SUITE_AES_CMAC:
1603 			key.algo = CRYPTO_ALGO_AES_CCM;
1604 			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1605 			break;
1606 		case WLAN_CIPHER_SUITE_CCMP:
1607 			key.algo = CRYPTO_ALGO_AES_CCM;
1608 			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1609 			break;
1610 		default:
1611 			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1612 			return -EINVAL;
1613 		}
1614 		convert_key_from_CPU(&key, &key_le);
1615 
1616 		brcmf_netdev_wait_pend8021x(ndev);
1617 		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1618 				      sizeof(key_le));
1619 		if (err) {
1620 			WL_ERR("WLC_SET_KEY error (%d)\n", err);
1621 			return err;
1622 		}
1623 	}
1624 	return err;
1625 }
1626 
1627 static s32
brcmf_cfg80211_add_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool pairwise,const u8 * mac_addr,struct key_params * params)1628 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1629 		    u8 key_idx, bool pairwise, const u8 *mac_addr,
1630 		    struct key_params *params)
1631 {
1632 	struct brcmf_wsec_key key;
1633 	s32 val;
1634 	s32 wsec;
1635 	s32 err = 0;
1636 	u8 keybuf[8];
1637 
1638 	WL_TRACE("Enter\n");
1639 	WL_CONN("key index (%d)\n", key_idx);
1640 	if (!check_sys_up(wiphy))
1641 		return -EIO;
1642 
1643 	if (mac_addr) {
1644 		WL_TRACE("Exit");
1645 		return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1646 	}
1647 	memset(&key, 0, sizeof(key));
1648 
1649 	key.len = (u32) params->key_len;
1650 	key.index = (u32) key_idx;
1651 
1652 	if (key.len > sizeof(key.data)) {
1653 		WL_ERR("Too long key length (%u)\n", key.len);
1654 		err = -EINVAL;
1655 		goto done;
1656 	}
1657 	memcpy(key.data, params->key, key.len);
1658 
1659 	key.flags = BRCMF_PRIMARY_KEY;
1660 	switch (params->cipher) {
1661 	case WLAN_CIPHER_SUITE_WEP40:
1662 		key.algo = CRYPTO_ALGO_WEP1;
1663 		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1664 		break;
1665 	case WLAN_CIPHER_SUITE_WEP104:
1666 		key.algo = CRYPTO_ALGO_WEP128;
1667 		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1668 		break;
1669 	case WLAN_CIPHER_SUITE_TKIP:
1670 		memcpy(keybuf, &key.data[24], sizeof(keybuf));
1671 		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1672 		memcpy(&key.data[16], keybuf, sizeof(keybuf));
1673 		key.algo = CRYPTO_ALGO_TKIP;
1674 		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1675 		break;
1676 	case WLAN_CIPHER_SUITE_AES_CMAC:
1677 		key.algo = CRYPTO_ALGO_AES_CCM;
1678 		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1679 		break;
1680 	case WLAN_CIPHER_SUITE_CCMP:
1681 		key.algo = CRYPTO_ALGO_AES_CCM;
1682 		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1683 		break;
1684 	default:
1685 		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1686 		err = -EINVAL;
1687 		goto done;
1688 	}
1689 
1690 	err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1691 	if (err)
1692 		goto done;
1693 
1694 	val = WEP_ENABLED;
1695 	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1696 	if (err) {
1697 		WL_ERR("get wsec error (%d)\n", err);
1698 		goto done;
1699 	}
1700 	wsec &= ~(WEP_ENABLED);
1701 	wsec |= val;
1702 	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1703 	if (err) {
1704 		WL_ERR("set wsec error (%d)\n", err);
1705 		goto done;
1706 	}
1707 
1708 	val = 1;		/* assume shared key. otherwise 0 */
1709 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1710 	if (err)
1711 		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1712 done:
1713 	WL_TRACE("Exit\n");
1714 	return err;
1715 }
1716 
1717 static s32
brcmf_cfg80211_del_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool pairwise,const u8 * mac_addr)1718 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1719 		    u8 key_idx, bool pairwise, const u8 *mac_addr)
1720 {
1721 	struct brcmf_wsec_key key;
1722 	s32 err = 0;
1723 	s32 val;
1724 	s32 wsec;
1725 
1726 	WL_TRACE("Enter\n");
1727 	if (!check_sys_up(wiphy))
1728 		return -EIO;
1729 
1730 	memset(&key, 0, sizeof(key));
1731 
1732 	key.index = (u32) key_idx;
1733 	key.flags = BRCMF_PRIMARY_KEY;
1734 	key.algo = CRYPTO_ALGO_OFF;
1735 
1736 	WL_CONN("key index (%d)\n", key_idx);
1737 
1738 	/* Set the new key/index */
1739 	err = send_key_to_dongle(ndev, &key);
1740 	if (err) {
1741 		if (err == -EINVAL) {
1742 			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1743 				/* we ignore this key index in this case */
1744 				WL_ERR("invalid key index (%d)\n", key_idx);
1745 		}
1746 		/* Ignore this error, may happen during DISASSOC */
1747 		err = -EAGAIN;
1748 		goto done;
1749 	}
1750 
1751 	val = 0;
1752 	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1753 	if (err) {
1754 		WL_ERR("get wsec error (%d)\n", err);
1755 		/* Ignore this error, may happen during DISASSOC */
1756 		err = -EAGAIN;
1757 		goto done;
1758 	}
1759 	wsec &= ~(WEP_ENABLED);
1760 	wsec |= val;
1761 	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1762 	if (err) {
1763 		WL_ERR("set wsec error (%d)\n", err);
1764 		/* Ignore this error, may happen during DISASSOC */
1765 		err = -EAGAIN;
1766 		goto done;
1767 	}
1768 
1769 	val = 0;		/* assume open key. otherwise 1 */
1770 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1771 	if (err) {
1772 		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1773 		/* Ignore this error, may happen during DISASSOC */
1774 		err = -EAGAIN;
1775 	}
1776 done:
1777 	WL_TRACE("Exit\n");
1778 	return err;
1779 }
1780 
1781 static s32
brcmf_cfg80211_get_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool pairwise,const u8 * mac_addr,void * cookie,void (* callback)(void * cookie,struct key_params * params))1782 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1783 		    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1784 		    void (*callback) (void *cookie, struct key_params * params))
1785 {
1786 	struct key_params params;
1787 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1788 	struct brcmf_cfg80211_security *sec;
1789 	s32 wsec;
1790 	s32 err = 0;
1791 
1792 	WL_TRACE("Enter\n");
1793 	WL_CONN("key index (%d)\n", key_idx);
1794 	if (!check_sys_up(wiphy))
1795 		return -EIO;
1796 
1797 	memset(&params, 0, sizeof(params));
1798 
1799 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1800 	if (err) {
1801 		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1802 		/* Ignore this error, may happen during DISASSOC */
1803 		err = -EAGAIN;
1804 		goto done;
1805 	}
1806 	switch (wsec) {
1807 	case WEP_ENABLED:
1808 		sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1809 		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1810 			params.cipher = WLAN_CIPHER_SUITE_WEP40;
1811 			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1812 		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1813 			params.cipher = WLAN_CIPHER_SUITE_WEP104;
1814 			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1815 		}
1816 		break;
1817 	case TKIP_ENABLED:
1818 		params.cipher = WLAN_CIPHER_SUITE_TKIP;
1819 		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1820 		break;
1821 	case AES_ENABLED:
1822 		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1823 		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1824 		break;
1825 	default:
1826 		WL_ERR("Invalid algo (0x%x)\n", wsec);
1827 		err = -EINVAL;
1828 		goto done;
1829 	}
1830 	callback(cookie, &params);
1831 
1832 done:
1833 	WL_TRACE("Exit\n");
1834 	return err;
1835 }
1836 
1837 static s32
brcmf_cfg80211_config_default_mgmt_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx)1838 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1839 				    struct net_device *ndev, u8 key_idx)
1840 {
1841 	WL_INFO("Not supported\n");
1842 
1843 	return -EOPNOTSUPP;
1844 }
1845 
1846 static s32
brcmf_cfg80211_get_station(struct wiphy * wiphy,struct net_device * ndev,u8 * mac,struct station_info * sinfo)1847 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1848 			u8 *mac, struct station_info *sinfo)
1849 {
1850 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1851 	struct brcmf_scb_val_le scb_val;
1852 	int rssi;
1853 	s32 rate;
1854 	s32 err = 0;
1855 	u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1856 
1857 	WL_TRACE("Enter\n");
1858 	if (!check_sys_up(wiphy))
1859 		return -EIO;
1860 
1861 	if (memcmp(mac, bssid, ETH_ALEN)) {
1862 		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1863 			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
1864 			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1865 			bssid[0], bssid[1], bssid[2], bssid[3],
1866 			bssid[4], bssid[5]);
1867 		err = -ENOENT;
1868 		goto done;
1869 	}
1870 
1871 	/* Report the current tx rate */
1872 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1873 	if (err) {
1874 		WL_ERR("Could not get rate (%d)\n", err);
1875 	} else {
1876 		sinfo->filled |= STATION_INFO_TX_BITRATE;
1877 		sinfo->txrate.legacy = rate * 5;
1878 		WL_CONN("Rate %d Mbps\n", rate / 2);
1879 	}
1880 
1881 	if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1882 		scb_val.val = cpu_to_le32(0);
1883 		err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1884 				      sizeof(struct brcmf_scb_val_le));
1885 		if (err)
1886 			WL_ERR("Could not get rssi (%d)\n", err);
1887 
1888 		rssi = le32_to_cpu(scb_val.val);
1889 		sinfo->filled |= STATION_INFO_SIGNAL;
1890 		sinfo->signal = rssi;
1891 		WL_CONN("RSSI %d dBm\n", rssi);
1892 	}
1893 
1894 done:
1895 	WL_TRACE("Exit\n");
1896 	return err;
1897 }
1898 
1899 static s32
brcmf_cfg80211_set_power_mgmt(struct wiphy * wiphy,struct net_device * ndev,bool enabled,s32 timeout)1900 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1901 			   bool enabled, s32 timeout)
1902 {
1903 	s32 pm;
1904 	s32 err = 0;
1905 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1906 
1907 	WL_TRACE("Enter\n");
1908 
1909 	/*
1910 	 * Powersave enable/disable request is coming from the
1911 	 * cfg80211 even before the interface is up. In that
1912 	 * scenario, driver will be storing the power save
1913 	 * preference in cfg_priv struct to apply this to
1914 	 * FW later while initializing the dongle
1915 	 */
1916 	cfg_priv->pwr_save = enabled;
1917 	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1918 
1919 		WL_INFO("Device is not ready,"
1920 			"storing the value in cfg_priv struct\n");
1921 		goto done;
1922 	}
1923 
1924 	pm = enabled ? PM_FAST : PM_OFF;
1925 	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1926 
1927 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1928 	if (err) {
1929 		if (err == -ENODEV)
1930 			WL_ERR("net_device is not ready yet\n");
1931 		else
1932 			WL_ERR("error (%d)\n", err);
1933 	}
1934 done:
1935 	WL_TRACE("Exit\n");
1936 	return err;
1937 }
1938 
1939 static s32
brcmf_cfg80211_set_bitrate_mask(struct wiphy * wiphy,struct net_device * ndev,const u8 * addr,const struct cfg80211_bitrate_mask * mask)1940 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1941 			     const u8 *addr,
1942 			     const struct cfg80211_bitrate_mask *mask)
1943 {
1944 	struct brcm_rateset_le rateset_le;
1945 	s32 rate;
1946 	s32 val;
1947 	s32 err_bg;
1948 	s32 err_a;
1949 	u32 legacy;
1950 	s32 err = 0;
1951 
1952 	WL_TRACE("Enter\n");
1953 	if (!check_sys_up(wiphy))
1954 		return -EIO;
1955 
1956 	/* addr param is always NULL. ignore it */
1957 	/* Get current rateset */
1958 	err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1959 			      sizeof(rateset_le));
1960 	if (err) {
1961 		WL_ERR("could not get current rateset (%d)\n", err);
1962 		goto done;
1963 	}
1964 
1965 	legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1966 	if (!legacy)
1967 		legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1968 			     0xFFFF);
1969 
1970 	val = wl_g_rates[legacy - 1].bitrate * 100000;
1971 
1972 	if (val < le32_to_cpu(rateset_le.count))
1973 		/* Select rate by rateset index */
1974 		rate = rateset_le.rates[val] & 0x7f;
1975 	else
1976 		/* Specified rate in bps */
1977 		rate = val / 500000;
1978 
1979 	WL_CONN("rate %d mbps\n", rate / 2);
1980 
1981 	/*
1982 	 *
1983 	 *      Set rate override,
1984 	 *      Since the is a/b/g-blind, both a/bg_rate are enforced.
1985 	 */
1986 	err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1987 	err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1988 	if (err_bg && err_a) {
1989 		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1990 		err = err_bg | err_a;
1991 	}
1992 
1993 done:
1994 	WL_TRACE("Exit\n");
1995 	return err;
1996 }
1997 
brcmf_inform_single_bss(struct brcmf_cfg80211_priv * cfg_priv,struct brcmf_bss_info_le * bi)1998 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1999 				   struct brcmf_bss_info_le *bi)
2000 {
2001 	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2002 	struct ieee80211_channel *notify_channel;
2003 	struct cfg80211_bss *bss;
2004 	struct ieee80211_supported_band *band;
2005 	s32 err = 0;
2006 	u16 channel;
2007 	u32 freq;
2008 	u16 notify_capability;
2009 	u16 notify_interval;
2010 	u8 *notify_ie;
2011 	size_t notify_ielen;
2012 	s32 notify_signal;
2013 
2014 	if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2015 		WL_ERR("Bss info is larger than buffer. Discarding\n");
2016 		return 0;
2017 	}
2018 
2019 	channel = bi->ctl_ch ? bi->ctl_ch :
2020 				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2021 
2022 	if (channel <= CH_MAX_2G_CHANNEL)
2023 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
2024 	else
2025 		band = wiphy->bands[IEEE80211_BAND_5GHZ];
2026 
2027 	freq = ieee80211_channel_to_frequency(channel, band->band);
2028 	notify_channel = ieee80211_get_channel(wiphy, freq);
2029 
2030 	notify_capability = le16_to_cpu(bi->capability);
2031 	notify_interval = le16_to_cpu(bi->beacon_period);
2032 	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2033 	notify_ielen = le32_to_cpu(bi->ie_length);
2034 	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2035 
2036 	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2037 			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2038 			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2039 	WL_CONN("Channel: %d(%d)\n", channel, freq);
2040 	WL_CONN("Capability: %X\n", notify_capability);
2041 	WL_CONN("Beacon interval: %d\n", notify_interval);
2042 	WL_CONN("Signal: %d\n", notify_signal);
2043 
2044 	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2045 		0, notify_capability, notify_interval, notify_ie,
2046 		notify_ielen, notify_signal, GFP_KERNEL);
2047 
2048 	if (!bss)
2049 		return -ENOMEM;
2050 
2051 	cfg80211_put_bss(bss);
2052 
2053 	return err;
2054 }
2055 
2056 static struct brcmf_bss_info_le *
next_bss_le(struct brcmf_scan_results * list,struct brcmf_bss_info_le * bss)2057 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2058 {
2059 	if (bss == NULL)
2060 		return list->bss_info_le;
2061 	return (struct brcmf_bss_info_le *)((unsigned long)bss +
2062 					    le32_to_cpu(bss->length));
2063 }
2064 
brcmf_inform_bss(struct brcmf_cfg80211_priv * cfg_priv)2065 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2066 {
2067 	struct brcmf_scan_results *bss_list;
2068 	struct brcmf_bss_info_le *bi = NULL;	/* must be initialized */
2069 	s32 err = 0;
2070 	int i;
2071 
2072 	bss_list = cfg_priv->bss_list;
2073 	if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2074 		WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2075 		       bss_list->version);
2076 		return -EOPNOTSUPP;
2077 	}
2078 	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2079 	for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2080 		bi = next_bss_le(bss_list, bi);
2081 		err = brcmf_inform_single_bss(cfg_priv, bi);
2082 		if (err)
2083 			break;
2084 	}
2085 	return err;
2086 }
2087 
wl_inform_ibss(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const u8 * bssid)2088 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2089 			  struct net_device *ndev, const u8 *bssid)
2090 {
2091 	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2092 	struct ieee80211_channel *notify_channel;
2093 	struct brcmf_bss_info_le *bi = NULL;
2094 	struct ieee80211_supported_band *band;
2095 	struct cfg80211_bss *bss;
2096 	u8 *buf = NULL;
2097 	s32 err = 0;
2098 	u16 channel;
2099 	u32 freq;
2100 	u16 notify_capability;
2101 	u16 notify_interval;
2102 	u8 *notify_ie;
2103 	size_t notify_ielen;
2104 	s32 notify_signal;
2105 
2106 	WL_TRACE("Enter\n");
2107 
2108 	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2109 	if (buf == NULL) {
2110 		err = -ENOMEM;
2111 		goto CleanUp;
2112 	}
2113 
2114 	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2115 
2116 	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2117 	if (err) {
2118 		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2119 		goto CleanUp;
2120 	}
2121 
2122 	bi = (struct brcmf_bss_info_le *)(buf + 4);
2123 
2124 	channel = bi->ctl_ch ? bi->ctl_ch :
2125 				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2126 
2127 	if (channel <= CH_MAX_2G_CHANNEL)
2128 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
2129 	else
2130 		band = wiphy->bands[IEEE80211_BAND_5GHZ];
2131 
2132 	freq = ieee80211_channel_to_frequency(channel, band->band);
2133 	notify_channel = ieee80211_get_channel(wiphy, freq);
2134 
2135 	notify_capability = le16_to_cpu(bi->capability);
2136 	notify_interval = le16_to_cpu(bi->beacon_period);
2137 	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2138 	notify_ielen = le32_to_cpu(bi->ie_length);
2139 	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2140 
2141 	WL_CONN("channel: %d(%d)\n", channel, freq);
2142 	WL_CONN("capability: %X\n", notify_capability);
2143 	WL_CONN("beacon interval: %d\n", notify_interval);
2144 	WL_CONN("signal: %d\n", notify_signal);
2145 
2146 	bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2147 		0, notify_capability, notify_interval,
2148 		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2149 
2150 	if (!bss) {
2151 		err = -ENOMEM;
2152 		goto CleanUp;
2153 	}
2154 
2155 	cfg80211_put_bss(bss);
2156 
2157 CleanUp:
2158 
2159 	kfree(buf);
2160 
2161 	WL_TRACE("Exit\n");
2162 
2163 	return err;
2164 }
2165 
brcmf_is_ibssmode(struct brcmf_cfg80211_priv * cfg_priv)2166 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2167 {
2168 	return cfg_priv->conf->mode == WL_MODE_IBSS;
2169 }
2170 
2171 /*
2172  * Traverse a string of 1-byte tag/1-byte length/variable-length value
2173  * triples, returning a pointer to the substring whose first element
2174  * matches tag
2175  */
brcmf_parse_tlvs(void * buf,int buflen,uint key)2176 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2177 {
2178 	struct brcmf_tlv *elt;
2179 	int totlen;
2180 
2181 	elt = (struct brcmf_tlv *) buf;
2182 	totlen = buflen;
2183 
2184 	/* find tagged parameter */
2185 	while (totlen >= 2) {
2186 		int len = elt->len;
2187 
2188 		/* validate remaining totlen */
2189 		if ((elt->id == key) && (totlen >= (len + 2)))
2190 			return elt;
2191 
2192 		elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2193 		totlen -= (len + 2);
2194 	}
2195 
2196 	return NULL;
2197 }
2198 
brcmf_update_bss_info(struct brcmf_cfg80211_priv * cfg_priv)2199 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2200 {
2201 	struct brcmf_bss_info_le *bi;
2202 	struct brcmf_ssid *ssid;
2203 	struct brcmf_tlv *tim;
2204 	u16 beacon_interval;
2205 	u8 dtim_period;
2206 	size_t ie_len;
2207 	u8 *ie;
2208 	s32 err = 0;
2209 
2210 	WL_TRACE("Enter\n");
2211 	if (brcmf_is_ibssmode(cfg_priv))
2212 		return err;
2213 
2214 	ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2215 
2216 	*(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2217 	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2218 			cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2219 	if (err) {
2220 		WL_ERR("Could not get bss info %d\n", err);
2221 		goto update_bss_info_out;
2222 	}
2223 
2224 	bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2225 	err = brcmf_inform_single_bss(cfg_priv, bi);
2226 	if (err)
2227 		goto update_bss_info_out;
2228 
2229 	ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2230 	ie_len = le32_to_cpu(bi->ie_length);
2231 	beacon_interval = le16_to_cpu(bi->beacon_period);
2232 
2233 	tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2234 	if (tim)
2235 		dtim_period = tim->data[1];
2236 	else {
2237 		/*
2238 		* active scan was done so we could not get dtim
2239 		* information out of probe response.
2240 		* so we speficially query dtim information to dongle.
2241 		*/
2242 		u32 var;
2243 		err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2244 					   "dtim_assoc", &var);
2245 		if (err) {
2246 			WL_ERR("wl dtim_assoc failed (%d)\n", err);
2247 			goto update_bss_info_out;
2248 		}
2249 		dtim_period = (u8)var;
2250 	}
2251 
2252 	brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2253 	brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2254 
2255 update_bss_info_out:
2256 	WL_TRACE("Exit");
2257 	return err;
2258 }
2259 
brcmf_term_iscan(struct brcmf_cfg80211_priv * cfg_priv)2260 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2261 {
2262 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2263 	struct brcmf_ssid ssid;
2264 
2265 	if (cfg_priv->iscan_on) {
2266 		iscan->state = WL_ISCAN_STATE_IDLE;
2267 
2268 		if (iscan->timer_on) {
2269 			del_timer_sync(&iscan->timer);
2270 			iscan->timer_on = 0;
2271 		}
2272 
2273 		cancel_work_sync(&iscan->work);
2274 
2275 		/* Abort iscan running in FW */
2276 		memset(&ssid, 0, sizeof(ssid));
2277 		brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2278 	}
2279 }
2280 
brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl * iscan,bool aborted)2281 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2282 					bool aborted)
2283 {
2284 	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2285 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
2286 
2287 	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2288 		WL_ERR("Scan complete while device not scanning\n");
2289 		return;
2290 	}
2291 	if (cfg_priv->scan_request) {
2292 		WL_SCAN("ISCAN Completed scan: %s\n",
2293 				aborted ? "Aborted" : "Done");
2294 		cfg80211_scan_done(cfg_priv->scan_request, aborted);
2295 		brcmf_set_mpc(ndev, 1);
2296 		cfg_priv->scan_request = NULL;
2297 	}
2298 	cfg_priv->iscan_kickstart = false;
2299 }
2300 
brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl * iscan)2301 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2302 {
2303 	if (iscan->state != WL_ISCAN_STATE_IDLE) {
2304 		WL_SCAN("wake up iscan\n");
2305 		schedule_work(&iscan->work);
2306 		return 0;
2307 	}
2308 
2309 	return -EIO;
2310 }
2311 
2312 static s32
brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl * iscan,u32 * status,struct brcmf_scan_results ** bss_list)2313 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2314 		     struct brcmf_scan_results **bss_list)
2315 {
2316 	struct brcmf_iscan_results list;
2317 	struct brcmf_scan_results *results;
2318 	struct brcmf_scan_results_le *results_le;
2319 	struct brcmf_iscan_results *list_buf;
2320 	s32 err = 0;
2321 
2322 	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2323 	list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2324 	results = &list_buf->results;
2325 	results_le = &list_buf->results_le;
2326 	results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2327 	results->version = 0;
2328 	results->count = 0;
2329 
2330 	memset(&list, 0, sizeof(list));
2331 	list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2332 	err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2333 				     BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2334 				     iscan->scan_buf, WL_ISCAN_BUF_MAX);
2335 	if (err) {
2336 		WL_ERR("error (%d)\n", err);
2337 		return err;
2338 	}
2339 	results->buflen = le32_to_cpu(results_le->buflen);
2340 	results->version = le32_to_cpu(results_le->version);
2341 	results->count = le32_to_cpu(results_le->count);
2342 	WL_SCAN("results->count = %d\n", results_le->count);
2343 	WL_SCAN("results->buflen = %d\n", results_le->buflen);
2344 	*status = le32_to_cpu(list_buf->status_le);
2345 	WL_SCAN("status = %d\n", *status);
2346 	*bss_list = results;
2347 
2348 	return err;
2349 }
2350 
brcmf_iscan_done(struct brcmf_cfg80211_priv * cfg_priv)2351 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2352 {
2353 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2354 	s32 err = 0;
2355 
2356 	iscan->state = WL_ISCAN_STATE_IDLE;
2357 	brcmf_inform_bss(cfg_priv);
2358 	brcmf_notify_iscan_complete(iscan, false);
2359 
2360 	return err;
2361 }
2362 
brcmf_iscan_pending(struct brcmf_cfg80211_priv * cfg_priv)2363 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2364 {
2365 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2366 	s32 err = 0;
2367 
2368 	/* Reschedule the timer */
2369 	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2370 	iscan->timer_on = 1;
2371 
2372 	return err;
2373 }
2374 
brcmf_iscan_inprogress(struct brcmf_cfg80211_priv * cfg_priv)2375 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2376 {
2377 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2378 	s32 err = 0;
2379 
2380 	brcmf_inform_bss(cfg_priv);
2381 	brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2382 	/* Reschedule the timer */
2383 	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2384 	iscan->timer_on = 1;
2385 
2386 	return err;
2387 }
2388 
brcmf_iscan_aborted(struct brcmf_cfg80211_priv * cfg_priv)2389 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2390 {
2391 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2392 	s32 err = 0;
2393 
2394 	iscan->state = WL_ISCAN_STATE_IDLE;
2395 	brcmf_notify_iscan_complete(iscan, true);
2396 
2397 	return err;
2398 }
2399 
brcmf_cfg80211_iscan_handler(struct work_struct * work)2400 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2401 {
2402 	struct brcmf_cfg80211_iscan_ctrl *iscan =
2403 			container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2404 				     work);
2405 	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2406 	struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2407 	u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2408 
2409 	if (iscan->timer_on) {
2410 		del_timer_sync(&iscan->timer);
2411 		iscan->timer_on = 0;
2412 	}
2413 
2414 	if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2415 		status = BRCMF_SCAN_RESULTS_ABORTED;
2416 		WL_ERR("Abort iscan\n");
2417 	}
2418 
2419 	el->handler[status](cfg_priv);
2420 }
2421 
brcmf_iscan_timer(unsigned long data)2422 static void brcmf_iscan_timer(unsigned long data)
2423 {
2424 	struct brcmf_cfg80211_iscan_ctrl *iscan =
2425 			(struct brcmf_cfg80211_iscan_ctrl *)data;
2426 
2427 	if (iscan) {
2428 		iscan->timer_on = 0;
2429 		WL_SCAN("timer expired\n");
2430 		brcmf_wakeup_iscan(iscan);
2431 	}
2432 }
2433 
brcmf_invoke_iscan(struct brcmf_cfg80211_priv * cfg_priv)2434 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2435 {
2436 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2437 
2438 	if (cfg_priv->iscan_on) {
2439 		iscan->state = WL_ISCAN_STATE_IDLE;
2440 		INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2441 	}
2442 
2443 	return 0;
2444 }
2445 
brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop * el)2446 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2447 {
2448 	memset(el, 0, sizeof(*el));
2449 	el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2450 	el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2451 	el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2452 	el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2453 	el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2454 }
2455 
brcmf_init_iscan(struct brcmf_cfg80211_priv * cfg_priv)2456 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2457 {
2458 	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2459 	int err = 0;
2460 
2461 	if (cfg_priv->iscan_on) {
2462 		iscan->ndev = cfg_to_ndev(cfg_priv);
2463 		brcmf_init_iscan_eloop(&iscan->el);
2464 		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2465 		init_timer(&iscan->timer);
2466 		iscan->timer.data = (unsigned long) iscan;
2467 		iscan->timer.function = brcmf_iscan_timer;
2468 		err = brcmf_invoke_iscan(cfg_priv);
2469 		if (!err)
2470 			iscan->data = cfg_priv;
2471 	}
2472 
2473 	return err;
2474 }
2475 
brcmf_delay(u32 ms)2476 static __always_inline void brcmf_delay(u32 ms)
2477 {
2478 	if (ms < 1000 / HZ) {
2479 		cond_resched();
2480 		mdelay(ms);
2481 	} else {
2482 		msleep(ms);
2483 	}
2484 }
2485 
brcmf_cfg80211_resume(struct wiphy * wiphy)2486 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2487 {
2488 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2489 
2490 	/*
2491 	 * Check for WL_STATUS_READY before any function call which
2492 	 * could result is bus access. Don't block the resume for
2493 	 * any driver error conditions
2494 	 */
2495 	WL_TRACE("Enter\n");
2496 
2497 	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2498 		brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2499 
2500 	WL_TRACE("Exit\n");
2501 	return 0;
2502 }
2503 
brcmf_cfg80211_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wow)2504 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2505 				  struct cfg80211_wowlan *wow)
2506 {
2507 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2508 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
2509 
2510 	WL_TRACE("Enter\n");
2511 
2512 	/*
2513 	 * Check for WL_STATUS_READY before any function call which
2514 	 * could result is bus access. Don't block the suspend for
2515 	 * any driver error conditions
2516 	 */
2517 
2518 	/*
2519 	 * While going to suspend if associated with AP disassociate
2520 	 * from AP to save power while system is in suspended state
2521 	 */
2522 	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2523 	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2524 	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2525 		WL_INFO("Disassociating from AP"
2526 			" while entering suspend state\n");
2527 		brcmf_link_down(cfg_priv);
2528 
2529 		/*
2530 		 * Make sure WPA_Supplicant receives all the event
2531 		 * generated due to DISASSOC call to the fw to keep
2532 		 * the state fw and WPA_Supplicant state consistent
2533 		 */
2534 		brcmf_delay(500);
2535 	}
2536 
2537 	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2538 	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2539 		brcmf_term_iscan(cfg_priv);
2540 
2541 	if (cfg_priv->scan_request) {
2542 		/* Indidate scan abort to cfg80211 layer */
2543 		WL_INFO("Terminating scan in progress\n");
2544 		cfg80211_scan_done(cfg_priv->scan_request, true);
2545 		cfg_priv->scan_request = NULL;
2546 	}
2547 	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2548 	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2549 
2550 	/* Turn off watchdog timer */
2551 	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2552 		WL_INFO("Enable MPC\n");
2553 		brcmf_set_mpc(ndev, 1);
2554 	}
2555 
2556 	WL_TRACE("Exit\n");
2557 
2558 	return 0;
2559 }
2560 
2561 static __used s32
brcmf_dev_bufvar_set(struct net_device * ndev,s8 * name,s8 * buf,s32 len)2562 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2563 {
2564 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2565 	u32 buflen;
2566 
2567 	buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2568 			       WL_DCMD_LEN_MAX);
2569 	BUG_ON(!buflen);
2570 
2571 	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2572 			       buflen);
2573 }
2574 
2575 static s32
brcmf_dev_bufvar_get(struct net_device * ndev,s8 * name,s8 * buf,s32 buf_len)2576 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2577 		  s32 buf_len)
2578 {
2579 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2580 	u32 len;
2581 	s32 err = 0;
2582 
2583 	len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2584 			    WL_DCMD_LEN_MAX);
2585 	BUG_ON(!len);
2586 	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2587 			      WL_DCMD_LEN_MAX);
2588 	if (err) {
2589 		WL_ERR("error (%d)\n", err);
2590 		return err;
2591 	}
2592 	memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2593 
2594 	return err;
2595 }
2596 
2597 static __used s32
brcmf_update_pmklist(struct net_device * ndev,struct brcmf_cfg80211_pmk_list * pmk_list,s32 err)2598 brcmf_update_pmklist(struct net_device *ndev,
2599 		     struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2600 {
2601 	int i, j;
2602 	int pmkid_len;
2603 
2604 	pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2605 
2606 	WL_CONN("No of elements %d\n", pmkid_len);
2607 	for (i = 0; i < pmkid_len; i++) {
2608 		WL_CONN("PMKID[%d]: %pM =\n", i,
2609 			&pmk_list->pmkids.pmkid[i].BSSID);
2610 		for (j = 0; j < WLAN_PMKID_LEN; j++)
2611 			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2612 	}
2613 
2614 	if (!err)
2615 		brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2616 					sizeof(*pmk_list));
2617 
2618 	return err;
2619 }
2620 
2621 static s32
brcmf_cfg80211_set_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)2622 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2623 			 struct cfg80211_pmksa *pmksa)
2624 {
2625 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2626 	struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2627 	s32 err = 0;
2628 	int i;
2629 	int pmkid_len;
2630 
2631 	WL_TRACE("Enter\n");
2632 	if (!check_sys_up(wiphy))
2633 		return -EIO;
2634 
2635 	pmkid_len = le32_to_cpu(pmkids->npmkid);
2636 	for (i = 0; i < pmkid_len; i++)
2637 		if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2638 			break;
2639 	if (i < WL_NUM_PMKIDS_MAX) {
2640 		memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2641 		memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2642 		if (i == pmkid_len) {
2643 			pmkid_len++;
2644 			pmkids->npmkid = cpu_to_le32(pmkid_len);
2645 		}
2646 	} else
2647 		err = -EINVAL;
2648 
2649 	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2650 		pmkids->pmkid[pmkid_len].BSSID);
2651 	for (i = 0; i < WLAN_PMKID_LEN; i++)
2652 		WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2653 
2654 	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2655 
2656 	WL_TRACE("Exit\n");
2657 	return err;
2658 }
2659 
2660 static s32
brcmf_cfg80211_del_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)2661 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2662 		      struct cfg80211_pmksa *pmksa)
2663 {
2664 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2665 	struct pmkid_list pmkid;
2666 	s32 err = 0;
2667 	int i, pmkid_len;
2668 
2669 	WL_TRACE("Enter\n");
2670 	if (!check_sys_up(wiphy))
2671 		return -EIO;
2672 
2673 	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2674 	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2675 
2676 	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2677 	       &pmkid.pmkid[0].BSSID);
2678 	for (i = 0; i < WLAN_PMKID_LEN; i++)
2679 		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2680 
2681 	pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2682 	for (i = 0; i < pmkid_len; i++)
2683 		if (!memcmp
2684 		    (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2685 		     ETH_ALEN))
2686 			break;
2687 
2688 	if ((pmkid_len > 0)
2689 	    && (i < pmkid_len)) {
2690 		memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2691 		       sizeof(struct pmkid));
2692 		for (; i < (pmkid_len - 1); i++) {
2693 			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2694 			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2695 			       ETH_ALEN);
2696 			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2697 			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2698 			       WLAN_PMKID_LEN);
2699 		}
2700 		cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2701 	} else
2702 		err = -EINVAL;
2703 
2704 	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2705 
2706 	WL_TRACE("Exit\n");
2707 	return err;
2708 
2709 }
2710 
2711 static s32
brcmf_cfg80211_flush_pmksa(struct wiphy * wiphy,struct net_device * ndev)2712 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2713 {
2714 	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2715 	s32 err = 0;
2716 
2717 	WL_TRACE("Enter\n");
2718 	if (!check_sys_up(wiphy))
2719 		return -EIO;
2720 
2721 	memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2722 	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2723 
2724 	WL_TRACE("Exit\n");
2725 	return err;
2726 
2727 }
2728 
2729 static struct cfg80211_ops wl_cfg80211_ops = {
2730 	.change_virtual_intf = brcmf_cfg80211_change_iface,
2731 	.scan = brcmf_cfg80211_scan,
2732 	.set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2733 	.join_ibss = brcmf_cfg80211_join_ibss,
2734 	.leave_ibss = brcmf_cfg80211_leave_ibss,
2735 	.get_station = brcmf_cfg80211_get_station,
2736 	.set_tx_power = brcmf_cfg80211_set_tx_power,
2737 	.get_tx_power = brcmf_cfg80211_get_tx_power,
2738 	.add_key = brcmf_cfg80211_add_key,
2739 	.del_key = brcmf_cfg80211_del_key,
2740 	.get_key = brcmf_cfg80211_get_key,
2741 	.set_default_key = brcmf_cfg80211_config_default_key,
2742 	.set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2743 	.set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2744 	.set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2745 	.connect = brcmf_cfg80211_connect,
2746 	.disconnect = brcmf_cfg80211_disconnect,
2747 	.suspend = brcmf_cfg80211_suspend,
2748 	.resume = brcmf_cfg80211_resume,
2749 	.set_pmksa = brcmf_cfg80211_set_pmksa,
2750 	.del_pmksa = brcmf_cfg80211_del_pmksa,
2751 	.flush_pmksa = brcmf_cfg80211_flush_pmksa
2752 };
2753 
brcmf_mode_to_nl80211_iftype(s32 mode)2754 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2755 {
2756 	s32 err = 0;
2757 
2758 	switch (mode) {
2759 	case WL_MODE_BSS:
2760 		return NL80211_IFTYPE_STATION;
2761 	case WL_MODE_IBSS:
2762 		return NL80211_IFTYPE_ADHOC;
2763 	default:
2764 		return NL80211_IFTYPE_UNSPECIFIED;
2765 	}
2766 
2767 	return err;
2768 }
2769 
brcmf_alloc_wdev(s32 sizeof_iface,struct device * ndev)2770 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2771 					  struct device *ndev)
2772 {
2773 	struct wireless_dev *wdev;
2774 	s32 err = 0;
2775 
2776 	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2777 	if (!wdev)
2778 		return ERR_PTR(-ENOMEM);
2779 
2780 	wdev->wiphy =
2781 	    wiphy_new(&wl_cfg80211_ops,
2782 		      sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2783 	if (!wdev->wiphy) {
2784 		WL_ERR("Could not allocate wiphy device\n");
2785 		err = -ENOMEM;
2786 		goto wiphy_new_out;
2787 	}
2788 	set_wiphy_dev(wdev->wiphy, ndev);
2789 	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2790 	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2791 	wdev->wiphy->interface_modes =
2792 	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2793 	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2794 	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set
2795 						* it as 11a by default.
2796 						* This will be updated with
2797 						* 11n phy tables in
2798 						* "ifconfig up"
2799 						* if phy has 11n capability
2800 						*/
2801 	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2802 	wdev->wiphy->cipher_suites = __wl_cipher_suites;
2803 	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2804 	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;	/* enable power
2805 								 * save mode
2806 								 * by default
2807 								 */
2808 	err = wiphy_register(wdev->wiphy);
2809 	if (err < 0) {
2810 		WL_ERR("Could not register wiphy device (%d)\n", err);
2811 		goto wiphy_register_out;
2812 	}
2813 	return wdev;
2814 
2815 wiphy_register_out:
2816 	wiphy_free(wdev->wiphy);
2817 
2818 wiphy_new_out:
2819 	kfree(wdev);
2820 
2821 	return ERR_PTR(err);
2822 }
2823 
brcmf_free_wdev(struct brcmf_cfg80211_priv * cfg_priv)2824 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2825 {
2826 	struct wireless_dev *wdev = cfg_priv->wdev;
2827 
2828 	if (!wdev) {
2829 		WL_ERR("wdev is invalid\n");
2830 		return;
2831 	}
2832 	wiphy_unregister(wdev->wiphy);
2833 	wiphy_free(wdev->wiphy);
2834 	kfree(wdev);
2835 	cfg_priv->wdev = NULL;
2836 }
2837 
brcmf_is_linkup(struct brcmf_cfg80211_priv * cfg_priv,const struct brcmf_event_msg * e)2838 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2839 			    const struct brcmf_event_msg *e)
2840 {
2841 	u32 event = be32_to_cpu(e->event_type);
2842 	u32 status = be32_to_cpu(e->status);
2843 
2844 	if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2845 		WL_CONN("Processing set ssid\n");
2846 		cfg_priv->link_up = true;
2847 		return true;
2848 	}
2849 
2850 	return false;
2851 }
2852 
brcmf_is_linkdown(struct brcmf_cfg80211_priv * cfg_priv,const struct brcmf_event_msg * e)2853 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2854 			      const struct brcmf_event_msg *e)
2855 {
2856 	u32 event = be32_to_cpu(e->event_type);
2857 	u16 flags = be16_to_cpu(e->flags);
2858 
2859 	if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2860 		WL_CONN("Processing link down\n");
2861 		return true;
2862 	}
2863 	return false;
2864 }
2865 
brcmf_is_nonetwork(struct brcmf_cfg80211_priv * cfg_priv,const struct brcmf_event_msg * e)2866 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2867 			       const struct brcmf_event_msg *e)
2868 {
2869 	u32 event = be32_to_cpu(e->event_type);
2870 	u32 status = be32_to_cpu(e->status);
2871 
2872 	if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2873 		WL_CONN("Processing Link %s & no network found\n",
2874 				be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2875 				"up" : "down");
2876 		return true;
2877 	}
2878 
2879 	if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2880 		WL_CONN("Processing connecting & no network found\n");
2881 		return true;
2882 	}
2883 
2884 	return false;
2885 }
2886 
brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv * cfg_priv)2887 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2888 {
2889 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2890 
2891 	kfree(conn_info->req_ie);
2892 	conn_info->req_ie = NULL;
2893 	conn_info->req_ie_len = 0;
2894 	kfree(conn_info->resp_ie);
2895 	conn_info->resp_ie = NULL;
2896 	conn_info->resp_ie_len = 0;
2897 }
2898 
brcmf_get_assoc_ies(struct brcmf_cfg80211_priv * cfg_priv)2899 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2900 {
2901 	struct net_device *ndev = cfg_to_ndev(cfg_priv);
2902 	struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2903 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2904 	u32 req_len;
2905 	u32 resp_len;
2906 	s32 err = 0;
2907 
2908 	brcmf_clear_assoc_ies(cfg_priv);
2909 
2910 	err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2911 				WL_ASSOC_INFO_MAX);
2912 	if (err) {
2913 		WL_ERR("could not get assoc info (%d)\n", err);
2914 		return err;
2915 	}
2916 	assoc_info =
2917 		(struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2918 	req_len = le32_to_cpu(assoc_info->req_len);
2919 	resp_len = le32_to_cpu(assoc_info->resp_len);
2920 	if (req_len) {
2921 		err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2922 					   cfg_priv->extra_buf,
2923 					   WL_ASSOC_INFO_MAX);
2924 		if (err) {
2925 			WL_ERR("could not get assoc req (%d)\n", err);
2926 			return err;
2927 		}
2928 		conn_info->req_ie_len = req_len;
2929 		conn_info->req_ie =
2930 		    kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2931 			    GFP_KERNEL);
2932 	} else {
2933 		conn_info->req_ie_len = 0;
2934 		conn_info->req_ie = NULL;
2935 	}
2936 	if (resp_len) {
2937 		err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2938 					   cfg_priv->extra_buf,
2939 					   WL_ASSOC_INFO_MAX);
2940 		if (err) {
2941 			WL_ERR("could not get assoc resp (%d)\n", err);
2942 			return err;
2943 		}
2944 		conn_info->resp_ie_len = resp_len;
2945 		conn_info->resp_ie =
2946 		    kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2947 			    GFP_KERNEL);
2948 	} else {
2949 		conn_info->resp_ie_len = 0;
2950 		conn_info->resp_ie = NULL;
2951 	}
2952 	WL_CONN("req len (%d) resp len (%d)\n",
2953 	       conn_info->req_ie_len, conn_info->resp_ie_len);
2954 
2955 	return err;
2956 }
2957 
2958 static s32
brcmf_bss_roaming_done(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const struct brcmf_event_msg * e)2959 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2960 		       struct net_device *ndev,
2961 		       const struct brcmf_event_msg *e)
2962 {
2963 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2964 	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2965 	struct brcmf_channel_info_le channel_le;
2966 	struct ieee80211_channel *notify_channel;
2967 	struct ieee80211_supported_band *band;
2968 	u32 freq;
2969 	s32 err = 0;
2970 	u32 target_channel;
2971 
2972 	WL_TRACE("Enter\n");
2973 
2974 	brcmf_get_assoc_ies(cfg_priv);
2975 	brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2976 	brcmf_update_bss_info(cfg_priv);
2977 
2978 	brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2979 			sizeof(channel_le));
2980 
2981 	target_channel = le32_to_cpu(channel_le.target_channel);
2982 	WL_CONN("Roamed to channel %d\n", target_channel);
2983 
2984 	if (target_channel <= CH_MAX_2G_CHANNEL)
2985 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
2986 	else
2987 		band = wiphy->bands[IEEE80211_BAND_5GHZ];
2988 
2989 	freq = ieee80211_channel_to_frequency(target_channel, band->band);
2990 	notify_channel = ieee80211_get_channel(wiphy, freq);
2991 
2992 	cfg80211_roamed(ndev, notify_channel,
2993 			(u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2994 			conn_info->req_ie, conn_info->req_ie_len,
2995 			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2996 	WL_CONN("Report roaming result\n");
2997 
2998 	set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2999 	WL_TRACE("Exit\n");
3000 	return err;
3001 }
3002 
3003 static s32
brcmf_bss_connect_done(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const struct brcmf_event_msg * e,bool completed)3004 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3005 		       struct net_device *ndev, const struct brcmf_event_msg *e,
3006 		       bool completed)
3007 {
3008 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3009 	s32 err = 0;
3010 
3011 	WL_TRACE("Enter\n");
3012 
3013 	if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3014 		if (completed) {
3015 			brcmf_get_assoc_ies(cfg_priv);
3016 			brcmf_update_prof(cfg_priv, NULL, &e->addr,
3017 					  WL_PROF_BSSID);
3018 			brcmf_update_bss_info(cfg_priv);
3019 		}
3020 		cfg80211_connect_result(ndev,
3021 					(u8 *)brcmf_read_prof(cfg_priv,
3022 							      WL_PROF_BSSID),
3023 					conn_info->req_ie,
3024 					conn_info->req_ie_len,
3025 					conn_info->resp_ie,
3026 					conn_info->resp_ie_len,
3027 					completed ? WLAN_STATUS_SUCCESS :
3028 						    WLAN_STATUS_AUTH_TIMEOUT,
3029 					GFP_KERNEL);
3030 		if (completed)
3031 			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3032 		WL_CONN("Report connect result - connection %s\n",
3033 				completed ? "succeeded" : "failed");
3034 	}
3035 	WL_TRACE("Exit\n");
3036 	return err;
3037 }
3038 
3039 static s32
brcmf_notify_connect_status(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const struct brcmf_event_msg * e,void * data)3040 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3041 			    struct net_device *ndev,
3042 			    const struct brcmf_event_msg *e, void *data)
3043 {
3044 	s32 err = 0;
3045 
3046 	if (brcmf_is_linkup(cfg_priv, e)) {
3047 		WL_CONN("Linkup\n");
3048 		if (brcmf_is_ibssmode(cfg_priv)) {
3049 			brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3050 				WL_PROF_BSSID);
3051 			wl_inform_ibss(cfg_priv, ndev, e->addr);
3052 			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3053 			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3054 			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3055 		} else
3056 			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3057 	} else if (brcmf_is_linkdown(cfg_priv, e)) {
3058 		WL_CONN("Linkdown\n");
3059 		if (brcmf_is_ibssmode(cfg_priv)) {
3060 			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3061 			if (test_and_clear_bit(WL_STATUS_CONNECTED,
3062 				&cfg_priv->status))
3063 				brcmf_link_down(cfg_priv);
3064 		} else {
3065 			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3066 			if (test_and_clear_bit(WL_STATUS_CONNECTED,
3067 				&cfg_priv->status)) {
3068 				cfg80211_disconnected(ndev, 0, NULL, 0,
3069 					GFP_KERNEL);
3070 				brcmf_link_down(cfg_priv);
3071 			}
3072 		}
3073 		brcmf_init_prof(cfg_priv->profile);
3074 	} else if (brcmf_is_nonetwork(cfg_priv, e)) {
3075 		if (brcmf_is_ibssmode(cfg_priv))
3076 			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3077 		else
3078 			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3079 	}
3080 
3081 	return err;
3082 }
3083 
3084 static s32
brcmf_notify_roaming_status(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const struct brcmf_event_msg * e,void * data)3085 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3086 			    struct net_device *ndev,
3087 			    const struct brcmf_event_msg *e, void *data)
3088 {
3089 	s32 err = 0;
3090 	u32 event = be32_to_cpu(e->event_type);
3091 	u32 status = be32_to_cpu(e->status);
3092 
3093 	if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3094 		if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3095 			brcmf_bss_roaming_done(cfg_priv, ndev, e);
3096 		else
3097 			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3098 	}
3099 
3100 	return err;
3101 }
3102 
3103 static s32
brcmf_notify_mic_status(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const struct brcmf_event_msg * e,void * data)3104 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3105 			struct net_device *ndev,
3106 			const struct brcmf_event_msg *e, void *data)
3107 {
3108 	u16 flags = be16_to_cpu(e->flags);
3109 	enum nl80211_key_type key_type;
3110 
3111 	if (flags & BRCMF_EVENT_MSG_GROUP)
3112 		key_type = NL80211_KEYTYPE_GROUP;
3113 	else
3114 		key_type = NL80211_KEYTYPE_PAIRWISE;
3115 
3116 	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3117 				     NULL, GFP_KERNEL);
3118 
3119 	return 0;
3120 }
3121 
3122 static s32
brcmf_notify_scan_status(struct brcmf_cfg80211_priv * cfg_priv,struct net_device * ndev,const struct brcmf_event_msg * e,void * data)3123 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3124 			 struct net_device *ndev,
3125 			 const struct brcmf_event_msg *e, void *data)
3126 {
3127 	struct brcmf_channel_info_le channel_inform_le;
3128 	struct brcmf_scan_results_le *bss_list_le;
3129 	u32 len = WL_SCAN_BUF_MAX;
3130 	s32 err = 0;
3131 	bool scan_abort = false;
3132 	u32 scan_channel;
3133 
3134 	WL_TRACE("Enter\n");
3135 
3136 	if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3137 		WL_TRACE("Exit\n");
3138 		return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3139 	}
3140 
3141 	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3142 		WL_ERR("Scan complete while device not scanning\n");
3143 		scan_abort = true;
3144 		err = -EINVAL;
3145 		goto scan_done_out;
3146 	}
3147 
3148 	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3149 			      sizeof(channel_inform_le));
3150 	if (err) {
3151 		WL_ERR("scan busy (%d)\n", err);
3152 		scan_abort = true;
3153 		goto scan_done_out;
3154 	}
3155 	scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3156 	if (scan_channel)
3157 		WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3158 	cfg_priv->bss_list = cfg_priv->scan_results;
3159 	bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3160 
3161 	memset(cfg_priv->scan_results, 0, len);
3162 	bss_list_le->buflen = cpu_to_le32(len);
3163 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3164 			      cfg_priv->scan_results, len);
3165 	if (err) {
3166 		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3167 		err = -EINVAL;
3168 		scan_abort = true;
3169 		goto scan_done_out;
3170 	}
3171 	cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3172 	cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3173 	cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3174 
3175 	err = brcmf_inform_bss(cfg_priv);
3176 	if (err) {
3177 		scan_abort = true;
3178 		goto scan_done_out;
3179 	}
3180 
3181 scan_done_out:
3182 	if (cfg_priv->scan_request) {
3183 		WL_SCAN("calling cfg80211_scan_done\n");
3184 		cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3185 		brcmf_set_mpc(ndev, 1);
3186 		cfg_priv->scan_request = NULL;
3187 	}
3188 
3189 	WL_TRACE("Exit\n");
3190 
3191 	return err;
3192 }
3193 
brcmf_init_conf(struct brcmf_cfg80211_conf * conf)3194 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3195 {
3196 	conf->mode = (u32)-1;
3197 	conf->frag_threshold = (u32)-1;
3198 	conf->rts_threshold = (u32)-1;
3199 	conf->retry_short = (u32)-1;
3200 	conf->retry_long = (u32)-1;
3201 	conf->tx_power = -1;
3202 }
3203 
brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop * el)3204 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3205 {
3206 	memset(el, 0, sizeof(*el));
3207 	el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3208 	el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3209 	el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3210 	el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3211 	el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3212 }
3213 
brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv * cfg_priv)3214 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3215 {
3216 	kfree(cfg_priv->scan_results);
3217 	cfg_priv->scan_results = NULL;
3218 	kfree(cfg_priv->bss_info);
3219 	cfg_priv->bss_info = NULL;
3220 	kfree(cfg_priv->conf);
3221 	cfg_priv->conf = NULL;
3222 	kfree(cfg_priv->profile);
3223 	cfg_priv->profile = NULL;
3224 	kfree(cfg_priv->scan_req_int);
3225 	cfg_priv->scan_req_int = NULL;
3226 	kfree(cfg_priv->dcmd_buf);
3227 	cfg_priv->dcmd_buf = NULL;
3228 	kfree(cfg_priv->extra_buf);
3229 	cfg_priv->extra_buf = NULL;
3230 	kfree(cfg_priv->iscan);
3231 	cfg_priv->iscan = NULL;
3232 	kfree(cfg_priv->pmk_list);
3233 	cfg_priv->pmk_list = NULL;
3234 }
3235 
brcmf_init_priv_mem(struct brcmf_cfg80211_priv * cfg_priv)3236 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3237 {
3238 	cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3239 	if (!cfg_priv->scan_results)
3240 		goto init_priv_mem_out;
3241 	cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3242 	if (!cfg_priv->conf)
3243 		goto init_priv_mem_out;
3244 	cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3245 	if (!cfg_priv->profile)
3246 		goto init_priv_mem_out;
3247 	cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3248 	if (!cfg_priv->bss_info)
3249 		goto init_priv_mem_out;
3250 	cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3251 					 GFP_KERNEL);
3252 	if (!cfg_priv->scan_req_int)
3253 		goto init_priv_mem_out;
3254 	cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3255 	if (!cfg_priv->dcmd_buf)
3256 		goto init_priv_mem_out;
3257 	cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3258 	if (!cfg_priv->extra_buf)
3259 		goto init_priv_mem_out;
3260 	cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3261 	if (!cfg_priv->iscan)
3262 		goto init_priv_mem_out;
3263 	cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3264 	if (!cfg_priv->pmk_list)
3265 		goto init_priv_mem_out;
3266 
3267 	return 0;
3268 
3269 init_priv_mem_out:
3270 	brcmf_deinit_priv_mem(cfg_priv);
3271 
3272 	return -ENOMEM;
3273 }
3274 
3275 /*
3276 * retrieve first queued event from head
3277 */
3278 
brcmf_deq_event(struct brcmf_cfg80211_priv * cfg_priv)3279 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3280 	struct brcmf_cfg80211_priv *cfg_priv)
3281 {
3282 	struct brcmf_cfg80211_event_q *e = NULL;
3283 
3284 	spin_lock_irq(&cfg_priv->evt_q_lock);
3285 	if (!list_empty(&cfg_priv->evt_q_list)) {
3286 		e = list_first_entry(&cfg_priv->evt_q_list,
3287 				     struct brcmf_cfg80211_event_q, evt_q_list);
3288 		list_del(&e->evt_q_list);
3289 	}
3290 	spin_unlock_irq(&cfg_priv->evt_q_lock);
3291 
3292 	return e;
3293 }
3294 
3295 /*
3296 *	push event to tail of the queue
3297 *
3298 *	remark: this function may not sleep as it is called in atomic context.
3299 */
3300 
3301 static s32
brcmf_enq_event(struct brcmf_cfg80211_priv * cfg_priv,u32 event,const struct brcmf_event_msg * msg)3302 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3303 		const struct brcmf_event_msg *msg)
3304 {
3305 	struct brcmf_cfg80211_event_q *e;
3306 	s32 err = 0;
3307 	ulong flags;
3308 
3309 	e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
3310 	if (!e)
3311 		return -ENOMEM;
3312 
3313 	e->etype = event;
3314 	memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3315 
3316 	spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
3317 	list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3318 	spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
3319 
3320 	return err;
3321 }
3322 
brcmf_put_event(struct brcmf_cfg80211_event_q * e)3323 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3324 {
3325 	kfree(e);
3326 }
3327 
brcmf_cfg80211_event_handler(struct work_struct * work)3328 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3329 {
3330 	struct brcmf_cfg80211_priv *cfg_priv =
3331 			container_of(work, struct brcmf_cfg80211_priv,
3332 				     event_work);
3333 	struct brcmf_cfg80211_event_q *e;
3334 
3335 	e = brcmf_deq_event(cfg_priv);
3336 	if (unlikely(!e)) {
3337 		WL_ERR("event queue empty...\n");
3338 		return;
3339 	}
3340 
3341 	do {
3342 		WL_INFO("event type (%d)\n", e->etype);
3343 		if (cfg_priv->el.handler[e->etype])
3344 			cfg_priv->el.handler[e->etype](cfg_priv,
3345 						       cfg_to_ndev(cfg_priv),
3346 						       &e->emsg, e->edata);
3347 		else
3348 			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3349 		brcmf_put_event(e);
3350 	} while ((e = brcmf_deq_event(cfg_priv)));
3351 
3352 }
3353 
brcmf_init_eq(struct brcmf_cfg80211_priv * cfg_priv)3354 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3355 {
3356 	spin_lock_init(&cfg_priv->evt_q_lock);
3357 	INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3358 }
3359 
brcmf_flush_eq(struct brcmf_cfg80211_priv * cfg_priv)3360 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3361 {
3362 	struct brcmf_cfg80211_event_q *e;
3363 
3364 	spin_lock_irq(&cfg_priv->evt_q_lock);
3365 	while (!list_empty(&cfg_priv->evt_q_list)) {
3366 		e = list_first_entry(&cfg_priv->evt_q_list,
3367 				     struct brcmf_cfg80211_event_q, evt_q_list);
3368 		list_del(&e->evt_q_list);
3369 		kfree(e);
3370 	}
3371 	spin_unlock_irq(&cfg_priv->evt_q_lock);
3372 }
3373 
wl_init_priv(struct brcmf_cfg80211_priv * cfg_priv)3374 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3375 {
3376 	s32 err = 0;
3377 
3378 	cfg_priv->scan_request = NULL;
3379 	cfg_priv->pwr_save = true;
3380 	cfg_priv->iscan_on = true;	/* iscan on & off switch.
3381 				 we enable iscan per default */
3382 	cfg_priv->roam_on = true;	/* roam on & off switch.
3383 				 we enable roam per default */
3384 
3385 	cfg_priv->iscan_kickstart = false;
3386 	cfg_priv->active_scan = true;	/* we do active scan for
3387 				 specific scan per default */
3388 	cfg_priv->dongle_up = false;	/* dongle is not up yet */
3389 	brcmf_init_eq(cfg_priv);
3390 	err = brcmf_init_priv_mem(cfg_priv);
3391 	if (err)
3392 		return err;
3393 	INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3394 	brcmf_init_eloop_handler(&cfg_priv->el);
3395 	mutex_init(&cfg_priv->usr_sync);
3396 	err = brcmf_init_iscan(cfg_priv);
3397 	if (err)
3398 		return err;
3399 	brcmf_init_conf(cfg_priv->conf);
3400 	brcmf_init_prof(cfg_priv->profile);
3401 	brcmf_link_down(cfg_priv);
3402 
3403 	return err;
3404 }
3405 
wl_deinit_priv(struct brcmf_cfg80211_priv * cfg_priv)3406 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3407 {
3408 	cancel_work_sync(&cfg_priv->event_work);
3409 	cfg_priv->dongle_up = false;	/* dongle down */
3410 	brcmf_flush_eq(cfg_priv);
3411 	brcmf_link_down(cfg_priv);
3412 	brcmf_term_iscan(cfg_priv);
3413 	brcmf_deinit_priv_mem(cfg_priv);
3414 }
3415 
brcmf_cfg80211_attach(struct net_device * ndev,struct device * busdev,void * data)3416 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3417 						 struct device *busdev,
3418 						 void *data)
3419 {
3420 	struct wireless_dev *wdev;
3421 	struct brcmf_cfg80211_priv *cfg_priv;
3422 	struct brcmf_cfg80211_iface *ci;
3423 	struct brcmf_cfg80211_dev *cfg_dev;
3424 	s32 err = 0;
3425 
3426 	if (!ndev) {
3427 		WL_ERR("ndev is invalid\n");
3428 		return NULL;
3429 	}
3430 	cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3431 	if (!cfg_dev)
3432 		return NULL;
3433 
3434 	wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3435 	if (IS_ERR(wdev)) {
3436 		kfree(cfg_dev);
3437 		return NULL;
3438 	}
3439 
3440 	wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3441 	cfg_priv = wdev_to_cfg(wdev);
3442 	cfg_priv->wdev = wdev;
3443 	cfg_priv->pub = data;
3444 	ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3445 	ci->cfg_priv = cfg_priv;
3446 	ndev->ieee80211_ptr = wdev;
3447 	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3448 	wdev->netdev = ndev;
3449 	err = wl_init_priv(cfg_priv);
3450 	if (err) {
3451 		WL_ERR("Failed to init iwm_priv (%d)\n", err);
3452 		goto cfg80211_attach_out;
3453 	}
3454 	brcmf_set_drvdata(cfg_dev, ci);
3455 
3456 	return cfg_dev;
3457 
3458 cfg80211_attach_out:
3459 	brcmf_free_wdev(cfg_priv);
3460 	kfree(cfg_dev);
3461 	return NULL;
3462 }
3463 
brcmf_cfg80211_detach(struct brcmf_cfg80211_dev * cfg_dev)3464 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3465 {
3466 	struct brcmf_cfg80211_priv *cfg_priv;
3467 
3468 	cfg_priv = brcmf_priv_get(cfg_dev);
3469 
3470 	wl_deinit_priv(cfg_priv);
3471 	brcmf_free_wdev(cfg_priv);
3472 	brcmf_set_drvdata(cfg_dev, NULL);
3473 	kfree(cfg_dev);
3474 }
3475 
3476 void
brcmf_cfg80211_event(struct net_device * ndev,const struct brcmf_event_msg * e,void * data)3477 brcmf_cfg80211_event(struct net_device *ndev,
3478 		  const struct brcmf_event_msg *e, void *data)
3479 {
3480 	u32 event_type = be32_to_cpu(e->event_type);
3481 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3482 
3483 	if (!brcmf_enq_event(cfg_priv, event_type, e))
3484 		schedule_work(&cfg_priv->event_work);
3485 }
3486 
brcmf_dongle_mode(struct net_device * ndev,s32 iftype)3487 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3488 {
3489 	s32 infra = 0;
3490 	s32 err = 0;
3491 
3492 	switch (iftype) {
3493 	case NL80211_IFTYPE_MONITOR:
3494 	case NL80211_IFTYPE_WDS:
3495 		WL_ERR("type (%d) : currently we do not support this mode\n",
3496 		       iftype);
3497 		err = -EINVAL;
3498 		return err;
3499 	case NL80211_IFTYPE_ADHOC:
3500 		infra = 0;
3501 		break;
3502 	case NL80211_IFTYPE_STATION:
3503 		infra = 1;
3504 		break;
3505 	default:
3506 		err = -EINVAL;
3507 		WL_ERR("invalid type (%d)\n", iftype);
3508 		return err;
3509 	}
3510 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3511 	if (err) {
3512 		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3513 		return err;
3514 	}
3515 
3516 	return 0;
3517 }
3518 
brcmf_dongle_eventmsg(struct net_device * ndev)3519 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3520 {
3521 	/* Room for "event_msgs" + '\0' + bitvec */
3522 	s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3523 	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3524 	s32 err = 0;
3525 
3526 	WL_TRACE("Enter\n");
3527 
3528 	/* Setup event_msgs */
3529 	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3530 			iovbuf, sizeof(iovbuf));
3531 	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3532 	if (err) {
3533 		WL_ERR("Get event_msgs error (%d)\n", err);
3534 		goto dongle_eventmsg_out;
3535 	}
3536 	memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3537 
3538 	setbit(eventmask, BRCMF_E_SET_SSID);
3539 	setbit(eventmask, BRCMF_E_ROAM);
3540 	setbit(eventmask, BRCMF_E_PRUNE);
3541 	setbit(eventmask, BRCMF_E_AUTH);
3542 	setbit(eventmask, BRCMF_E_REASSOC);
3543 	setbit(eventmask, BRCMF_E_REASSOC_IND);
3544 	setbit(eventmask, BRCMF_E_DEAUTH_IND);
3545 	setbit(eventmask, BRCMF_E_DISASSOC_IND);
3546 	setbit(eventmask, BRCMF_E_DISASSOC);
3547 	setbit(eventmask, BRCMF_E_JOIN);
3548 	setbit(eventmask, BRCMF_E_ASSOC_IND);
3549 	setbit(eventmask, BRCMF_E_PSK_SUP);
3550 	setbit(eventmask, BRCMF_E_LINK);
3551 	setbit(eventmask, BRCMF_E_NDIS_LINK);
3552 	setbit(eventmask, BRCMF_E_MIC_ERROR);
3553 	setbit(eventmask, BRCMF_E_PMKID_CACHE);
3554 	setbit(eventmask, BRCMF_E_TXFAIL);
3555 	setbit(eventmask, BRCMF_E_JOIN_START);
3556 	setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3557 
3558 	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3559 			iovbuf, sizeof(iovbuf));
3560 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3561 	if (err) {
3562 		WL_ERR("Set event_msgs error (%d)\n", err);
3563 		goto dongle_eventmsg_out;
3564 	}
3565 
3566 dongle_eventmsg_out:
3567 	WL_TRACE("Exit\n");
3568 	return err;
3569 }
3570 
3571 static s32
brcmf_dongle_roam(struct net_device * ndev,u32 roamvar,u32 bcn_timeout)3572 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3573 {
3574 	s8 iovbuf[32];
3575 	s32 err = 0;
3576 	__le32 roamtrigger[2];
3577 	__le32 roam_delta[2];
3578 	__le32 bcn_to_le;
3579 	__le32 roamvar_le;
3580 
3581 	/*
3582 	 * Setup timeout if Beacons are lost and roam is
3583 	 * off to report link down
3584 	 */
3585 	if (roamvar) {
3586 		bcn_to_le = cpu_to_le32(bcn_timeout);
3587 		brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3588 			sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3589 		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3590 				   iovbuf, sizeof(iovbuf));
3591 		if (err) {
3592 			WL_ERR("bcn_timeout error (%d)\n", err);
3593 			goto dongle_rom_out;
3594 		}
3595 	}
3596 
3597 	/*
3598 	 * Enable/Disable built-in roaming to allow supplicant
3599 	 * to take care of roaming
3600 	 */
3601 	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3602 	roamvar_le = cpu_to_le32(roamvar);
3603 	brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3604 				sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3605 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3606 	if (err) {
3607 		WL_ERR("roam_off error (%d)\n", err);
3608 		goto dongle_rom_out;
3609 	}
3610 
3611 	roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3612 	roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3613 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3614 			(void *)roamtrigger, sizeof(roamtrigger));
3615 	if (err) {
3616 		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3617 		goto dongle_rom_out;
3618 	}
3619 
3620 	roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3621 	roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3622 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3623 				(void *)roam_delta, sizeof(roam_delta));
3624 	if (err) {
3625 		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3626 		goto dongle_rom_out;
3627 	}
3628 
3629 dongle_rom_out:
3630 	return err;
3631 }
3632 
3633 static s32
brcmf_dongle_scantime(struct net_device * ndev,s32 scan_assoc_time,s32 scan_unassoc_time,s32 scan_passive_time)3634 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3635 		      s32 scan_unassoc_time, s32 scan_passive_time)
3636 {
3637 	s32 err = 0;
3638 	__le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3639 	__le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3640 	__le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3641 
3642 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3643 			   &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3644 	if (err) {
3645 		if (err == -EOPNOTSUPP)
3646 			WL_INFO("Scan assoc time is not supported\n");
3647 		else
3648 			WL_ERR("Scan assoc time error (%d)\n", err);
3649 		goto dongle_scantime_out;
3650 	}
3651 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3652 			   &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3653 	if (err) {
3654 		if (err == -EOPNOTSUPP)
3655 			WL_INFO("Scan unassoc time is not supported\n");
3656 		else
3657 			WL_ERR("Scan unassoc time error (%d)\n", err);
3658 		goto dongle_scantime_out;
3659 	}
3660 
3661 	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3662 			   &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3663 	if (err) {
3664 		if (err == -EOPNOTSUPP)
3665 			WL_INFO("Scan passive time is not supported\n");
3666 		else
3667 			WL_ERR("Scan passive time error (%d)\n", err);
3668 		goto dongle_scantime_out;
3669 	}
3670 
3671 dongle_scantime_out:
3672 	return err;
3673 }
3674 
wl_update_wiphybands(struct brcmf_cfg80211_priv * cfg_priv)3675 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3676 {
3677 	struct wiphy *wiphy;
3678 	s32 phy_list;
3679 	s8 phy;
3680 	s32 err = 0;
3681 
3682 	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3683 			      &phy_list, sizeof(phy_list));
3684 	if (err) {
3685 		WL_ERR("error (%d)\n", err);
3686 		return err;
3687 	}
3688 
3689 	phy = ((char *)&phy_list)[1];
3690 	WL_INFO("%c phy\n", phy);
3691 	if (phy == 'n' || phy == 'a') {
3692 		wiphy = cfg_to_wiphy(cfg_priv);
3693 		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3694 	}
3695 
3696 	return err;
3697 }
3698 
brcmf_dongle_probecap(struct brcmf_cfg80211_priv * cfg_priv)3699 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3700 {
3701 	return wl_update_wiphybands(cfg_priv);
3702 }
3703 
brcmf_config_dongle(struct brcmf_cfg80211_priv * cfg_priv)3704 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3705 {
3706 	struct net_device *ndev;
3707 	struct wireless_dev *wdev;
3708 	s32 power_mode;
3709 	s32 err = 0;
3710 
3711 	if (cfg_priv->dongle_up)
3712 		return err;
3713 
3714 	ndev = cfg_to_ndev(cfg_priv);
3715 	wdev = ndev->ieee80211_ptr;
3716 
3717 	brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3718 			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3719 
3720 	err = brcmf_dongle_eventmsg(ndev);
3721 	if (err)
3722 		goto default_conf_out;
3723 
3724 	power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3725 	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3726 	if (err)
3727 		goto default_conf_out;
3728 	WL_INFO("power save set to %s\n",
3729 		(power_mode ? "enabled" : "disabled"));
3730 
3731 	err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3732 				WL_BEACON_TIMEOUT);
3733 	if (err)
3734 		goto default_conf_out;
3735 	err = brcmf_dongle_mode(ndev, wdev->iftype);
3736 	if (err && err != -EINPROGRESS)
3737 		goto default_conf_out;
3738 	err = brcmf_dongle_probecap(cfg_priv);
3739 	if (err)
3740 		goto default_conf_out;
3741 
3742 	/* -EINPROGRESS: Call commit handler */
3743 
3744 default_conf_out:
3745 
3746 	cfg_priv->dongle_up = true;
3747 
3748 	return err;
3749 
3750 }
3751 
brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv * cfg_priv)3752 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3753 {
3754 	char buf[10+IFNAMSIZ];
3755 	struct dentry *fd;
3756 	s32 err = 0;
3757 
3758 	sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3759 	cfg_priv->debugfsdir = debugfs_create_dir(buf,
3760 					cfg_to_wiphy(cfg_priv)->debugfsdir);
3761 
3762 	fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3763 		(u16 *)&cfg_priv->profile->beacon_interval);
3764 	if (!fd) {
3765 		err = -ENOMEM;
3766 		goto err_out;
3767 	}
3768 
3769 	fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3770 		(u8 *)&cfg_priv->profile->dtim_period);
3771 	if (!fd) {
3772 		err = -ENOMEM;
3773 		goto err_out;
3774 	}
3775 
3776 err_out:
3777 	return err;
3778 }
3779 
brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv * cfg_priv)3780 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3781 {
3782 	debugfs_remove_recursive(cfg_priv->debugfsdir);
3783 	cfg_priv->debugfsdir = NULL;
3784 }
3785 
__brcmf_cfg80211_up(struct brcmf_cfg80211_priv * cfg_priv)3786 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3787 {
3788 	s32 err = 0;
3789 
3790 	set_bit(WL_STATUS_READY, &cfg_priv->status);
3791 
3792 	brcmf_debugfs_add_netdev_params(cfg_priv);
3793 
3794 	err = brcmf_config_dongle(cfg_priv);
3795 	if (err)
3796 		return err;
3797 
3798 	brcmf_invoke_iscan(cfg_priv);
3799 
3800 	return err;
3801 }
3802 
__brcmf_cfg80211_down(struct brcmf_cfg80211_priv * cfg_priv)3803 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3804 {
3805 	/*
3806 	 * While going down, if associated with AP disassociate
3807 	 * from AP to save power
3808 	 */
3809 	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3810 	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3811 	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3812 		WL_INFO("Disassociating from AP");
3813 		brcmf_link_down(cfg_priv);
3814 
3815 		/* Make sure WPA_Supplicant receives all the event
3816 		   generated due to DISASSOC call to the fw to keep
3817 		   the state fw and WPA_Supplicant state consistent
3818 		 */
3819 		brcmf_delay(500);
3820 	}
3821 
3822 	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3823 	brcmf_term_iscan(cfg_priv);
3824 	if (cfg_priv->scan_request) {
3825 		cfg80211_scan_done(cfg_priv->scan_request, true);
3826 		/* May need to perform this to cover rmmod */
3827 		/* wl_set_mpc(cfg_to_ndev(wl), 1); */
3828 		cfg_priv->scan_request = NULL;
3829 	}
3830 	clear_bit(WL_STATUS_READY, &cfg_priv->status);
3831 	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3832 	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3833 
3834 	brcmf_debugfs_remove_netdev(cfg_priv);
3835 
3836 	return 0;
3837 }
3838 
brcmf_cfg80211_up(struct brcmf_cfg80211_dev * cfg_dev)3839 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3840 {
3841 	struct brcmf_cfg80211_priv *cfg_priv;
3842 	s32 err = 0;
3843 
3844 	cfg_priv = brcmf_priv_get(cfg_dev);
3845 	mutex_lock(&cfg_priv->usr_sync);
3846 	err = __brcmf_cfg80211_up(cfg_priv);
3847 	mutex_unlock(&cfg_priv->usr_sync);
3848 
3849 	return err;
3850 }
3851 
brcmf_cfg80211_down(struct brcmf_cfg80211_dev * cfg_dev)3852 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3853 {
3854 	struct brcmf_cfg80211_priv *cfg_priv;
3855 	s32 err = 0;
3856 
3857 	cfg_priv = brcmf_priv_get(cfg_dev);
3858 	mutex_lock(&cfg_priv->usr_sync);
3859 	err = __brcmf_cfg80211_down(cfg_priv);
3860 	mutex_unlock(&cfg_priv->usr_sync);
3861 
3862 	return err;
3863 }
3864 
brcmf_add_ie(struct brcmf_cfg80211_priv * cfg_priv,u8 t,u8 l,u8 * v)3865 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3866 			       u8 t, u8 l, u8 *v)
3867 {
3868 	struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3869 	s32 err = 0;
3870 
3871 	if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3872 		WL_ERR("ei crosses buffer boundary\n");
3873 		return -ENOSPC;
3874 	}
3875 	ie->buf[ie->offset] = t;
3876 	ie->buf[ie->offset + 1] = l;
3877 	memcpy(&ie->buf[ie->offset + 2], v, l);
3878 	ie->offset += l + 2;
3879 
3880 	return err;
3881 }
3882