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