xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8822cs/os_dep/linux/ioctl_cfg80211.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define  _IOCTL_CFG80211_C_
16 
17 #include <drv_types.h>
18 #include <hal_data.h>
19 
20 #ifdef CONFIG_IOCTL_CFG80211
21 
22 #ifndef DBG_RTW_CFG80211_STA_PARAM
23 #define DBG_RTW_CFG80211_STA_PARAM 0
24 #endif
25 
26 #ifndef DBG_RTW_CFG80211_MESH_CONF
27 #define DBG_RTW_CFG80211_MESH_CONF 0
28 #endif
29 
30 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
31 #define STATION_INFO_INACTIVE_TIME	BIT(NL80211_STA_INFO_INACTIVE_TIME)
32 #define STATION_INFO_RX_BYTES		BIT(NL80211_STA_INFO_RX_BYTES)
33 #define STATION_INFO_TX_BYTES		BIT(NL80211_STA_INFO_TX_BYTES)
34 #define STATION_INFO_LLID			BIT(NL80211_STA_INFO_LLID)
35 #define STATION_INFO_PLID			BIT(NL80211_STA_INFO_PLID)
36 #define STATION_INFO_PLINK_STATE	BIT(NL80211_STA_INFO_PLINK_STATE)
37 #define STATION_INFO_SIGNAL			BIT(NL80211_STA_INFO_SIGNAL)
38 #define STATION_INFO_TX_BITRATE		BIT(NL80211_STA_INFO_TX_BITRATE)
39 #define STATION_INFO_RX_PACKETS		BIT(NL80211_STA_INFO_RX_PACKETS)
40 #define STATION_INFO_TX_PACKETS		BIT(NL80211_STA_INFO_TX_PACKETS)
41 #define STATION_INFO_TX_RETRIES		BIT(NL80211_STA_INFO_TX_RETRIES)
42 #define STATION_INFO_TX_FAILED		BIT(NL80211_STA_INFO_TX_FAILED)
43 #define STATION_INFO_RX_BITRATE		BIT(NL80211_STA_INFO_RX_BITRATE)
44 #define STATION_INFO_LOCAL_PM		BIT(NL80211_STA_INFO_LOCAL_PM)
45 #define STATION_INFO_PEER_PM		BIT(NL80211_STA_INFO_PEER_PM)
46 #define STATION_INFO_NONPEER_PM		BIT(NL80211_STA_INFO_NONPEER_PM)
47 #define STATION_INFO_RX_BYTES64		BIT(NL80211_STA_INFO_RX_BYTES64)
48 #define STATION_INFO_TX_BYTES64		BIT(NL80211_STA_INFO_TX_BYTES64)
49 #define STATION_INFO_ASSOC_REQ_IES	0
50 #endif /* Linux kernel >= 4.0.0 */
51 
52 #define RTW_MAX_MGMT_TX_CNT (8)
53 #define RTW_MAX_MGMT_TX_MS_GAS (500)
54 
55 #define RTW_SCAN_IE_LEN_MAX      2304
56 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 /* ms */
57 #define RTW_MAX_NUM_PMKIDS 4
58 
59 #define RTW_CH_MAX_2G_CHANNEL               14      /* Max channel in 2G band */
60 
61 #ifdef CONFIG_WAPI_SUPPORT
62 
63 #ifndef WLAN_CIPHER_SUITE_SMS4
64 #define WLAN_CIPHER_SUITE_SMS4          0x00147201
65 #endif
66 
67 #ifndef WLAN_AKM_SUITE_WAPI_PSK
68 #define WLAN_AKM_SUITE_WAPI_PSK         0x000FAC04
69 #endif
70 
71 #ifndef WLAN_AKM_SUITE_WAPI_CERT
72 #define WLAN_AKM_SUITE_WAPI_CERT        0x000FAC12
73 #endif
74 
75 #ifndef NL80211_WAPI_VERSION_1
76 #define NL80211_WAPI_VERSION_1          (1 << 2)
77 #endif
78 
79 #endif /* CONFIG_WAPI_SUPPORT */
80 
81 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 12))
82 #ifdef CONFIG_RTW_80211R
83 #define WLAN_AKM_SUITE_FT_8021X		0x000FAC03
84 #define WLAN_AKM_SUITE_FT_PSK		0x000FAC04
85 #define WLAN_AKM_SUITE_FT_OVER_SAE	0x000FAC09
86 #define WLAN_AKM_SUITE_FT_FILS_SHA256	0x000FAC16
87 #endif
88 #endif
89 
90 #define WIFI_CIPHER_SUITE_GCMP		0x000FAC08
91 #define WIFI_CIPHER_SUITE_GCMP_256	0x000FAC09
92 #define WIFI_CIPHER_SUITE_CCMP_256	0x000FAC0A
93 #define WIFI_CIPHER_SUITE_BIP_GMAC_128	0x000FAC0B
94 #define WIFI_CIPHER_SUITE_BIP_GMAC_256	0x000FAC0C
95 #define WIFI_CIPHER_SUITE_BIP_CMAC_256	0x000FAC0D
96 
97 /*
98  * If customer need, defining this flag will make driver
99  * always return -EBUSY at the condition of scan deny.
100  */
101 /* #define CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY */
102 
103 static const u32 rtw_cipher_suites[] = {
104 	WLAN_CIPHER_SUITE_WEP40,
105 	WLAN_CIPHER_SUITE_WEP104,
106 	WLAN_CIPHER_SUITE_TKIP,
107 	WLAN_CIPHER_SUITE_CCMP,
108 #ifdef CONFIG_WAPI_SUPPORT
109 	WLAN_CIPHER_SUITE_SMS4,
110 #endif /* CONFIG_WAPI_SUPPORT */
111 #ifdef CONFIG_IEEE80211W
112 	WLAN_CIPHER_SUITE_AES_CMAC,
113 	WIFI_CIPHER_SUITE_GCMP,
114 	WIFI_CIPHER_SUITE_GCMP_256,
115 	WIFI_CIPHER_SUITE_CCMP_256,
116 	WIFI_CIPHER_SUITE_BIP_GMAC_128,
117 	WIFI_CIPHER_SUITE_BIP_GMAC_256,
118 	WIFI_CIPHER_SUITE_BIP_CMAC_256,
119 #endif /* CONFIG_IEEE80211W */
120 };
121 
122 #define RATETAB_ENT(_rate, _rateid, _flags) \
123 	{								\
124 		.bitrate	= (_rate),				\
125 		.hw_value	= (_rateid),				\
126 		.flags		= (_flags),				\
127 	}
128 
129 #define CHAN2G(_channel, _freq, _flags) {			\
130 		.band			= NL80211_BAND_2GHZ,		\
131 		.center_freq		= (_freq),			\
132 		.hw_value		= (_channel),			\
133 		.flags			= (_flags),			\
134 		.max_antenna_gain	= 0,				\
135 		.max_power		= 0,				\
136 	}
137 
138 #define CHAN5G(_channel, _flags) {				\
139 		.band			= NL80211_BAND_5GHZ,		\
140 		.center_freq		= 5000 + (5 * (_channel)),	\
141 		.hw_value		= (_channel),			\
142 		.flags			= (_flags),			\
143 		.max_antenna_gain	= 0,				\
144 		.max_power		= 0,				\
145 	}
146 
147 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
148 /* if wowlan is not supported, kernel generate a disconnect at each suspend
149  * cf: /net/wireless/sysfs.c, so register a stub wowlan.
150  * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
151  * (from user space, e.g. iw phy0 wowlan enable)
152  */
153 static const struct wiphy_wowlan_support wowlan_stub = {
154 	.flags = WIPHY_WOWLAN_ANY,
155 	.n_patterns = 0,
156 	.pattern_max_len = 0,
157 	.pattern_min_len = 0,
158 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
159 	.max_pkt_offset = 0,
160 #endif
161 };
162 #endif
163 
164 static struct ieee80211_rate rtw_rates[] = {
165 	RATETAB_ENT(10,  0x1,   0),
166 	RATETAB_ENT(20,  0x2,   0),
167 	RATETAB_ENT(55,  0x4,   0),
168 	RATETAB_ENT(110, 0x8,   0),
169 	RATETAB_ENT(60,  0x10,  0),
170 	RATETAB_ENT(90,  0x20,  0),
171 	RATETAB_ENT(120, 0x40,  0),
172 	RATETAB_ENT(180, 0x80,  0),
173 	RATETAB_ENT(240, 0x100, 0),
174 	RATETAB_ENT(360, 0x200, 0),
175 	RATETAB_ENT(480, 0x400, 0),
176 	RATETAB_ENT(540, 0x800, 0),
177 };
178 
179 #define rtw_a_rates		(rtw_rates + 4)
180 #define RTW_A_RATES_NUM	8
181 #define rtw_g_rates		(rtw_rates + 0)
182 #define RTW_G_RATES_NUM	12
183 
184 /* from center_ch_2g */
185 static struct ieee80211_channel rtw_2ghz_channels[MAX_CHANNEL_NUM_2G] = {
186 	CHAN2G(1, 2412, 0),
187 	CHAN2G(2, 2417, 0),
188 	CHAN2G(3, 2422, 0),
189 	CHAN2G(4, 2427, 0),
190 	CHAN2G(5, 2432, 0),
191 	CHAN2G(6, 2437, 0),
192 	CHAN2G(7, 2442, 0),
193 	CHAN2G(8, 2447, 0),
194 	CHAN2G(9, 2452, 0),
195 	CHAN2G(10, 2457, 0),
196 	CHAN2G(11, 2462, 0),
197 	CHAN2G(12, 2467, 0),
198 	CHAN2G(13, 2472, 0),
199 	CHAN2G(14, 2484, 0),
200 };
201 
202 /* from center_ch_5g_20m */
203 static struct ieee80211_channel rtw_5ghz_a_channels[MAX_CHANNEL_NUM_5G] = {
204 	CHAN5G(36, 0),	CHAN5G(40, 0),	CHAN5G(44, 0),	CHAN5G(48, 0),
205 
206 	CHAN5G(52, 0),	CHAN5G(56, 0),	CHAN5G(60, 0),	CHAN5G(64, 0),
207 
208 	CHAN5G(100, 0),	CHAN5G(104, 0),	CHAN5G(108, 0),	CHAN5G(112, 0),
209 	CHAN5G(116, 0),	CHAN5G(120, 0),	CHAN5G(124, 0),	CHAN5G(128, 0),
210 	CHAN5G(132, 0),	CHAN5G(136, 0),	CHAN5G(140, 0),	CHAN5G(144, 0),
211 
212 	CHAN5G(149, 0),	CHAN5G(153, 0),	CHAN5G(157, 0),	CHAN5G(161, 0),
213 	CHAN5G(165, 0),	CHAN5G(169, 0),	CHAN5G(173, 0),	CHAN5G(177, 0),
214 };
215 
216 enum nl80211_band _rtw_band_to_nl80211_band[] = {
217 	[BAND_ON_2_4G] =	NL80211_BAND_2GHZ,
218 	[BAND_ON_5G] =		NL80211_BAND_5GHZ,
219 #if CONFIG_IEEE80211_BAND_6GHZ
220 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
221 	[BAND_ON_6G] =		NL80211_BAND_6GHZ,
222 	#else
223 	[BAND_ON_6G] =		NUM_NL80211_BANDS,
224 	#endif
225 #endif
226 };
227 
228 BAND_TYPE _nl80211_band_to_rtw_band[] = {
229 	[NL80211_BAND_2GHZ] =	BAND_ON_2_4G,
230 	[NL80211_BAND_5GHZ] =	BAND_ON_5G,
231 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
232 	[NL80211_BAND_60GHZ] = BAND_MAX,
233 #endif
234 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
235 	#if CONFIG_IEEE80211_BAND_6GHZ
236 	[NL80211_BAND_6GHZ] =	BAND_ON_6G,
237 	#else
238 	[NL80211_BAND_6GHZ] =	BAND_MAX,
239 	#endif
240 #endif
241 };
242 
243 
244 static int rtw_cfg80211_set_assocresp_ies(struct net_device *net, const u8 *buf, int len);
245 
246 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
rtw_chbw_to_cfg80211_chan_def(struct wiphy * wiphy,struct cfg80211_chan_def * chdef,u8 ch,u8 bw,u8 offset,u8 ht)247 static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_chan_def *chdef, u8 ch, u8 bw, u8 offset, u8 ht)
248 {
249 	int freq, cfreq;
250 	struct ieee80211_channel *chan;
251 	u8 ret = _FAIL;
252 
253 	_rtw_memset(chdef, 0, sizeof(*chdef));
254 
255 	freq = rtw_ch2freq(ch);
256 	if (!freq)
257 		goto exit;
258 
259 	cfreq = rtw_get_center_ch(ch, bw, offset);
260 	if (!cfreq)
261 		goto exit;
262 	cfreq = rtw_ch2freq(cfreq);
263 	if (!cfreq)
264 		goto exit;
265 
266 	chan = ieee80211_get_channel(wiphy, freq);
267 	if (!chan)
268 		goto exit;
269 
270 	if (bw == CHANNEL_WIDTH_20)
271 		chdef->width = ht ? NL80211_CHAN_WIDTH_20 : NL80211_CHAN_WIDTH_20_NOHT;
272 	else if (bw == CHANNEL_WIDTH_40)
273 		chdef->width = NL80211_CHAN_WIDTH_40;
274 	else if (bw == CHANNEL_WIDTH_80)
275 		chdef->width = NL80211_CHAN_WIDTH_80;
276 	else if (bw == CHANNEL_WIDTH_160)
277 		chdef->width = NL80211_CHAN_WIDTH_160;
278 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
279 	else if (bw == CHANNEL_WIDTH_5)
280 		chdef->width = NL80211_CHAN_WIDTH_5;
281 	else if (bw == CHANNEL_WIDTH_10)
282 		chdef->width = NL80211_CHAN_WIDTH_10;
283 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */
284 	else {
285 		rtw_warn_on(1);
286 		goto exit;
287 	}
288 
289 	chdef->chan = chan;
290 	chdef->center_freq1 = cfreq;
291 
292 	ret = _SUCCESS;
293 
294 exit:
295 	return ret;
296 }
297 
nl80211_chan_width_str(enum nl80211_chan_width cwidth)298 static const char *nl80211_chan_width_str(enum nl80211_chan_width cwidth)
299 {
300 	switch (cwidth) {
301 	case NL80211_CHAN_WIDTH_20_NOHT:
302 		return "20_NOHT";
303 	case NL80211_CHAN_WIDTH_20:
304 		return "20";
305 	case NL80211_CHAN_WIDTH_40:
306 		return "40";
307 	case NL80211_CHAN_WIDTH_80:
308 		return "80";
309 	case NL80211_CHAN_WIDTH_80P80:
310 		return "80+80";
311 	case NL80211_CHAN_WIDTH_160:
312 		return "160";
313 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
314 	case NL80211_CHAN_WIDTH_5:
315 		return "5";
316 	case NL80211_CHAN_WIDTH_10:
317 		return "10";
318 #endif
319 	default:
320 		return "INVALID";
321 	};
322 }
323 
rtw_get_chbw_from_cfg80211_chan_def(struct cfg80211_chan_def * chdef,u8 * ht,u8 * ch,u8 * bw,u8 * offset)324 static void rtw_get_chbw_from_cfg80211_chan_def(struct cfg80211_chan_def *chdef, u8 *ht, u8 *ch, u8 *bw, u8 *offset)
325 {
326 	int pri_freq;
327 	struct ieee80211_channel *chan = chdef->chan;
328 
329 	pri_freq = rtw_ch2freq(chan->hw_value);
330 	if (!pri_freq) {
331 		RTW_INFO("invalid channel:%d\n", chan->hw_value);
332 		rtw_warn_on(1);
333 		*ch = 0;
334 		return;
335 	}
336 
337 	switch (chdef->width) {
338 	case NL80211_CHAN_WIDTH_20_NOHT:
339 		*ht = 0;
340 		*bw = CHANNEL_WIDTH_20;
341 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
342 		*ch = chan->hw_value;
343 		break;
344 	case NL80211_CHAN_WIDTH_20:
345 		*ht = 1;
346 		*bw = CHANNEL_WIDTH_20;
347 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
348 		*ch = chan->hw_value;
349 		break;
350 	case NL80211_CHAN_WIDTH_40:
351 		*ht = 1;
352 		*bw = CHANNEL_WIDTH_40;
353 		*offset = pri_freq > chdef->center_freq1 ? HAL_PRIME_CHNL_OFFSET_UPPER : HAL_PRIME_CHNL_OFFSET_LOWER;
354 		if (rtw_get_offset_by_chbw(chan->hw_value, *bw, offset))
355 			*ch = chan->hw_value;
356 		break;
357 	case NL80211_CHAN_WIDTH_80:
358 		*ht = 1;
359 		*bw = CHANNEL_WIDTH_80;
360 		if (rtw_get_offset_by_chbw(chan->hw_value, *bw, offset))
361 			*ch = chan->hw_value;
362 		break;
363 	case NL80211_CHAN_WIDTH_160:
364 		*ht = 1;
365 		*bw = CHANNEL_WIDTH_160;
366 		if (rtw_get_offset_by_chbw(chan->hw_value, *bw, offset))
367 			*ch = chan->hw_value;
368 		break;
369 	case NL80211_CHAN_WIDTH_80P80:
370 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
371 	case NL80211_CHAN_WIDTH_5:
372 	case NL80211_CHAN_WIDTH_10:
373 	#endif
374 	default:
375 		*ht = 0;
376 		*bw = CHANNEL_WIDTH_20;
377 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
378 		RTW_INFO("unsupported cwidth:%s\n", nl80211_chan_width_str(chdef->width));
379 		rtw_warn_on(1);
380 	};
381 }
382 
383 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
nl80211_channel_type_str(enum nl80211_channel_type ctype)384 static const char *nl80211_channel_type_str(enum nl80211_channel_type ctype)
385 {
386 	switch (ctype) {
387 	case NL80211_CHAN_NO_HT:
388 		return "NO_HT";
389 	case NL80211_CHAN_HT20:
390 		return "HT20";
391 	case NL80211_CHAN_HT40MINUS:
392 		return "HT40-";
393 	case NL80211_CHAN_HT40PLUS:
394 		return "HT40+";
395 	default:
396 		return "INVALID";
397 	};
398 }
399 
rtw_chbw_to_nl80211_channel_type(u8 ch,u8 bw,u8 offset,u8 ht)400 static enum nl80211_channel_type rtw_chbw_to_nl80211_channel_type(u8 ch, u8 bw, u8 offset, u8 ht)
401 {
402 	rtw_warn_on(!ht && (bw >= CHANNEL_WIDTH_40 || offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE));
403 
404 	if (!ht)
405 		return NL80211_CHAN_NO_HT;
406 	if (bw >= CHANNEL_WIDTH_40) {
407 		if (offset == HAL_PRIME_CHNL_OFFSET_UPPER)
408 			return NL80211_CHAN_HT40MINUS;
409 		else if (offset == HAL_PRIME_CHNL_OFFSET_LOWER)
410 			return NL80211_CHAN_HT40PLUS;
411 		else
412 			rtw_warn_on(1);
413 	}
414 	return NL80211_CHAN_HT20;
415 }
416 
rtw_get_chbw_from_nl80211_channel_type(struct ieee80211_channel * chan,enum nl80211_channel_type ctype,u8 * ht,u8 * ch,u8 * bw,u8 * offset)417 static void rtw_get_chbw_from_nl80211_channel_type(struct ieee80211_channel *chan, enum nl80211_channel_type ctype, u8 *ht, u8 *ch, u8 *bw, u8 *offset)
418 {
419 	int pri_freq;
420 
421 	pri_freq = rtw_ch2freq(chan->hw_value);
422 	if (!pri_freq) {
423 		RTW_INFO("invalid channel:%d\n", chan->hw_value);
424 		rtw_warn_on(1);
425 		*ch = 0;
426 		return;
427 	}
428 	*ch = chan->hw_value;
429 
430 	switch (ctype) {
431 	case NL80211_CHAN_NO_HT:
432 		*ht = 0;
433 		*bw = CHANNEL_WIDTH_20;
434 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
435 		break;
436 	case NL80211_CHAN_HT20:
437 		*ht = 1;
438 		*bw = CHANNEL_WIDTH_20;
439 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
440 		break;
441 	case NL80211_CHAN_HT40MINUS:
442 		*ht = 1;
443 		*bw = CHANNEL_WIDTH_40;
444 		*offset = HAL_PRIME_CHNL_OFFSET_UPPER;
445 		break;
446 	case NL80211_CHAN_HT40PLUS:
447 		*ht = 1;
448 		*bw = CHANNEL_WIDTH_40;
449 		*offset = HAL_PRIME_CHNL_OFFSET_LOWER;
450 		break;
451 	default:
452 		*ht = 0;
453 		*bw = CHANNEL_WIDTH_20;
454 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
455 		RTW_INFO("unsupported ctype:%s\n", nl80211_channel_type_str(ctype));
456 		rtw_warn_on(1);
457 	};
458 }
459 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) */
460 
461 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
rtw_cfg80211_allow_ch_switch_notify(_adapter * adapter)462 bool rtw_cfg80211_allow_ch_switch_notify(_adapter *adapter)
463 {
464 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
465 	if ((!MLME_IS_AP(adapter))
466 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
467 		&& (!MLME_IS_ADHOC(adapter))
468 		&& (!MLME_IS_ADHOC_MASTER(adapter))
469 		&& (!MLME_IS_MESH(adapter))
470 #elif defined(CONFIG_RTW_MESH)
471 		&& (!MLME_IS_MESH(adapter))
472 #endif
473 		)
474 		return 0;
475 #endif
476 	return 1;
477 }
478 
rtw_cfg80211_ch_switch_notify(_adapter * adapter,u8 ch,u8 bw,u8 offset,u8 ht,bool started)479 u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset,
480 	u8 ht, bool started)
481 {
482 	struct wiphy *wiphy = adapter_to_wiphy(adapter);
483 	u8 ret = _SUCCESS;
484 
485 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
486 	struct cfg80211_chan_def chdef;
487 
488 	ret = rtw_chbw_to_cfg80211_chan_def(wiphy, &chdef, ch, bw, offset, ht);
489 	if (ret != _SUCCESS)
490 		goto exit;
491 
492 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
493 	if (started) {
494 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0))
495 
496 		/* --- cfg80211_ch_switch_started_notfiy() ---
497 		 *  A new parameter, bool quiet, is added from Linux kernel v5.11,
498 		 *  to see if block-tx was requested by the AP. since currently,
499 		 *  the API is used for station before connected in rtw_chk_start_clnt_join()
500 		 *  the quiet is set to false here first. May need to refine it if
501 		 *  called by others with block-tx.
502 		 */
503 
504 		cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, false);
505 #else
506 		cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0);
507 #endif
508 		goto exit;
509 	}
510 #endif
511 
512 	if (!rtw_cfg80211_allow_ch_switch_notify(adapter))
513 		goto exit;
514 
515 	cfg80211_ch_switch_notify(adapter->pnetdev, &chdef);
516 
517 #else
518 	int freq = rtw_ch2freq(ch);
519 	enum nl80211_channel_type ctype;
520 
521 	if (!rtw_cfg80211_allow_ch_switch_notify(adapter))
522 		goto exit;
523 
524 	if (!freq) {
525 		ret = _FAIL;
526 		goto exit;
527 	}
528 
529 	ctype = rtw_chbw_to_nl80211_channel_type(ch, bw, offset, ht);
530 	cfg80211_ch_switch_notify(adapter->pnetdev, freq, ctype);
531 #endif
532 
533 exit:
534 	return ret;
535 }
536 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */
537 
rtw_2g_channels_init(struct ieee80211_channel * channels)538 void rtw_2g_channels_init(struct ieee80211_channel *channels)
539 {
540 	_rtw_memcpy((void *)channels, (void *)rtw_2ghz_channels, sizeof(rtw_2ghz_channels));
541 }
542 
rtw_5g_channels_init(struct ieee80211_channel * channels)543 void rtw_5g_channels_init(struct ieee80211_channel *channels)
544 {
545 	_rtw_memcpy((void *)channels, (void *)rtw_5ghz_a_channels, sizeof(rtw_5ghz_a_channels));
546 }
547 
rtw_2g_rates_init(struct ieee80211_rate * rates)548 void rtw_2g_rates_init(struct ieee80211_rate *rates)
549 {
550 	_rtw_memcpy(rates, rtw_g_rates,
551 		sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM
552 	);
553 }
554 
rtw_5g_rates_init(struct ieee80211_rate * rates)555 void rtw_5g_rates_init(struct ieee80211_rate *rates)
556 {
557 	_rtw_memcpy(rates, rtw_a_rates,
558 		sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM
559 	);
560 }
561 
rtw_spt_band_alloc(BAND_TYPE band)562 struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band)
563 {
564 	struct ieee80211_supported_band *spt_band = NULL;
565 	int n_channels, n_bitrates;
566 
567 	if (rtw_band_to_nl80211_band(band) == NUM_NL80211_BANDS)
568 		goto exit;
569 
570 	if (band == BAND_ON_2_4G) {
571 		n_channels = MAX_CHANNEL_NUM_2G;
572 		n_bitrates = RTW_G_RATES_NUM;
573 	} else if (band == BAND_ON_5G) {
574 		n_channels = MAX_CHANNEL_NUM_5G;
575 		n_bitrates = RTW_A_RATES_NUM;
576 	} else
577 		goto exit;
578 
579 	spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
580 		sizeof(struct ieee80211_supported_band)
581 		+ sizeof(struct ieee80211_channel) * n_channels
582 		+ sizeof(struct ieee80211_rate) * n_bitrates
583 	);
584 	if (!spt_band)
585 		goto exit;
586 
587 	spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band) + sizeof(struct ieee80211_supported_band));
588 	spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels) + sizeof(struct ieee80211_channel) * n_channels);
589 	spt_band->band = rtw_band_to_nl80211_band(band);
590 	spt_band->n_channels = n_channels;
591 	spt_band->n_bitrates = n_bitrates;
592 
593 exit:
594 	return spt_band;
595 }
596 
rtw_spt_band_free(struct ieee80211_supported_band * spt_band)597 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
598 {
599 	u32 size = 0;
600 
601 	if (!spt_band)
602 		return;
603 
604 	if (spt_band->band == NL80211_BAND_2GHZ) {
605 		size = sizeof(struct ieee80211_supported_band)
606 			+ sizeof(struct ieee80211_channel) * MAX_CHANNEL_NUM_2G
607 			+ sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM;
608 	} else if (spt_band->band == NL80211_BAND_5GHZ) {
609 		size = sizeof(struct ieee80211_supported_band)
610 			+ sizeof(struct ieee80211_channel) * MAX_CHANNEL_NUM_5G
611 			+ sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM;
612 	} else {
613 
614 	}
615 	rtw_mfree((u8 *)spt_band, size);
616 }
617 
618 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
619 static const struct ieee80211_txrx_stypes
620 	rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
621 	[NL80211_IFTYPE_ADHOC] = {
622 		.tx = 0xffff,
623 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
624 	},
625 	[NL80211_IFTYPE_STATION] = {
626 		.tx = 0xffff,
627 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
628 		BIT(IEEE80211_STYPE_AUTH >> 4) |
629 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
630 	},
631 	[NL80211_IFTYPE_AP] = {
632 		.tx = 0xffff,
633 		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
634 		BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
635 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
636 		BIT(IEEE80211_STYPE_DISASSOC >> 4) |
637 		BIT(IEEE80211_STYPE_AUTH >> 4) |
638 		BIT(IEEE80211_STYPE_DEAUTH >> 4) |
639 		BIT(IEEE80211_STYPE_ACTION >> 4)
640 	},
641 	[NL80211_IFTYPE_AP_VLAN] = {
642 		/* copy AP */
643 		.tx = 0xffff,
644 		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
645 		BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
646 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
647 		BIT(IEEE80211_STYPE_DISASSOC >> 4) |
648 		BIT(IEEE80211_STYPE_AUTH >> 4) |
649 		BIT(IEEE80211_STYPE_DEAUTH >> 4) |
650 		BIT(IEEE80211_STYPE_ACTION >> 4)
651 	},
652 	[NL80211_IFTYPE_P2P_CLIENT] = {
653 		.tx = 0xffff,
654 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
655 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
656 	},
657 	[NL80211_IFTYPE_P2P_GO] = {
658 		.tx = 0xffff,
659 		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
660 		BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
661 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
662 		BIT(IEEE80211_STYPE_DISASSOC >> 4) |
663 		BIT(IEEE80211_STYPE_AUTH >> 4) |
664 		BIT(IEEE80211_STYPE_DEAUTH >> 4) |
665 		BIT(IEEE80211_STYPE_ACTION >> 4)
666 	},
667 #if defined(RTW_DEDICATED_P2P_DEVICE)
668 	[NL80211_IFTYPE_P2P_DEVICE] = {
669 		.tx = 0xffff,
670 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
671 			BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
672 	},
673 #endif
674 #if defined(CONFIG_RTW_MESH)
675 	[NL80211_IFTYPE_MESH_POINT] = {
676 		.tx = 0xffff,
677 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
678 			| BIT(IEEE80211_STYPE_AUTH >> 4)
679 	},
680 #endif
681 
682 };
683 #endif
684 
nl80211_iftype_to_rtw_network_type(enum nl80211_iftype type)685 NDIS_802_11_NETWORK_INFRASTRUCTURE nl80211_iftype_to_rtw_network_type(enum nl80211_iftype type)
686 {
687 	switch (type) {
688 	case NL80211_IFTYPE_ADHOC:
689 		return Ndis802_11IBSS;
690 
691 	#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
692 	case NL80211_IFTYPE_P2P_CLIENT:
693 	#endif
694 	case NL80211_IFTYPE_STATION:
695 		return Ndis802_11Infrastructure;
696 
697 #ifdef CONFIG_AP_MODE
698 	#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
699 	case NL80211_IFTYPE_P2P_GO:
700 	#endif
701 	case NL80211_IFTYPE_AP:
702 		return Ndis802_11APMode;
703 #endif
704 
705 #ifdef CONFIG_RTW_MESH
706 	case NL80211_IFTYPE_MESH_POINT:
707 		return Ndis802_11_mesh;
708 #endif
709 
710 #ifdef CONFIG_WIFI_MONITOR
711 	case NL80211_IFTYPE_MONITOR:
712 		return Ndis802_11Monitor;
713 #endif /* CONFIG_WIFI_MONITOR */
714 
715 	default:
716 		return Ndis802_11InfrastructureMax;
717 	}
718 }
719 
nl80211_iftype_to_rtw_mlme_state(enum nl80211_iftype type)720 u32 nl80211_iftype_to_rtw_mlme_state(enum nl80211_iftype type)
721 {
722 	switch (type) {
723 	case NL80211_IFTYPE_ADHOC:
724 		return WIFI_ADHOC_STATE;
725 
726 	#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
727 	case NL80211_IFTYPE_P2P_CLIENT:
728 	#endif
729 	case NL80211_IFTYPE_STATION:
730 		return WIFI_STATION_STATE;
731 
732 #ifdef CONFIG_AP_MODE
733 	#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
734 	case NL80211_IFTYPE_P2P_GO:
735 	#endif
736 	case NL80211_IFTYPE_AP:
737 		return WIFI_AP_STATE;
738 #endif
739 
740 #ifdef CONFIG_RTW_MESH
741 	case NL80211_IFTYPE_MESH_POINT:
742 		return WIFI_MESH_STATE;
743 #endif
744 
745 	case NL80211_IFTYPE_MONITOR:
746 		return WIFI_MONITOR_STATE;
747 
748 	default:
749 		return WIFI_NULL_STATE;
750 	}
751 }
752 
rtw_cfg80211_sync_iftype(_adapter * adapter)753 static int rtw_cfg80211_sync_iftype(_adapter *adapter)
754 {
755 	struct wireless_dev *rtw_wdev = adapter->rtw_wdev;
756 
757 	if (!(nl80211_iftype_to_rtw_mlme_state(rtw_wdev->iftype) & MLME_STATE(adapter))) {
758 		/* iftype and mlme state is not syc */
759 		NDIS_802_11_NETWORK_INFRASTRUCTURE network_type;
760 
761 		network_type = nl80211_iftype_to_rtw_network_type(rtw_wdev->iftype);
762 		if (network_type != Ndis802_11InfrastructureMax) {
763 			if (rtw_pwr_wakeup(adapter) == _FAIL) {
764 				RTW_WARN(FUNC_ADPT_FMT" call rtw_pwr_wakeup fail\n", FUNC_ADPT_ARG(adapter));
765 				return _FAIL;
766 			}
767 
768 			rtw_set_802_11_infrastructure_mode(adapter, network_type, 0);
769 			rtw_setopmode_cmd(adapter, network_type, RTW_CMDF_WAIT_ACK);
770 		} else {
771 			rtw_warn_on(1);
772 			RTW_WARN(FUNC_ADPT_FMT" iftype:%u is not support\n", FUNC_ADPT_ARG(adapter), rtw_wdev->iftype);
773 			return _FAIL;
774 		}
775 	}
776 
777 	return _SUCCESS;
778 }
779 
rtw_get_systime_us(void)780 static u64 rtw_get_systime_us(void)
781 {
782 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0))
783 	return ktime_to_us(ktime_get_boottime());
784 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
785 	struct timespec ts;
786 	get_monotonic_boottime(&ts);
787 	return ((u64)ts.tv_sec * 1000000) + ts.tv_nsec / 1000;
788 #else
789 	struct timeval tv;
790 	do_gettimeofday(&tv);
791 	return ((u64)tv.tv_sec * 1000000) + tv.tv_usec;
792 #endif
793 }
794 
795 /* Try to remove non target BSS's SR to reduce PBC overlap rate */
rtw_cfg80211_clear_wps_sr_of_non_target_bss(_adapter * padapter,struct wlan_network * pnetwork,struct cfg80211_ssid * req_ssid)796 static int rtw_cfg80211_clear_wps_sr_of_non_target_bss(_adapter *padapter, struct wlan_network *pnetwork, struct cfg80211_ssid *req_ssid)
797 {
798 	int ret = 0;
799 	u8 *psr = NULL, sr = 0;
800 	NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
801 	u32 wpsielen = 0;
802 	u8 *wpsie = NULL;
803 
804 	if (pssid->SsidLength == req_ssid->ssid_len
805 		&& _rtw_memcmp(pssid->Ssid, req_ssid->ssid, req_ssid->ssid_len) == _TRUE)
806 		goto exit;
807 
808 	wpsie = rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_
809 		, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
810 	if (wpsie && wpsielen > 0)
811 		psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, &sr, NULL);
812 
813 	if (psr && sr) {
814 		if (0)
815 			RTW_INFO("clear sr of non target bss:%s("MAC_FMT")\n"
816 				, pssid->Ssid, MAC_ARG(pnetwork->network.MacAddress));
817 		*psr = 0; /* clear sr */
818 		ret = 1;
819 	}
820 
821 exit:
822 	return ret;
823 }
824 
825 #define MAX_BSSINFO_LEN 1000
rtw_cfg80211_inform_bss(_adapter * padapter,struct wlan_network * pnetwork)826 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
827 {
828 	struct ieee80211_channel *notify_channel;
829 	struct cfg80211_bss *bss = NULL;
830 	/* struct ieee80211_supported_band *band;       */
831 	u16 channel;
832 	u32 freq;
833 	u64 notify_timestamp;
834 	u16 notify_capability;
835 	u16 notify_interval;
836 	u8 *notify_ie;
837 	size_t notify_ielen;
838 	s32 notify_signal;
839 	/* u8 buf[MAX_BSSINFO_LEN]; */
840 
841 	u8 *pbuf;
842 	size_t buf_size = MAX_BSSINFO_LEN;
843 	size_t len, bssinf_len = 0;
844 	struct rtw_ieee80211_hdr *pwlanhdr;
845 	unsigned short *fctrl;
846 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
847 
848 	struct wireless_dev *wdev = padapter->rtw_wdev;
849 	struct wiphy *wiphy = wdev->wiphy;
850 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
851 
852 	pbuf = rtw_zmalloc(buf_size);
853 	if (pbuf == NULL) {
854 		RTW_INFO("%s pbuf allocate failed  !!\n", __FUNCTION__);
855 		return bss;
856 	}
857 
858 	/* RTW_INFO("%s\n", __func__); */
859 
860 	bssinf_len = pnetwork->network.IELength + sizeof(struct rtw_ieee80211_hdr_3addr);
861 	if (bssinf_len > buf_size) {
862 		RTW_INFO("%s IE Length too long > %zu byte\n", __FUNCTION__, buf_size);
863 		goto exit;
864 	}
865 
866 #ifndef CONFIG_WAPI_SUPPORT
867 	{
868 		u16 wapi_len = 0;
869 
870 		if (rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len) > 0) {
871 			if (wapi_len > 0) {
872 				RTW_INFO("%s, no support wapi!\n", __FUNCTION__);
873 				goto exit;
874 			}
875 		}
876 	}
877 #endif /* !CONFIG_WAPI_SUPPORT */
878 
879 	channel = pnetwork->network.Configuration.DSConfig;
880 	freq = rtw_ch2freq(channel);
881 	notify_channel = ieee80211_get_channel(wiphy, freq);
882 
883 	if (0)
884 		notify_timestamp = le64_to_cpu(*(u64 *)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
885 	else
886 		notify_timestamp = rtw_get_systime_us();
887 
888 	notify_interval = le16_to_cpu(*(u16 *)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
889 	notify_capability = le16_to_cpu(*(u16 *)rtw_get_capability_from_ie(pnetwork->network.IEs));
890 
891 	notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
892 	notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
893 
894 	/* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
895 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
896 		is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
897 		notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */
898 	} else {
899 		notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */
900 	}
901 
902 #if 0
903 	RTW_INFO("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
904 	RTW_INFO("Channel: %d(%d)\n", channel, freq);
905 	RTW_INFO("Capability: %X\n", notify_capability);
906 	RTW_INFO("Beacon interval: %d\n", notify_interval);
907 	RTW_INFO("Signal: %d\n", notify_signal);
908 	RTW_INFO("notify_timestamp: %llu\n", notify_timestamp);
909 #endif
910 
911 	/* pbuf = buf; */
912 
913 	pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
914 	fctrl = &(pwlanhdr->frame_ctl);
915 	*(fctrl) = 0;
916 
917 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
918 	/* pmlmeext->mgnt_seq++; */
919 
920 	if (pnetwork->network.Reserved[0] == BSS_TYPE_BCN) { /* WIFI_BEACON */
921 		_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
922 		set_frame_sub_type(pbuf, WIFI_BEACON);
923 	} else {
924 		_rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
925 		set_frame_sub_type(pbuf, WIFI_PROBERSP);
926 	}
927 
928 	_rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
929 	_rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
930 
931 
932 	/* pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); */
933 	len = sizeof(struct rtw_ieee80211_hdr_3addr);
934 	_rtw_memcpy((pbuf + len), pnetwork->network.IEs, pnetwork->network.IELength);
935 	*((u64 *)(pbuf + len)) = cpu_to_le64(notify_timestamp);
936 
937 	len += pnetwork->network.IELength;
938 
939 	#if defined(CONFIG_P2P) && 0
940 	if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
941 		RTW_INFO("%s, got p2p_ie\n", __func__);
942 	#endif
943 
944 #if 1
945 	bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf,
946 					len, notify_signal, GFP_ATOMIC);
947 #else
948 
949 	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
950 		notify_timestamp, notify_capability, notify_interval, notify_ie,
951 		notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
952 #endif
953 
954 	if (unlikely(!bss)) {
955 		RTW_INFO(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
956 		goto exit;
957 	}
958 
959 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38))
960 #ifndef COMPAT_KERNEL_RELEASE
961 	/* patch for cfg80211, update beacon ies to information_elements */
962 	if (pnetwork->network.Reserved[0] == BSS_TYPE_BCN) { /* WIFI_BEACON */
963 
964 		if (bss->len_information_elements != bss->len_beacon_ies) {
965 			bss->information_elements = bss->beacon_ies;
966 			bss->len_information_elements =  bss->len_beacon_ies;
967 		}
968 	}
969 #endif /* COMPAT_KERNEL_RELEASE */
970 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38) */
971 
972 #if 0
973 	{
974 		if (bss->information_elements == bss->proberesp_ies) {
975 			if (bss->len_information_elements !=  bss->len_proberesp_ies)
976 				RTW_INFO("error!, len_information_elements != bss->len_proberesp_ies\n");
977 		} else if (bss->len_information_elements <  bss->len_beacon_ies) {
978 			bss->information_elements = bss->beacon_ies;
979 			bss->len_information_elements =  bss->len_beacon_ies;
980 		}
981 	}
982 #endif
983 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
984 	cfg80211_put_bss(wiphy, bss);
985 #else
986 	cfg80211_put_bss(bss);
987 #endif
988 
989 exit:
990 	if (pbuf)
991 		rtw_mfree(pbuf, buf_size);
992 	return bss;
993 
994 }
995 
996 /*
997 	Check the given bss is valid by kernel API cfg80211_get_bss()
998 	@padapter : the given adapter
999 
1000 	return _TRUE if bss is valid,  _FALSE for not found.
1001 */
rtw_cfg80211_check_bss(_adapter * padapter)1002 int rtw_cfg80211_check_bss(_adapter *padapter)
1003 {
1004 	WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
1005 	struct cfg80211_bss *bss = NULL;
1006 	struct ieee80211_channel *notify_channel = NULL;
1007 	u32 freq;
1008 
1009 	if (!(pnetwork) || !(padapter->rtw_wdev))
1010 		return _FALSE;
1011 
1012 	freq = rtw_ch2freq(pnetwork->Configuration.DSConfig);
1013 	notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
1014 	bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
1015 			pnetwork->MacAddress, pnetwork->Ssid.Ssid,
1016 			pnetwork->Ssid.SsidLength,
1017 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
1018 			pnetwork->InfrastructureMode == Ndis802_11Infrastructure?IEEE80211_BSS_TYPE_ESS:IEEE80211_BSS_TYPE_IBSS,
1019 			IEEE80211_PRIVACY(pnetwork->Privacy));
1020 #else
1021 			pnetwork->InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS, pnetwork->InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS);
1022 #endif
1023 
1024 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
1025 	cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
1026 #else
1027 	cfg80211_put_bss(bss);
1028 #endif
1029 
1030 	return bss != NULL;
1031 }
1032 
rtw_cfg80211_ibss_indicate_connect(_adapter * padapter)1033 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
1034 {
1035 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1036 	struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1037 	struct wireless_dev *pwdev = padapter->rtw_wdev;
1038 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
1039 	struct wiphy *wiphy = pwdev->wiphy;
1040 	int freq = 2412;
1041 	struct ieee80211_channel *notify_channel;
1042 #endif
1043 
1044 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1045 
1046 	if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
1047 		return;
1048 
1049 	if (!rtw_cfg80211_check_bss(padapter)) {
1050 		WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
1051 		struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
1052 
1053 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
1054 
1055 			_rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
1056 			if (cur_network) {
1057 				if (!rtw_cfg80211_inform_bss(padapter, cur_network))
1058 					RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
1059 				else
1060 					RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
1061 			} else {
1062 				RTW_INFO("cur_network is not exist!!!\n");
1063 				return ;
1064 			}
1065 		} else {
1066 			if (scanned == NULL)
1067 				rtw_warn_on(1);
1068 
1069 			if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
1070 				&& _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
1071 			) {
1072 				if (!rtw_cfg80211_inform_bss(padapter, scanned))
1073 					RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
1074 				else {
1075 					/* RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
1076 				}
1077 			} else {
1078 				RTW_INFO("scanned & pnetwork compare fail\n");
1079 				rtw_warn_on(1);
1080 			}
1081 		}
1082 
1083 		if (!rtw_cfg80211_check_bss(padapter))
1084 			RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
1085 	}
1086 	/* notify cfg80211 that device joined an IBSS */
1087 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
1088 	freq = rtw_ch2freq(cur_network->network.Configuration.DSConfig);
1089 	if (1)
1090 		RTW_INFO("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq);
1091 	notify_channel = ieee80211_get_channel(wiphy, freq);
1092 	cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, notify_channel, GFP_ATOMIC);
1093 #else
1094 	cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
1095 #endif
1096 }
1097 
rtw_cfg80211_indicate_connect(_adapter * padapter)1098 void rtw_cfg80211_indicate_connect(_adapter *padapter)
1099 {
1100 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1101 	struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1102 	struct wireless_dev *pwdev = padapter->rtw_wdev;
1103 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1104 	_irqL irqL;
1105 #ifdef CONFIG_P2P
1106 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1107 #endif
1108 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1109 	struct cfg80211_roam_info roam_info ={};
1110 #endif
1111 
1112 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1113 	if (pwdev->iftype != NL80211_IFTYPE_STATION
1114 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1115 		&& pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
1116 		#endif
1117 	)
1118 		return;
1119 
1120 	if (!MLME_IS_STA(padapter))
1121 		return;
1122 
1123 #ifdef CONFIG_P2P
1124 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1125 		#if !RTW_P2P_GROUP_INTERFACE
1126 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1127 			rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1128 			rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1129 			rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1130 			RTW_INFO("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
1131 		}
1132 		#endif
1133 	}
1134 #endif /* CONFIG_P2P */
1135 
1136 	if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1137 		WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
1138 		struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
1139 
1140 		/* RTW_INFO(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
1141 
1142 		if (scanned == NULL) {
1143 			rtw_warn_on(1);
1144 			goto check_bss;
1145 		}
1146 
1147 		if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
1148 			&& _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
1149 		) {
1150 			if (!rtw_cfg80211_inform_bss(padapter, scanned))
1151 				RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
1152 			else {
1153 				/* RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
1154 			}
1155 		} else {
1156 			RTW_INFO("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
1157 				scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
1158 				pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
1159 			);
1160 			rtw_warn_on(1);
1161 		}
1162 	}
1163 
1164 check_bss:
1165 	if (!rtw_cfg80211_check_bss(padapter))
1166 		RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
1167 
1168 	_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1169 
1170 	if (rtw_to_roam(padapter) > 0) {
1171 		#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
1172 		struct wiphy *wiphy = pwdev->wiphy;
1173 		struct ieee80211_channel *notify_channel;
1174 		u32 freq;
1175 		u16 channel = cur_network->network.Configuration.DSConfig;
1176 
1177 		freq = rtw_ch2freq(channel);
1178 		notify_channel = ieee80211_get_channel(wiphy, freq);
1179 		#endif
1180 
1181 		#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1182 		roam_info.bssid = cur_network->network.MacAddress;
1183 		roam_info.req_ie = pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2;
1184 		roam_info.req_ie_len = pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2;
1185 		roam_info.resp_ie = pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6;
1186 		roam_info.resp_ie_len = pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6;
1187 
1188 		cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
1189 		#else
1190 		cfg80211_roamed(padapter->pnetdev
1191 			#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
1192 			, notify_channel
1193 			#endif
1194 			, cur_network->network.MacAddress
1195 			, pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2
1196 			, pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2
1197 			, pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
1198 			, pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6
1199 			, GFP_ATOMIC);
1200 		#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/
1201 
1202 		RTW_INFO(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
1203 
1204 #ifdef CONFIG_RTW_80211R
1205 		if (rtw_ft_roam(padapter))
1206 			rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA);
1207 #endif
1208 	} else {
1209 		#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
1210 		RTW_INFO("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
1211 		#endif
1212 
1213 		if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE)
1214 			rtw_cfg80211_connect_result(pwdev, cur_network->network.MacAddress
1215 				, pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2
1216 				, pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2
1217 				, pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
1218 				, pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6
1219 				, WLAN_STATUS_SUCCESS, GFP_ATOMIC);
1220 		#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
1221 		RTW_INFO("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
1222 		#endif
1223 	}
1224 
1225 	rtw_wdev_free_connect_req(pwdev_priv);
1226 
1227 	_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1228 }
1229 
rtw_cfg80211_indicate_disconnect(_adapter * padapter,u16 reason,u8 locally_generated)1230 void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated)
1231 {
1232 	struct wireless_dev *pwdev = padapter->rtw_wdev;
1233 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1234 	_irqL irqL;
1235 #ifdef CONFIG_P2P
1236 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1237 #endif
1238 
1239 	RTW_INFO(FUNC_ADPT_FMT" ,reason = %d\n", FUNC_ADPT_ARG(padapter), reason);
1240 
1241 	/*always replace privated definitions with wifi reserved value 0*/
1242 	if (WLAN_REASON_IS_PRIVATE(reason))
1243 		reason = 0;
1244 
1245 	if (pwdev->iftype != NL80211_IFTYPE_STATION
1246 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1247 		&& pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
1248 		#endif
1249 	)
1250 		return;
1251 
1252 	if (!MLME_IS_STA(padapter))
1253 		return;
1254 
1255 #ifdef CONFIG_P2P
1256 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1257 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1258 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1259 
1260 			#if RTW_P2P_GROUP_INTERFACE
1261 			#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1262 			if (pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
1263 			#endif
1264 			#endif
1265 				rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1266 
1267 			RTW_INFO("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
1268 		}
1269 	}
1270 #endif /* CONFIG_P2P */
1271 
1272 	_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1273 
1274 	if (padapter->ndev_unregistering || !rtw_wdev_not_indic_disco(pwdev_priv)) {
1275 		#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
1276 		RTW_INFO("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
1277 
1278 		if (pwdev->sme_state == CFG80211_SME_CONNECTING) {
1279 			RTW_INFO(FUNC_ADPT_FMT" call cfg80211_connect_result, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1280 			rtw_cfg80211_connect_result(pwdev, NULL, NULL, 0, NULL, 0,
1281 				reason?reason:WLAN_STATUS_UNSPECIFIED_FAILURE,
1282 				GFP_ATOMIC);
1283 		} else if (pwdev->sme_state == CFG80211_SME_CONNECTED) {
1284 			RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1285 			rtw_cfg80211_disconnected(pwdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
1286 		}
1287 
1288 		RTW_INFO("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
1289 		#else
1290 		if (pwdev_priv->connect_req) {
1291 			RTW_INFO(FUNC_ADPT_FMT" call cfg80211_connect_result, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1292 			rtw_cfg80211_connect_result(pwdev, NULL, NULL, 0, NULL, 0,
1293 				reason?reason:WLAN_STATUS_UNSPECIFIED_FAILURE,
1294 				GFP_ATOMIC);
1295 		} else {
1296 			RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1297 			rtw_cfg80211_disconnected(pwdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
1298 		}
1299 		#endif
1300 	}
1301 
1302 	rtw_wdev_free_connect_req(pwdev_priv);
1303 
1304 	_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1305 }
1306 
1307 
1308 #ifdef CONFIG_AP_MODE
rtw_cfg80211_ap_set_encryption(struct net_device * dev,struct ieee_param * param)1309 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param)
1310 {
1311 	int ret = 0;
1312 	u32 wep_key_idx, wep_key_len;
1313 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
1314 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1315 	struct security_priv *psecuritypriv = &(padapter->securitypriv);
1316 	struct sta_priv *pstapriv = &padapter->stapriv;
1317 
1318 	RTW_INFO("%s\n", __FUNCTION__);
1319 
1320 	param->u.crypt.err = 0;
1321 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1322 
1323 	if (is_broadcast_mac_addr(param->sta_addr)) {
1324 		if (param->u.crypt.idx >= WEP_KEYS
1325 			#ifdef CONFIG_IEEE80211W
1326 			&& param->u.crypt.idx > BIP_MAX_KEYID
1327 			#endif
1328 		) {
1329 			ret = -EINVAL;
1330 			goto exit;
1331 		}
1332 	} else {
1333 		psta = rtw_get_stainfo(pstapriv, param->sta_addr);
1334 		if (!psta) {
1335 			ret = -EINVAL;
1336 			RTW_INFO(FUNC_ADPT_FMT", sta "MAC_FMT" not found\n"
1337 				, FUNC_ADPT_ARG(padapter), MAC_ARG(param->sta_addr));
1338 			goto exit;
1339 		}
1340 	}
1341 
1342 	if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
1343 		/* todo:clear default encryption keys */
1344 
1345 		RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
1346 
1347 		goto exit;
1348 	}
1349 
1350 
1351 	if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
1352 		RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
1353 
1354 		wep_key_idx = param->u.crypt.idx;
1355 		wep_key_len = param->u.crypt.key_len;
1356 
1357 		RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
1358 
1359 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
1360 			ret = -EINVAL;
1361 			goto exit;
1362 		}
1363 
1364 		if (wep_key_len > 0)
1365 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
1366 
1367 		if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1368 			/* wep default key has not been set, so use this key index as default key. */
1369 
1370 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1371 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1372 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1373 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1374 
1375 			if (wep_key_len == 13) {
1376 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1377 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1378 			}
1379 
1380 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1381 		}
1382 
1383 		_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1384 
1385 		psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1386 
1387 		rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
1388 
1389 		goto exit;
1390 
1391 	}
1392 
1393 	if (!psta) { /* group key */
1394 		if (param->u.crypt.set_tx == 0) { /* group key, TX only */
1395 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1396 				RTW_INFO(FUNC_ADPT_FMT" set WEP TX GTK idx:%u, len:%u\n"
1397 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1398 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1399 				psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1400 				if (param->u.crypt.key_len == 13)
1401 					psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1402 
1403 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
1404 				RTW_INFO(FUNC_ADPT_FMT" set TKIP TX GTK idx:%u, len:%u\n"
1405 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1406 				psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
1407 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1408 				/* set mic key */
1409 				_rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1410 				_rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1411 				psecuritypriv->busetkipkey = _TRUE;
1412 
1413 			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1414 				RTW_INFO(FUNC_ADPT_FMT" set CCMP TX GTK idx:%u, len:%u\n"
1415 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1416 				psecuritypriv->dot118021XGrpPrivacy = _AES_;
1417 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1418 
1419 			} else if (strcmp(param->u.crypt.alg, "GCMP") == 0) {
1420 				RTW_INFO(FUNC_ADPT_FMT" set GCMP TX GTK idx:%u, len:%u\n"
1421 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1422 				psecuritypriv->dot118021XGrpPrivacy = _GCMP_;
1423 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
1424 					param->u.crypt.key,
1425 					(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1426 
1427 			} else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0) {
1428 				RTW_INFO(FUNC_ADPT_FMT" set GCMP_256 TX GTK idx:%u, len:%u\n"
1429 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1430 				psecuritypriv->dot118021XGrpPrivacy = _GCMP_256_;
1431 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
1432 					param->u.crypt.key,
1433 					(param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1434 
1435 			} else if (strcmp(param->u.crypt.alg, "CCMP_256") == 0) {
1436 				RTW_INFO(FUNC_ADPT_FMT" set CCMP_256 TX GTK idx:%u, len:%u\n"
1437 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1438 				psecuritypriv->dot118021XGrpPrivacy = _CCMP_256_;
1439 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
1440 					param->u.crypt.key,
1441 					(param->u.crypt.key_len > 32 ? 32: param->u.crypt.key_len));
1442 
1443 			#ifdef CONFIG_IEEE80211W
1444 			} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1445 				psecuritypriv->dot11wCipher = _BIP_CMAC_128_;
1446 				RTW_INFO(FUNC_ADPT_FMT" set TX CMAC-128 IGTK idx:%u, len:%u\n"
1447 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1448 				_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1449 				padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1450 				psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1451 				padapter->securitypriv.binstallBIPkey = _TRUE;
1452 				goto exit;
1453 			} else if (strcmp(param->u.crypt.alg, "BIP_GMAC_128") == 0) {
1454 				RTW_INFO(FUNC_ADPT_FMT" set TX GMAC-128 IGTK idx:%u, len:%u\n"
1455 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1456 				psecuritypriv->dot11wCipher = _BIP_GMAC_128_;
1457 				_rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey,
1458 					param->u.crypt.key, param->u.crypt.key_len);
1459 				psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1460 				psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1461 				psecuritypriv->binstallBIPkey = _TRUE;
1462 				goto exit;
1463 			} else if (strcmp(param->u.crypt.alg, "BIP_GMAC_256") == 0) {
1464 				RTW_INFO(FUNC_ADPT_FMT" set TX GMAC-256 IGTK idx:%u, len:%u\n"
1465 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1466 				psecuritypriv->dot11wCipher = _BIP_GMAC_256_;
1467 				_rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey,
1468 					param->u.crypt.key, param->u.crypt.key_len);
1469 				padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1470 				psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1471 				padapter->securitypriv.binstallBIPkey = _TRUE;
1472 				goto exit;
1473 			} else if (strcmp(param->u.crypt.alg, "BIP_CMAC_256") == 0) {
1474 				RTW_INFO(FUNC_ADPT_FMT" set TX CMAC-256 IGTK idx:%u, len:%u\n"
1475 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1476 				psecuritypriv->dot11wCipher = _BIP_CMAC_256_;
1477 				_rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey,
1478 					param->u.crypt.key, param->u.crypt.key_len);
1479 				psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1480 				psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1481 				psecuritypriv->binstallBIPkey = _TRUE;
1482 				goto exit;
1483 			#endif /* CONFIG_IEEE80211W */
1484 
1485 			} else if (strcmp(param->u.crypt.alg, "none") == 0) {
1486 				RTW_INFO(FUNC_ADPT_FMT" clear group key, idx:%u\n"
1487 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx);
1488 				psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
1489 			} else {
1490 				RTW_WARN(FUNC_ADPT_FMT" set group key, not support\n"
1491 					, FUNC_ADPT_ARG(padapter));
1492 				goto exit;
1493 			}
1494 
1495 			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
1496 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1497 			if (pbcmc_sta) {
1498 				pbcmc_sta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
1499 				pbcmc_sta->ieee8021x_blocked = _FALSE;
1500 				pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy			 */
1501 			}
1502 			psecuritypriv->binstallGrpkey = _TRUE;
1503 			psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
1504 
1505 			rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1506 		}
1507 
1508 		goto exit;
1509 
1510 	}
1511 
1512 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
1513 		if (param->u.crypt.set_tx == 1) {
1514 			/* pairwise key */
1515 			if (param->u.crypt.key_len == 32)
1516 				_rtw_memcpy(psta->dot118021x_UncstKey.skey,
1517 						param->u.crypt.key,
1518 						(param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1519 			else
1520 				_rtw_memcpy(psta->dot118021x_UncstKey.skey,
1521 						param->u.crypt.key,
1522 						(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1523 
1524 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1525 				RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n"
1526 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1527 					, param->u.crypt.idx, param->u.crypt.key_len);
1528 				psta->dot118021XPrivacy = _WEP40_;
1529 				if (param->u.crypt.key_len == 13)
1530 					psta->dot118021XPrivacy = _WEP104_;
1531 
1532 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
1533 				RTW_INFO(FUNC_ADPT_FMT" set TKIP PTK of "MAC_FMT" idx:%u, len:%u\n"
1534 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1535 					, param->u.crypt.idx, param->u.crypt.key_len);
1536 				psta->dot118021XPrivacy = _TKIP_;
1537 				/* set mic key */
1538 				_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1539 				_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1540 				psecuritypriv->busetkipkey = _TRUE;
1541 
1542 			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1543 				RTW_INFO(FUNC_ADPT_FMT" set CCMP PTK of "MAC_FMT" idx:%u, len:%u\n"
1544 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1545 					, param->u.crypt.idx, param->u.crypt.key_len);
1546 				psta->dot118021XPrivacy = _AES_;
1547 
1548 			} else if (strcmp(param->u.crypt.alg, "GCMP") == 0) {
1549 				RTW_INFO(FUNC_ADPT_FMT" set GCMP PTK of "MAC_FMT" idx:%u, len:%u\n"
1550 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1551 					, param->u.crypt.idx, param->u.crypt.key_len);
1552 				psta->dot118021XPrivacy = _GCMP_;
1553 
1554 			} else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0) {
1555 				RTW_INFO(FUNC_ADPT_FMT" set GCMP_256 PTK of "MAC_FMT" idx:%u, len:%u\n"
1556 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1557 					, param->u.crypt.idx, param->u.crypt.key_len);
1558 				psta->dot118021XPrivacy = _GCMP_256_;
1559 
1560 			} else if (strcmp(param->u.crypt.alg, "CCMP_256") == 0) {
1561 				RTW_INFO(FUNC_ADPT_FMT" set CCMP_256 PTK of "MAC_FMT" idx:%u, len:%u\n"
1562 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1563 					, param->u.crypt.idx, param->u.crypt.key_len);
1564 				psta->dot118021XPrivacy = _CCMP_256_;
1565 
1566 			} else if (strcmp(param->u.crypt.alg, "none") == 0) {
1567 				RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n"
1568 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1569 					, param->u.crypt.idx);
1570 				psta->dot118021XPrivacy = _NO_PRIVACY_;
1571 			} else {
1572 				RTW_WARN(FUNC_ADPT_FMT" set pairwise key of "MAC_FMT", not support\n"
1573 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
1574 				goto exit;
1575 			}
1576 
1577 			psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
1578 			psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1579 			psta->ieee8021x_blocked = _FALSE;
1580 
1581 			if (psta->dot118021XPrivacy != _NO_PRIVACY_) {
1582 				psta->bpairwise_key_installed = _TRUE;
1583 
1584 				/* WPA2 key-handshake has completed */
1585 				if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
1586 					psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
1587 			}
1588 
1589 			rtw_ap_set_pairwise_key(padapter, psta);
1590 		} else {
1591 			/* peer's group key, RX only */
1592 			#ifdef CONFIG_RTW_MESH
1593 			if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1594 				RTW_INFO(FUNC_ADPT_FMT" set CCMP GTK of "MAC_FMT", idx:%u, len:%u\n"
1595 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1596 					, param->u.crypt.idx, param->u.crypt.key_len);
1597 				psta->group_privacy = _AES_;
1598 				_rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1599 				psta->gtk_bmp |= BIT(param->u.crypt.idx);
1600 				psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1601 
1602 			} else if (strcmp(param->u.crypt.alg, "GCMP") == 0) {
1603 				RTW_INFO(FUNC_ADPT_FMT" set GCMP GTK of "MAC_FMT", idx:%u, len:%u\n"
1604 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1605 					, param->u.crypt.idx, param->u.crypt.key_len);
1606 				psta->group_privacy = _GCMP_;
1607 				_rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1608 				psta->gtk_bmp |= BIT(param->u.crypt.idx);
1609 				psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1610 
1611 			} else if (strcmp(param->u.crypt.alg, "CCMP_256") == 0) {
1612 				RTW_INFO(FUNC_ADPT_FMT" set CCMP_256 GTK of "MAC_FMT", idx:%u, len:%u\n"
1613 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1614 					, param->u.crypt.idx, param->u.crypt.key_len);
1615 				psta->group_privacy = _CCMP_256_;
1616 				_rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1617 				psta->gtk_bmp |= BIT(param->u.crypt.idx);
1618 				psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1619 
1620 			} else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0) {
1621 				RTW_INFO(FUNC_ADPT_FMT" set GCMP_256 GTK of "MAC_FMT", idx:%u, len:%u\n"
1622 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1623 					, param->u.crypt.idx, param->u.crypt.key_len);
1624 				psta->group_privacy = _GCMP_256_;
1625 				_rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1626 				psta->gtk_bmp |= BIT(param->u.crypt.idx);
1627 				psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1628 
1629 			#ifdef CONFIG_IEEE80211W
1630 			} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1631 				RTW_INFO(FUNC_ADPT_FMT" set CMAC-128 IGTK of "MAC_FMT", idx:%u, len:%u\n"
1632 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1633 					, param->u.crypt.idx, param->u.crypt.key_len);
1634 				psta->dot11wCipher = _BIP_CMAC_128_;
1635 				_rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1636 				psta->igtk_bmp |= BIT(param->u.crypt.idx);
1637 				psta->igtk_id = param->u.crypt.idx;
1638 				psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1639 				goto exit;
1640 
1641 			} else if (strcmp(param->u.crypt.alg, "BIP_GMAC_128") == 0) {
1642 				RTW_INFO(FUNC_ADPT_FMT" set GMAC-128 IGTK of "MAC_FMT", idx:%u, len:%u\n"
1643 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1644 					, param->u.crypt.idx, param->u.crypt.key_len);
1645 				psta->dot11wCipher = _BIP_GMAC_128_;
1646 				_rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1647 				psta->igtk_bmp |= BIT(param->u.crypt.idx);
1648 				psta->igtk_id = param->u.crypt.idx;
1649 				psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1650 				goto exit;
1651 
1652 			} else if (strcmp(param->u.crypt.alg, "BIP_CMAC_256") == 0) {
1653 				RTW_INFO(FUNC_ADPT_FMT" set CMAC-256 IGTK of "MAC_FMT", idx:%u, len:%u\n"
1654 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1655 					, param->u.crypt.idx, param->u.crypt.key_len);
1656 				psta->dot11wCipher = _BIP_CMAC_256_;
1657 				_rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1658 				psta->igtk_bmp |= BIT(param->u.crypt.idx);
1659 				psta->igtk_id = param->u.crypt.idx;
1660 				psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1661 				goto exit;
1662 
1663 			} else if (strcmp(param->u.crypt.alg, "BIP_GMAC_256") == 0) {
1664 				RTW_INFO(FUNC_ADPT_FMT" set GMAC-256 IGTK of "MAC_FMT", idx:%u, len:%u\n"
1665 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1666 					, param->u.crypt.idx, param->u.crypt.key_len);
1667 				psta->dot11wCipher = _BIP_GMAC_256_;
1668 				_rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1669 				psta->igtk_bmp |= BIT(param->u.crypt.idx);
1670 				psta->igtk_id = param->u.crypt.idx;
1671 				psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1672 				goto exit;
1673 			#endif /* CONFIG_IEEE80211W */
1674 
1675 			} else if (strcmp(param->u.crypt.alg, "none") == 0) {
1676 				RTW_INFO(FUNC_ADPT_FMT" clear group key of "MAC_FMT", idx:%u\n"
1677 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1678 					, param->u.crypt.idx);
1679 				psta->group_privacy = _NO_PRIVACY_;
1680 				psta->gtk_bmp &= ~BIT(param->u.crypt.idx);
1681 			} else
1682 			#endif /* CONFIG_RTW_MESH */
1683 			{
1684 				RTW_WARN(FUNC_ADPT_FMT" set group key of "MAC_FMT", not support\n"
1685 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
1686 				goto exit;
1687 			}
1688 
1689 			#ifdef CONFIG_RTW_MESH
1690 			rtw_ap_set_sta_key(padapter, psta->cmn.mac_addr, psta->group_privacy
1691 				, param->u.crypt.key, param->u.crypt.idx, 1);
1692 			#endif
1693 		}
1694 
1695 	}
1696 
1697 exit:
1698 	return ret;
1699 }
1700 #endif /* CONFIG_AP_MODE */
1701 
rtw_cfg80211_set_encryption(struct net_device * dev,struct ieee_param * param)1702 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param)
1703 {
1704 	int ret = 0;
1705 	u32 wep_key_idx, wep_key_len;
1706 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1707 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1708 	struct security_priv *psecuritypriv = &padapter->securitypriv;
1709 #ifdef CONFIG_P2P
1710 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1711 #endif /* CONFIG_P2P */
1712 
1713 	RTW_INFO("%s\n", __func__);
1714 
1715 	param->u.crypt.err = 0;
1716 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1717 
1718 	if (is_broadcast_mac_addr(param->sta_addr)) {
1719 		if (param->u.crypt.idx >= WEP_KEYS
1720 			#ifdef CONFIG_IEEE80211W
1721 			&& param->u.crypt.idx > BIP_MAX_KEYID
1722 			#endif
1723 		) {
1724 			ret = -EINVAL;
1725 			goto exit;
1726 		}
1727 	} else {
1728 #ifdef CONFIG_WAPI_SUPPORT
1729 		if (strcmp(param->u.crypt.alg, "SMS4"))
1730 #endif
1731 		{
1732 			ret = -EINVAL;
1733 			goto exit;
1734 		}
1735 	}
1736 
1737 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1738 		RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
1739 
1740 		wep_key_idx = param->u.crypt.idx;
1741 		wep_key_len = param->u.crypt.key_len;
1742 
1743 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
1744 			ret = -EINVAL;
1745 			goto exit;
1746 		}
1747 
1748 		if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1749 			/* wep default key has not been set, so use this key index as default key. */
1750 
1751 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
1752 
1753 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1754 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1755 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1756 
1757 			if (wep_key_len == 13) {
1758 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1759 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1760 			}
1761 
1762 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1763 		}
1764 
1765 		_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1766 
1767 		psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1768 
1769 		rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
1770 
1771 		goto exit;
1772 	}
1773 
1774 	if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
1775 		struct sta_info *psta, *pbcmc_sta;
1776 		struct sta_priv *pstapriv = &padapter->stapriv;
1777 
1778 		/* RTW_INFO("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X\n", __func__); */
1779 
1780 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
1781 #ifdef CONFIG_RTW_80211R
1782 			if (rtw_ft_roam(padapter))
1783 				psta = rtw_get_stainfo(pstapriv, pmlmepriv->assoc_bssid);
1784 			else
1785 #endif
1786 				psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1787 			if (psta == NULL) {
1788 				/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
1789 				RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);
1790 			} else {
1791 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
1792 				if (strcmp(param->u.crypt.alg, "none") != 0)
1793 					psta->ieee8021x_blocked = _FALSE;
1794 
1795 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1796 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1797 					psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1798 
1799 				if (param->u.crypt.set_tx == 1) { /* pairwise key */
1800 					RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n"
1801 						, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
1802 
1803 					if (strcmp(param->u.crypt.alg, "GCMP_256") == 0
1804 						|| strcmp(param->u.crypt.alg, "CCMP_256") == 0) {
1805 						_rtw_memcpy(psta->dot118021x_UncstKey.skey,
1806 							param->u.crypt.key,
1807 							((param->u.crypt.key_len > 32) ?
1808 								32 : param->u.crypt.key_len));
1809 					} else
1810 						_rtw_memcpy(psta->dot118021x_UncstKey.skey,
1811 							param->u.crypt.key,
1812 							(param->u.crypt.key_len > 16 ?
1813 								16 : param->u.crypt.key_len));
1814 
1815 					if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
1816 						_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1817 						_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1818 						padapter->securitypriv.busetkipkey = _FALSE;
1819 					}
1820 					psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
1821 					psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1822 					psta->bpairwise_key_installed = _TRUE;
1823 					#ifdef CONFIG_RTW_80211R
1824 					psta->ft_pairwise_key_installed = _TRUE;
1825 					#endif
1826 					rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
1827 
1828 				} else { /* group key */
1829 					if (strcmp(param->u.crypt.alg, "TKIP") == 0
1830 						|| strcmp(param->u.crypt.alg, "CCMP") == 0
1831 						|| strcmp(param->u.crypt.alg, "GCMP") == 0) {
1832 						RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"
1833 							, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
1834 						_rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,
1835 							param->u.crypt.key,
1836 							(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1837 
1838 						if (strcmp(param->u.crypt.alg, "TKIP") == 0 && param->u.crypt.key_len >= 32) {
1839 							_rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1840 							_rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1841 						}
1842 
1843 						padapter->securitypriv.binstallGrpkey = _TRUE;
1844 						if (param->u.crypt.idx < 4)
1845 							_rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8);
1846 						padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1847 						rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
1848 					} else if (strcmp(param->u.crypt.alg, "GCMP_256") == 0
1849 						|| strcmp(param->u.crypt.alg, "CCMP_256") == 0) {
1850 						RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"
1851 							, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
1852 						_rtw_memcpy(
1853 							padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,
1854 							param->u.crypt.key,
1855 							(param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1856 						padapter->securitypriv.binstallGrpkey = _TRUE;
1857 						padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1858 						rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
1859 					#ifdef CONFIG_IEEE80211W
1860 					} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1861 						psecuritypriv->dot11wCipher = _BIP_CMAC_128_;
1862 						RTW_INFO(FUNC_ADPT_FMT" set CMAC-128 IGTK idx:%u, len:%u\n"
1863 							, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1864 						_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,
1865 							param->u.crypt.key,
1866 							(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1867 						psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1868 						psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1869 						psecuritypriv->binstallBIPkey = _TRUE;
1870 					} else if (strcmp(param->u.crypt.alg, "BIP_GMAC_128") == 0) {
1871 						psecuritypriv->dot11wCipher = _BIP_GMAC_128_;
1872 						RTW_INFO(FUNC_ADPT_FMT" set GMAC-128 IGTK idx:%u, len:%u\n"
1873 							, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1874 						_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,
1875 							param->u.crypt.key,
1876 							(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1877 						psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1878 						psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1879 						psecuritypriv->binstallBIPkey = _TRUE;
1880 					} else if (strcmp(param->u.crypt.alg, "BIP_GMAC_256") == 0) {
1881 						psecuritypriv->dot11wCipher = _BIP_GMAC_256_;
1882 						RTW_INFO(FUNC_ADPT_FMT" set GMAC-256 IGTK idx:%u, len:%u\n"
1883 							, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1884 						_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,
1885 							param->u.crypt.key,
1886 							(param->u.crypt.key_len > 32 ? 32 : param->u.crypt.key_len));
1887 						psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1888 						psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1889 						psecuritypriv->binstallBIPkey = _TRUE;
1890 					} else if (strcmp(param->u.crypt.alg, "BIP_CMAC_256") == 0) {
1891 						psecuritypriv->dot11wCipher = _BIP_CMAC_256_;
1892 						RTW_INFO(FUNC_ADPT_FMT" set CMAC-256 IGTK idx:%u, len:%u\n"
1893 							, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1894 						_rtw_memcpy(psecuritypriv->dot11wBIPKey[param->u.crypt.idx].skey,
1895 							param->u.crypt.key, param->u.crypt.key_len);
1896 						psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1897 						psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1898 						psecuritypriv->binstallBIPkey = _TRUE;
1899 					#endif /* CONFIG_IEEE80211W */
1900 
1901 					}
1902 
1903 #ifdef CONFIG_P2P
1904 					if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1905 						if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1906 							rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1907 					}
1908 #endif /* CONFIG_P2P */
1909 
1910 					/* WPA/WPA2 key-handshake has completed */
1911 					clr_fwstate(pmlmepriv, WIFI_UNDER_KEY_HANDSHAKE);
1912 
1913 				}
1914 			}
1915 
1916 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1917 			if (pbcmc_sta == NULL) {
1918 				/* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
1919 			} else {
1920 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
1921 				if (strcmp(param->u.crypt.alg, "none") != 0)
1922 					pbcmc_sta->ieee8021x_blocked = _FALSE;
1923 
1924 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1925 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1926 					pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1927 			}
1928 		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1929 		}
1930 	}
1931 
1932 	#ifdef CONFIG_WAPI_SUPPORT
1933 	if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1934 		rtw_wapi_set_set_encryption(padapter, param);
1935 	#endif
1936 
1937 exit:
1938 
1939 	RTW_INFO("%s, ret=%d\n", __func__, ret);
1940 
1941 
1942 	return ret;
1943 }
1944 
cfg80211_rtw_add_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool pairwise,const u8 * mac_addr,struct key_params * params)1945 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev
1946 	, u8 key_index
1947 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1948 	, bool pairwise
1949 #endif
1950 	, const u8 *mac_addr, struct key_params *params)
1951 {
1952 	char *alg_name;
1953 	u32 param_len;
1954 	struct ieee_param *param = NULL;
1955 	int ret = 0;
1956 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1957 	struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
1958 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1959 #ifdef CONFIG_TDLS
1960 	struct sta_info *ptdls_sta;
1961 #endif /* CONFIG_TDLS */
1962 
1963 	if (mac_addr)
1964 		RTW_INFO(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1965 	RTW_INFO(FUNC_NDEV_FMT" cipher=0x%x\n", FUNC_NDEV_ARG(ndev), params->cipher);
1966 	RTW_INFO(FUNC_NDEV_FMT" key_len=%d, key_index=%d\n", FUNC_NDEV_ARG(ndev), params->key_len, key_index);
1967 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1968 	RTW_INFO(FUNC_NDEV_FMT" pairwise=%d\n", FUNC_NDEV_ARG(ndev), pairwise);
1969 #endif
1970 
1971 	if (rtw_cfg80211_sync_iftype(padapter) != _SUCCESS) {
1972 		ret = -ENOTSUPP;
1973 		goto addkey_end;
1974 	}
1975 
1976 	param_len = sizeof(struct ieee_param) + params->key_len;
1977 	param = rtw_malloc(param_len);
1978 	if (param == NULL)
1979 		return -1;
1980 
1981 	_rtw_memset(param, 0, param_len);
1982 
1983 	param->cmd = IEEE_CMD_SET_ENCRYPTION;
1984 	_rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
1985 
1986 	switch (params->cipher) {
1987 	case IW_AUTH_CIPHER_NONE:
1988 		/* todo: remove key */
1989 		/* remove = 1;	 */
1990 		alg_name = "none";
1991 		break;
1992 	case WLAN_CIPHER_SUITE_WEP40:
1993 	case WLAN_CIPHER_SUITE_WEP104:
1994 		alg_name = "WEP";
1995 		break;
1996 	case WLAN_CIPHER_SUITE_TKIP:
1997 		alg_name = "TKIP";
1998 		break;
1999 	case WLAN_CIPHER_SUITE_CCMP:
2000 		alg_name = "CCMP";
2001 		break;
2002 	case WIFI_CIPHER_SUITE_GCMP:
2003 		alg_name = "GCMP";
2004 		break;
2005 	case WIFI_CIPHER_SUITE_GCMP_256:
2006 		alg_name = "GCMP_256";
2007 		break;
2008 	case WIFI_CIPHER_SUITE_CCMP_256:
2009 		alg_name = "CCMP_256";
2010 		break;
2011 #ifdef CONFIG_IEEE80211W
2012 	case WLAN_CIPHER_SUITE_AES_CMAC:
2013 		alg_name = "BIP";
2014 		break;
2015 	case WIFI_CIPHER_SUITE_BIP_GMAC_128:
2016 		alg_name = "BIP_GMAC_128";
2017 		break;
2018 	case WIFI_CIPHER_SUITE_BIP_GMAC_256:
2019 		alg_name = "BIP_GMAC_256";
2020 		break;
2021 	case WIFI_CIPHER_SUITE_BIP_CMAC_256:
2022 		alg_name = "BIP_CMAC_256";
2023 		break;
2024 #endif /* CONFIG_IEEE80211W */
2025 #ifdef CONFIG_WAPI_SUPPORT
2026 	case WLAN_CIPHER_SUITE_SMS4:
2027 		alg_name = "SMS4";
2028 		if (pairwise == NL80211_KEYTYPE_PAIRWISE) {
2029 			if (key_index != 0 && key_index != 1) {
2030 				ret = -ENOTSUPP;
2031 				goto addkey_end;
2032 			}
2033 			_rtw_memcpy((void *)param->sta_addr, (void *)mac_addr, ETH_ALEN);
2034 		} else
2035 			RTW_INFO("mac_addr is null\n");
2036 		RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
2037 		break;
2038 #endif
2039 
2040 	default:
2041 		ret = -ENOTSUPP;
2042 		goto addkey_end;
2043 	}
2044 
2045 	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
2046 
2047 
2048 	if (!mac_addr || is_broadcast_ether_addr(mac_addr)
2049 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2050 		|| !pairwise
2051 		#endif
2052 	) {
2053 		param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
2054 	} else {
2055 		param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
2056 	}
2057 
2058 	param->u.crypt.idx = key_index;
2059 
2060 	if (params->seq_len && params->seq) {
2061 		_rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
2062 		RTW_INFO(FUNC_NDEV_FMT" seq_len:%u, seq:0x%llx\n", FUNC_NDEV_ARG(ndev)
2063 			, params->seq_len, RTW_GET_LE64(param->u.crypt.seq));
2064 	}
2065 
2066 	if (params->key_len && params->key) {
2067 		param->u.crypt.key_len = params->key_len;
2068 		_rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
2069 	}
2070 
2071 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
2072 #ifdef CONFIG_TDLS
2073 		if (rtw_tdls_is_driver_setup(padapter) == _FALSE && mac_addr) {
2074 			ptdls_sta = rtw_get_stainfo(&padapter->stapriv, (void *)mac_addr);
2075 			if (ptdls_sta != NULL && ptdls_sta->tdls_sta_state) {
2076 				_rtw_memcpy(ptdls_sta->tpk.tk, params->key, params->key_len);
2077 				rtw_tdls_set_key(padapter, ptdls_sta);
2078 				goto addkey_end;
2079 			}
2080 		}
2081 #endif /* CONFIG_TDLS */
2082 		ret = rtw_cfg80211_set_encryption(ndev, param);
2083 	} else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
2084 #ifdef CONFIG_AP_MODE
2085 		if (mac_addr)
2086 			_rtw_memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN);
2087 
2088 		ret = rtw_cfg80211_ap_set_encryption(ndev, param);
2089 #endif
2090 	} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
2091 		|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE
2092 	) {
2093 		/* RTW_INFO("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); */
2094 		ret = rtw_cfg80211_set_encryption(ndev, param);
2095 	} else
2096 		RTW_INFO("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
2097 
2098 
2099 addkey_end:
2100 	if (param)
2101 		rtw_mfree(param, param_len);
2102 
2103 	return ret;
2104 
2105 }
2106 
cfg80211_rtw_get_key(struct wiphy * wiphy,struct net_device * ndev,u8 keyid,bool pairwise,const u8 * mac_addr,void * cookie,void (* callback)(void * cookie,struct key_params *))2107 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev
2108 	, u8 keyid
2109 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2110 	, bool pairwise
2111 #endif
2112 	, const u8 *mac_addr, void *cookie
2113 	, void (*callback)(void *cookie, struct key_params *))
2114 {
2115 #define GET_KEY_PARAM_FMT_S " keyid=%d"
2116 #define GET_KEY_PARAM_ARG_S , keyid
2117 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2118 	#define GET_KEY_PARAM_FMT_2_6_37 ", pairwise=%d"
2119 	#define GET_KEY_PARAM_ARG_2_6_37 , pairwise
2120 #else
2121 	#define GET_KEY_PARAM_FMT_2_6_37 ""
2122 	#define GET_KEY_PARAM_ARG_2_6_37
2123 #endif
2124 #define GET_KEY_PARAM_FMT_E ", addr=%pM"
2125 #define GET_KEY_PARAM_ARG_E , mac_addr
2126 
2127 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
2128 	struct security_priv *sec = &adapter->securitypriv;
2129 	struct sta_priv *stapriv = &adapter->stapriv;
2130 	struct sta_info *sta = NULL;
2131 	u32 cipher = _NO_PRIVACY_;
2132 	union Keytype *key = NULL;
2133 	u8 key_len = 0;
2134 	u64 *pn = NULL;
2135 	u8 pn_len = 0;
2136 	u8 pn_val[8] = {0};
2137 
2138 	struct key_params params;
2139 	int ret = -ENOENT;
2140 
2141 	if (keyid >= WEP_KEYS
2142 		#ifdef CONFIG_IEEE80211W
2143 		&& keyid > BIP_MAX_KEYID
2144 		#endif
2145 	)
2146 		goto exit;
2147 
2148 	if (!mac_addr || is_broadcast_ether_addr(mac_addr)
2149 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2150 		|| (MLME_IS_STA(adapter) && !pairwise)
2151 		#endif
2152 	) {
2153 		/* WEP key, TX GTK/IGTK, RX GTK/IGTK(for STA mode) */
2154 		if (is_wep_enc(sec->dot118021XGrpPrivacy)) {
2155 			if (keyid >= WEP_KEYS)
2156 				goto exit;
2157 			if (!(sec->key_mask & BIT(keyid)))
2158 				goto exit;
2159 			cipher = sec->dot118021XGrpPrivacy;
2160 			key = &sec->dot11DefKey[keyid];
2161 		} else {
2162 			if (keyid < WEP_KEYS) {
2163 				if (sec->binstallGrpkey != _TRUE)
2164 					goto exit;
2165 				cipher = sec->dot118021XGrpPrivacy;
2166 				key = &sec->dot118021XGrpKey[keyid];
2167 				sta = rtw_get_bcmc_stainfo(adapter);
2168 				if (sta)
2169 					pn = &sta->dot11txpn.val;
2170 			#ifdef CONFIG_IEEE80211W
2171 			} else if (keyid <= BIP_MAX_KEYID) {
2172 				if (SEC_IS_BIP_KEY_INSTALLED(sec) != _TRUE)
2173 					goto exit;
2174 				cipher = sec->dot11wCipher;
2175 				key = &sec->dot11wBIPKey[keyid];
2176 				pn = &sec->dot11wBIPtxpn.val;
2177 			#endif
2178 			}
2179 		}
2180 	} else {
2181 		/* Pairwise key, RX GTK/IGTK for specific peer */
2182 		sta = rtw_get_stainfo(stapriv, mac_addr);
2183 		if (!sta)
2184 			goto exit;
2185 
2186 		if (keyid < WEP_KEYS && pairwise) {
2187 			if (sta->bpairwise_key_installed != _TRUE)
2188 				goto exit;
2189 			cipher = sta->dot118021XPrivacy;
2190 			key = &sta->dot118021x_UncstKey;
2191 		#ifdef CONFIG_RTW_MESH
2192 		} else if (keyid < WEP_KEYS && !pairwise) {
2193 			if (!(sta->gtk_bmp & BIT(keyid)))
2194 				goto exit;
2195 			cipher = sta->group_privacy;
2196 			key = &sta->gtk;
2197 		#ifdef CONFIG_IEEE80211W
2198 		} else if (keyid <= BIP_MAX_KEYID && !pairwise) {
2199 			if (!(sta->igtk_bmp & BIT(keyid)))
2200 				goto exit;
2201 			cipher = sta->dot11wCipher;
2202 			key = &sta->igtk;
2203 			pn = &sta->igtk_pn.val;
2204 		#endif
2205 		#endif /* CONFIG_RTW_MESH */
2206 		}
2207 	}
2208 
2209 	if (!key)
2210 		goto exit;
2211 
2212 	if (cipher == _WEP40_) {
2213 		cipher = WLAN_CIPHER_SUITE_WEP40;
2214 		key_len = sec->dot11DefKeylen[keyid];
2215 	} else if (cipher == _WEP104_) {
2216 		cipher = WLAN_CIPHER_SUITE_WEP104;
2217 		key_len = sec->dot11DefKeylen[keyid];
2218 	} else if (cipher == _TKIP_ || cipher == _TKIP_WTMIC_) {
2219 		cipher = WLAN_CIPHER_SUITE_TKIP;
2220 		key_len = 16;
2221 	} else if (cipher == _AES_) {
2222 		cipher = WLAN_CIPHER_SUITE_CCMP;
2223 		key_len = 16;
2224 #ifdef CONFIG_WAPI_SUPPORT
2225 	} else if (cipher == _SMS4_) {
2226 		cipher = WLAN_CIPHER_SUITE_SMS4;
2227 		key_len = 16;
2228 #endif
2229 	} else if (cipher == _GCMP_) {
2230 		cipher = WIFI_CIPHER_SUITE_GCMP;
2231 		key_len = 16;
2232 	} else if (cipher == _CCMP_256_) {
2233 		cipher = WIFI_CIPHER_SUITE_CCMP_256;
2234 		key_len = 32;
2235 	} else if (cipher == _GCMP_256_) {
2236 		cipher = WIFI_CIPHER_SUITE_GCMP_256;
2237 		key_len = 32;
2238 	#ifdef CONFIG_IEEE80211W
2239 	} else if (cipher == _BIP_CMAC_128_) {
2240 		cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2241 		key_len = 16;
2242 	} else if (cipher == _BIP_GMAC_128_) {
2243 		cipher = WIFI_CIPHER_SUITE_BIP_GMAC_128;
2244 		key_len = 16;
2245 	} else if (cipher == _BIP_GMAC_256_) {
2246 		cipher = WIFI_CIPHER_SUITE_BIP_GMAC_256;
2247 		key_len = 32;
2248 	} else if (cipher == _BIP_CMAC_256_) {
2249 		cipher = WIFI_CIPHER_SUITE_BIP_CMAC_256;
2250 		key_len = 32;
2251 	#endif
2252 	} else {
2253 		RTW_WARN(FUNC_NDEV_FMT" unknown cipher:%u\n", FUNC_NDEV_ARG(ndev), cipher);
2254 		rtw_warn_on(1);
2255 		goto exit;
2256 	}
2257 
2258 	if (pn) {
2259 		*((u64 *)pn_val) = cpu_to_le64(*pn);
2260 		pn_len = 6;
2261 	}
2262 
2263 	ret = 0;
2264 
2265 exit:
2266 	RTW_INFO(FUNC_NDEV_FMT
2267 		GET_KEY_PARAM_FMT_S
2268 		GET_KEY_PARAM_FMT_2_6_37
2269 		GET_KEY_PARAM_FMT_E
2270 		" ret %d\n", FUNC_NDEV_ARG(ndev)
2271 		GET_KEY_PARAM_ARG_S
2272 		GET_KEY_PARAM_ARG_2_6_37
2273 		GET_KEY_PARAM_ARG_E
2274 		, ret);
2275 	if (pn)
2276 		RTW_INFO(FUNC_NDEV_FMT " seq:0x%llx\n", FUNC_NDEV_ARG(ndev), *pn);
2277 
2278 	if (ret == 0) {
2279 		_rtw_memset(&params, 0, sizeof(params));
2280 
2281 		params.cipher = cipher;
2282 		params.key = key->skey;
2283 		params.key_len = key_len;
2284 		if (pn) {
2285 			params.seq = pn_val;
2286 			params.seq_len = pn_len;
2287 		}
2288 
2289 		callback(cookie, &params);
2290 	}
2291 
2292 	return ret;
2293 }
2294 
cfg80211_rtw_del_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool pairwise,const u8 * mac_addr)2295 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
2296 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2297 				u8 key_index, bool pairwise, const u8 *mac_addr)
2298 #else	/* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
2299 				u8 key_index, const u8 *mac_addr)
2300 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
2301 {
2302 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2303 	struct security_priv *psecuritypriv = &padapter->securitypriv;
2304 
2305 	RTW_INFO(FUNC_NDEV_FMT" key_index=%d, addr=%pM\n", FUNC_NDEV_ARG(ndev), key_index, mac_addr);
2306 
2307 	if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
2308 		/* clear the flag of wep default key set. */
2309 		psecuritypriv->bWepDefaultKeyIdxSet = 0;
2310 	}
2311 
2312 	return 0;
2313 }
2314 
cfg80211_rtw_set_default_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index,bool unicast,bool multicast)2315 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
2316 	struct net_device *ndev, u8 key_index
2317 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
2318 	, bool unicast, bool multicast
2319 	#endif
2320 )
2321 {
2322 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2323 	struct security_priv *psecuritypriv = &padapter->securitypriv;
2324 
2325 #define SET_DEF_KEY_PARAM_FMT " key_index=%d"
2326 #define SET_DEF_KEY_PARAM_ARG , key_index
2327 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
2328 	#define SET_DEF_KEY_PARAM_FMT_2_6_38 ", unicast=%d, multicast=%d"
2329 	#define SET_DEF_KEY_PARAM_ARG_2_6_38 , unicast, multicast
2330 #else
2331 	#define SET_DEF_KEY_PARAM_FMT_2_6_38 ""
2332 	#define SET_DEF_KEY_PARAM_ARG_2_6_38
2333 #endif
2334 
2335 	RTW_INFO(FUNC_NDEV_FMT
2336 		SET_DEF_KEY_PARAM_FMT
2337 		SET_DEF_KEY_PARAM_FMT_2_6_38
2338 		"\n", FUNC_NDEV_ARG(ndev)
2339 		SET_DEF_KEY_PARAM_ARG
2340 		SET_DEF_KEY_PARAM_ARG_2_6_38
2341 	);
2342 
2343 	if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) { /* set wep default key */
2344 		psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2345 
2346 		psecuritypriv->dot11PrivacyKeyIndex = key_index;
2347 
2348 		psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
2349 		psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2350 		if (psecuritypriv->dot11DefKeylen[key_index] == 13) {
2351 			psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
2352 			psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2353 		}
2354 
2355 		psecuritypriv->bWepDefaultKeyIdxSet = 1; /* set the flag to represent that wep default key has been set */
2356 	}
2357 
2358 	return 0;
2359 
2360 }
2361 
2362 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
cfg80211_rtw_set_default_mgmt_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_index)2363 int cfg80211_rtw_set_default_mgmt_key(struct wiphy *wiphy,
2364 	struct net_device *ndev, u8 key_index)
2365 {
2366 #define SET_DEF_KEY_PARAM_FMT " key_index=%d"
2367 #define SET_DEF_KEY_PARAM_ARG , key_index
2368 
2369 	RTW_INFO(FUNC_NDEV_FMT
2370 		SET_DEF_KEY_PARAM_FMT
2371 		"\n", FUNC_NDEV_ARG(ndev)
2372 		SET_DEF_KEY_PARAM_ARG
2373 	);
2374 
2375 	return 0;
2376 }
2377 #endif
2378 
2379 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
cfg80211_rtw_set_rekey_data(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_gtk_rekey_data * data)2380 static int cfg80211_rtw_set_rekey_data(struct wiphy *wiphy,
2381 	struct net_device *ndev,
2382 	struct cfg80211_gtk_rekey_data *data)
2383 {
2384 	/*int i;*/
2385 	struct sta_info *psta;
2386 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2387 	struct mlme_priv   *pmlmepriv = &padapter->mlmepriv;
2388 	struct sta_priv *pstapriv = &padapter->stapriv;
2389 	struct security_priv *psecuritypriv = &(padapter->securitypriv);
2390 
2391 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
2392 	if (psta == NULL) {
2393 		RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);
2394 		return -1;
2395 	}
2396 
2397 	_rtw_memcpy(psta->kek, data->kek, NL80211_KEK_LEN);
2398 	/*printk("\ncfg80211_rtw_set_rekey_data KEK:");
2399 	for(i=0;i<NL80211_KEK_LEN; i++)
2400 		printk(" %02x ", psta->kek[i]);*/
2401 	_rtw_memcpy(psta->kck, data->kck, NL80211_KCK_LEN);
2402 	/*printk("\ncfg80211_rtw_set_rekey_data KCK:");
2403 	for(i=0;i<NL80211_KCK_LEN; i++)
2404 		printk(" %02x ", psta->kck[i]);*/
2405 	_rtw_memcpy(psta->replay_ctr, data->replay_ctr, NL80211_REPLAY_CTR_LEN);
2406 	psecuritypriv->binstallKCK_KEK = _TRUE;
2407 	/*printk("\nREPLAY_CTR: ");
2408 	for(i=0;i<RTW_REPLAY_CTR_LEN; i++)
2409 		printk(" %02x ", psta->replay_ctr[i]);*/
2410 
2411 	return 0;
2412 }
2413 #endif /*CONFIG_GTK_OL*/
2414 
2415 #ifdef CONFIG_RTW_MESH
2416 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
rtw_mesh_ps_to_nl80211_mesh_power_mode(u8 ps)2417 static enum nl80211_mesh_power_mode rtw_mesh_ps_to_nl80211_mesh_power_mode(u8 ps)
2418 {
2419 	if (ps == RTW_MESH_PS_UNKNOWN)
2420 		return NL80211_MESH_POWER_UNKNOWN;
2421 	if (ps == RTW_MESH_PS_ACTIVE)
2422 		return NL80211_MESH_POWER_ACTIVE;
2423 	if (ps == RTW_MESH_PS_LSLEEP)
2424 		return NL80211_MESH_POWER_LIGHT_SLEEP;
2425 	if (ps == RTW_MESH_PS_DSLEEP)
2426 		return NL80211_MESH_POWER_DEEP_SLEEP;
2427 
2428 	rtw_warn_on(1);
2429 	return NL80211_MESH_POWER_UNKNOWN;
2430 }
2431 #endif
2432 
2433 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
rtw_plink_state_to_nl80211_plink_state(u8 plink_state)2434 enum nl80211_plink_state rtw_plink_state_to_nl80211_plink_state(u8 plink_state)
2435 {
2436 	if (plink_state == RTW_MESH_PLINK_UNKNOWN)
2437 		return NUM_NL80211_PLINK_STATES;
2438 	if (plink_state == RTW_MESH_PLINK_LISTEN)
2439 		return NL80211_PLINK_LISTEN;
2440 	if (plink_state == RTW_MESH_PLINK_OPN_SNT)
2441 		return NL80211_PLINK_OPN_SNT;
2442 	if (plink_state == RTW_MESH_PLINK_OPN_RCVD)
2443 		return NL80211_PLINK_OPN_RCVD;
2444 	if (plink_state == RTW_MESH_PLINK_CNF_RCVD)
2445 		return NL80211_PLINK_CNF_RCVD;
2446 	if (plink_state == RTW_MESH_PLINK_ESTAB)
2447 		return NL80211_PLINK_ESTAB;
2448 	if (plink_state == RTW_MESH_PLINK_HOLDING)
2449 		return NL80211_PLINK_HOLDING;
2450 	if (plink_state == RTW_MESH_PLINK_BLOCKED)
2451 		return NL80211_PLINK_BLOCKED;
2452 
2453 	rtw_warn_on(1);
2454 	return NUM_NL80211_PLINK_STATES;
2455 }
2456 
nl80211_plink_state_to_rtw_plink_state(enum nl80211_plink_state plink_state)2457 u8 nl80211_plink_state_to_rtw_plink_state(enum nl80211_plink_state plink_state)
2458 {
2459 	if (plink_state == NL80211_PLINK_LISTEN)
2460 		return RTW_MESH_PLINK_LISTEN;
2461 	if (plink_state == NL80211_PLINK_OPN_SNT)
2462 		return RTW_MESH_PLINK_OPN_SNT;
2463 	if (plink_state == NL80211_PLINK_OPN_RCVD)
2464 		return RTW_MESH_PLINK_OPN_RCVD;
2465 	if (plink_state == NL80211_PLINK_CNF_RCVD)
2466 		return RTW_MESH_PLINK_CNF_RCVD;
2467 	if (plink_state == NL80211_PLINK_ESTAB)
2468 		return RTW_MESH_PLINK_ESTAB;
2469 	if (plink_state == NL80211_PLINK_HOLDING)
2470 		return RTW_MESH_PLINK_HOLDING;
2471 	if (plink_state == NL80211_PLINK_BLOCKED)
2472 		return RTW_MESH_PLINK_BLOCKED;
2473 
2474 	rtw_warn_on(1);
2475 	return RTW_MESH_PLINK_UNKNOWN;
2476 }
2477 #endif
2478 
rtw_cfg80211_fill_mesh_only_sta_info(struct mesh_plink_ent * plink,struct sta_info * sta,struct station_info * sinfo)2479 static void rtw_cfg80211_fill_mesh_only_sta_info(struct mesh_plink_ent *plink, struct sta_info *sta, struct station_info *sinfo)
2480 {
2481 	sinfo->filled |= STATION_INFO_LLID;
2482 	sinfo->llid = plink->llid;
2483 	sinfo->filled |= STATION_INFO_PLID;
2484 	sinfo->plid = plink->plid;
2485 	sinfo->filled |= STATION_INFO_PLINK_STATE;
2486 	sinfo->plink_state = rtw_plink_state_to_nl80211_plink_state(plink->plink_state);
2487 	if (!sta && plink->scanned) {
2488 		sinfo->filled |= STATION_INFO_SIGNAL;
2489 		sinfo->signal = translate_percentage_to_dbm(plink->scanned->network.PhyInfo.SignalStrength);
2490 		sinfo->filled |= STATION_INFO_INACTIVE_TIME;
2491 		if (plink->plink_state == RTW_MESH_PLINK_UNKNOWN)
2492 			sinfo->inactive_time = 0 - 1;
2493 		else
2494 			sinfo->inactive_time = rtw_get_passing_time_ms(plink->scanned->last_scanned);
2495 	}
2496 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2497 	if (sta) {
2498 		sinfo->filled |= STATION_INFO_LOCAL_PM;
2499 		sinfo->local_pm = rtw_mesh_ps_to_nl80211_mesh_power_mode(sta->local_mps);
2500 		sinfo->filled |= STATION_INFO_PEER_PM;
2501 		sinfo->peer_pm = rtw_mesh_ps_to_nl80211_mesh_power_mode(sta->peer_mps);
2502 		sinfo->filled |= STATION_INFO_NONPEER_PM;
2503 		sinfo->nonpeer_pm = rtw_mesh_ps_to_nl80211_mesh_power_mode(sta->nonpeer_mps);
2504 	}
2505 #endif
2506 }
2507 #endif /* CONFIG_RTW_MESH */
2508 
rtw_desc_rate_to_nss_mcs(u8 rate_idx,u8 sgi,u8 * nss,u8 * mcs)2509 static void rtw_desc_rate_to_nss_mcs(u8 rate_idx, u8 sgi, u8 *nss, u8 *mcs)
2510 {
2511 	u8 mcs_in = 0, nss_in = 0;
2512 
2513 	if ((DESC_RATEMCS0 <= rate_idx) &&
2514 	   (rate_idx <= DESC_RATEMCS31)) {
2515 		mcs_in = rate_idx - DESC_RATEMCS0;
2516 	} else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) &&
2517 		   (rate_idx <= DESC_RATEVHTSS4MCS9)) {
2518 		mcs_in = (rate_idx - DESC_RATEVHTSS1MCS0) % 10;
2519 		nss_in = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1;
2520 	}
2521 
2522 	if (nss)
2523 		*nss = nss_in;
2524 	if (mcs)
2525 		*mcs = mcs_in;
2526 }
2527 
sta_set_rate_info(_adapter * adapter,struct rate_info * rinfo,u8 rtw_rate_idx,u8 sgi,u8 bw)2528 static void sta_set_rate_info(_adapter *adapter, struct rate_info *rinfo,
2529 			      u8 rtw_rate_idx, u8 sgi, u8 bw)
2530 {
2531 	u8 mcs = 0;
2532 	u8 nss = 0;
2533 
2534 	rinfo->flags = 0;
2535 	rtw_desc_rate_to_nss_mcs(rtw_rate_idx, sgi, &nss, &mcs);
2536 
2537 	if (sgi)
2538 		rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
2539 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
2540 	if (nss) {
2541 		rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
2542 		rinfo->bw = bw == CHANNEL_WIDTH_160 ? RATE_INFO_BW_160 :
2543 			    bw == CHANNEL_WIDTH_80 ? RATE_INFO_BW_80 :
2544 			    bw == CHANNEL_WIDTH_40 ? RATE_INFO_BW_40 : RATE_INFO_BW_20;
2545 		rinfo->nss = nss;
2546 		rinfo->mcs = mcs;
2547 	} else if (mcs) {
2548 		rinfo->flags |= RATE_INFO_FLAGS_MCS;
2549 		rinfo->bw = bw ? RATE_INFO_BW_40 : RATE_INFO_BW_20;
2550 		rinfo->mcs = mcs;
2551 	}
2552 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
2553 	if (nss) {
2554 		rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
2555 		rinfo->flags |= bw == CHANNEL_WIDTH_160 ? RATE_INFO_FLAGS_160_MHZ_WIDTH :
2556 				bw == CHANNEL_WIDTH_80 ? RATE_INFO_FLAGS_80_MHZ_WIDTH :
2557 				bw == CHANNEL_WIDTH_40 ? RATE_INFO_FLAGS_40_MHZ_WIDTH : 0;
2558 		rinfo->nss = nss;
2559 		rinfo->mcs = mcs;
2560 	} else if (mcs) {
2561 		rinfo->flags |= RATE_INFO_FLAGS_MCS;
2562 		rinfo->flags |= bw ? RATE_INFO_FLAGS_40_MHZ_WIDTH : 0;
2563 		rinfo->mcs = mcs;
2564 	}
2565 #else
2566 	if (nss) {
2567 		rinfo->legacy = 0;
2568 		RTW_INFO("Cannot report VHT rate in current kernel version\n");
2569 	} else if (mcs) {
2570 		rinfo->flags |= RATE_INFO_FLAGS_MCS;
2571 		rinfo->flags |= bw ? RATE_INFO_FLAGS_40_MHZ_WIDTH : 0;
2572 		rinfo->mcs = mcs;
2573 	}
2574 #endif
2575 	if (nss == 0 && mcs == 0)
2576 		rinfo->legacy = rtw_desc_rate_to_bitrate(0, rtw_rate_idx, 0);
2577 }
2578 
cfg80211_rtw_get_station(struct wiphy * wiphy,struct net_device * ndev,u8 * mac,struct station_info * sinfo)2579 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
2580 	struct net_device *ndev,
2581 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
2582 	u8 *mac,
2583 #else
2584 	const u8 *mac,
2585 #endif
2586 	struct station_info *sinfo)
2587 {
2588 	int ret = 0;
2589 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2590 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2591 	struct sta_info *psta = NULL;
2592 	struct sta_priv *pstapriv = &padapter->stapriv;
2593 #ifdef CONFIG_RTW_MESH
2594 	struct mesh_plink_ent *plink = NULL;
2595 #endif
2596 
2597 	sinfo->filled = 0;
2598 
2599 	if (!mac) {
2600 		RTW_INFO(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
2601 		ret = -ENOENT;
2602 		goto exit;
2603 	}
2604 
2605 	psta = rtw_get_stainfo(pstapriv, mac);
2606 #ifdef CONFIG_RTW_MESH
2607 	if (MLME_IS_MESH(padapter)) {
2608 		if (psta)
2609 			plink = psta->plink;
2610 		if (!plink)
2611 			plink = rtw_mesh_plink_get(padapter, mac);
2612 	}
2613 #endif /* CONFIG_RTW_MESH */
2614 
2615 	if ((!MLME_IS_MESH(padapter) && !psta)
2616 		#ifdef CONFIG_RTW_MESH
2617 		|| (MLME_IS_MESH(padapter) && !plink)
2618 		#endif
2619 	) {
2620 		RTW_INFO(FUNC_NDEV_FMT" no sta info for mac="MAC_FMT"\n"
2621 			, FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
2622 		ret = -ENOENT;
2623 		goto exit;
2624 	}
2625 
2626 #ifdef CONFIG_DEBUG_CFG80211
2627 	RTW_INFO(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
2628 #endif
2629 
2630 	/* for infra./P2PClient mode */
2631 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
2632 		&& check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
2633 	) {
2634 		struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
2635 
2636 		if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
2637 			RTW_INFO("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
2638 			ret = -ENOENT;
2639 			goto exit;
2640 		}
2641 
2642 		sinfo->filled |= STATION_INFO_SIGNAL;
2643 		sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
2644 
2645 		sinfo->filled |= STATION_INFO_TX_BITRATE;
2646 		sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
2647 	}
2648 
2649 	if (psta) {
2650 		u8 rtw_rate_idx, sgi, bw;
2651 
2652 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE
2653 			|| check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE
2654 		) {
2655 			sinfo->filled |= STATION_INFO_SIGNAL;
2656 			sinfo->signal = translate_percentage_to_dbm(psta->cmn.rssi_stat.rssi);
2657 		}
2658 		sinfo->filled |= STATION_INFO_INACTIVE_TIME;
2659 		sinfo->inactive_time = rtw_get_passing_time_ms(psta->sta_stats.last_rx_time);
2660 		sinfo->filled |= STATION_INFO_RX_PACKETS;
2661 		sinfo->rx_packets = sta_rx_data_pkts(psta);
2662 		sinfo->filled |= STATION_INFO_TX_PACKETS;
2663 		sinfo->tx_packets = psta->sta_stats.tx_pkts;
2664 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2665 		sinfo->filled |= STATION_INFO_RX_BYTES64;
2666 		sinfo->filled |= STATION_INFO_TX_BYTES64;
2667 #else
2668 		sinfo->filled |= STATION_INFO_RX_BYTES;
2669 		sinfo->filled |= STATION_INFO_TX_BYTES;
2670 #endif
2671 		sinfo->rx_bytes = psta->sta_stats.rx_bytes;
2672 		sinfo->tx_bytes = psta->sta_stats.tx_bytes;
2673 
2674 		/* Although according to cfg80211.h struct station_info */
2675 		/* @txrate: current unicast bitrate from this station */
2676 		/* We still report sinfo->txrate as bitrate to this station */
2677 		sinfo->filled |= STATION_INFO_TX_BITRATE;
2678 		rtw_rate_idx = rtw_get_current_tx_rate(padapter, psta);
2679 		sgi = rtw_get_current_tx_sgi(padapter, psta);
2680 		bw = psta->cmn.bw_mode;
2681 		sta_set_rate_info(padapter, &sinfo->txrate, rtw_rate_idx, sgi, bw);
2682 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
2683 		/* Although @rxrate: current unicast bitrate to this station */
2684 		/* We report sinfo->rxrate as bitrate from this station */
2685 		sinfo->filled |= STATION_INFO_RX_BITRATE;
2686 		rtw_rate_idx = psta->curr_rx_rate & 0x7f;
2687 		sgi = (psta->curr_rx_rate & 0x80) >> 7;
2688 		bw = psta->cmn.bw_mode;
2689 		sta_set_rate_info(padapter, &sinfo->rxrate, rtw_rate_idx, sgi, bw);
2690 #endif
2691 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2692 		if (rtw_get_sta_tx_stat(padapter, psta->cmn.mac_id, psta->cmn.mac_addr) != RTW_NOT_SUPPORT) {
2693 			sinfo->filled |= STATION_INFO_TX_FAILED;
2694 			sinfo->filled |= STATION_INFO_TX_RETRIES;
2695 			sinfo->tx_failed = psta->sta_stats.tx_fail_cnt_sum;
2696 			sinfo->tx_retries = psta->sta_stats.tx_retry_cnt_sum;
2697 		}
2698 #endif
2699 	}
2700 
2701 #ifdef CONFIG_RTW_MESH
2702 	if (MLME_IS_MESH(padapter))
2703 		rtw_cfg80211_fill_mesh_only_sta_info(plink, psta, sinfo);
2704 #endif
2705 
2706 exit:
2707 	return ret;
2708 }
2709 
2710 extern int netdev_open(struct net_device *pnetdev);
2711 
2712 #if 0
2713 enum nl80211_iftype {
2714 	NL80211_IFTYPE_UNSPECIFIED,
2715 	NL80211_IFTYPE_ADHOC, /* 1 */
2716 	NL80211_IFTYPE_STATION, /* 2 */
2717 	NL80211_IFTYPE_AP, /* 3 */
2718 	NL80211_IFTYPE_AP_VLAN,
2719 	NL80211_IFTYPE_WDS,
2720 	NL80211_IFTYPE_MONITOR, /* 6 */
2721 	NL80211_IFTYPE_MESH_POINT,
2722 	NL80211_IFTYPE_P2P_CLIENT, /* 8 */
2723 	NL80211_IFTYPE_P2P_GO, /* 9 */
2724 	/* keep last */
2725 	NUM_NL80211_IFTYPES,
2726 	NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
2727 };
2728 #endif
cfg80211_rtw_change_iface(struct wiphy * wiphy,struct net_device * ndev,enum nl80211_iftype type,u32 * flags,struct vif_params * params)2729 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
2730 				     struct net_device *ndev,
2731 				     enum nl80211_iftype type,
2732 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
2733 				     u32 *flags,
2734 #endif
2735 				     struct vif_params *params)
2736 {
2737 	enum nl80211_iftype old_type;
2738 	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
2739 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2740 	struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
2741 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2742 #ifdef CONFIG_P2P
2743 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2744 #endif
2745 #ifdef CONFIG_MONITOR_MODE_XMIT
2746 	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
2747 #endif
2748 	int ret = 0;
2749 	u8 change = _FALSE;
2750 
2751 	RTW_INFO(FUNC_NDEV_FMT" type=%d, hw_port:%d\n", FUNC_NDEV_ARG(ndev), type, padapter->hw_port);
2752 
2753 	if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
2754 		ret = -EPERM;
2755 		goto exit;
2756 	}
2757 
2758 
2759 	RTW_INFO(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
2760 	if (netdev_open(ndev) != 0) {
2761 		RTW_INFO(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
2762 		ret = -EPERM;
2763 		goto exit;
2764 	}
2765 
2766 
2767 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
2768 		RTW_INFO(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
2769 		ret = -EPERM;
2770 		goto exit;
2771 	}
2772 
2773 	old_type = rtw_wdev->iftype;
2774 	RTW_INFO(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
2775 		FUNC_NDEV_ARG(ndev), old_type, type);
2776 
2777 	if (old_type != type) {
2778 		change = _TRUE;
2779 		pmlmeext->action_public_rxseq = 0xffff;
2780 		pmlmeext->action_public_dialog_token = 0xff;
2781 	}
2782 
2783 	/* initial default type */
2784 	ndev->type = ARPHRD_ETHER;
2785 
2786 	/*
2787 	 * Disable Power Save in moniter mode,
2788 	 * and enable it after leaving moniter mode.
2789 	 */
2790 	if (type == NL80211_IFTYPE_MONITOR) {
2791 		rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE);
2792 		LeaveAllPowerSaveMode(padapter);
2793 	} else if (old_type == NL80211_IFTYPE_MONITOR) {
2794 		/* driver in moniter mode in last time */
2795 		rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE);
2796 	}
2797 
2798 	switch (type) {
2799 	case NL80211_IFTYPE_ADHOC:
2800 		networkType = Ndis802_11IBSS;
2801 		break;
2802 
2803 	case NL80211_IFTYPE_STATION:
2804 		networkType = Ndis802_11Infrastructure;
2805 		#ifdef CONFIG_P2P
2806 		if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
2807 			#if !RTW_P2P_GROUP_INTERFACE
2808 			if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)
2809 				|| rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
2810 			) {
2811 				/* it means remove GC/GO and change mode from GC/GO to station(P2P DEVICE) */
2812 				rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
2813 			}
2814 			#endif
2815 		}
2816 		#endif /* CONFIG_P2P */
2817 		break;
2818 
2819 	case NL80211_IFTYPE_AP:
2820 		networkType = Ndis802_11APMode;
2821 		#ifdef CONFIG_P2P
2822 		if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
2823 			#if !RTW_P2P_GROUP_INTERFACE
2824 			if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2825 				/* it means P2P Group created, we will be GO and change mode from  P2P DEVICE to AP(GO) */
2826 				rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
2827 			}
2828 			#endif
2829 		}
2830 		#endif /* CONFIG_P2P */
2831 		break;
2832 
2833 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
2834 	case NL80211_IFTYPE_P2P_CLIENT:
2835 		networkType = Ndis802_11Infrastructure;
2836 		if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
2837 			if (!rtw_p2p_enable(padapter, P2P_ROLE_CLIENT)) {
2838 				ret = -EOPNOTSUPP;
2839 				goto exit;
2840 			}
2841 		}
2842 		break;
2843 
2844 	case NL80211_IFTYPE_P2P_GO:
2845 		networkType = Ndis802_11APMode;
2846 		if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
2847 			if (!rtw_p2p_enable(padapter, P2P_ROLE_GO)) {
2848 				ret = -EOPNOTSUPP;
2849 				goto exit;
2850 			}
2851 		}
2852 		break;
2853 #endif /* defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) */
2854 
2855 #ifdef CONFIG_RTW_MESH
2856 	case NL80211_IFTYPE_MESH_POINT:
2857 		networkType = Ndis802_11_mesh;
2858 		break;
2859 #endif
2860 
2861 #ifdef CONFIG_WIFI_MONITOR
2862 	case NL80211_IFTYPE_MONITOR:
2863 		networkType = Ndis802_11Monitor;
2864 
2865 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
2866 		ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
2867 #else
2868 		ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
2869 #endif
2870 		break;
2871 #endif /* CONFIG_WIFI_MONITOR */
2872 	default:
2873 		ret = -EOPNOTSUPP;
2874 		goto exit;
2875 	}
2876 
2877 	rtw_wdev->iftype = type;
2878 
2879 	if (rtw_set_802_11_infrastructure_mode(padapter, networkType, 0) == _FALSE) {
2880 		rtw_wdev->iftype = old_type;
2881 		ret = -EPERM;
2882 		goto exit;
2883 	}
2884 
2885 	rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
2886 #ifdef CONFIG_MONITOR_MODE_XMIT
2887 	if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
2888 		rtw_indicate_connect(padapter);
2889 #endif
2890 
2891 	#if defined(CONFIG_RTW_WDS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
2892 	if (params->use_4addr != -1) {
2893 		RTW_INFO(FUNC_NDEV_FMT" use_4addr=%d\n"
2894 			, FUNC_NDEV_ARG(ndev), params->use_4addr);
2895 		adapter_set_use_wds(padapter, params->use_4addr);
2896 	}
2897 	#endif
2898 
2899 exit:
2900 
2901 	RTW_INFO(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
2902 	return ret;
2903 }
2904 
rtw_cfg80211_indicate_scan_done(_adapter * adapter,bool aborted)2905 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
2906 {
2907 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
2908 	_irqL	irqL;
2909 
2910 #if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
2911 	struct cfg80211_scan_info info;
2912 
2913 	memset(&info, 0, sizeof(info));
2914 	info.aborted = aborted;
2915 #endif
2916 
2917 	_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2918 	if (pwdev_priv->scan_request != NULL) {
2919 		#ifdef CONFIG_DEBUG_CFG80211
2920 		RTW_INFO("%s with scan req\n", __FUNCTION__);
2921 		#endif
2922 
2923 		/* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
2924 		if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
2925 			RTW_INFO("error wiphy compare\n");
2926 		else
2927 #if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
2928 			cfg80211_scan_done(pwdev_priv->scan_request, &info);
2929 #else
2930 			cfg80211_scan_done(pwdev_priv->scan_request, aborted);
2931 #endif
2932 
2933 		pwdev_priv->scan_request = NULL;
2934 	} else {
2935 		#ifdef CONFIG_DEBUG_CFG80211
2936 		RTW_INFO("%s without scan req\n", __FUNCTION__);
2937 		#endif
2938 	}
2939 	_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2940 }
2941 
rtw_cfg80211_wait_scan_req_empty(_adapter * adapter,u32 timeout_ms)2942 u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms)
2943 {
2944 	struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
2945 	u8 empty = _FALSE;
2946 	systime start;
2947 	u32 pass_ms;
2948 
2949 	start = rtw_get_current_time();
2950 
2951 	while (rtw_get_passing_time_ms(start) <= timeout_ms) {
2952 
2953 		if (RTW_CANNOT_RUN(adapter))
2954 			break;
2955 
2956 		if (!wdev_priv->scan_request) {
2957 			empty = _TRUE;
2958 			break;
2959 		}
2960 
2961 		rtw_msleep_os(10);
2962 	}
2963 
2964 	pass_ms = rtw_get_passing_time_ms(start);
2965 
2966 	if (empty == _FALSE && pass_ms > timeout_ms) {
2967 		RTW_PRINT(FUNC_ADPT_FMT" pass_ms:%u, timeout\n"
2968 			, FUNC_ADPT_ARG(adapter), pass_ms);
2969 		rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
2970 	}
2971 
2972 	return pass_ms;
2973 }
2974 
rtw_cfg80211_unlink_bss(_adapter * padapter,struct wlan_network * pnetwork)2975 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
2976 {
2977 	struct wireless_dev *pwdev = padapter->rtw_wdev;
2978 	struct wiphy *wiphy = pwdev->wiphy;
2979 	struct cfg80211_bss *bss = NULL;
2980 	WLAN_BSSID_EX select_network = pnetwork->network;
2981 
2982 	bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
2983 		select_network.MacAddress, select_network.Ssid.Ssid,
2984 		select_network.Ssid.SsidLength,
2985 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
2986 		select_network.InfrastructureMode == Ndis802_11Infrastructure?IEEE80211_BSS_TYPE_ESS:IEEE80211_BSS_TYPE_IBSS,
2987 		IEEE80211_PRIVACY(select_network.Privacy));
2988 #else
2989 		select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS,
2990 		select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS);
2991 #endif
2992 
2993 	if (bss) {
2994 		cfg80211_unlink_bss(wiphy, bss);
2995 		RTW_INFO("%s(): cfg80211_unlink %s!!\n", __func__, select_network.Ssid.Ssid);
2996 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
2997 		cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
2998 #else
2999 		cfg80211_put_bss(bss);
3000 #endif
3001 	}
3002 	return;
3003 }
3004 
3005 /* if target wps scan ongoing, target_ssid is filled */
rtw_cfg80211_is_target_wps_scan(struct cfg80211_scan_request * scan_req,struct cfg80211_ssid * target_ssid)3006 int rtw_cfg80211_is_target_wps_scan(struct cfg80211_scan_request *scan_req, struct cfg80211_ssid *target_ssid)
3007 {
3008 	int ret = 0;
3009 
3010 	if (scan_req->n_ssids != 1
3011 		|| scan_req->ssids[0].ssid_len == 0
3012 		|| scan_req->n_channels != 1
3013 	)
3014 		goto exit;
3015 
3016 	/* under target WPS scan */
3017 	_rtw_memcpy(target_ssid, scan_req->ssids, sizeof(struct cfg80211_ssid));
3018 	ret = 1;
3019 
3020 exit:
3021 	return ret;
3022 }
3023 
_rtw_cfg80211_surveydone_event_callback(_adapter * padapter,struct cfg80211_scan_request * scan_req)3024 static void _rtw_cfg80211_surveydone_event_callback(_adapter *padapter, struct cfg80211_scan_request *scan_req)
3025 {
3026 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
3027 	RT_CHANNEL_INFO *chset = rfctl->channel_set;
3028 	_irqL	irqL;
3029 	_list					*plist, *phead;
3030 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
3031 	_queue				*queue	= &(pmlmepriv->scanned_queue);
3032 	struct	wlan_network	*pnetwork = NULL;
3033 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
3034 	struct cfg80211_ssid target_ssid;
3035 	u8 target_wps_scan = 0;
3036 	u8 ch;
3037 
3038 #ifdef CONFIG_DEBUG_CFG80211
3039 	RTW_INFO("%s\n", __func__);
3040 #endif
3041 
3042 	if (scan_req)
3043 		target_wps_scan = rtw_cfg80211_is_target_wps_scan(scan_req, &target_ssid);
3044 	else {
3045 		_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3046 		if (pwdev_priv->scan_request != NULL)
3047 			target_wps_scan = rtw_cfg80211_is_target_wps_scan(pwdev_priv->scan_request, &target_ssid);
3048 		_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3049 	}
3050 
3051 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3052 
3053 	phead = get_list_head(queue);
3054 	plist = get_next(phead);
3055 
3056 	while (1) {
3057 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
3058 			break;
3059 
3060 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
3061 		ch = pnetwork->network.Configuration.DSConfig;
3062 
3063 		/* report network only if the current channel set contains the channel to which this network belongs */
3064 		if (rtw_chset_search_ch(chset, ch) >= 0
3065 			&& rtw_mlme_band_check(padapter, ch) == _TRUE
3066 			&& _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
3067 			&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
3068 				|| rtw_rfctl_dfs_domain_unknown(rfctl)
3069 				|| !rtw_chset_is_ch_non_ocp(chset, ch))
3070 		) {
3071 			if (target_wps_scan)
3072 				rtw_cfg80211_clear_wps_sr_of_non_target_bss(padapter, pnetwork, &target_ssid);
3073 			rtw_cfg80211_inform_bss(padapter, pnetwork);
3074 		}
3075 #if 0
3076 		/* check ralink testbed RSN IE length */
3077 		{
3078 			if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP", 13)) {
3079 				uint ie_len = 0;
3080 				u8 *p = NULL;
3081 				p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
3082 				RTW_INFO("ie_len=%d\n", ie_len);
3083 			}
3084 		}
3085 #endif
3086 		plist = get_next(plist);
3087 
3088 	}
3089 
3090 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3091 }
3092 
rtw_cfg80211_surveydone_event_callback(_adapter * padapter)3093 inline void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
3094 {
3095 	_rtw_cfg80211_surveydone_event_callback(padapter, NULL);
3096 }
3097 
rtw_cfg80211_set_probe_req_wpsp2pie(_adapter * padapter,char * buf,int len)3098 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
3099 {
3100 	int ret = 0;
3101 	uint wps_ielen = 0;
3102 	u8 *wps_ie;
3103 	u32	p2p_ielen = 0;
3104 	u8 *p2p_ie;
3105 	u32	wfd_ielen = 0;
3106 	u8 *wfd_ie;
3107 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3108 
3109 #ifdef CONFIG_DEBUG_CFG80211
3110 	RTW_INFO("%s, ielen=%d\n", __func__, len);
3111 #endif
3112 
3113 	if (len > 0) {
3114 		wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
3115 		if (wps_ie) {
3116 			#ifdef CONFIG_DEBUG_CFG80211
3117 			RTW_INFO("probe_req_wps_ielen=%d\n", wps_ielen);
3118 			#endif
3119 
3120 			if (pmlmepriv->wps_probe_req_ie) {
3121 				u32 free_len = pmlmepriv->wps_probe_req_ie_len;
3122 				pmlmepriv->wps_probe_req_ie_len = 0;
3123 				rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
3124 				pmlmepriv->wps_probe_req_ie = NULL;
3125 			}
3126 
3127 			pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
3128 			if (pmlmepriv->wps_probe_req_ie == NULL) {
3129 				RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
3130 				return -EINVAL;
3131 
3132 			}
3133 			_rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
3134 			pmlmepriv->wps_probe_req_ie_len = wps_ielen;
3135 		}
3136 
3137 		/* buf += wps_ielen; */
3138 		/* len -= wps_ielen; */
3139 
3140 		#ifdef CONFIG_P2P
3141 		p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
3142 		if (p2p_ie) {
3143 			struct wifidirect_info *wdinfo = &padapter->wdinfo;
3144 			u32 attr_contentlen = 0;
3145 			u8 listen_ch_attr[5];
3146 
3147 			#ifdef CONFIG_DEBUG_CFG80211
3148 			RTW_INFO("probe_req_p2p_ielen=%d\n", p2p_ielen);
3149 			#endif
3150 
3151 			if (pmlmepriv->p2p_probe_req_ie) {
3152 				u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
3153 				pmlmepriv->p2p_probe_req_ie_len = 0;
3154 				rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
3155 				pmlmepriv->p2p_probe_req_ie = NULL;
3156 			}
3157 
3158 			pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
3159 			if (pmlmepriv->p2p_probe_req_ie == NULL) {
3160 				RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
3161 				return -EINVAL;
3162 
3163 			}
3164 			_rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
3165 			pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
3166 
3167 			attr_contentlen = sizeof(listen_ch_attr);
3168 			if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8 *)listen_ch_attr, (uint *) &attr_contentlen)) {
3169 				if (wdinfo->listen_channel !=  listen_ch_attr[4]) {
3170 					RTW_INFO(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
3171 						FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
3172 						listen_ch_attr[3], listen_ch_attr[4]);
3173 					wdinfo->listen_channel = listen_ch_attr[4];
3174 				}
3175 			}
3176 		}
3177 		#endif /* CONFIG_P2P */
3178 
3179 		#ifdef CONFIG_WFD
3180 		wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
3181 		if (wfd_ie) {
3182 			#ifdef CONFIG_DEBUG_CFG80211
3183 			RTW_INFO("probe_req_wfd_ielen=%d\n", wfd_ielen);
3184 			#endif
3185 
3186 			if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
3187 				return -EINVAL;
3188 		}
3189 		#endif /* CONFIG_WFD */
3190 
3191 		#ifdef CONFIG_RTW_MBO
3192 		rtw_mbo_update_ie_data(padapter, buf, len);
3193 		#endif
3194 	}
3195 
3196 	return ret;
3197 
3198 }
3199 
3200 #ifdef CONFIG_CONCURRENT_MODE
rtw_cfg80211_scan_via_buddy(_adapter * padapter,struct cfg80211_scan_request * request)3201 u8 rtw_cfg80211_scan_via_buddy(_adapter *padapter, struct cfg80211_scan_request *request)
3202 {
3203 	int i;
3204 	u8 ret = _FALSE;
3205 	_adapter *iface = NULL;
3206 	_irqL	irqL;
3207 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3208 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
3209 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3210 
3211 	for (i = 0; i < dvobj->iface_nums; i++) {
3212 		struct mlme_priv *buddy_mlmepriv;
3213 		struct rtw_wdev_priv *buddy_wdev_priv;
3214 
3215 		iface = dvobj->padapters[i];
3216 		if (iface == NULL)
3217 			continue;
3218 
3219 		if (iface == padapter)
3220 			continue;
3221 
3222 		if (rtw_is_adapter_up(iface) == _FALSE)
3223 			continue;
3224 
3225 		buddy_mlmepriv = &iface->mlmepriv;
3226 		if (!check_fwstate(buddy_mlmepriv, WIFI_UNDER_SURVEY))
3227 			continue;
3228 
3229 		buddy_wdev_priv = adapter_wdev_data(iface);
3230 		_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3231 		_enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
3232 		if (buddy_wdev_priv->scan_request) {
3233 			pmlmepriv->scanning_via_buddy_intf = _TRUE;
3234 			_enter_critical_bh(&pmlmepriv->lock, &irqL);
3235 			set_fwstate(pmlmepriv, WIFI_UNDER_SURVEY);
3236 			_exit_critical_bh(&pmlmepriv->lock, &irqL);
3237 			pwdev_priv->scan_request = request;
3238 			ret = _TRUE;
3239 		}
3240 		_exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
3241 		_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3242 
3243 		if (ret == _TRUE)
3244 			goto exit;
3245 	}
3246 
3247 exit:
3248 	return ret;
3249 }
3250 
rtw_cfg80211_indicate_scan_done_for_buddy(_adapter * padapter,bool bscan_aborted)3251 void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_aborted)
3252 {
3253 	int i;
3254 	_adapter *iface = NULL;
3255 	_irqL	irqL;
3256 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3257 	struct mlme_priv *mlmepriv;
3258 	struct rtw_wdev_priv *wdev_priv;
3259 	bool indicate_buddy_scan;
3260 
3261 	for (i = 0; i < dvobj->iface_nums; i++) {
3262 		iface = dvobj->padapters[i];
3263 		if ((iface) && rtw_is_adapter_up(iface)) {
3264 
3265 			if (iface == padapter)
3266 				continue;
3267 
3268 			mlmepriv = &(iface->mlmepriv);
3269 			wdev_priv = adapter_wdev_data(iface);
3270 
3271 			indicate_buddy_scan = _FALSE;
3272 			_enter_critical_bh(&wdev_priv->scan_req_lock, &irqL);
3273 			if (mlmepriv->scanning_via_buddy_intf == _TRUE) {
3274 				mlmepriv->scanning_via_buddy_intf = _FALSE;
3275 				clr_fwstate(mlmepriv, WIFI_UNDER_SURVEY);
3276 				if (wdev_priv->scan_request)
3277 					indicate_buddy_scan = _TRUE;
3278 			}
3279 			_exit_critical_bh(&wdev_priv->scan_req_lock, &irqL);
3280 
3281 			if (indicate_buddy_scan == _TRUE) {
3282 				rtw_cfg80211_surveydone_event_callback(iface);
3283 				rtw_indicate_scan_done(iface, bscan_aborted);
3284 			}
3285 
3286 		}
3287 	}
3288 }
3289 #endif /* CONFIG_CONCURRENT_MODE */
3290 
cfg80211_rtw_scan(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_scan_request * request)3291 static int cfg80211_rtw_scan(struct wiphy *wiphy
3292 	#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
3293 	, struct net_device *ndev
3294 	#endif
3295 	, struct cfg80211_scan_request *request)
3296 {
3297 	int i;
3298 	u8 _status = _FALSE;
3299 	int ret = 0;
3300 	struct sitesurvey_parm parm;
3301 	_irqL	irqL;
3302 	u8 survey_times = 3;
3303 	u8 survey_times_for_one_ch = 6;
3304 	struct cfg80211_ssid *ssids = request->ssids;
3305 	int social_channel = 0, j = 0;
3306 	bool need_indicate_scan_done = _FALSE;
3307 	bool ps_denied = _FALSE;
3308 	u8 ssc_chk;
3309 	_adapter *padapter;
3310 	struct wireless_dev *wdev;
3311 	struct rtw_wdev_priv *pwdev_priv;
3312 	struct mlme_priv *pmlmepriv = NULL;
3313 #ifdef CONFIG_P2P
3314 	struct wifidirect_info *pwdinfo;
3315 #endif /* CONFIG_P2P */
3316 
3317 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3318 	wdev = request->wdev;
3319 	#if defined(RTW_DEDICATED_P2P_DEVICE)
3320 	if (wdev == wiphy_to_pd_wdev(wiphy))
3321 		padapter = wiphy_to_adapter(wiphy);
3322 	else
3323 	#endif
3324 	if (wdev_to_ndev(wdev))
3325 		padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
3326 	else {
3327 		ret = -EINVAL;
3328 		goto exit;
3329 	}
3330 #else
3331 	if (ndev == NULL) {
3332 		ret = -EINVAL;
3333 		goto exit;
3334 	}
3335 	padapter = (_adapter *)rtw_netdev_priv(ndev);
3336 	wdev = ndev_to_wdev(ndev);
3337 #endif
3338 
3339 	pwdev_priv = adapter_wdev_data(padapter);
3340 	pmlmepriv = &padapter->mlmepriv;
3341 #ifdef CONFIG_P2P
3342 	pwdinfo = &(padapter->wdinfo);
3343 #endif /* CONFIG_P2P */
3344 
3345 	RTW_INFO(FUNC_ADPT_FMT"%s\n", FUNC_ADPT_ARG(padapter)
3346 		, wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "");
3347 
3348 #ifdef CONFIG_RTW_SCAN_RAND
3349 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
3350 	if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
3351 		get_random_mask_addr(pwdev_priv->pno_mac_addr, request->mac_addr,
3352 				     request->mac_addr_mask);
3353 		print_hex_dump(KERN_DEBUG, "random mac_addr: ",
3354 			DUMP_PREFIX_OFFSET, 16, 1, pwdev_priv->pno_mac_addr, ETH_ALEN, 1);
3355 	}
3356 	else
3357 		memset(pwdev_priv->pno_mac_addr, 0xFF, ETH_ALEN);
3358 
3359 #endif
3360 #endif
3361 
3362 
3363 #if 1
3364 	ssc_chk = rtw_sitesurvey_condition_check(padapter, _TRUE);
3365 
3366 	if (ssc_chk == SS_DENY_MP_MODE)
3367 		goto bypass_p2p_chk;
3368 #ifdef DBG_LA_MODE
3369 	if (ssc_chk == SS_DENY_LA_MODE)
3370 		goto bypass_p2p_chk;
3371 #endif
3372 #ifdef CONFIG_P2P
3373 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
3374 		if (request->n_ssids && ssids
3375 			&& _rtw_memcmp(ssids[0].ssid, "DIRECT-", 7)
3376 			&& rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
3377 		) {
3378 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3379 				if (!rtw_p2p_enable(padapter, P2P_ROLE_DEVICE)) {
3380 					ret = -EOPNOTSUPP;
3381 					goto exit;
3382 				}
3383 			} else {
3384 				rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3385 				#ifdef CONFIG_DEBUG_CFG80211
3386 				RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3387 				#endif
3388 			}
3389 			rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3390 
3391 			if (request->n_channels == 3 &&
3392 				request->channels[0]->hw_value == 1 &&
3393 				request->channels[1]->hw_value == 6 &&
3394 				request->channels[2]->hw_value == 11
3395 			)
3396 				social_channel = 1;
3397 		}
3398 	}
3399 #endif /*CONFIG_P2P*/
3400 
3401 	if (request->ie && request->ie_len > 0)
3402 		rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
3403 
3404 bypass_p2p_chk:
3405 
3406 	switch (ssc_chk) {
3407 		case SS_ALLOW :
3408 			break;
3409 
3410 		case SS_DENY_MP_MODE:
3411 			ret = -EPERM;
3412 			goto exit;
3413 		#ifdef DBG_LA_MODE
3414 		case SS_DENY_LA_MODE:
3415 			ret = -EPERM;
3416 			goto exit;
3417 		#endif
3418 		#ifdef CONFIG_RTW_REPEATER_SON
3419 		case SS_DENY_RSON_SCANING :
3420 		#endif
3421 		case SS_DENY_BLOCK_SCAN :
3422 		case SS_DENY_SELF_AP_UNDER_WPS :
3423 		case SS_DENY_SELF_AP_UNDER_LINKING :
3424 		case SS_DENY_SELF_AP_UNDER_SURVEY :
3425 		case SS_DENY_SELF_STA_UNDER_SURVEY :
3426 		#ifdef CONFIG_CONCURRENT_MODE
3427 		case SS_DENY_BUDDY_UNDER_LINK_WPS :
3428 		#endif
3429 		case SS_DENY_BUSY_TRAFFIC :
3430 		case SS_DENY_ADAPTIVITY:
3431 			need_indicate_scan_done = _TRUE;
3432 			goto check_need_indicate_scan_done;
3433 
3434 		case SS_DENY_BY_DRV :
3435 			#ifdef CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY
3436 			ret = -EBUSY;
3437 			goto exit;
3438 			#else
3439 			need_indicate_scan_done = _TRUE;
3440 			goto check_need_indicate_scan_done;
3441 			#endif
3442 			break;
3443 
3444 		case SS_DENY_SELF_STA_UNDER_LINKING :
3445 			ret = -EBUSY;
3446 			goto check_need_indicate_scan_done;
3447 
3448 		#ifdef CONFIG_CONCURRENT_MODE
3449 		case SS_DENY_BUDDY_UNDER_SURVEY :
3450 			{
3451 				bool scan_via_buddy = rtw_cfg80211_scan_via_buddy(padapter, request);
3452 
3453 				if (scan_via_buddy == _FALSE)
3454 					need_indicate_scan_done = _TRUE;
3455 
3456 				goto check_need_indicate_scan_done;
3457 			}
3458 		#endif
3459 
3460 		default :
3461 			RTW_ERR("site survey check code (%d) unknown\n", ssc_chk);
3462 			need_indicate_scan_done = _TRUE;
3463 			goto check_need_indicate_scan_done;
3464 	}
3465 
3466 	rtw_ps_deny(padapter, PS_DENY_SCAN);
3467 	ps_denied = _TRUE;
3468 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
3469 		need_indicate_scan_done = _TRUE;
3470 		goto check_need_indicate_scan_done;
3471 	}
3472 
3473 #else
3474 
3475 
3476 #ifdef CONFIG_MP_INCLUDED
3477 	if (rtw_mp_mode_check(padapter)) {
3478 		RTW_INFO("MP mode block Scan request\n");
3479 		ret = -EPERM;
3480 		goto exit;
3481 	}
3482 #endif
3483 
3484 #ifdef CONFIG_P2P
3485 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
3486 		if (request->n_ssids && ssids
3487 			&& _rtw_memcmp(ssids[0].ssid, "DIRECT-", 7)
3488 			&& rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
3489 		) {
3490 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3491 				rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
3492 			else {
3493 				rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3494 				#ifdef CONFIG_DEBUG_CFG80211
3495 				RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3496 				#endif
3497 			}
3498 			rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3499 
3500 			if (request->n_channels == 3 &&
3501 				request->channels[0]->hw_value == 1 &&
3502 				request->channels[1]->hw_value == 6 &&
3503 				request->channels[2]->hw_value == 11
3504 			)
3505 				social_channel = 1;
3506 		}
3507 	}
3508 #endif /*CONFIG_P2P*/
3509 
3510 	if (request->ie && request->ie_len > 0)
3511 		rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
3512 
3513 #ifdef CONFIG_RTW_REPEATER_SON
3514 	if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {
3515 		RTW_INFO(FUNC_ADPT_FMT" blocking scan for under rson scanning process\n", FUNC_ADPT_ARG(padapter));
3516 		need_indicate_scan_done = _TRUE;
3517 		goto check_need_indicate_scan_done;
3518 	}
3519 #endif
3520 
3521 	if (adapter_wdev_data(padapter)->block_scan == _TRUE) {
3522 		RTW_INFO(FUNC_ADPT_FMT" wdev_priv.block_scan is set\n", FUNC_ADPT_ARG(padapter));
3523 		need_indicate_scan_done = _TRUE;
3524 		goto check_need_indicate_scan_done;
3525 	}
3526 
3527 	rtw_ps_deny(padapter, PS_DENY_SCAN);
3528 	ps_denied = _TRUE;
3529 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
3530 		need_indicate_scan_done = _TRUE;
3531 		goto check_need_indicate_scan_done;
3532 	}
3533 
3534 	if (rtw_is_scan_deny(padapter)) {
3535 		RTW_INFO(FUNC_ADPT_FMT	": scan deny\n", FUNC_ADPT_ARG(padapter));
3536 #ifdef CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY
3537 		ret = -EBUSY;
3538 		goto exit;
3539 #else
3540 		need_indicate_scan_done = _TRUE;
3541 		goto check_need_indicate_scan_done;
3542 #endif
3543 	}
3544 
3545 	/* check fw state*/
3546 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
3547 
3548 #ifdef CONFIG_DEBUG_CFG80211
3549 		RTW_INFO(FUNC_ADPT_FMT" under WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter));
3550 #endif
3551 
3552 		if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) {
3553 			RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
3554 
3555 			if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
3556 				RTW_INFO("AP mode process WPS\n");
3557 
3558 			need_indicate_scan_done = _TRUE;
3559 			goto check_need_indicate_scan_done;
3560 		}
3561 	}
3562 
3563 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) {
3564 		RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
3565 		need_indicate_scan_done = _TRUE;
3566 		goto check_need_indicate_scan_done;
3567 	} else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) {
3568 		RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
3569 		ret = -EBUSY;
3570 		goto check_need_indicate_scan_done;
3571 	}
3572 
3573 #ifdef CONFIG_CONCURRENT_MODE
3574 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) {
3575 		RTW_INFO("%s exit due to buddy_intf's mlme state under linking or wps\n", __func__);
3576 		need_indicate_scan_done = _TRUE;
3577 		goto check_need_indicate_scan_done;
3578 
3579 	} else if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY)) {
3580 		bool scan_via_buddy = rtw_cfg80211_scan_via_buddy(padapter, request);
3581 
3582 		if (scan_via_buddy == _FALSE)
3583 			need_indicate_scan_done = _TRUE;
3584 
3585 		goto check_need_indicate_scan_done;
3586 	}
3587 #endif /* CONFIG_CONCURRENT_MODE */
3588 
3589 #ifdef RTW_BUSY_DENY_SCAN
3590 	/*
3591 	 * busy traffic check
3592 	 * Rules:
3593 	 * 1. If (scan interval <= BUSY_TRAFFIC_SCAN_DENY_PERIOD) always allow
3594 	 *    scan, otherwise goto rule 2.
3595 	 * 2. Deny scan if any interface is busy, otherwise allow scan.
3596 	 */
3597 	if (pmlmepriv->lastscantime
3598 	    && (rtw_get_passing_time_ms(pmlmepriv->lastscantime) >
3599 		registry_par->scan_interval_thr)
3600 	    && rtw_mi_busy_traffic_check(padapter)) {
3601 		RTW_WARN(FUNC_ADPT_FMT ": scan abort!! BusyTraffic\n",
3602 			 FUNC_ADPT_ARG(padapter));
3603  		need_indicate_scan_done = _TRUE;
3604 		goto check_need_indicate_scan_done;
3605 	}
3606 #endif /* RTW_BUSY_DENY_SCAN */
3607 #endif
3608 
3609 #ifdef CONFIG_P2P
3610 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
3611 		rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
3612 
3613 		if (social_channel == 0)
3614 			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
3615 		else
3616 			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
3617 	}
3618 #endif /* CONFIG_P2P */
3619 
3620 	rtw_init_sitesurvey_parm(padapter, &parm);
3621 
3622 	/* parsing request ssids, n_ssids */
3623 	for (i = 0; i < request->n_ssids && ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
3624 		#ifdef CONFIG_DEBUG_CFG80211
3625 		RTW_INFO("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
3626 		#endif
3627 		_rtw_memcpy(&parm.ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
3628 		parm.ssid[i].SsidLength = ssids[i].ssid_len;
3629 	}
3630 	parm.ssid_num = i;
3631 
3632 	/* no ssid entry, set the scan type as passvie */
3633 	if (request->n_ssids == 0)
3634 		parm.scan_mode = SCAN_PASSIVE;
3635 
3636 	/* parsing channels, n_channels */
3637 	for (i = 0; i < request->n_channels && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
3638 		#ifdef CONFIG_DEBUG_CFG80211
3639 		RTW_INFO(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
3640 		#endif
3641 		parm.ch[i].hw_value = request->channels[i]->hw_value;
3642 		parm.ch[i].flags = request->channels[i]->flags;
3643 	}
3644 	parm.ch_num = i;
3645 
3646 	if (request->n_channels == 1) {
3647 		for (i = 1; i < survey_times_for_one_ch; i++)
3648 			_rtw_memcpy(&parm.ch[i], &parm.ch[0], sizeof(struct rtw_ieee80211_channel));
3649 		parm.ch_num = survey_times_for_one_ch;
3650 	} else if (request->n_channels <= 4) {
3651 		for (j = request->n_channels - 1; j >= 0; j--)
3652 			for (i = 0; i < survey_times; i++)
3653 				_rtw_memcpy(&parm.ch[j * survey_times + i], &parm.ch[j], sizeof(struct rtw_ieee80211_channel));
3654 		parm.ch_num = survey_times * request->n_channels;
3655 	}
3656 
3657 	_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3658 	_enter_critical_bh(&pmlmepriv->lock, &irqL);
3659 	_status = rtw_sitesurvey_cmd(padapter, &parm);
3660 	if (_status == _SUCCESS)
3661 		pwdev_priv->scan_request = request;
3662 	else
3663 		ret = -1;
3664 	_exit_critical_bh(&pmlmepriv->lock, &irqL);
3665 	_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3666 
3667 check_need_indicate_scan_done:
3668 	if (_TRUE == need_indicate_scan_done) {
3669 #if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
3670 		struct cfg80211_scan_info info;
3671 
3672 		memset(&info, 0, sizeof(info));
3673 		info.aborted = 0;
3674 #endif
3675 		/* the process time of scan results must be over at least 1ms in the newly Android */
3676 		rtw_msleep_os(1);
3677 
3678 		_rtw_cfg80211_surveydone_event_callback(padapter, request);
3679 #if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
3680 		cfg80211_scan_done(request, &info);
3681 #else
3682 		cfg80211_scan_done(request, 0);
3683 #endif
3684 	}
3685 
3686 	if (ps_denied == _TRUE)
3687 		rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
3688 
3689 exit:
3690 #ifdef RTW_BUSY_DENY_SCAN
3691 	if (pmlmepriv)
3692 		pmlmepriv->lastscantime = rtw_get_current_time();
3693 #endif
3694 
3695 	return ret;
3696 }
3697 
3698 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
cfg80211_rtw_abort_scan(struct wiphy * wiphy,struct wireless_dev * wdev)3699 static void cfg80211_rtw_abort_scan(struct wiphy *wiphy,
3700 				    struct wireless_dev *wdev)
3701 {
3702 	_adapter *padapter = wiphy_to_adapter(wiphy);
3703 
3704 	RTW_INFO("=>"FUNC_ADPT_FMT" - Abort Scan\n", FUNC_ADPT_ARG(padapter));
3705 	if (wdev->iftype != NL80211_IFTYPE_STATION) {
3706 		RTW_ERR("abort scan ignored, iftype(%d)\n", wdev->iftype);
3707 		return;
3708 	}
3709 	rtw_scan_abort(padapter);
3710 }
3711 #endif
3712 
cfg80211_rtw_set_wiphy_params(struct wiphy * wiphy,u32 changed)3713 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
3714 {
3715 #if 0
3716 	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
3717 
3718 	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
3719 	    (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
3720 		int ret;
3721 
3722 		iwm->conf.rts_threshold = wiphy->rts_threshold;
3723 
3724 		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
3725 				CFG_RTS_THRESHOLD,
3726 				iwm->conf.rts_threshold);
3727 		if (ret < 0)
3728 			return ret;
3729 	}
3730 
3731 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
3732 	    (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
3733 		int ret;
3734 
3735 		iwm->conf.frag_threshold = wiphy->frag_threshold;
3736 
3737 		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
3738 				CFG_FRAG_THRESHOLD,
3739 				iwm->conf.frag_threshold);
3740 		if (ret < 0)
3741 			return ret;
3742 	}
3743 #endif
3744 	RTW_INFO("%s\n", __func__);
3745 	return 0;
3746 }
3747 
3748 
3749 
rtw_cfg80211_set_wpa_version(struct security_priv * psecuritypriv,u32 wpa_version)3750 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
3751 {
3752 	RTW_INFO("%s, wpa_version=%d\n", __func__, wpa_version);
3753 
3754 	if (!wpa_version) {
3755 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
3756 		return 0;
3757 	}
3758 
3759 
3760 	if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
3761 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
3762 
3763 #if 0
3764 	if (wpa_version & NL80211_WPA_VERSION_2)
3765 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
3766 #endif
3767 
3768 	#ifdef CONFIG_WAPI_SUPPORT
3769 	if (wpa_version & NL80211_WAPI_VERSION_1)
3770 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
3771 	#endif
3772 
3773 	return 0;
3774 
3775 }
3776 
rtw_cfg80211_set_auth_type(struct security_priv * psecuritypriv,enum nl80211_auth_type sme_auth_type)3777 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
3778 		enum nl80211_auth_type sme_auth_type)
3779 {
3780 	RTW_INFO("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
3781 
3782 #ifndef CONFIG_KERNEL_PATCH_EXTERNAL_AUTH
3783 	if (NL80211_AUTHTYPE_MAX <= (int)MLME_AUTHTYPE_SAE) {
3784 		if (MLME_AUTHTYPE_SAE == psecuritypriv->auth_type) {
3785 			/* This case pre handle in
3786 			 * rtw_check_connect_sae_compat()
3787 			 */
3788 			psecuritypriv->auth_alg = WLAN_AUTH_SAE;
3789 			return 0;
3790 		}
3791 	} else
3792 #endif
3793 	if (sme_auth_type == (int)MLME_AUTHTYPE_SAE) {
3794 		psecuritypriv->auth_type = MLME_AUTHTYPE_SAE;
3795 		psecuritypriv->auth_alg = WLAN_AUTH_SAE;
3796 		return 0;
3797 	}
3798 
3799 	psecuritypriv->auth_type = sme_auth_type;
3800 
3801 	switch (sme_auth_type) {
3802 	case NL80211_AUTHTYPE_AUTOMATIC:
3803 
3804 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3805 
3806 		break;
3807 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
3808 
3809 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3810 
3811 		if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
3812 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3813 
3814 #ifdef CONFIG_WAPI_SUPPORT
3815 		if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
3816 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3817 #endif
3818 
3819 		break;
3820 	case NL80211_AUTHTYPE_SHARED_KEY:
3821 
3822 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
3823 
3824 		psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
3825 
3826 
3827 		break;
3828 	default:
3829 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3830 		/* return -ENOTSUPP; */
3831 	}
3832 
3833 	return 0;
3834 
3835 }
3836 
rtw_cfg80211_set_cipher(struct security_priv * psecuritypriv,u32 cipher,bool ucast)3837 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
3838 {
3839 	u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
3840 
3841 	u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
3842 		&psecuritypriv->dot118021XGrpPrivacy;
3843 
3844 	RTW_INFO("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
3845 
3846 
3847 	if (!cipher) {
3848 		*profile_cipher = _NO_PRIVACY_;
3849 		psecuritypriv->ndisencryptstatus = ndisencryptstatus;
3850 		return 0;
3851 	}
3852 
3853 	switch (cipher) {
3854 	case IW_AUTH_CIPHER_NONE:
3855 		*profile_cipher = _NO_PRIVACY_;
3856 		ndisencryptstatus = Ndis802_11EncryptionDisabled;
3857 #ifdef CONFIG_WAPI_SUPPORT
3858 		if (psecuritypriv->dot11PrivacyAlgrthm == _SMS4_)
3859 			*profile_cipher = _SMS4_;
3860 #endif
3861 		break;
3862 	case WLAN_CIPHER_SUITE_WEP40:
3863 		*profile_cipher = _WEP40_;
3864 		ndisencryptstatus = Ndis802_11Encryption1Enabled;
3865 		break;
3866 	case WLAN_CIPHER_SUITE_WEP104:
3867 		*profile_cipher = _WEP104_;
3868 		ndisencryptstatus = Ndis802_11Encryption1Enabled;
3869 		break;
3870 	case WLAN_CIPHER_SUITE_TKIP:
3871 		*profile_cipher = _TKIP_;
3872 		ndisencryptstatus = Ndis802_11Encryption2Enabled;
3873 		break;
3874 	case WLAN_CIPHER_SUITE_CCMP:
3875 		*profile_cipher = _AES_;
3876 		ndisencryptstatus = Ndis802_11Encryption3Enabled;
3877 		break;
3878 	case WIFI_CIPHER_SUITE_GCMP:
3879 		*profile_cipher = _GCMP_;
3880 		ndisencryptstatus = Ndis802_11Encryption3Enabled;
3881 		break;
3882 	case WIFI_CIPHER_SUITE_GCMP_256:
3883 		*profile_cipher = _GCMP_256_;
3884 		ndisencryptstatus = Ndis802_11Encryption3Enabled;
3885 		break;
3886 	case WIFI_CIPHER_SUITE_CCMP_256:
3887 		*profile_cipher = _CCMP_256_;
3888 		ndisencryptstatus = Ndis802_11Encryption3Enabled;
3889 		break;
3890 #ifdef CONFIG_WAPI_SUPPORT
3891 	case WLAN_CIPHER_SUITE_SMS4:
3892 		*profile_cipher = _SMS4_;
3893 		ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
3894 		break;
3895 #endif
3896 	default:
3897 		RTW_INFO("Unsupported cipher: 0x%x\n", cipher);
3898 		return -ENOTSUPP;
3899 	}
3900 
3901 	if (ucast) {
3902 		psecuritypriv->ndisencryptstatus = ndisencryptstatus;
3903 
3904 		/* if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_) */
3905 		/*	psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; */
3906 	}
3907 
3908 	return 0;
3909 }
3910 
rtw_cfg80211_set_key_mgt(struct security_priv * psecuritypriv,u32 key_mgt)3911 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
3912 {
3913 	RTW_INFO("%s, key_mgt=0x%x\n", __func__, key_mgt);
3914 
3915 	if (key_mgt == WLAN_AKM_SUITE_8021X) {
3916 		/* *auth_type = UMAC_AUTH_TYPE_8021X; */
3917 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3918 		psecuritypriv->rsn_akm_suite_type = 1;
3919 	} else if (key_mgt == WLAN_AKM_SUITE_PSK) {
3920 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3921 		psecuritypriv->rsn_akm_suite_type = 2;
3922 	}
3923 #ifdef CONFIG_WAPI_SUPPORT
3924 	else if (key_mgt == WLAN_AKM_SUITE_WAPI_PSK)
3925 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3926 	else if (key_mgt == WLAN_AKM_SUITE_WAPI_CERT)
3927 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3928 #endif
3929 #ifdef CONFIG_RTW_80211R
3930 	else if (key_mgt == WLAN_AKM_SUITE_FT_8021X) {
3931 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3932 		psecuritypriv->rsn_akm_suite_type = 3;
3933 	} else if (key_mgt == WLAN_AKM_SUITE_FT_PSK) {
3934 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3935 		psecuritypriv->rsn_akm_suite_type = 4;
3936 	} else if ((key_mgt == WLAN_AKM_SUITE_FT_OVER_SAE)
3937 		|| (key_mgt == WLAN_AKM_SUITE_FT_FILS_SHA256)
3938 		) {
3939 		RTW_INFO("FT-SAE key mgt: 0x%x\n", key_mgt);
3940 		if (key_mgt == WLAN_AKM_SUITE_FT_OVER_SAE)
3941 			psecuritypriv->rsn_akm_suite_type = 9;
3942 	}
3943 #endif
3944 	else if (key_mgt == WLAN_AKM_SUITE_SAE) {
3945 		psecuritypriv->rsn_akm_suite_type = 8;
3946 	} else {
3947 		RTW_INFO("Invalid key mgt: 0x%x\n", key_mgt);
3948 		/* return -EINVAL; */
3949 	}
3950 
3951 	return 0;
3952 }
3953 
rtw_cfg80211_set_wpa_ie(_adapter * padapter,u8 * pie,size_t ielen)3954 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
3955 {
3956 	u8 *buf = NULL, *pos = NULL;
3957 	int group_cipher = 0, pairwise_cipher = 0;
3958 	u8 mfp_opt = MFP_NO;
3959 	int ret = 0;
3960 	int wpa_ielen = 0;
3961 	int wpa2_ielen = 0;
3962 	int rsnx_ielen = 0;
3963 	u8 *pwpa, *pwpa2, *prsnx;
3964 	u8 null_addr[] = {0, 0, 0, 0, 0, 0};
3965 
3966 	if (pie == NULL || !ielen) {
3967 		/* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
3968 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
3969 		goto exit;
3970 	}
3971 
3972 	if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
3973 		ret = -EINVAL;
3974 		goto exit;
3975 	}
3976 
3977 	buf = rtw_zmalloc(ielen);
3978 	if (buf == NULL) {
3979 		ret =  -ENOMEM;
3980 		goto exit;
3981 	}
3982 
3983 	_rtw_memcpy(buf, pie , ielen);
3984 
3985 	RTW_INFO("set wpa_ie(length:%zu):\n", ielen);
3986 	RTW_INFO_DUMP(NULL, buf, ielen);
3987 
3988 	pos = buf;
3989 	if (ielen < RSN_HEADER_LEN) {
3990 		ret  = -1;
3991 		goto exit;
3992 	}
3993 
3994 	pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
3995 	if (pwpa && wpa_ielen > 0) {
3996 		if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
3997 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3998 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
3999 			_rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
4000 
4001 			RTW_INFO("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
4002 		}
4003 	}
4004 
4005 	pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
4006 	if (pwpa2 && wpa2_ielen > 0) {
4007 		if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL, NULL, &mfp_opt, NULL) == _SUCCESS) {
4008 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
4009 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
4010 			_rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen + 2);
4011 
4012 			RTW_INFO("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
4013 		}
4014 
4015 		prsnx = rtw_get_ie(buf, WLAN_EID_RSNX, &rsnx_ielen, ielen);
4016 		if (prsnx && (rsnx_ielen > 0)) {
4017 			if ((rsnx_ielen + 2) <= MAX_RSNX_IE_LEN) {
4018 				_rtw_memset(padapter->securitypriv.rsnx_ie, 0,
4019 					MAX_RSNX_IE_LEN);
4020 				padapter->securitypriv.rsnx_ie_len = \
4021 					(rsnx_ielen + 2);
4022 				_rtw_memcpy(padapter->securitypriv.rsnx_ie,
4023 					prsnx,
4024 				padapter->securitypriv.rsnx_ie_len);
4025 			} else
4026 				RTW_ERR("%s:no more buf to save RSNX Cap!\n",
4027 					__func__);
4028 		} else {
4029 			_rtw_memset(padapter->securitypriv.rsnx_ie, 0,
4030 					MAX_RSNX_IE_LEN);
4031 			padapter->securitypriv.rsnx_ie_len = 0;
4032 		}
4033 	} /* end of (pwpa2 && wpa2_ielen > 0) */
4034 
4035 	if (group_cipher == 0)
4036 		group_cipher = WPA_CIPHER_NONE;
4037 	if (pairwise_cipher == 0)
4038 		pairwise_cipher = WPA_CIPHER_NONE;
4039 
4040 	switch (group_cipher) {
4041 	case WPA_CIPHER_NONE:
4042 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
4043 		padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
4044 		break;
4045 	case WPA_CIPHER_WEP40:
4046 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
4047 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
4048 		break;
4049 	case WPA_CIPHER_TKIP:
4050 		padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
4051 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
4052 		break;
4053 	case WPA_CIPHER_CCMP:
4054 		padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
4055 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4056 		break;
4057 	case WPA_CIPHER_GCMP:
4058 		padapter->securitypriv.dot118021XGrpPrivacy = _GCMP_;
4059 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4060 		break;
4061 	case WPA_CIPHER_GCMP_256:
4062 		padapter->securitypriv.dot118021XGrpPrivacy = _GCMP_256_;
4063 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4064 		break;
4065 	case WPA_CIPHER_CCMP_256:
4066 		padapter->securitypriv.dot118021XGrpPrivacy = _CCMP_256_;
4067 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4068 		break;
4069 	case WPA_CIPHER_WEP104:
4070 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
4071 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
4072 		break;
4073 	}
4074 
4075 	switch (pairwise_cipher) {
4076 	case WPA_CIPHER_NONE:
4077 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
4078 		padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
4079 		break;
4080 	case WPA_CIPHER_WEP40:
4081 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
4082 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
4083 		break;
4084 	case WPA_CIPHER_TKIP:
4085 		padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
4086 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
4087 		break;
4088 	case WPA_CIPHER_CCMP:
4089 		padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
4090 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4091 		break;
4092 	case WPA_CIPHER_GCMP:
4093 		padapter->securitypriv.dot11PrivacyAlgrthm = _GCMP_;
4094 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4095 		break;
4096 	case WPA_CIPHER_GCMP_256:
4097 		padapter->securitypriv.dot11PrivacyAlgrthm = _GCMP_256_;
4098 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4099 		break;
4100 	case WPA_CIPHER_CCMP_256:
4101 		padapter->securitypriv.dot11PrivacyAlgrthm = _CCMP_256_;
4102 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
4103 		break;
4104 	case WPA_CIPHER_WEP104:
4105 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
4106 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
4107 		break;
4108 	}
4109 
4110 	if (mfp_opt == MFP_INVALID) {
4111 		RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));
4112 		ret = -EINVAL;
4113 		goto exit;
4114 	}
4115 	padapter->securitypriv.mfp_opt = mfp_opt;
4116 
4117 	{/* handle wps_ie */
4118 		uint wps_ielen;
4119 		u8 *wps_ie;
4120 
4121 		wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
4122 		if (wps_ie && wps_ielen > 0) {
4123 			RTW_INFO("got wps_ie, wps_ielen:%u\n", wps_ielen);
4124 			padapter->securitypriv.wps_ie_len = wps_ielen < MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN;
4125 			_rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
4126 			set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
4127 		} else
4128 			_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
4129 	}
4130 
4131 	{/* handle owe_ie */
4132 		uint owe_ielen;
4133 		u8 *owe_ie;
4134 
4135 		owe_ie = rtw_get_owe_ie(buf, ielen, NULL, &owe_ielen);
4136 		if (owe_ie && owe_ielen > 0) {
4137 			RTW_INFO("got owe_ie, owe_ielen:%u\n", owe_ielen);
4138 			padapter->securitypriv.owe_ie_len = owe_ielen < MAX_OWE_IE_LEN ? owe_ielen : MAX_OWE_IE_LEN;
4139 			_rtw_memcpy(padapter->securitypriv.owe_ie, owe_ie, padapter->securitypriv.owe_ie_len);
4140 		}
4141 	}
4142 
4143 	#ifdef CONFIG_P2P
4144 	{/* check p2p_ie for assoc req; */
4145 		uint p2p_ielen = 0;
4146 		u8 *p2p_ie;
4147 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4148 
4149 		p2p_ie = rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen);
4150 		if (p2p_ie) {
4151 			#ifdef CONFIG_DEBUG_CFG80211
4152 			RTW_INFO("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
4153 			#endif
4154 
4155 			if (pmlmepriv->p2p_assoc_req_ie) {
4156 				u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
4157 				pmlmepriv->p2p_assoc_req_ie_len = 0;
4158 				rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
4159 				pmlmepriv->p2p_assoc_req_ie = NULL;
4160 			}
4161 
4162 			pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
4163 			if (pmlmepriv->p2p_assoc_req_ie == NULL) {
4164 				RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4165 				goto exit;
4166 			}
4167 			_rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
4168 			pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
4169 		}
4170 	}
4171 	#endif /* CONFIG_P2P */
4172 
4173 	#ifdef CONFIG_WFD
4174 	{
4175 		uint wfd_ielen = 0;
4176 		u8 *wfd_ie;
4177 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4178 
4179 		wfd_ie = rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen);
4180 		if (wfd_ie) {
4181 			#ifdef CONFIG_DEBUG_CFG80211
4182 			RTW_INFO("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
4183 			#endif
4184 
4185 			if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
4186 				goto exit;
4187 		}
4188 	}
4189 	#endif /* CONFIG_WFD */
4190 
4191 	#ifdef CONFIG_RTW_MULTI_AP
4192 	padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA;
4193 	if (padapter->multi_ap)
4194 		adapter_set_use_wds(padapter, 1);
4195 	#endif
4196 
4197 	/* TKIP and AES disallow multicast packets until installing group key */
4198 	if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
4199 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
4200 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _AES_
4201 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _GCMP_
4202 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _GCMP_256_
4203 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _CCMP_256_)
4204 		/* WPS open need to enable multicast */
4205 		/* || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
4206 		rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
4207 
4208 
4209 exit:
4210 	if (buf)
4211 		rtw_mfree(buf, ielen);
4212 	if (ret)
4213 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
4214 
4215 	return ret;
4216 }
4217 
cfg80211_rtw_join_ibss(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ibss_params * params)4218 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
4219 				  struct cfg80211_ibss_params *params)
4220 {
4221 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4222 	NDIS_802_11_SSID ndis_ssid;
4223 	struct security_priv *psecuritypriv = &padapter->securitypriv;
4224 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4225 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4226 	struct cfg80211_chan_def *pch_def;
4227 #endif
4228 	struct ieee80211_channel *pch;
4229 	int ret = 0;
4230 
4231 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4232 	pch_def = (struct cfg80211_chan_def *)(&params->chandef);
4233 	pch = (struct ieee80211_channel *) pch_def->chan;
4234 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
4235 	pch = (struct ieee80211_channel *)(params->channel);
4236 #endif
4237 
4238 	if (!params->ssid || !params->ssid_len) {
4239 		ret = -EINVAL;
4240 		goto exit;
4241 	}
4242 
4243 	if (params->ssid_len > IW_ESSID_MAX_SIZE) {
4244 		ret = -E2BIG;
4245 		goto exit;
4246 	}
4247 
4248 	rtw_ps_deny(padapter, PS_DENY_JOIN);
4249 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
4250 		ret = -EPERM;
4251 		goto cancel_ps_deny;
4252 	}
4253 
4254 #ifdef CONFIG_CONCURRENT_MODE
4255 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING)) {
4256 		RTW_INFO("%s, but buddy_intf is under linking\n", __FUNCTION__);
4257 		ret = -EINVAL;
4258 		goto cancel_ps_deny;
4259 	}
4260 	rtw_mi_buddy_scan_abort(padapter, _TRUE); /* OR rtw_mi_scan_abort(padapter, _TRUE);*/
4261 #endif /*CONFIG_CONCURRENT_MODE*/
4262 
4263 
4264 	_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
4265 	ndis_ssid.SsidLength = params->ssid_len;
4266 	_rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
4267 
4268 	/* RTW_INFO("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len); */
4269 
4270 	psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
4271 	psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
4272 	psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
4273 	psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
4274 	psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
4275 
4276 	ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
4277 	rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
4278 
4279 	RTW_INFO("%s: center_freq = %d\n", __func__, pch->center_freq);
4280 	pmlmeext->cur_channel = rtw_freq2ch(pch->center_freq);
4281 
4282 	if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
4283 		ret = -1;
4284 		goto cancel_ps_deny;
4285 	}
4286 
4287 cancel_ps_deny:
4288 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
4289 exit:
4290 	return ret;
4291 }
4292 
cfg80211_rtw_leave_ibss(struct wiphy * wiphy,struct net_device * ndev)4293 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
4294 {
4295 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4296 	struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
4297 	enum nl80211_iftype old_type;
4298 	int ret = 0;
4299 
4300 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4301 
4302 #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
4303 	rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 1);
4304 #endif
4305 
4306 	old_type = rtw_wdev->iftype;
4307 
4308 	rtw_set_to_roam(padapter, 0);
4309 
4310 	if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
4311 		rtw_scan_abort(padapter);
4312 		LeaveAllPowerSaveMode(padapter);
4313 
4314 		rtw_wdev->iftype = NL80211_IFTYPE_STATION;
4315 
4316 		if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure, 0) == _FALSE) {
4317 			rtw_wdev->iftype = old_type;
4318 			ret = -EPERM;
4319 			goto leave_ibss;
4320 		}
4321 		rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, RTW_CMDF_WAIT_ACK);
4322 	}
4323 
4324 leave_ibss:
4325 #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
4326 	rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 0);
4327 #endif
4328 
4329 	return 0;
4330 }
4331 
rtw_cfg80211_is_connect_requested(_adapter * adapter)4332 bool rtw_cfg80211_is_connect_requested(_adapter *adapter)
4333 {
4334 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
4335 	_irqL irqL;
4336 	bool requested;
4337 
4338 	_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
4339 	requested = pwdev_priv->connect_req ? 1 : 0;
4340 	_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
4341 
4342 	return requested;
4343 }
4344 
_rtw_disconnect(struct wiphy * wiphy,struct net_device * ndev)4345 static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev)
4346 {
4347 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4348 
4349 
4350 	/* if(check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) */
4351 	{
4352 		rtw_scan_abort(padapter);
4353 		rtw_join_abort_timeout(padapter, 300);
4354 		LeaveAllPowerSaveMode(padapter);
4355 		rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK);
4356 #ifdef CONFIG_RTW_REPEATER_SON
4357 		rtw_rson_do_disconnect(padapter);
4358 #endif
4359 		RTW_INFO("%s...call rtw_indicate_disconnect\n", __func__);
4360 
4361 		rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK);
4362 
4363 		/* indicate locally_generated = 0 when suspend */
4364 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
4365 		rtw_indicate_disconnect(padapter, 0, wiphy->dev.power.is_prepared ? _FALSE : _TRUE);
4366 		#else
4367 		/*
4368 		* for kernel < 4.2, DISCONNECT event is hardcoded with
4369 		* NL80211_ATTR_DISCONNECTED_BY_AP=1 in NL80211 layer
4370 		* no need to judge if under suspend
4371 		*/
4372 		rtw_indicate_disconnect(padapter, 0, _TRUE);
4373 		#endif
4374 
4375 		rtw_pwr_wakeup(padapter);
4376 	}
4377 	return 0;
4378 }
4379 
4380 #if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) \
4381     && !defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH)
rtw_check_connect_sae_compat(struct cfg80211_connect_params * sme)4382 static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme)
4383 {
4384 	struct rtw_ieee802_11_elems elems;
4385 	struct rsne_info info;
4386 	u8 AKM_SUITE_SAE[] = { 0x00, 0x0f, 0xac, 8 };
4387 #ifdef CONFIG_RTW_80211R
4388 	u8 AKM_SUITE_FTSAE[] = { 0x00, 0x0f, 0xac, 9 };
4389 #endif
4390 	int i;
4391 
4392 	if (sme->auth_type != (int)MLME_AUTHTYPE_SHARED_KEY)
4393 		return false;
4394 
4395 	if (rtw_ieee802_11_parse_elems((u8 *)sme->ie, sme->ie_len, &elems, 0)
4396 	    == ParseFailed)
4397 		return false;
4398 
4399 	if (!elems.rsn_ie)
4400 		return false;
4401 
4402 	if (rtw_rsne_info_parse(elems.rsn_ie - 2, elems.rsn_ie_len + 2, &info) == _FAIL)
4403 		return false;
4404 
4405 	for (i = 0; i < info.akm_cnt; i++) {
4406 		if ((memcmp(info.akm_list + i * RSN_SELECTOR_LEN,
4407 			   AKM_SUITE_SAE, RSN_SELECTOR_LEN) == 0)
4408 	#ifdef CONFIG_RTW_80211R
4409 			|| (memcmp(info.akm_list + i * RSN_SELECTOR_LEN,
4410                            AKM_SUITE_FTSAE, RSN_SELECTOR_LEN) == 0)
4411 	#endif
4412 		)
4413 			return true;
4414 	}
4415 	return false;
4416 }
4417 #else
4418 #define rtw_check_connect_sae_compat(sme)	false
4419 #endif
4420 
cfg80211_rtw_connect(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * sme)4421 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
4422 				struct cfg80211_connect_params *sme)
4423 {
4424 	int ret = 0;
4425 	NDIS_802_11_AUTHENTICATION_MODE authmode;
4426 	NDIS_802_11_SSID ndis_ssid;
4427 	/* u8 matched_by_bssid=_FALSE; */
4428 	/* u8 matched_by_ssid=_FALSE; */
4429 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4430 	struct security_priv *psecuritypriv = &padapter->securitypriv;
4431 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
4432 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4433 	_irqL irqL;
4434 
4435 #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_CONNECT)
4436 	rtw_wdev_set_not_indic_disco(pwdev_priv, 1);
4437 #endif
4438 
4439 	RTW_INFO("=>"FUNC_NDEV_FMT" - Start to Connection\n", FUNC_NDEV_ARG(ndev));
4440 	RTW_INFO("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n",
4441 		sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type);
4442 
4443 	if (rtw_check_connect_sae_compat(sme)) {
4444 		sme->auth_type = (int)MLME_AUTHTYPE_SAE;
4445 		psecuritypriv->auth_type = MLME_AUTHTYPE_SAE;
4446 		psecuritypriv->auth_alg = WLAN_AUTH_SAE;
4447 		RTW_INFO("%s set sme->auth_type for SAE compat\n", __FUNCTION__);
4448 	}
4449 
4450 	if (pwdev_priv->block == _TRUE) {
4451 		ret = -EBUSY;
4452 		RTW_INFO("%s wdev_priv.block is set\n", __FUNCTION__);
4453 		goto exit;
4454 	}
4455 
4456        if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING) == _TRUE) {
4457 
4458 		_rtw_disconnect(wiphy, ndev);
4459 		RTW_INFO("%s disconnect before connecting! fw_state=0x%x\n",
4460 			__FUNCTION__, pmlmepriv->fw_state);
4461 	}
4462 
4463 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
4464 	printk("MStar Android!\n");
4465 	if (pwdev_priv->bandroid_scan == _FALSE) {
4466 #ifdef CONFIG_P2P
4467 		struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4468 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4469 #endif /* CONFIG_P2P */
4470 		{
4471 			ret = -EBUSY;
4472 			printk("Android hasn't attached yet!\n");
4473 			goto exit;
4474 		}
4475 	}
4476 #endif
4477 
4478 	if (!sme->ssid || !sme->ssid_len) {
4479 		ret = -EINVAL;
4480 		goto exit;
4481 	}
4482 
4483 	if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
4484 		ret = -E2BIG;
4485 		goto exit;
4486 	}
4487 
4488 	rtw_ps_deny(padapter, PS_DENY_JOIN);
4489 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
4490 		ret = -EPERM;
4491 		goto cancel_ps_deny;
4492 	}
4493 
4494 	rtw_mi_scan_abort(padapter, _TRUE);
4495 
4496 	rtw_join_abort_timeout(padapter, 300);
4497 #ifdef CONFIG_CONCURRENT_MODE
4498 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING)) {
4499 		ret = -EINVAL;
4500 		goto cancel_ps_deny;
4501 	}
4502 #endif
4503 
4504 	_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
4505 	ndis_ssid.SsidLength = sme->ssid_len;
4506 	_rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
4507 
4508 	RTW_INFO("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
4509 
4510 
4511 	if (sme->bssid)
4512 		RTW_INFO("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
4513 
4514 
4515 	psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
4516 	psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
4517 	psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
4518 	psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
4519 	psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
4520 	psecuritypriv->auth_alg = WLAN_AUTH_OPEN;
4521 	psecuritypriv->extauth_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4522 
4523 #ifdef CONFIG_WAPI_SUPPORT
4524 	padapter->wapiInfo.bWapiEnable = false;
4525 #endif
4526 
4527 	ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
4528 	if (ret < 0)
4529 		goto cancel_ps_deny;
4530 
4531 #ifdef CONFIG_WAPI_SUPPORT
4532 	if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
4533 		padapter->wapiInfo.bWapiEnable = true;
4534 		padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
4535 		padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
4536 	}
4537 #endif
4538 
4539 	ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
4540 
4541 #ifdef CONFIG_WAPI_SUPPORT
4542 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
4543 		padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
4544 #endif
4545 
4546 
4547 	if (ret < 0)
4548 		goto cancel_ps_deny;
4549 
4550 	RTW_INFO("%s, ie_len=%zu\n", __func__, sme->ie_len);
4551 
4552 	ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
4553 	if (ret < 0)
4554 		goto cancel_ps_deny;
4555 
4556 	if (sme->crypto.n_ciphers_pairwise) {
4557 		ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
4558 		if (ret < 0)
4559 			goto cancel_ps_deny;
4560 	}
4561 
4562 	/* For WEP Shared auth */
4563 	if (sme->key_len > 0 && sme->key) {
4564 		u32 wep_key_idx, wep_key_len, wep_total_len;
4565 		NDIS_802_11_WEP	*pwep = NULL;
4566 		RTW_INFO("%s(): Shared/Auto WEP\n", __FUNCTION__);
4567 
4568 		wep_key_idx = sme->key_idx;
4569 		wep_key_len = sme->key_len;
4570 
4571 		if (sme->key_idx > WEP_KEYS) {
4572 			ret = -EINVAL;
4573 			goto cancel_ps_deny;
4574 		}
4575 
4576 		if (wep_key_len > 0) {
4577 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
4578 			wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
4579 			pwep = (NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
4580 			if (pwep == NULL) {
4581 				RTW_INFO(" wpa_set_encryption: pwep allocate fail !!!\n");
4582 				ret = -ENOMEM;
4583 				goto cancel_ps_deny;
4584 			}
4585 
4586 			_rtw_memset(pwep, 0, wep_total_len);
4587 
4588 			pwep->KeyLength = wep_key_len;
4589 			pwep->Length = wep_total_len;
4590 
4591 			if (wep_key_len == 13) {
4592 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
4593 				padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
4594 			}
4595 		} else {
4596 			ret = -EINVAL;
4597 			goto cancel_ps_deny;
4598 		}
4599 
4600 		pwep->KeyIndex = wep_key_idx;
4601 		pwep->KeyIndex |= 0x80000000;
4602 
4603 		_rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
4604 
4605 		if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
4606 			ret = -EOPNOTSUPP ;
4607 
4608 		if (pwep)
4609 			rtw_mfree((u8 *)pwep, wep_total_len);
4610 
4611 		if (ret < 0)
4612 			goto cancel_ps_deny;
4613 	}
4614 
4615 	ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
4616 	if (ret < 0)
4617 		return ret;
4618 
4619 	if (sme->crypto.n_akm_suites) {
4620 		ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
4621 		if (ret < 0)
4622 			goto cancel_ps_deny;
4623 	}
4624 #ifdef CONFIG_8011R
4625 	else {
4626 		/*It could be a connection without RSN IEs*/
4627 		psecuritypriv->rsn_akm_suite_type = 0;
4628 	}
4629 #endif
4630 
4631 #ifdef CONFIG_WAPI_SUPPORT
4632 	if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK)
4633 		padapter->wapiInfo.bWapiPSK = true;
4634 	else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT)
4635 		padapter->wapiInfo.bWapiPSK = false;
4636 #endif
4637 
4638 	authmode = psecuritypriv->ndisauthtype;
4639 	rtw_set_802_11_authentication_mode(padapter, authmode);
4640 
4641 	/* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
4642 
4643 #ifdef CONFIG_RTW_MBO
4644 	rtw_mbo_update_ie_data(padapter, (u8 *)sme->ie, sme->ie_len);
4645 #endif
4646 
4647 	if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid, \
4648 			sme->channel ? sme->channel->hw_value : 0) == _FALSE) {
4649 		ret = -1;
4650 		goto cancel_ps_deny;
4651 	}
4652 
4653 
4654 	_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
4655 
4656 	if (pwdev_priv->connect_req) {
4657 		rtw_wdev_free_connect_req(pwdev_priv);
4658 		RTW_INFO(FUNC_NDEV_FMT" free existing connect_req\n", FUNC_NDEV_ARG(ndev));
4659 	}
4660 
4661 	pwdev_priv->connect_req = (struct cfg80211_connect_params *)rtw_malloc(sizeof(*pwdev_priv->connect_req));
4662 	if (pwdev_priv->connect_req)
4663 		_rtw_memcpy(pwdev_priv->connect_req, sme, sizeof(*pwdev_priv->connect_req));
4664 	else
4665 		RTW_WARN(FUNC_NDEV_FMT" alloc connect_req fail\n", FUNC_NDEV_ARG(ndev));
4666 
4667 	_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
4668 
4669 	RTW_INFO("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
4670 		psecuritypriv->dot118021XGrpPrivacy);
4671 
4672 cancel_ps_deny:
4673 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
4674 
4675 exit:
4676 	RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
4677 
4678 #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_CONNECT)
4679 	rtw_wdev_set_not_indic_disco(pwdev_priv, 0);
4680 #endif
4681 
4682 	return ret;
4683 }
4684 
cfg80211_rtw_disconnect(struct wiphy * wiphy,struct net_device * ndev,u16 reason_code)4685 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
4686 				   u16 reason_code)
4687 {
4688 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4689 
4690 	RTW_INFO(FUNC_NDEV_FMT" - Start to Disconnect\n", FUNC_NDEV_ARG(ndev));
4691 
4692 #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
4693 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
4694 	if (!wiphy->dev.power.is_prepared)
4695 	#endif
4696 		rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 1);
4697 #endif
4698 
4699 	rtw_set_to_roam(padapter, 0);
4700 
4701 	/* if(check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) */
4702 	{
4703 		_rtw_disconnect(wiphy, ndev);
4704 	}
4705 
4706 #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
4707 	rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 0);
4708 #endif
4709 
4710 	RTW_INFO(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
4711 	return 0;
4712 }
4713 
4714 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
4715 #ifdef CONFIG_RTW_DEBUG
nl80211_tx_power_setting_str(int type)4716 static const char *nl80211_tx_power_setting_str(int type)
4717 {
4718 	switch (type) {
4719 	case NL80211_TX_POWER_AUTOMATIC:
4720 		return "AUTO";
4721 	case NL80211_TX_POWER_LIMITED:
4722 		return "LIMIT";
4723 	case NL80211_TX_POWER_FIXED:
4724 		return "FIX";
4725 	default:
4726 		return "UNKNOWN";
4727 	};
4728 }
4729 #endif	/*	CONFIG_RTW_DEBUG	*/
4730 
cfg80211_rtw_set_txpower(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_tx_power_setting type,int mbm)4731 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
4732 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4733 	struct wireless_dev *wdev,
4734 #endif
4735 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) || defined(COMPAT_KERNEL_RELEASE)
4736 	enum nl80211_tx_power_setting type, int mbm)
4737 #else
4738 	enum tx_power_setting type, int dbm)
4739 #endif
4740 {
4741 #if !((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) || defined(COMPAT_KERNEL_RELEASE))
4742 	int mbm = dbm * 100;
4743 #endif
4744 	struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
4745 	_adapter *adapter = wiphy_to_adapter(wiphy);
4746 	int ret = -EOPNOTSUPP;
4747 
4748 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4749 	if (wdev) {
4750 		RTW_WARN(FUNC_WIPHY_FMT" wdev specific control is not supported\n", FUNC_WIPHY_ARG(wiphy));
4751 		goto exit;
4752 	}
4753 #endif
4754 
4755 	RTW_INFO(FUNC_WIPHY_FMT" type:%s(%u) mbm:%d\n", FUNC_WIPHY_ARG(wiphy)
4756 		, nl80211_tx_power_setting_str(type), type, mbm);
4757 
4758 	switch (type) {
4759 	case NL80211_TX_POWER_AUTOMATIC:
4760 		wiphy_data->txpwr_total_lmt_mbm = UNSPECIFIED_MBM;
4761 		wiphy_data->txpwr_total_target_mbm = UNSPECIFIED_MBM;
4762 		ret = 0;
4763 		break;
4764 	case NL80211_TX_POWER_LIMITED:
4765 		if (!phy_is_txpwr_user_mbm_valid(adapter, mbm)) {
4766 			RTW_WARN(FUNC_WIPHY_FMT" mbm:%d not support\n", FUNC_WIPHY_ARG(wiphy), mbm);
4767 			goto exit;
4768 		}
4769 		wiphy_data->txpwr_total_lmt_mbm = mbm;
4770 		wiphy_data->txpwr_total_target_mbm = UNSPECIFIED_MBM;
4771 		ret = 0;
4772 		break;
4773 	case NL80211_TX_POWER_FIXED:
4774 		if (!phy_is_txpwr_user_mbm_valid(adapter, mbm)) {
4775 			RTW_WARN(FUNC_WIPHY_FMT" mbm:%d not support\n", FUNC_WIPHY_ARG(wiphy), mbm);
4776 			goto exit;
4777 		}
4778 		wiphy_data->txpwr_total_lmt_mbm = UNSPECIFIED_MBM;
4779 		wiphy_data->txpwr_total_target_mbm = mbm;
4780 		ret = 0;
4781 		break;
4782 	default:
4783 		RTW_WARN(FUNC_WIPHY_FMT" unknown type:%d\n", FUNC_WIPHY_ARG(wiphy), type);
4784 	}
4785 
4786 	if (ret == 0)
4787 		rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_update_txpwr_level)), adapter, 2000);
4788 
4789 exit:
4790 	return ret;
4791 }
4792 
cfg80211_rtw_get_txpower(struct wiphy * wiphy,struct wireless_dev * wdev,int * dbm)4793 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
4794 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4795 	struct wireless_dev *wdev,
4796 #endif
4797 	int *dbm)
4798 {
4799 	struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
4800 	s16 mbm;
4801 
4802 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4803 	if (wdev && wdev_to_ndev(wdev)) {
4804 		_adapter *adapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
4805 		mbm = rtw_adapter_get_oper_txpwr_max_mbm(adapter, 1);
4806 		RTW_INFO(FUNC_ADPT_FMT" total max: %d mbm\n", FUNC_ADPT_ARG(adapter), mbm);
4807 	} else
4808 #endif
4809 	{
4810 		mbm = rtw_get_oper_txpwr_max_mbm(dvobj, 1);
4811 		RTW_INFO(FUNC_WIPHY_FMT" total max: %d mbm\n", FUNC_WIPHY_ARG(wiphy), mbm);
4812 	}
4813 
4814 	*dbm = mbm / MBM_PDBM;
4815 
4816 	return 0;
4817 }
4818 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */
4819 
rtw_cfg80211_pwr_mgmt(_adapter * adapter)4820 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
4821 {
4822 	struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
4823 	struct wireless_dev *wdev = rtw_wdev_priv->rtw_wdev;
4824 
4825 	return wdev->ps;
4826 }
4827 
cfg80211_rtw_set_power_mgmt(struct wiphy * wiphy,struct net_device * ndev,bool enabled,int timeout)4828 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
4829 				       struct net_device *ndev,
4830 				       bool enabled, int timeout)
4831 {
4832 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4833 
4834 	RTW_INFO(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
4835 		enabled, timeout);
4836 
4837 #ifdef CONFIG_LPS
4838 	if (!enabled)
4839 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 0);
4840 #endif
4841 
4842 	return 0;
4843 }
4844 
_rtw_set_pmksa(struct net_device * ndev,u8 * bssid,u8 * pmkid)4845 static void _rtw_set_pmksa(struct net_device *ndev,
4846 	u8 *bssid, u8 *pmkid)
4847 {
4848 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4849 	struct security_priv *psecuritypriv = &padapter->securitypriv;
4850 	u8 index, blInserted = _FALSE;
4851 
4852 	/* overwrite PMKID */
4853 	for (index = 0 ; index < NUM_PMKID_CACHE; index++) {
4854 		if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, bssid, ETH_ALEN) == _TRUE) {
4855 			/* BSSID is matched, the same AP => rewrite with new PMKID. */
4856 			RTW_INFO("BSSID("MAC_FMT") exists in the PMKList.\n", MAC_ARG(bssid));
4857 
4858 			_rtw_memcpy(psecuritypriv->PMKIDList[index].PMKID, pmkid, WLAN_PMKID_LEN);
4859 			psecuritypriv->PMKIDList[index].bUsed = _TRUE;
4860 			blInserted = _TRUE;
4861 			break;
4862 		}
4863 	}
4864 
4865 	if (!blInserted) {
4866 		/* Find a new entry */
4867 		RTW_INFO("Use the new entry index = %d for this PMKID.\n",
4868 			psecuritypriv->PMKIDIndex);
4869 
4870 		_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, bssid, ETH_ALEN);
4871 		_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmkid, WLAN_PMKID_LEN);
4872 
4873 		psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
4874 		psecuritypriv->PMKIDIndex++ ;
4875 		if (psecuritypriv->PMKIDIndex == 16)
4876 			psecuritypriv->PMKIDIndex = 0;
4877 	}
4878 }
4879 
cfg80211_rtw_set_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)4880 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
4881 				  struct net_device *ndev,
4882 				  struct cfg80211_pmksa *pmksa)
4883 {
4884 	u8	index, blInserted = _FALSE;
4885 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4886 	struct mlme_priv *mlme = &padapter->mlmepriv;
4887 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
4888 	u8	strZeroMacAddress[ETH_ALEN] = { 0x00 };
4889 	bool sae_auth = rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE);
4890 
4891 	RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
4892 		, MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
4893 
4894 	if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
4895 		return -EINVAL;
4896 
4897 	_rtw_set_pmksa(ndev, (u8 *)pmksa->bssid, (u8 *)pmksa->pmkid);
4898 
4899 	if (sae_auth &&
4900 		(psecuritypriv->extauth_status == WLAN_STATUS_SUCCESS)) {
4901 		RTW_PRINT("SAE: auth success, start assoc\n");
4902 		start_clnt_assoc(padapter);
4903 	}
4904 
4905 	return 0;
4906 }
4907 
cfg80211_rtw_del_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)4908 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
4909 				  struct net_device *ndev,
4910 				  struct cfg80211_pmksa *pmksa)
4911 {
4912 	u8	index, bMatched = _FALSE;
4913 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4914 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
4915 
4916 	RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
4917 		, MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
4918 
4919 	for (index = 0 ; index < NUM_PMKID_CACHE; index++) {
4920 		if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) == _TRUE) {
4921 			/* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
4922 			_rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN);
4923 			_rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN);
4924 			psecuritypriv->PMKIDList[index].bUsed = _FALSE;
4925 			bMatched = _TRUE;
4926 			RTW_INFO(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
4927 			break;
4928 		}
4929 	}
4930 
4931 	if (_FALSE == bMatched) {
4932 		RTW_INFO(FUNC_NDEV_FMT" do not have matched BSSID\n"
4933 			, FUNC_NDEV_ARG(ndev));
4934 		return -EINVAL;
4935 	}
4936 
4937 	return 0;
4938 }
4939 
cfg80211_rtw_flush_pmksa(struct wiphy * wiphy,struct net_device * ndev)4940 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
4941 				    struct net_device *ndev)
4942 {
4943 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4944 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
4945 
4946 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4947 
4948 	_rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
4949 	psecuritypriv->PMKIDIndex = 0;
4950 
4951 	return 0;
4952 }
4953 
rtw_cfg80211_monitor_if_open(struct net_device * ndev)4954 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
4955 {
4956 	int ret = 0;
4957 
4958 	RTW_INFO("%s\n", __func__);
4959 
4960 	return ret;
4961 }
4962 
rtw_cfg80211_monitor_if_close(struct net_device * ndev)4963 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
4964 {
4965 	int ret = 0;
4966 
4967 	RTW_INFO("%s\n", __func__);
4968 
4969 	return ret;
4970 }
4971 
rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff * skb,struct net_device * ndev)4972 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
4973 {
4974 	int ret = 0;
4975 	int rtap_len;
4976 	int qos_len = 0;
4977 	int dot11_hdr_len = 24;
4978 	int snap_len = 6;
4979 	unsigned char *pdata;
4980 	u16 frame_ctl;
4981 	unsigned char src_mac_addr[ETH_ALEN];
4982 	unsigned char dst_mac_addr[ETH_ALEN];
4983 	struct rtw_ieee80211_hdr *dot11_hdr;
4984 	struct ieee80211_radiotap_header *rtap_hdr;
4985 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4986 #ifdef CONFIG_DFS_MASTER
4987 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
4988 #endif
4989 
4990 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4991 
4992 	rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
4993 
4994 	if (IS_CH_WAITING(rfctl)) {
4995 		#ifdef CONFIG_DFS_MASTER
4996 		if (rtw_rfctl_overlap_radar_detect_ch(rfctl))
4997 			goto fail;
4998 		#endif
4999 	}
5000 
5001 	if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
5002 		goto fail;
5003 
5004 	rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
5005 	if (unlikely(rtap_hdr->it_version))
5006 		goto fail;
5007 
5008 	rtap_len = ieee80211_get_radiotap_len(skb->data);
5009 	if (unlikely(skb->len < rtap_len))
5010 		goto fail;
5011 
5012 	if (rtap_len != 14) {
5013 		RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
5014 		goto fail;
5015 	}
5016 
5017 	/* Skip the ratio tap header */
5018 	skb_pull(skb, rtap_len);
5019 
5020 	dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
5021 	frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
5022 	/* Check if the QoS bit is set */
5023 	if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
5024 		/* Check if this ia a Wireless Distribution System (WDS) frame
5025 		 * which has 4 MAC addresses
5026 		 */
5027 		if (dot11_hdr->frame_ctl & 0x0080)
5028 			qos_len = 2;
5029 		if ((dot11_hdr->frame_ctl & 0x0300) == 0x0300)
5030 			dot11_hdr_len += 6;
5031 
5032 		memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
5033 		memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
5034 
5035 		/* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
5036 		 * for two MAC addresses
5037 		 */
5038 		skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
5039 		pdata = (unsigned char *)skb->data;
5040 		memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
5041 		memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
5042 
5043 		RTW_INFO("should be eapol packet\n");
5044 
5045 		/* Use the real net device to transmit the packet */
5046 		ret = _rtw_xmit_entry(skb, padapter->pnetdev);
5047 
5048 		return ret;
5049 
5050 	} else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE))
5051 		== (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION)
5052 	) {
5053 		/* only for action frames */
5054 		struct xmit_frame		*pmgntframe;
5055 		struct pkt_attrib	*pattrib;
5056 		unsigned char	*pframe;
5057 		/* u8 category, action, OUI_Subtype, dialogToken=0; */
5058 		/* unsigned char	*frame_body; */
5059 		struct rtw_ieee80211_hdr *pwlanhdr;
5060 		struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
5061 		struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5062 		u8 *buf = skb->data;
5063 		u32 len = skb->len;
5064 		u8 category, action;
5065 		int type = -1;
5066 
5067 		if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
5068 			RTW_INFO(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
5069 				le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
5070 			goto fail;
5071 		}
5072 
5073 		RTW_INFO("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
5074 			MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
5075 		#ifdef CONFIG_P2P
5076 		type = rtw_p2p_check_frames(padapter, buf, len, _TRUE);
5077 		if (type >= 0)
5078 			goto dump;
5079 		#endif
5080 		if (category == RTW_WLAN_CATEGORY_PUBLIC)
5081 			RTW_INFO("RTW_Tx:%s\n", action_public_str(action));
5082 		else
5083 			RTW_INFO("RTW_Tx:category(%u), action(%u)\n", category, action);
5084 #ifdef CONFIG_P2P
5085 dump:
5086 #endif
5087 		/* starting alloc mgmt frame to dump it */
5088 		pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5089 		if (pmgntframe == NULL)
5090 			goto fail;
5091 
5092 		/* update attribute */
5093 		pattrib = &pmgntframe->attrib;
5094 		update_mgntframe_attrib(padapter, pattrib);
5095 		pattrib->retry_ctrl = _FALSE;
5096 
5097 		_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5098 
5099 		pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5100 
5101 		_rtw_memcpy(pframe, (void *)buf, len);
5102 		pattrib->pktlen = len;
5103 
5104 #ifdef CONFIG_P2P
5105 		if (type >= 0)
5106 			rtw_xframe_chk_wfd_ie(pmgntframe);
5107 #endif /* CONFIG_P2P */
5108 
5109 		pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5110 		/* update seq number */
5111 		pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
5112 		pattrib->seqnum = pmlmeext->mgnt_seq;
5113 		pmlmeext->mgnt_seq++;
5114 
5115 		pattrib->last_txcmdsz = pattrib->pktlen;
5116 
5117 		dump_mgntframe(padapter, pmgntframe);
5118 
5119 	} else
5120 		RTW_INFO("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE));
5121 
5122 
5123 fail:
5124 
5125 	rtw_skb_free(skb);
5126 
5127 	return 0;
5128 
5129 }
5130 
5131 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
rtw_cfg80211_monitor_if_set_multicast_list(struct net_device * ndev)5132 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
5133 {
5134 	RTW_INFO("%s\n", __func__);
5135 }
5136 #endif
rtw_cfg80211_monitor_if_set_mac_address(struct net_device * ndev,void * addr)5137 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
5138 {
5139 	int ret = 0;
5140 
5141 	RTW_INFO("%s\n", __func__);
5142 
5143 	return ret;
5144 }
5145 
5146 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
5147 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
5148 	.ndo_open = rtw_cfg80211_monitor_if_open,
5149 	.ndo_stop = rtw_cfg80211_monitor_if_close,
5150 	.ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
5151 	#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
5152 	.ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
5153 	#endif
5154 	.ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
5155 };
5156 #endif
5157 
rtw_cfg80211_add_monitor_if(_adapter * padapter,char * name,struct net_device ** ndev)5158 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
5159 {
5160 	int ret = 0;
5161 	struct net_device *mon_ndev = NULL;
5162 	struct wireless_dev *mon_wdev = NULL;
5163 	struct rtw_netdev_priv_indicator *pnpi;
5164 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
5165 
5166 	if (!name) {
5167 		RTW_INFO(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
5168 		ret = -EINVAL;
5169 		goto out;
5170 	}
5171 
5172 	if (pwdev_priv->pmon_ndev) {
5173 		RTW_INFO(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
5174 			FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
5175 		ret = -EBUSY;
5176 		goto out;
5177 	}
5178 
5179 	mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
5180 	if (!mon_ndev) {
5181 		RTW_INFO(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
5182 		ret = -ENOMEM;
5183 		goto out;
5184 	}
5185 
5186 	mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
5187 	strncpy(mon_ndev->name, name, IFNAMSIZ);
5188 	mon_ndev->name[IFNAMSIZ - 1] = 0;
5189 #if (LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 8))
5190 	mon_ndev->priv_destructor = rtw_ndev_destructor;
5191 #else
5192 	mon_ndev->destructor = rtw_ndev_destructor;
5193 #endif
5194 
5195 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
5196 	mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
5197 #else
5198 	mon_ndev->open = rtw_cfg80211_monitor_if_open;
5199 	mon_ndev->stop = rtw_cfg80211_monitor_if_close;
5200 	mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
5201 	mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
5202 #endif
5203 
5204 	pnpi = netdev_priv(mon_ndev);
5205 	pnpi->priv = padapter;
5206 	pnpi->sizeof_priv = sizeof(_adapter);
5207 
5208 	/*  wdev */
5209 	mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
5210 	if (!mon_wdev) {
5211 		RTW_INFO(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
5212 		ret = -ENOMEM;
5213 		goto out;
5214 	}
5215 
5216 	mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
5217 	mon_wdev->netdev = mon_ndev;
5218 	mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
5219 	mon_ndev->ieee80211_ptr = mon_wdev;
5220 
5221 	ret = register_netdevice(mon_ndev);
5222 	if (ret)
5223 		goto out;
5224 
5225 	*ndev = pwdev_priv->pmon_ndev = mon_ndev;
5226 	_rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
5227 
5228 out:
5229 	if (ret && mon_wdev) {
5230 		rtw_mfree((u8 *)mon_wdev, sizeof(struct wireless_dev));
5231 		mon_wdev = NULL;
5232 	}
5233 
5234 	if (ret && mon_ndev) {
5235 		free_netdev(mon_ndev);
5236 		*ndev = mon_ndev = NULL;
5237 	}
5238 
5239 	return ret;
5240 }
5241 
5242 #ifdef CONFIG_AP_MODE
rtw_cfg80211_indicate_sta_assoc(_adapter * padapter,u8 * pmgmt_frame,uint frame_len)5243 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
5244 {
5245 #if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE)
5246 	s32 freq;
5247 	int channel;
5248 	struct wireless_dev *pwdev = padapter->rtw_wdev;
5249 	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5250 #endif
5251 	struct net_device *ndev = padapter->pnetdev;
5252 
5253 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
5254 
5255 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
5256 	{
5257 		struct station_info sinfo;
5258 		u8 ie_offset;
5259 		if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ)
5260 			ie_offset = _ASOCREQ_IE_OFFSET_;
5261 		else /* WIFI_REASSOCREQ */
5262 			ie_offset = _REASOCREQ_IE_OFFSET_;
5263 
5264 		memset(&sinfo, 0, sizeof(sinfo));
5265 		sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
5266 		sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
5267 		sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
5268 		cfg80211_new_sta(ndev, get_addr2_ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
5269 	}
5270 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
5271 	channel = pmlmeext->cur_channel;
5272 	freq = rtw_ch2freq(channel);
5273 
5274 	#ifdef COMPAT_KERNEL_RELEASE
5275 	rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
5276 	#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
5277 	rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
5278 	#else /* COMPAT_KERNEL_RELEASE */
5279 	{
5280 		/* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)  when calling cfg80211_send_rx_assoc() */
5281 		#ifndef CONFIG_PLATFORM_MSTAR
5282 		pwdev->iftype = NL80211_IFTYPE_STATION;
5283 		#endif /* CONFIG_PLATFORM_MSTAR */
5284 		RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
5285 		rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
5286 		RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
5287 		pwdev->iftype = NL80211_IFTYPE_AP;
5288 		/* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */
5289 	}
5290 	#endif /* COMPAT_KERNEL_RELEASE */
5291 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
5292 
5293 }
5294 
rtw_cfg80211_indicate_sta_disassoc(_adapter * padapter,const u8 * da,unsigned short reason)5295 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason)
5296 {
5297 #if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE)
5298 	s32 freq;
5299 	int channel;
5300 	u8 *pmgmt_frame;
5301 	uint frame_len;
5302 	struct rtw_ieee80211_hdr *pwlanhdr;
5303 	unsigned short *fctrl;
5304 	u8 mgmt_buf[128] = {0};
5305 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5306 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5307 	struct wireless_dev *wdev = padapter->rtw_wdev;
5308 #endif
5309 	struct net_device *ndev = padapter->pnetdev;
5310 
5311 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
5312 
5313 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
5314 	cfg80211_del_sta(ndev, da, GFP_ATOMIC);
5315 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
5316 	channel = pmlmeext->cur_channel;
5317 	freq = rtw_ch2freq(channel);
5318 
5319 	pmgmt_frame = mgmt_buf;
5320 	pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
5321 
5322 	fctrl = &(pwlanhdr->frame_ctl);
5323 	*(fctrl) = 0;
5324 
5325 	_rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
5326 	_rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
5327 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5328 
5329 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5330 	pmlmeext->mgnt_seq++;
5331 	set_frame_sub_type(pmgmt_frame, WIFI_DEAUTH);
5332 
5333 	pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
5334 	frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
5335 
5336 	reason = cpu_to_le16(reason);
5337 	pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
5338 
5339 	#ifdef COMPAT_KERNEL_RELEASE
5340 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
5341 	#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
5342 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
5343 	#else /* COMPAT_KERNEL_RELEASE */
5344 	cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
5345 	/* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */
5346 	#endif /* COMPAT_KERNEL_RELEASE */
5347 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
5348 }
5349 
rtw_add_beacon(_adapter * adapter,const u8 * head,size_t head_len,const u8 * tail,size_t tail_len)5350 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
5351 {
5352 	int ret = 0;
5353 	u8 *pbuf = NULL;
5354 	uint len, wps_ielen = 0;
5355 	uint p2p_ielen = 0;
5356 	u8 got_p2p_ie = _FALSE;
5357 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5358 	/* struct sta_priv *pstapriv = &padapter->stapriv; */
5359 
5360 
5361 	RTW_INFO("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
5362 
5363 
5364 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
5365 		return -EINVAL;
5366 
5367 	if (head_len < 24)
5368 		return -EINVAL;
5369 
5370 	#ifdef CONFIG_FW_HANDLE_TXBCN
5371 	if (!rtw_ap_nums_check(adapter)) {
5372 		RTW_ERR(FUNC_ADPT_FMT"failed, con't support over %d BCN\n", FUNC_ADPT_ARG(adapter), CONFIG_LIMITED_AP_NUM);
5373 		return -EINVAL;
5374 	}
5375 	#endif /*CONFIG_FW_HANDLE_TXBCN*/
5376 
5377 	pbuf = rtw_zmalloc(head_len + tail_len);
5378 	if (!pbuf) {
5379 		ret = -ENOMEM;
5380 		goto exit;
5381 	}
5382 
5383 
5384 	/* _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); */
5385 
5386 	/* if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) */
5387 	/*	pstapriv->max_num_sta = NUM_STA; */
5388 
5389 
5390 	_rtw_memcpy(pbuf, (void *)head + 24, head_len - 24); /* 24=beacon header len. */
5391 	_rtw_memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
5392 
5393 	len = head_len + tail_len - 24;
5394 
5395 	/* check wps ie if inclued */
5396 	if (rtw_get_wps_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &wps_ielen))
5397 		RTW_INFO("add bcn, wps_ielen=%d\n", wps_ielen);
5398 
5399 #ifdef CONFIG_P2P
5400 	if (adapter->wdinfo.driver_interface == DRIVER_CFG80211) {
5401 		/* check p2p if enable */
5402 		if (rtw_get_p2p_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &p2p_ielen)) {
5403 			struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
5404 
5405 			RTW_INFO("got p2p_ie, len=%d\n", p2p_ielen);
5406 
5407 			got_p2p_ie = _TRUE;
5408 
5409 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5410 
5411 				if (rtw_p2p_enable(adapter, P2P_ROLE_GO)) {
5412 					RTW_INFO("Enable P2P function for the first time\n");
5413 					adapter->stapriv.expire_to = 3; /* 3x2 = 6 sec in p2p mode */
5414 				} else {
5415 					ret = -EOPNOTSUPP;
5416 					goto exit;
5417 				}
5418 			} else {
5419 				RTW_INFO("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
5420 
5421 				rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
5422 				rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
5423 				pwdinfo->intent = 15;
5424 			}
5425 		}
5426 	}
5427 #endif /* CONFIG_P2P */
5428 
5429 	if (adapter_to_dvobj(adapter)->wpas_type == RTW_WPAS_ANDROID) {
5430 		/* pbss_network->IEs will not include p2p_ie, wfd ie */
5431 		rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
5432 		rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
5433 	}
5434 
5435 	if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS) {
5436 #ifdef CONFIG_P2P
5437 		/* check p2p if enable */
5438 		if (got_p2p_ie == _TRUE) {
5439 			struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
5440 			struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
5441 			pwdinfo->operating_channel = pmlmeext->cur_channel;
5442 		}
5443 #endif /* CONFIG_P2P */
5444 		ret = 0;
5445 	} else
5446 		ret = -EINVAL;
5447 
5448 exit:
5449 	if (pbuf)
5450 		rtw_mfree(pbuf, head_len + tail_len);
5451 
5452 	return ret;
5453 }
5454 
5455 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
cfg80211_rtw_add_beacon(struct wiphy * wiphy,struct net_device * ndev,struct beacon_parameters * info)5456 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
5457 		struct beacon_parameters *info)
5458 {
5459 	int ret = 0;
5460 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5461 
5462 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5463 
5464 	if (rtw_cfg80211_sync_iftype(adapter) != _SUCCESS) {
5465 		ret = -ENOTSUPP;
5466 		goto exit;
5467 	}
5468 	rtw_mi_scan_abort(adapter, _TRUE);
5469 	rtw_mi_buddy_set_scan_deny(adapter, 300);
5470 	ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
5471 
5472 exit:
5473 	return ret;
5474 }
5475 
cfg80211_rtw_set_beacon(struct wiphy * wiphy,struct net_device * ndev,struct beacon_parameters * info)5476 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
5477 		struct beacon_parameters *info)
5478 {
5479 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5480 	struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5481 
5482 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5483 
5484 	pmlmeext->bstart_bss = _TRUE;
5485 
5486 	cfg80211_rtw_add_beacon(wiphy, ndev, info);
5487 
5488 	return 0;
5489 }
5490 
cfg80211_rtw_del_beacon(struct wiphy * wiphy,struct net_device * ndev)5491 static int	cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
5492 {
5493 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5494 
5495 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5496 
5497 	rtw_stop_ap_cmd(adapter, RTW_CMDF_WAIT_ACK);
5498 	return 0;
5499 }
5500 #else
cfg80211_rtw_start_ap(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ap_settings * settings)5501 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
5502 		struct cfg80211_ap_settings *settings)
5503 {
5504 	int ret = 0;
5505 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5506 
5507 	RTW_INFO(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
5508 		settings->hidden_ssid, settings->auth_type);
5509 
5510 	if (rtw_cfg80211_sync_iftype(adapter) != _SUCCESS) {
5511 		ret = -ENOTSUPP;
5512 		goto exit;
5513 	}
5514 
5515 	if (adapter_to_dvobj(adapter)->wpas_type == RTW_WPAS_W1FI) {
5516 		struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5517 
5518 		/* turn on the beacon send */
5519 		pmlmeext->bstart_bss = _TRUE;
5520 	}
5521 
5522 	/* Kernel < v5.x, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC. if
5523 	 * the AKM SAE in the RSN IE, we have to update the auth_type for SAE in
5524 	 * rtw_check_beacon_data().
5525 	 *
5526 	 * we only update auth_type when rtw_check_beacon_data()
5527 	 */
5528 	/* rtw_cfg80211_set_auth_type(&adapter->securitypriv, settings->auth_type); */
5529 
5530 	rtw_mi_scan_abort(adapter, _TRUE);
5531 	rtw_mi_buddy_set_scan_deny(adapter, 300);
5532 
5533 	adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
5534 	ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
5535 		settings->beacon.tail, settings->beacon.tail_len);
5536 
5537 #ifdef CONFIG_RTW_80211R_AP
5538 	rtw_ft_update_assocresp_ies(ndev, settings);
5539 #endif
5540 
5541 	if (settings->beacon.assocresp_ies &&
5542 		settings->beacon.assocresp_ies_len > 0) {
5543 		rtw_cfg80211_set_assocresp_ies(ndev,
5544 			settings->beacon.assocresp_ies,
5545 			settings->beacon.assocresp_ies_len);
5546 	}
5547 
5548 	if (settings->ssid && settings->ssid_len) {
5549 		WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
5550 		WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
5551 
5552 		if (0)
5553 			RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
5554 				settings->ssid, settings->ssid_len,
5555 				pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
5556 
5557 		_rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
5558 		pbss_network->Ssid.SsidLength = settings->ssid_len;
5559 		_rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
5560 		pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
5561 
5562 		if (0)
5563 			RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
5564 				pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
5565 				pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
5566 	}
5567 
5568 exit:
5569 	return ret;
5570 }
5571 
rtw_cfg80211_set_assocresp_ies(struct net_device * net,const u8 * buf,int len)5572 static int rtw_cfg80211_set_assocresp_ies(struct net_device *net, const u8 *buf, int len)
5573 {
5574 	int ret = 0;
5575 	_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
5576 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5577 
5578 	RTW_INFO("%s, ielen=%d\n", __func__, len);
5579 
5580 	if (len <= 0)
5581 		goto exit;
5582 
5583 	if (pmlmepriv->assoc_rsp) {
5584 		u32 free_len = pmlmepriv->assoc_rsp_len;
5585 
5586 		pmlmepriv->assoc_rsp_len = 0;
5587 		rtw_mfree(pmlmepriv->assoc_rsp, free_len);
5588 		pmlmepriv->assoc_rsp = NULL;
5589 	}
5590 
5591 	pmlmepriv->assoc_rsp = rtw_malloc(len);
5592 	if (pmlmepriv->assoc_rsp == NULL) {
5593 		RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5594 		return -EINVAL;
5595 	}
5596 	_rtw_memcpy(pmlmepriv->assoc_rsp, buf, len);
5597 	pmlmepriv->assoc_rsp_len = len;
5598 
5599 exit:
5600 	return ret;
5601 }
5602 
cfg80211_rtw_change_beacon(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_beacon_data * info)5603 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
5604 		struct cfg80211_beacon_data *info)
5605 {
5606 	int ret = 0;
5607 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5608 
5609 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5610 
5611 #ifdef not_yet
5612 	/*
5613 	 * @proberesp_ies: extra information element(s) to add into Probe Response
5614 	 *	frames or %NULL
5615 	 * @proberesp_ies_len: length of proberesp_ies in octets
5616 	 */
5617 	if (info->proberesp_ies_len > 0)
5618 		rtw_cfg80211_set_proberesp_ies(ndev, info->proberesp_ies, info->proberesp_ies_len);
5619 #endif /* not_yet */
5620 
5621 	if (info->assocresp_ies_len > 0)
5622 		rtw_cfg80211_set_assocresp_ies(ndev, info->assocresp_ies, info->assocresp_ies_len);
5623 
5624 	ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
5625 
5626 	return ret;
5627 }
5628 
cfg80211_rtw_stop_ap(struct wiphy * wiphy,struct net_device * ndev)5629 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
5630 {
5631 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5632 
5633 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5634 
5635 	rtw_stop_ap_cmd(adapter, RTW_CMDF_WAIT_ACK);
5636 	return 0;
5637 }
5638 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) */
5639 
5640 #if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
cfg80211_rtw_set_mac_acl(struct wiphy * wiphy,struct net_device * ndev,const struct cfg80211_acl_data * params)5641 static int cfg80211_rtw_set_mac_acl(struct wiphy *wiphy, struct net_device *ndev,
5642 		const struct cfg80211_acl_data *params)
5643 {
5644 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5645 	u8 acl_mode = RTW_ACL_MODE_DISABLED;
5646 	int ret = -1;
5647 	int i;
5648 
5649 	if (!params) {
5650 		RTW_WARN(FUNC_ADPT_FMT" params NULL\n", FUNC_ADPT_ARG(adapter));
5651 		rtw_macaddr_acl_clear(adapter, RTW_ACL_PERIOD_BSS);
5652 		goto exit;
5653 	}
5654 
5655 	RTW_INFO(FUNC_ADPT_FMT" acl_policy:%d, entry_num:%d\n"
5656 		, FUNC_ADPT_ARG(adapter), params->acl_policy, params->n_acl_entries);
5657 
5658 	if (params->acl_policy == NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED)
5659 		acl_mode = RTW_ACL_MODE_ACCEPT_UNLESS_LISTED;
5660 	else if (params->acl_policy == NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
5661 		acl_mode = RTW_ACL_MODE_DENY_UNLESS_LISTED;
5662 
5663 	rtw_macaddr_acl_clear(adapter, RTW_ACL_PERIOD_BSS);
5664 
5665 	rtw_set_macaddr_acl(adapter, RTW_ACL_PERIOD_BSS, acl_mode);
5666 
5667 	for (i = 0; i < params->n_acl_entries; i++)
5668 		rtw_acl_add_sta(adapter, RTW_ACL_PERIOD_BSS, params->mac_addrs[i].addr);
5669 
5670 	ret = 0;
5671 
5672 exit:
5673 	return ret;
5674 }
5675 #endif /* CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) */
5676 
5677 const char *_nl80211_sta_flags_str[] = {
5678 	"INVALID",
5679 	"AUTHORIZED",
5680 	"SHORT_PREAMBLE",
5681 	"WME",
5682 	"MFP",
5683 	"AUTHENTICATED",
5684 	"TDLS_PEER",
5685 	"ASSOCIATED",
5686 };
5687 
5688 #define nl80211_sta_flags_str(_f) ((_f <= NL80211_STA_FLAG_MAX) ? _nl80211_sta_flags_str[_f] : _nl80211_sta_flags_str[0])
5689 
5690 const char *_nl80211_plink_state_str[] = {
5691 	"LISTEN",
5692 	"OPN_SNT",
5693 	"OPN_RCVD",
5694 	"CNF_RCVD",
5695 	"ESTAB",
5696 	"HOLDING",
5697 	"BLOCKED",
5698 	"UNKNOWN",
5699 };
5700 
5701 #define nl80211_plink_state_str(_s) ((_s < NUM_NL80211_PLINK_STATES) ? _nl80211_plink_state_str[_s] : _nl80211_plink_state_str[NUM_NL80211_PLINK_STATES])
5702 
5703 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
5704 #define NL80211_PLINK_ACTION_NO_ACTION PLINK_ACTION_INVALID
5705 #define NL80211_PLINK_ACTION_OPEN PLINK_ACTION_OPEN
5706 #define NL80211_PLINK_ACTION_BLOCK PLINK_ACTION_BLOCK
5707 #define NUM_NL80211_PLINK_ACTIONS 3
5708 #endif
5709 
5710 const char *_nl80211_plink_actions_str[] = {
5711 	"NO_ACTION",
5712 	"OPEN",
5713 	"BLOCK",
5714 	"UNKNOWN",
5715 };
5716 
5717 #define nl80211_plink_actions_str(_a) ((_a < NUM_NL80211_PLINK_ACTIONS) ? _nl80211_plink_actions_str[_a] : _nl80211_plink_actions_str[NUM_NL80211_PLINK_ACTIONS])
5718 
5719 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
5720 const char *_nl80211_mesh_power_mode_str[] = {
5721 	"UNKNOWN",
5722 	"ACTIVE",
5723 	"LIGHT_SLEEP",
5724 	"DEEP_SLEEP",
5725 };
5726 
5727 #define nl80211_mesh_power_mode_str(_p) ((_p <= NL80211_MESH_POWER_MAX) ? _nl80211_mesh_power_mode_str[_p] : _nl80211_mesh_power_mode_str[0])
5728 #endif
5729 
dump_station_parameters(void * sel,struct wiphy * wiphy,const struct station_parameters * params)5730 void dump_station_parameters(void *sel, struct wiphy *wiphy, const struct station_parameters *params)
5731 {
5732 #if DBG_RTW_CFG80211_STA_PARAM
5733 	if (params->supported_rates_len) {
5734 		#define SUPP_RATES_BUF_LEN (3 * RTW_G_RATES_NUM + 1)
5735 		int i;
5736 		char supp_rates_buf[SUPP_RATES_BUF_LEN] = {0};
5737 		u8 cnt = 0;
5738 
5739 		rtw_warn_on(params->supported_rates_len > RTW_G_RATES_NUM);
5740 
5741 		for (i = 0; i < params->supported_rates_len; i++) {
5742 			if (i >= RTW_G_RATES_NUM)
5743 				break;
5744 			cnt += snprintf(supp_rates_buf + cnt, SUPP_RATES_BUF_LEN - cnt -1
5745 				, "%02X ", params->supported_rates[i]);
5746 			if (cnt >= SUPP_RATES_BUF_LEN - 1)
5747 				break;
5748 		}
5749 
5750 		RTW_PRINT_SEL(sel, "supported_rates:%s\n", supp_rates_buf);
5751 	}
5752 
5753 	if (params->vlan)
5754 		RTW_PRINT_SEL(sel, "vlan:"NDEV_FMT"\n", NDEV_ARG(params->vlan));
5755 
5756 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
5757 	if (params->sta_flags_mask) {
5758 		#define STA_FLAGS_BUF_LEN 128
5759 		int i = 0;
5760 		char sta_flags_buf[STA_FLAGS_BUF_LEN] = {0};
5761 		u8 cnt = 0;
5762 
5763 		for (i = 1; i <= NL80211_STA_FLAG_MAX; i++) {
5764 			if (params->sta_flags_mask & BIT(i)) {
5765 				cnt += snprintf(sta_flags_buf + cnt, STA_FLAGS_BUF_LEN - cnt -1, "%s=%u "
5766 					, nl80211_sta_flags_str(i), (params->sta_flags_set & BIT(i)) ? 1 : 0);
5767 				if (cnt >= STA_FLAGS_BUF_LEN - 1)
5768 					break;
5769 			}
5770 		}
5771 
5772 		RTW_PRINT_SEL(sel, "sta_flags:%s\n", sta_flags_buf);
5773 	}
5774 #else
5775 	u32 station_flags;
5776 	#error "TBD\n"
5777 #endif
5778 
5779 	if (params->listen_interval != -1)
5780 		RTW_PRINT_SEL(sel, "listen_interval:%d\n", params->listen_interval);
5781 
5782 	if (params->aid)
5783 		RTW_PRINT_SEL(sel, "aid:%u\n", params->aid);
5784 
5785 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
5786 	if (params->peer_aid)
5787 		RTW_PRINT_SEL(sel, "peer_aid:%u\n", params->peer_aid);
5788 #endif
5789 
5790 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26))
5791 	if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
5792 		RTW_PRINT_SEL(sel, "plink_action:%s\n", nl80211_plink_actions_str(params->plink_action));
5793 #endif
5794 
5795 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
5796 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
5797 	if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5798 	#endif
5799 		RTW_PRINT_SEL(sel, "plink_state:%s\n"
5800 			, nl80211_plink_state_str(params->plink_state));
5801 #endif
5802 
5803 #if 0 /* TODO */
5804 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
5805 	const struct ieee80211_ht_cap *ht_capa;
5806 #endif
5807 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
5808 	const struct ieee80211_vht_cap *vht_capa;
5809 #endif
5810 #endif
5811 
5812 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
5813 	if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
5814 		RTW_PRINT_SEL(sel, "uapsd_queues:0x%02x\n", params->uapsd_queues);
5815 	if (params->max_sp)
5816 		RTW_PRINT_SEL(sel, "max_sp:%u\n", params->max_sp);
5817 #endif
5818 
5819 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
5820 	if (params->local_pm != NL80211_MESH_POWER_UNKNOWN) {
5821 		RTW_PRINT_SEL(sel, "local_pm:%s\n"
5822 			, nl80211_mesh_power_mode_str(params->local_pm));
5823 	}
5824 
5825 	if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
5826 		RTW_PRINT_SEL(sel, "capability:0x%04x\n", params->capability);
5827 
5828 #if 0 /* TODO */
5829 	const u8 *ext_capab;
5830 	u8 ext_capab_len;
5831 #endif
5832 #endif
5833 
5834 #if 0 /* TODO */
5835 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
5836 	const u8 *supported_channels;
5837 	u8 supported_channels_len;
5838 	const u8 *supported_oper_classes;
5839 	u8 supported_oper_classes_len;
5840 #endif
5841 
5842 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
5843 	u8 opmode_notif;
5844 	bool opmode_notif_used;
5845 #endif
5846 
5847 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
5848 	int support_p2p_ps;
5849 #endif
5850 #endif
5851 #endif /* DBG_RTW_CFG80211_STA_PARAM */
5852 }
5853 
cfg80211_rtw_add_station(struct wiphy * wiphy,struct net_device * ndev,u8 * mac,struct station_parameters * params)5854 static int	cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
5855 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
5856 	u8 *mac,
5857 #else
5858 	const u8 *mac,
5859 #endif
5860 	struct station_parameters *params)
5861 {
5862 	int ret = 0;
5863 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
5864 #if defined(CONFIG_TDLS) || defined(CONFIG_RTW_MESH)
5865 	struct sta_priv *pstapriv = &padapter->stapriv;
5866 #endif
5867 #ifdef CONFIG_TDLS
5868 	struct sta_info *psta;
5869 #endif /* CONFIG_TDLS */
5870 
5871 	RTW_INFO(FUNC_NDEV_FMT" mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
5872 
5873 #if CONFIG_RTW_MACADDR_ACL
5874 	if (rtw_access_ctrl(padapter, mac) == _FALSE) {
5875 		RTW_INFO(FUNC_NDEV_FMT" deny by macaddr ACL\n", FUNC_NDEV_ARG(ndev));
5876 		ret = -EINVAL;
5877 		goto exit;
5878 	}
5879 #endif
5880 
5881 	dump_station_parameters(RTW_DBGDUMP, wiphy, params);
5882 
5883 #ifdef CONFIG_RTW_MESH
5884 	if (MLME_IS_MESH(padapter)) {
5885 		struct rtw_mesh_cfg *mcfg = &padapter->mesh_cfg;
5886 		struct rtw_mesh_info *minfo = &padapter->mesh_info;
5887 		struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
5888 		struct mesh_plink_ent *plink = NULL;
5889 		struct wlan_network *scanned = NULL;
5890 		bool acnode = 0;
5891 		u8 add_new_sta = 0, probe_req = 0;
5892 		_irqL irqL;
5893 
5894 		if (params->plink_state != NL80211_PLINK_LISTEN) {
5895 			RTW_WARN(FUNC_NDEV_FMT" %s\n", FUNC_NDEV_ARG(ndev), nl80211_plink_state_str(params->plink_state));
5896 			rtw_warn_on(1);
5897 		}
5898 		if (!params->aid || params->aid > pstapriv->max_aid) {
5899 			RTW_WARN(FUNC_NDEV_FMT" invalid aid:%u\n", FUNC_NDEV_ARG(ndev), params->aid);
5900 			rtw_warn_on(1);
5901 			ret = -EINVAL;
5902 			goto exit;
5903 		}
5904 
5905 		_enter_critical_bh(&(plink_ctl->lock), &irqL);
5906 
5907 		plink = _rtw_mesh_plink_get(padapter, mac);
5908 		if (plink)
5909 			goto release_plink_ctl;
5910 
5911 		#if CONFIG_RTW_MESH_PEER_BLACKLIST
5912 		if (rtw_mesh_peer_blacklist_search(padapter, mac)) {
5913 			RTW_INFO(FUNC_NDEV_FMT" deny by peer blacklist\n"
5914 				, FUNC_NDEV_ARG(ndev));
5915 			ret = -EINVAL;
5916 			goto release_plink_ctl;
5917 		}
5918 		#endif
5919 
5920 		scanned = rtw_find_network(&padapter->mlmepriv.scanned_queue, mac);
5921 		if (!scanned
5922 			|| rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms
5923 		) {
5924 			if (!scanned)
5925 				RTW_INFO(FUNC_NDEV_FMT" corresponding network not found\n", FUNC_NDEV_ARG(ndev));
5926 			else
5927 				RTW_INFO(FUNC_NDEV_FMT" corresponding network too old\n", FUNC_NDEV_ARG(ndev));
5928 
5929 			if (adapter_to_rfctl(padapter)->offch_state == OFFCHS_NONE)
5930 				probe_req = 1;
5931 
5932 			ret = -EINVAL;
5933 			goto release_plink_ctl;
5934 		}
5935 
5936 		#if CONFIG_RTW_MESH_ACNODE_PREVENT
5937 		if (plink_ctl->acnode_rsvd)
5938 			acnode = rtw_mesh_scanned_is_acnode_confirmed(padapter, scanned);
5939 		#endif
5940 
5941 		/* wpa_supplicant's auto peer will initiate peering when candidate peer is reported without max_peer_links consideration */
5942 		if (plink_ctl->num >= mcfg->max_peer_links + acnode ? 1 : 0) {
5943 			RTW_INFO(FUNC_NDEV_FMT" exceed max_peer_links:%u%s\n"
5944 				, FUNC_NDEV_ARG(ndev), mcfg->max_peer_links, acnode ? " acn" : "");
5945 			ret = -EINVAL;
5946 			goto release_plink_ctl;
5947 		}
5948 
5949 		if (!rtw_bss_is_candidate_mesh_peer(padapter, &scanned->network, 1, 1)) {
5950 			RTW_WARN(FUNC_NDEV_FMT" corresponding network is not candidate with same ch\n"
5951 				, FUNC_NDEV_ARG(ndev));
5952 			ret = -EINVAL;
5953 			goto release_plink_ctl;
5954 		}
5955 
5956 		#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
5957 		if (!rtw_mesh_cto_mgate_network_filter(padapter, scanned)) {
5958 			RTW_INFO(FUNC_NDEV_FMT" peer filtered out by cto_mgate check\n"
5959 				, FUNC_NDEV_ARG(ndev));
5960 			ret = -EINVAL;
5961 			goto release_plink_ctl;
5962 		}
5963 		#endif
5964 
5965 		if (_rtw_mesh_plink_add(padapter, mac) == _SUCCESS) {
5966 			/* hook corresponding network in scan queue */
5967 			plink = _rtw_mesh_plink_get(padapter, mac);
5968 			plink->aid = params->aid;
5969 			plink->scanned = scanned;
5970 
5971 			#if CONFIG_RTW_MESH_ACNODE_PREVENT
5972 			if (acnode) {
5973 				RTW_INFO(FUNC_ADPT_FMT" acnode "MAC_FMT"\n"
5974 				, FUNC_ADPT_ARG(padapter), MAC_ARG(scanned->network.MacAddress));
5975 			}
5976 			#endif
5977 
5978 			add_new_sta = 1;
5979 		} else {
5980 			RTW_WARN(FUNC_NDEV_FMT" rtw_mesh_plink_add not success\n"
5981 				, FUNC_NDEV_ARG(ndev));
5982 			ret = -EINVAL;
5983 		}
5984 release_plink_ctl:
5985 		_exit_critical_bh(&(plink_ctl->lock), &irqL);
5986 
5987 		if (probe_req)
5988 			issue_probereq(padapter, &padapter->mlmepriv.cur_network.network.mesh_id, mac);
5989 
5990 		if (add_new_sta) {
5991 			struct station_info sinfo;
5992 
5993 			#ifdef CONFIG_DFS_MASTER
5994 			if (IS_UNDER_CAC(adapter_to_rfctl(padapter)))
5995 				rtw_force_stop_cac(adapter_to_rfctl(padapter), 300);
5996 			#endif
5997 
5998 			/* indicate new sta */
5999 			_rtw_memset(&sinfo, 0, sizeof(sinfo));
6000 			cfg80211_new_sta(ndev, mac, &sinfo, GFP_ATOMIC);
6001 		}
6002 		goto exit;
6003 	}
6004 #endif /* CONFIG_RTW_MESH */
6005 
6006 #ifdef CONFIG_TDLS
6007 	psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
6008 	if (psta == NULL) {
6009 		psta = rtw_alloc_stainfo(pstapriv, (u8 *)mac);
6010 		if (psta == NULL) {
6011 			RTW_INFO("[%s] Alloc station for "MAC_FMT" fail\n", __FUNCTION__, MAC_ARG(mac));
6012 			ret = -EOPNOTSUPP;
6013 			goto exit;
6014 		}
6015 	}
6016 #endif /* CONFIG_TDLS */
6017 
6018 exit:
6019 	return ret;
6020 }
6021 
cfg80211_rtw_del_station(struct wiphy * wiphy,struct net_device * ndev,u8 * mac)6022 static int	cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
6023 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
6024 	u8 *mac
6025 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
6026 	const u8 *mac
6027 #else
6028 	struct station_del_parameters *params
6029 #endif
6030 )
6031 {
6032 	int ret = 0;
6033 	_irqL irqL;
6034 	_list	*phead, *plist;
6035 	u8 updated = _FALSE;
6036 	const u8 *target_mac;
6037 	struct sta_info *psta = NULL;
6038 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
6039 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6040 	struct sta_priv *pstapriv = &padapter->stapriv;
6041 
6042 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
6043 	target_mac = mac;
6044 #else
6045 	target_mac = params->mac;
6046 #endif
6047 
6048 	RTW_INFO("+"FUNC_NDEV_FMT" mac=%pM\n", FUNC_NDEV_ARG(ndev), target_mac);
6049 
6050 	if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) != _TRUE) {
6051 		RTW_INFO("%s, fw_state != FW_LINKED|WIFI_AP_STATE|WIFI_MESH_STATE\n", __func__);
6052 		return -EINVAL;
6053 	}
6054 
6055 
6056 	if (!target_mac) {
6057 		RTW_INFO("flush all sta, and cam_entry\n");
6058 
6059 		flush_all_cam_entry(padapter);	/* clear CAM */
6060 
6061 #ifdef CONFIG_AP_MODE
6062 		ret = rtw_sta_flush(padapter, _TRUE);
6063 #endif
6064 		return ret;
6065 	}
6066 
6067 
6068 	RTW_INFO("free sta macaddr =" MAC_FMT "\n", MAC_ARG(target_mac));
6069 
6070 	if (target_mac[0] == 0xff && target_mac[1] == 0xff &&
6071 	    target_mac[2] == 0xff && target_mac[3] == 0xff &&
6072 	    target_mac[4] == 0xff && target_mac[5] == 0xff)
6073 		return -EINVAL;
6074 
6075 
6076 	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
6077 
6078 	phead = &pstapriv->asoc_list;
6079 	plist = get_next(phead);
6080 
6081 	/* check asoc_queue */
6082 	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
6083 		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
6084 
6085 		plist = get_next(plist);
6086 
6087 		if (_rtw_memcmp((u8 *)target_mac, psta->cmn.mac_addr, ETH_ALEN)) {
6088 			if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) {
6089 				RTW_INFO("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
6090 
6091 				#ifdef CONFIG_AP_MODE
6092 				if (MLME_IS_AP(padapter)) {
6093 					rtw_list_delete(&psta->asoc_list);
6094 					pstapriv->asoc_list_cnt--;
6095 					#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
6096 					if (psta->tbtx_enable)
6097 						pstapriv->tbtx_asoc_list_cnt--;
6098 					#endif
6099 					STA_SET_MESH_PLINK(psta, NULL);
6100 
6101 					ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_IEEE_802_1X_AUTH_FAILED, _TRUE);
6102 					psta = NULL;
6103 					break;
6104 				}
6105 				#endif
6106 			} else {
6107 				RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid);
6108 
6109 				rtw_list_delete(&psta->asoc_list);
6110 				pstapriv->asoc_list_cnt--;
6111 				#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
6112 				if (psta->tbtx_enable)
6113 					pstapriv->tbtx_asoc_list_cnt--;
6114 				#endif
6115 				STA_SET_MESH_PLINK(psta, NULL);
6116 
6117 				/* _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); */
6118 				if (MLME_IS_AP(padapter))
6119 					updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
6120 				else
6121 					updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
6122 				/* _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); */
6123 
6124 				psta = NULL;
6125 
6126 				break;
6127 			}
6128 
6129 		}
6130 
6131 	}
6132 
6133 	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
6134 
6135 	associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
6136 
6137 #ifdef CONFIG_RTW_MESH
6138 	if (MLME_IS_MESH(padapter))
6139 		rtw_mesh_plink_del(padapter, target_mac);
6140 #endif
6141 
6142 	RTW_INFO("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6143 
6144 	return ret;
6145 
6146 }
6147 
cfg80211_rtw_change_station(struct wiphy * wiphy,struct net_device * ndev,u8 * mac,struct station_parameters * params)6148 static int	cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
6149 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
6150 	u8 *mac,
6151 #else
6152 	const u8 *mac,
6153 #endif
6154 	struct station_parameters *params)
6155 {
6156 	_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
6157 	int ret = 0;
6158 
6159 	RTW_INFO(FUNC_ADPT_FMT" mac:"MAC_FMT"\n", FUNC_ADPT_ARG(adapter), MAC_ARG(mac));
6160 
6161 	dump_station_parameters(RTW_DBGDUMP, wiphy, params);
6162 
6163 #ifdef CONFIG_RTW_MESH
6164 	if (MLME_IS_MESH(adapter)) {
6165 		enum cfg80211_station_type sta_type = CFG80211_STA_MESH_PEER_USER;
6166 		u8 plink_state = nl80211_plink_state_to_rtw_plink_state(params->plink_state);
6167 
6168 		ret = cfg80211_check_station_change(wiphy, params, sta_type);
6169 		if (ret) {
6170 			RTW_INFO("cfg80211_check_station_change return %d\n", ret);
6171 			goto exit;
6172 		}
6173 
6174 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
6175 		if (!(params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE))
6176 			goto exit;
6177 		#endif
6178 
6179 		if (rtw_mesh_set_plink_state_cmd(adapter, mac, plink_state) != _SUCCESS)
6180 			ret = -ENOENT;
6181 	}
6182 
6183 exit:
6184 #endif /* CONFIG_RTW_MESH */
6185 
6186 	if (ret)
6187 		RTW_INFO(FUNC_ADPT_FMT" mac:"MAC_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), MAC_ARG(mac), ret);
6188 	return ret;
6189 }
6190 
rtw_sta_info_get_by_idx(struct sta_priv * pstapriv,const int idx,u8 * asoc_list_num)6191 struct sta_info *rtw_sta_info_get_by_idx(struct sta_priv *pstapriv, const int idx, u8 *asoc_list_num)
6192 {
6193 	_list	*phead, *plist;
6194 	struct sta_info *psta = NULL;
6195 	int i = 0;
6196 
6197 	phead = &pstapriv->asoc_list;
6198 	plist = get_next(phead);
6199 
6200 	/* check asoc_queue */
6201 	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
6202 		if (idx == i)
6203 			psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
6204 		plist = get_next(plist);
6205 		i++;
6206 	}
6207 
6208 	if (asoc_list_num)
6209 		*asoc_list_num = i;
6210 
6211 	return psta;
6212 }
6213 
cfg80211_rtw_dump_station(struct wiphy * wiphy,struct net_device * ndev,int idx,u8 * mac,struct station_info * sinfo)6214 static int	cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
6215 		int idx, u8 *mac, struct station_info *sinfo)
6216 {
6217 #define DBG_DUMP_STATION 0
6218 
6219 	int ret = 0;
6220 	_irqL irqL;
6221 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
6222 	struct sta_priv *pstapriv = &padapter->stapriv;
6223 	struct sta_info *psta = NULL;
6224 #ifdef CONFIG_RTW_MESH
6225 	struct mesh_plink_ent *plink = NULL;
6226 #endif
6227 	u8 asoc_list_num;
6228 
6229 	if (DBG_DUMP_STATION)
6230 		RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6231 
6232 	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
6233 	psta = rtw_sta_info_get_by_idx(pstapriv, idx, &asoc_list_num);
6234 	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
6235 
6236 #ifdef CONFIG_RTW_MESH
6237 	if (MLME_IS_MESH(padapter)) {
6238 		if (psta)
6239 			plink = psta->plink;
6240 		if (!plink)
6241 			plink = rtw_mesh_plink_get_no_estab_by_idx(padapter, idx - asoc_list_num);
6242 	}
6243 #endif /* CONFIG_RTW_MESH */
6244 
6245 	if ((!MLME_IS_MESH(padapter) && !psta)
6246 		#ifdef CONFIG_RTW_MESH
6247 		|| (MLME_IS_MESH(padapter) && !plink)
6248 		#endif
6249 	) {
6250 		if (DBG_DUMP_STATION)
6251 			RTW_INFO(FUNC_NDEV_FMT" end with idx:%d\n", FUNC_NDEV_ARG(ndev), idx);
6252 		ret = -ENOENT;
6253 		goto exit;
6254 	}
6255 
6256 	if (psta)
6257 		_rtw_memcpy(mac, psta->cmn.mac_addr, ETH_ALEN);
6258 	#ifdef CONFIG_RTW_MESH
6259 	else
6260 		_rtw_memcpy(mac, plink->addr, ETH_ALEN);
6261 	#endif
6262 
6263 	sinfo->filled = 0;
6264 
6265 	if (psta) {
6266 		sinfo->filled |= STATION_INFO_SIGNAL;
6267 		sinfo->signal = translate_percentage_to_dbm(psta->cmn.rssi_stat.rssi);
6268 		sinfo->filled |= STATION_INFO_INACTIVE_TIME;
6269 		sinfo->inactive_time = rtw_get_passing_time_ms(psta->sta_stats.last_rx_time);
6270 	}
6271 
6272 #ifdef CONFIG_RTW_MESH
6273 	if (MLME_IS_MESH(padapter))
6274 		rtw_cfg80211_fill_mesh_only_sta_info(plink, psta, sinfo);
6275 #endif
6276 
6277 exit:
6278 	return ret;
6279 }
6280 
6281 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
cfg80211_rtw_change_bss(struct wiphy * wiphy,struct net_device * ndev,struct bss_parameters * params)6282 static int	cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
6283 		struct bss_parameters *params)
6284 {
6285 	_adapter *adapter = rtw_netdev_priv(ndev);
6286 
6287 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
6288 
6289 if (0) {
6290 	if (params->use_cts_prot != -1)
6291 		RTW_INFO("use_cts_prot=%d\n", params->use_cts_prot);
6292 	if (params->use_short_preamble != -1)
6293 		RTW_INFO("use_short_preamble=%d\n", params->use_short_preamble);
6294 	if (params->use_short_slot_time != -1)
6295 		RTW_INFO("use_short_slot_time=%d\n", params->use_short_slot_time);
6296 
6297 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
6298 	if (params->basic_rates && params->basic_rates_len) {
6299 		RTW_INFO("basic_rates_len=%d\n", params->basic_rates_len);
6300 		RTW_INFO_DUMP("basic_rates=", params->basic_rates, params->basic_rates_len);
6301 	}
6302 #endif
6303 }
6304 
6305 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6306 	if (params->ap_isolate != -1) {
6307 		RTW_INFO("ap_isolate=%d\n", params->ap_isolate);
6308 		adapter->mlmepriv.ap_isolate = params->ap_isolate ? 1 : 0;
6309 	}
6310 #endif
6311 
6312 if (0) {
6313 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
6314 	if (params->ht_opmode != -1)
6315 		RTW_INFO("ht_opmode=0x%04x\n", params->ht_opmode);
6316 #endif
6317 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
6318 	if (params->p2p_ctwindow != -1)
6319 		RTW_INFO("p2p_ctwindow=%d\n", params->p2p_ctwindow);
6320 	if (params->p2p_opp_ps != -1)
6321 		RTW_INFO("p2p_opp_ps=%d\n", params->p2p_opp_ps);
6322 #endif
6323 }
6324 	return 0;
6325 }
6326 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) */
6327 
6328 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
cfg80211_rtw_set_txq_params(struct wiphy * wiphy,struct net_device * ndev,struct ieee80211_txq_params * params)6329 static int	cfg80211_rtw_set_txq_params(struct wiphy *wiphy
6330 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
6331 	, struct net_device *ndev
6332 #endif
6333 	, struct ieee80211_txq_params *params)
6334 {
6335 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
6336 	_adapter *padapter = rtw_netdev_priv(ndev);
6337 #else
6338 	_adapter *padapter = wiphy_to_adapter(wiphy);
6339 #endif
6340 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6341 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6342 	u8	ac, AIFS, ECWMin, ECWMax, aSifsTime;
6343 	u16	TXOP;
6344 	u8	shift_count = 0;
6345 	u32	acParm;
6346 
6347 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
6348 	ac = params->ac;
6349 #else
6350 	ac = params->queue;
6351 #endif
6352 
6353 	switch (ac) {
6354 	case NL80211_TXQ_Q_VO:
6355 		ac = XMIT_VO_QUEUE;
6356 		break;
6357 
6358 	case NL80211_TXQ_Q_VI:
6359 		ac = XMIT_VI_QUEUE;
6360 		break;
6361 
6362 	case NL80211_TXQ_Q_BE:
6363 		ac = XMIT_BE_QUEUE;
6364 		break;
6365 
6366 	case NL80211_TXQ_Q_BK:
6367 		ac = XMIT_BK_QUEUE;
6368 		break;
6369 
6370 	default:
6371 		break;
6372 	}
6373 
6374 #if 0
6375 	RTW_INFO("ac=%d\n", ac);
6376 	RTW_INFO("txop=%u\n", params->txop);
6377 	RTW_INFO("cwmin=%u\n", params->cwmin);
6378 	RTW_INFO("cwmax=%u\n", params->cwmax);
6379 	RTW_INFO("aifs=%u\n", params->aifs);
6380 #endif
6381 
6382 	if (is_supported_5g(pmlmeext->cur_wireless_mode) ||
6383 	    (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
6384 		aSifsTime = 16;
6385 	else
6386 		aSifsTime = 10;
6387 
6388 	AIFS = params->aifs * pmlmeinfo->slotTime + aSifsTime;
6389 
6390 	while ((params->cwmin + 1) >> shift_count != 1) {
6391 		shift_count++;
6392 		if (shift_count == 15)
6393 			break;
6394 	}
6395 
6396 	ECWMin = shift_count;
6397 
6398 	shift_count = 0;
6399 	while ((params->cwmax + 1) >> shift_count != 1) {
6400 		shift_count++;
6401 		if (shift_count == 15)
6402 			break;
6403 	}
6404 
6405 	ECWMax = shift_count;
6406 
6407 	TXOP = le16_to_cpu(params->txop);
6408 
6409 	acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
6410 
6411 	set_txq_params_cmd(padapter, acParm, ac);
6412 
6413 	return 0;
6414 }
6415 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) */
6416 
6417 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
cfg80211_rtw_set_channel(struct wiphy * wiphy,struct net_device * ndev,struct ieee80211_channel * chan,enum nl80211_channel_type channel_type)6418 static int	cfg80211_rtw_set_channel(struct wiphy *wiphy
6419 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6420 	, struct net_device *ndev
6421 	#endif
6422 	, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
6423 {
6424 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6425 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
6426 #else
6427 	_adapter *padapter = wiphy_to_adapter(wiphy);
6428 #endif
6429 	int chan_target = (u8) ieee80211_frequency_to_channel(chan->center_freq);
6430 	int chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6431 	int chan_width = CHANNEL_WIDTH_20;
6432 
6433 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6434 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6435 #endif
6436 
6437 	switch (channel_type) {
6438 	case NL80211_CHAN_NO_HT:
6439 	case NL80211_CHAN_HT20:
6440 		chan_width = CHANNEL_WIDTH_20;
6441 		chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6442 		break;
6443 	case NL80211_CHAN_HT40MINUS:
6444 		chan_width = CHANNEL_WIDTH_40;
6445 		chan_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
6446 		break;
6447 	case NL80211_CHAN_HT40PLUS:
6448 		chan_width = CHANNEL_WIDTH_40;
6449 		chan_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
6450 		break;
6451 	default:
6452 		chan_width = CHANNEL_WIDTH_20;
6453 		chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6454 		break;
6455 	}
6456 
6457 	RTW_INFO(FUNC_ADPT_FMT" ch:%d bw:%d, offset:%d\n"
6458 		, FUNC_ADPT_ARG(padapter), chan_target, chan_width, chan_offset);
6459 
6460 	rtw_set_chbw_cmd(padapter, chan_target, chan_width, chan_offset, RTW_CMDF_WAIT_ACK);
6461 
6462 	return 0;
6463 }
6464 #endif /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))*/
6465 
6466 /*
6467 static int	cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
6468 		struct cfg80211_auth_request *req)
6469 {
6470 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6471 
6472 	return 0;
6473 }
6474 
6475 static int	cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
6476 		struct cfg80211_assoc_request *req)
6477 {
6478 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6479 
6480 	return 0;
6481 }
6482 */
6483 
rtw_cfg80211_set_beacon_wpsp2pie(struct net_device * ndev,char * buf,int len)6484 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
6485 {
6486 	int ret = 0;
6487 	uint wps_ielen = 0;
6488 	u8 *wps_ie;
6489 	u32	p2p_ielen = 0;
6490 	u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04};
6491 	u8 *p2p_ie;
6492 	u32	wfd_ielen = 0;
6493 	u8 *wfd_ie;
6494 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
6495 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6496 	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6497 
6498 	RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
6499 
6500 	if (len > 0) {
6501 		wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
6502 		if (wps_ie) {
6503 			#ifdef CONFIG_DEBUG_CFG80211
6504 			RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen);
6505 			#endif
6506 
6507 			if (pmlmepriv->wps_beacon_ie) {
6508 				u32 free_len = pmlmepriv->wps_beacon_ie_len;
6509 				pmlmepriv->wps_beacon_ie_len = 0;
6510 				rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
6511 				pmlmepriv->wps_beacon_ie = NULL;
6512 			}
6513 
6514 			pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
6515 			if (pmlmepriv->wps_beacon_ie == NULL) {
6516 				RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6517 				return -EINVAL;
6518 
6519 			}
6520 
6521 			_rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
6522 			pmlmepriv->wps_beacon_ie_len = wps_ielen;
6523 
6524 			update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, RTW_CMDF_WAIT_ACK);
6525 
6526 		}
6527 
6528 		/* buf += wps_ielen; */
6529 		/* len -= wps_ielen; */
6530 
6531 		#ifdef CONFIG_P2P
6532 		p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
6533 		if (p2p_ie) {
6534 			#ifdef CONFIG_DEBUG_CFG80211
6535 			RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen);
6536 			#endif
6537 
6538 			if (pmlmepriv->p2p_beacon_ie) {
6539 				u32 free_len = pmlmepriv->p2p_beacon_ie_len;
6540 				pmlmepriv->p2p_beacon_ie_len = 0;
6541 				rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
6542 				pmlmepriv->p2p_beacon_ie = NULL;
6543 			}
6544 
6545 			pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
6546 			if (pmlmepriv->p2p_beacon_ie == NULL) {
6547 				RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6548 				return -EINVAL;
6549 
6550 			}
6551 
6552 			_rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
6553 			pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
6554 
6555 		}
6556 		#endif /* CONFIG_P2P */
6557 
6558 
6559 		#ifdef CONFIG_WFD
6560 		wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
6561 		if (wfd_ie) {
6562 			#ifdef CONFIG_DEBUG_CFG80211
6563 			RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen);
6564 			#endif
6565 
6566 			if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS)
6567 				return -EINVAL;
6568 		}
6569 		#endif /* CONFIG_WFD */
6570 
6571 		pmlmeext->bstart_bss = _TRUE;
6572 
6573 	}
6574 
6575 	return ret;
6576 
6577 }
6578 
rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device * net,char * buf,int len)6579 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
6580 {
6581 	int ret = 0;
6582 	uint wps_ielen = 0;
6583 	u8 *wps_ie;
6584 	u32	p2p_ielen = 0;
6585 	u8 *p2p_ie;
6586 	u32	wfd_ielen = 0;
6587 	u8 *wfd_ie;
6588 	_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
6589 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6590 
6591 #ifdef CONFIG_DEBUG_CFG80211
6592 	RTW_INFO("%s, ielen=%d\n", __func__, len);
6593 #endif
6594 
6595 	if (len > 0) {
6596 		wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
6597 		if (wps_ie) {
6598 			uint	attr_contentlen = 0;
6599 			u16	uconfig_method, *puconfig_method = NULL;
6600 
6601 			#ifdef CONFIG_DEBUG_CFG80211
6602 			RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen);
6603 			#endif
6604 
6605 			if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
6606 				u8 sr = 0;
6607 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6608 
6609 				if (sr != 0)
6610 					RTW_INFO("%s, got sr\n", __func__);
6611 				else {
6612 					RTW_INFO("GO mode process WPS under site-survey,  sr no set\n");
6613 					return ret;
6614 				}
6615 			}
6616 
6617 			if (pmlmepriv->wps_probe_resp_ie) {
6618 				u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
6619 				pmlmepriv->wps_probe_resp_ie_len = 0;
6620 				rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
6621 				pmlmepriv->wps_probe_resp_ie = NULL;
6622 			}
6623 
6624 			pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
6625 			if (pmlmepriv->wps_probe_resp_ie == NULL) {
6626 				RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6627 				return -EINVAL;
6628 
6629 			}
6630 
6631 			/* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */
6632 			puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen);
6633 			if (puconfig_method != NULL) {
6634 				/* struct registry_priv *pregistrypriv = &padapter->registrypriv; */
6635 				struct wireless_dev *wdev = padapter->rtw_wdev;
6636 
6637 				#ifdef CONFIG_DEBUG_CFG80211
6638 				/* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */
6639 				#endif
6640 
6641 				#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6642 				/* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */
6643 				if (wdev->iftype == NL80211_IFTYPE_P2P_GO) {
6644 					uconfig_method = WPS_CM_PUSH_BUTTON;
6645 					uconfig_method = cpu_to_be16(uconfig_method);
6646 
6647 					*puconfig_method &= ~uconfig_method;
6648 				}
6649 				#endif
6650 			}
6651 
6652 			_rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
6653 			pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
6654 
6655 		}
6656 
6657 		/* buf += wps_ielen; */
6658 		/* len -= wps_ielen; */
6659 
6660 		#ifdef CONFIG_P2P
6661 		p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
6662 		if (p2p_ie) {
6663 			u8 is_GO = _FALSE;
6664 			u32 attr_contentlen = 0;
6665 			u16 cap_attr = 0;
6666 
6667 			#ifdef CONFIG_DEBUG_CFG80211
6668 			RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen);
6669 			#endif
6670 
6671 			/* Check P2P Capability ATTR */
6672 			attr_contentlen = sizeof(cap_attr);
6673 			if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) {
6674 				u8 grp_cap = 0;
6675 				/* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */
6676 				cap_attr = le16_to_cpu(cap_attr);
6677 				grp_cap = (u8)((cap_attr >> 8) & 0xff);
6678 
6679 				is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE;
6680 
6681 				if (is_GO)
6682 					RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
6683 			}
6684 
6685 
6686 			if (is_GO == _FALSE) {
6687 				if (pmlmepriv->p2p_probe_resp_ie) {
6688 					u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
6689 					pmlmepriv->p2p_probe_resp_ie_len = 0;
6690 					rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
6691 					pmlmepriv->p2p_probe_resp_ie = NULL;
6692 				}
6693 
6694 				pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
6695 				if (pmlmepriv->p2p_probe_resp_ie == NULL) {
6696 					RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6697 					return -EINVAL;
6698 
6699 				}
6700 				_rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
6701 				pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
6702 			} else {
6703 				if (pmlmepriv->p2p_go_probe_resp_ie) {
6704 					u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
6705 					pmlmepriv->p2p_go_probe_resp_ie_len = 0;
6706 					rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
6707 					pmlmepriv->p2p_go_probe_resp_ie = NULL;
6708 				}
6709 
6710 				pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
6711 				if (pmlmepriv->p2p_go_probe_resp_ie == NULL) {
6712 					RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6713 					return -EINVAL;
6714 
6715 				}
6716 				_rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
6717 				pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
6718 			}
6719 
6720 		}
6721 		#endif /* CONFIG_P2P */
6722 
6723 
6724 		#ifdef CONFIG_WFD
6725 		wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
6726 		#ifdef CONFIG_DEBUG_CFG80211
6727 		RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen);
6728 		#endif
6729 
6730 		if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS)
6731 			return -EINVAL;
6732 		#endif /* CONFIG_WFD */
6733 
6734 	}
6735 
6736 	return ret;
6737 
6738 }
6739 
rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device * net,char * buf,int len)6740 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
6741 {
6742 	int ret = 0;
6743 	_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
6744 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6745 	u8 *ie;
6746 	u32 ie_len;
6747 
6748 	RTW_INFO("%s, ielen=%d\n", __func__, len);
6749 
6750 	if (len <= 0)
6751 		goto exit;
6752 
6753 	ie = rtw_get_wps_ie(buf, len, NULL, &ie_len);
6754 	if (ie && ie_len) {
6755 		if (pmlmepriv->wps_assoc_resp_ie) {
6756 			u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
6757 
6758 			pmlmepriv->wps_assoc_resp_ie_len = 0;
6759 			rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
6760 			pmlmepriv->wps_assoc_resp_ie = NULL;
6761 		}
6762 
6763 		pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
6764 		if (pmlmepriv->wps_assoc_resp_ie == NULL) {
6765 			RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6766 			return -EINVAL;
6767 		}
6768 		_rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len);
6769 		pmlmepriv->wps_assoc_resp_ie_len = ie_len;
6770 	}
6771 #ifdef CONFIG_P2P
6772 	ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len);
6773 	if (ie && ie_len) {
6774 		if (pmlmepriv->p2p_assoc_resp_ie) {
6775 			u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len;
6776 
6777 			pmlmepriv->p2p_assoc_resp_ie_len = 0;
6778 			rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len);
6779 			pmlmepriv->p2p_assoc_resp_ie = NULL;
6780 		}
6781 
6782 		pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len);
6783 		if (pmlmepriv->p2p_assoc_resp_ie == NULL) {
6784 			RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6785 			return -EINVAL;
6786 		}
6787 		_rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len);
6788 		pmlmepriv->p2p_assoc_resp_ie_len = ie_len;
6789 	}
6790 #endif
6791 #ifdef CONFIG_WFD
6792 	ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len);
6793 	if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS)
6794 		return -EINVAL;
6795 #endif
6796 
6797 exit:
6798 	return ret;
6799 }
6800 
rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device * net,char * buf,int len,int type)6801 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
6802 	int type)
6803 {
6804 	int ret = 0;
6805 	uint wps_ielen = 0;
6806 	u32	p2p_ielen = 0;
6807 
6808 #ifdef CONFIG_DEBUG_CFG80211
6809 	RTW_INFO("%s, ielen=%d\n", __func__, len);
6810 #endif
6811 
6812 	if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0))
6813 		#ifdef CONFIG_P2P
6814 		|| (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0))
6815 		#endif
6816 	) {
6817 		if (net != NULL) {
6818 			switch (type) {
6819 			case 0x1: /* BEACON */
6820 				ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
6821 				break;
6822 			case 0x2: /* PROBE_RESP */
6823 				ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
6824 				#ifdef CONFIG_P2P
6825 				if (ret == 0)
6826 					adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time();
6827 				#endif
6828 				break;
6829 			case 0x4: /* ASSOC_RESP */
6830 				ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
6831 				break;
6832 			}
6833 		}
6834 	}
6835 
6836 	return ret;
6837 
6838 }
6839 #endif /* CONFIG_AP_MODE */
6840 
6841 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6842 static struct wireless_dev *
6843 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
6844 static struct net_device *
6845 #else
6846 static int
6847 #endif
cfg80211_rtw_add_virtual_intf(struct wiphy * wiphy,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u32 * flags,struct vif_params * params)6848 	cfg80211_rtw_add_virtual_intf(
6849 		struct wiphy *wiphy,
6850 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
6851 		const char *name,
6852 		#else
6853 		char *name,
6854 		#endif
6855 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
6856 		unsigned char name_assign_type,
6857 		#endif
6858 		enum nl80211_iftype type,
6859 		#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
6860 		u32 *flags,
6861 		#endif
6862 		struct vif_params *params)
6863 {
6864 	int ret = 0;
6865 	struct wireless_dev *wdev = NULL;
6866 	struct net_device *ndev = NULL;
6867 	_adapter *padapter;
6868 	struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
6869 
6870 	rtw_set_rtnl_lock_holder(dvobj, current);
6871 
6872 	RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type);
6873 
6874 	switch (type) {
6875 	case NL80211_IFTYPE_MONITOR:
6876 		padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */
6877 		ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
6878 		if (ret == 0)
6879 			wdev = ndev->ieee80211_ptr;
6880 		break;
6881 
6882 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
6883 	case NL80211_IFTYPE_P2P_CLIENT:
6884 	case NL80211_IFTYPE_P2P_GO:
6885 #endif
6886 	case NL80211_IFTYPE_STATION:
6887 	case NL80211_IFTYPE_AP:
6888 #ifdef CONFIG_RTW_MESH
6889 	case NL80211_IFTYPE_MESH_POINT:
6890 #endif
6891 		padapter = dvobj_get_unregisterd_adapter(dvobj);
6892 		if (!padapter) {
6893 			RTW_WARN("adapter pool empty!\n");
6894 			ret = -ENODEV;
6895 			break;
6896 		}
6897 
6898 		#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P)
6899 		#if defined(CONFIG_P2P) && ((KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE) || defined(COMPAT_KERNEL_RELEASE))
6900 		if ((type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) && (padapter->iface_id != padapter->registrypriv.sel_p2p_iface)) {
6901 			RTW_ERR("%s, iface_id:%d is not P2P interface!\n", __func__, padapter->iface_id);
6902 			ret = -EOPNOTSUPP;
6903 			break;
6904 		}
6905 		#endif
6906 		#endif
6907 
6908 		if (rtw_os_ndev_init(padapter, name) != _SUCCESS) {
6909 			RTW_WARN("ndev init fail!\n");
6910 			ret = -ENODEV;
6911 			break;
6912 		}
6913 		#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
6914 		if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)
6915 			rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
6916 		#endif
6917 		ndev = padapter->pnetdev;
6918 		wdev = ndev->ieee80211_ptr;
6919 		break;
6920 
6921 #if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
6922 	case NL80211_IFTYPE_P2P_DEVICE:
6923 		ret = rtw_pd_iface_alloc(wiphy, name, &wdev);
6924 		break;
6925 #endif
6926 
6927 	case NL80211_IFTYPE_ADHOC:
6928 	case NL80211_IFTYPE_AP_VLAN:
6929 	case NL80211_IFTYPE_WDS:
6930 	default:
6931 		ret = -ENODEV;
6932 		RTW_INFO("Unsupported interface type\n");
6933 		break;
6934 	}
6935 
6936 	if (ndev)
6937 		RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret);
6938 	else
6939 		RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret);
6940 
6941 	rtw_set_rtnl_lock_holder(dvobj, NULL);
6942 
6943 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6944 	return wdev ? wdev : ERR_PTR(ret);
6945 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
6946 	return ndev ? ndev : ERR_PTR(ret);
6947 #else
6948 	return ret;
6949 #endif
6950 }
6951 
cfg80211_rtw_del_virtual_intf(struct wiphy * wiphy,struct wireless_dev * wdev)6952 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
6953 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6954 	struct wireless_dev *wdev
6955 #else
6956 	struct net_device *ndev
6957 #endif
6958 )
6959 {
6960 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6961 	struct net_device *ndev = wdev_to_ndev(wdev);
6962 #endif
6963 	int ret = 0;
6964 	struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
6965 	_adapter *adapter;
6966 	struct rtw_wdev_priv *pwdev_priv;
6967 
6968 	rtw_set_rtnl_lock_holder(dvobj, current);
6969 
6970 	if (ndev) {
6971 		adapter = (_adapter *)rtw_netdev_priv(ndev);
6972 		pwdev_priv = adapter_wdev_data(adapter);
6973 
6974 		if (ndev == pwdev_priv->pmon_ndev) {
6975 			unregister_netdevice(ndev);
6976 			pwdev_priv->pmon_ndev = NULL;
6977 			pwdev_priv->ifname_mon[0] = '\0';
6978 			RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev));
6979 		} else {
6980 			RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev));
6981 			rtw_os_ndev_unregister(adapter);
6982 		}
6983 	} else
6984 #if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
6985 	if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
6986 		if (wdev == wiphy_to_pd_wdev(wiphy))
6987 			rtw_pd_iface_free(wiphy);
6988 		else {
6989 			RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
6990 			rtw_warn_on(1);
6991 		}
6992 	} else
6993 #endif
6994 	{
6995 		ret = -EINVAL;
6996 		goto exit;
6997 	}
6998 
6999 exit:
7000 	rtw_set_rtnl_lock_holder(dvobj, NULL);
7001 	return ret;
7002 }
7003 
7004 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
cfg80211_rtw_get_channel(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_chan_def * chandef)7005 static int cfg80211_rtw_get_channel(struct wiphy *wiphy,
7006 	struct wireless_dev *wdev,
7007 	struct cfg80211_chan_def *chandef)
7008 {
7009 	_adapter *padapter = wiphy_to_adapter(wiphy);
7010 	struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv);
7011 	u8 ht_option = 0;
7012 	u8 report = 0;
7013 	int retval = 1;
7014 
7015 	if (MLME_IS_ASOC(padapter)) {
7016 #ifdef CONFIG_80211N_HT
7017 		ht_option = padapter->mlmepriv.htpriv.ht_option;
7018 #endif /* CONFIG_80211N_HT */
7019 		report = 1;
7020 	} else if (MLME_IS_MONITOR(padapter)) {
7021 		/* monitor mode always set to HT
7022 		   we don't support sniffer No HT */
7023 		ht_option = 1;
7024 		report = 1;
7025 	}
7026 
7027 	if (report) {
7028 		rtw_chbw_to_cfg80211_chan_def(wiphy, chandef,
7029 			mlmeext->cur_channel, mlmeext->cur_bwmode,
7030 			mlmeext->cur_ch_offset, ht_option);
7031 		retval = 0;
7032 	}
7033 
7034 	return retval;
7035 }
7036 
rtw_get_chbwoff_from_cfg80211_chan_def(struct cfg80211_chan_def * chandef,u8 * ht,u8 * ch,u8 * bw,u8 * offset)7037 static void rtw_get_chbwoff_from_cfg80211_chan_def(
7038 	struct cfg80211_chan_def *chandef,
7039 	u8 *ht, u8 *ch, u8 *bw, u8 *offset)
7040 {
7041 	struct ieee80211_channel *chan = chandef->chan;
7042 
7043 	*ch = chan->hw_value;
7044 	*ht = 1;
7045 
7046 	switch (chandef->width) {
7047 	case NL80211_CHAN_WIDTH_20_NOHT:
7048 		*ht = 0;
7049 		fallthrough;
7050 		/* fall through */
7051 	case NL80211_CHAN_WIDTH_20:
7052 		*bw = CHANNEL_WIDTH_20;
7053 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7054 		break;
7055 	case NL80211_CHAN_WIDTH_40:
7056 		*bw = CHANNEL_WIDTH_40;
7057 		*offset = (chandef->center_freq1 > chan->center_freq) ?
7058 			HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER;
7059 		break;
7060 	case NL80211_CHAN_WIDTH_80:
7061 		*bw = CHANNEL_WIDTH_80;
7062 		*offset = (chandef->center_freq1 > chan->center_freq) ?
7063 			HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER;
7064 		break;
7065 	case NL80211_CHAN_WIDTH_160:
7066 		*bw = CHANNEL_WIDTH_160;
7067 		*offset = (chandef->center_freq1 > chan->center_freq) ?
7068 			HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER;
7069 		break;
7070 	case NL80211_CHAN_WIDTH_80P80:
7071 		*bw = CHANNEL_WIDTH_80_80;
7072 		*offset = (chandef->center_freq1 > chan->center_freq) ?
7073 			HAL_PRIME_CHNL_OFFSET_LOWER : HAL_PRIME_CHNL_OFFSET_UPPER;
7074 		break;
7075 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7076 	case NL80211_CHAN_WIDTH_5:
7077 		*bw = CHANNEL_WIDTH_5;
7078 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7079 		break;
7080 	case NL80211_CHAN_WIDTH_10:
7081 		*bw = CHANNEL_WIDTH_10;
7082 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7083 		break;
7084 #endif
7085 	default:
7086 		*ht = 0;
7087 		*bw = CHANNEL_WIDTH_20;
7088 		*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7089 		RTW_INFO("unsupported cwidth:%u\n", chandef->width);
7090 		rtw_warn_on(1);
7091 	};
7092 }
7093 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) */
7094 
cfg80211_rtw_set_monitor_channel(struct wiphy * wiphy,struct cfg80211_chan_def * chandef)7095 static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy
7096 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
7097 	, struct cfg80211_chan_def *chandef
7098 #else
7099 	, struct ieee80211_channel *chan
7100 	, enum nl80211_channel_type channel_type
7101 #endif
7102 	)
7103 {
7104 	_adapter *padapter = wiphy_to_adapter(wiphy);
7105 	u8 target_channal, target_offset, target_width, ht_option;
7106 
7107 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
7108 #ifdef CONFIG_DEBUG_CFG80211
7109 	RTW_INFO("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n"
7110 		, chandef->chan->center_freq
7111 		, chandef->chan->hw_value
7112 		, chandef->width
7113 		, chandef->center_freq1
7114 		, chandef->center_freq2);
7115 #endif /* CONFIG_DEBUG_CFG80211 */
7116 
7117 	rtw_get_chbwoff_from_cfg80211_chan_def(chandef,
7118 		&ht_option, &target_channal, &target_width, &target_offset);
7119 #else
7120 #ifdef CONFIG_DEBUG_CFG80211
7121 	RTW_INFO("center_freq %u Mhz ch %u channel_type %u\n"
7122 		, chan->center_freq
7123 		, chan->hw_value
7124 		, channel_type);
7125 #endif /* CONFIG_DEBUG_CFG80211 */
7126 
7127 	rtw_get_chbw_from_nl80211_channel_type(chan, channel_type,
7128 		&ht_option, &target_channal, &target_width, &target_offset);
7129 #endif
7130 	RTW_INFO(FUNC_ADPT_FMT" ch:%d bw:%d, offset:%d\n",
7131 		FUNC_ADPT_ARG(padapter), target_channal,
7132 		target_width, target_offset);
7133 
7134 	rtw_set_chbw_cmd(padapter, target_channal, target_width,
7135 		target_offset, RTW_CMDF_WAIT_ACK);
7136 
7137 	return 0;
7138 }
7139 
rtw_cfg80211_external_auth_request(_adapter * padapter,union recv_frame * rframe)7140 void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rframe)
7141 {
7142 	struct rtw_external_auth_params params;
7143 	struct wireless_dev *wdev = padapter->rtw_wdev;
7144 	struct net_device *netdev = wdev_to_ndev(wdev);
7145 	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7146 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7147 
7148 	u8 frame[256] = { 0 };
7149 	uint frame_len = 24;
7150 	s32 freq = 0;
7151 
7152 	/* rframe, in this case is null point */
7153 
7154 	freq = rtw_ch2freq(pmlmeext->cur_channel);
7155 
7156 #if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \
7157     || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH)
7158 	params.action = EXTERNAL_AUTH_START;
7159 	_rtw_memcpy(params.bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7160 	params.ssid.ssid_len = pmlmeinfo->network.Ssid.SsidLength;
7161 	_rtw_memcpy(params.ssid.ssid, pmlmeinfo->network.Ssid.Ssid,
7162 		pmlmeinfo->network.Ssid.SsidLength);
7163 	params.key_mgmt_suite = 0x8ac0f00;
7164 
7165 	RTW_INFO("external auth: use kernel API: cfg80211_external_auth_request()\n");
7166 	cfg80211_external_auth_request(netdev,
7167 		(struct cfg80211_external_auth_params *)&params, GFP_ATOMIC);
7168 #elif (KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE)
7169 	set_frame_sub_type(frame, WIFI_AUTH);
7170 
7171 	_rtw_memcpy(frame + 4, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7172 	_rtw_memcpy(frame + 10, adapter_mac_addr(padapter), ETH_ALEN);
7173 	_rtw_memcpy(frame + 16, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7174 	RTW_PUT_LE32((frame + 18), 0x8ac0f00);
7175 	RTW_PUT_LE32((frame + 24), 0x0003);
7176 
7177 	if (pmlmeinfo->network.Ssid.SsidLength) {
7178 		*(frame + 26) = pmlmeinfo->network.Ssid.SsidLength;
7179 		_rtw_memcpy(frame + 27, pmlmeinfo->network.Ssid.Ssid,
7180 			pmlmeinfo->network.Ssid.SsidLength);
7181 		frame_len = 27 + pmlmeinfo->network.Ssid.SsidLength;
7182 	}
7183 
7184 	RTW_INFO("external auth: with wpa_supplicant patch\n");
7185 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7186 #endif
7187 }
7188 
rtw_cfg80211_rx_probe_request(_adapter * adapter,union recv_frame * rframe)7189 void rtw_cfg80211_rx_probe_request(_adapter *adapter, union recv_frame *rframe)
7190 {
7191 	struct wireless_dev *wdev = adapter->rtw_wdev;
7192 	u8 *frame = get_recvframe_data(rframe);
7193 	uint frame_len = rframe->u.hdr.len;
7194 	s32 freq;
7195 	u8 ch, sch = rtw_get_oper_ch(adapter);
7196 
7197 	ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
7198 	freq = rtw_ch2freq(ch);
7199 
7200 #ifdef CONFIG_DEBUG_CFG80211
7201 	RTW_INFO("RTW_Rx: probe request, ch=%d(%d), ta="MAC_FMT"\n"
7202 		, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
7203 #endif
7204 
7205 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
7206 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7207 #else
7208 	cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
7209 #endif
7210 }
7211 
rtw_cfg80211_rx_action_p2p(_adapter * adapter,union recv_frame * rframe)7212 void rtw_cfg80211_rx_action_p2p(_adapter *adapter, union recv_frame *rframe)
7213 {
7214 	struct wireless_dev *wdev = adapter->rtw_wdev;
7215 	u8 *frame = get_recvframe_data(rframe);
7216 	uint frame_len = rframe->u.hdr.len;
7217 	s32 freq;
7218 	u8 ch, sch = rtw_get_oper_ch(adapter);
7219 	u8 category, action;
7220 	int type;
7221 
7222 	ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
7223 	freq = rtw_ch2freq(ch);
7224 
7225 	RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
7226 		, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
7227 #ifdef CONFIG_P2P
7228 	type = rtw_p2p_check_frames(adapter, frame, frame_len, _FALSE);
7229 	if (type >= 0)
7230 		goto indicate;
7231 #endif
7232 	rtw_action_frame_parse(frame, frame_len, &category, &action);
7233 	RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
7234 #ifdef CONFIG_P2P
7235 indicate:
7236 #endif
7237 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
7238 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7239 #else
7240 	cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
7241 #endif
7242 }
7243 
rtw_cfg80211_rx_p2p_action_public(_adapter * adapter,union recv_frame * rframe)7244 void rtw_cfg80211_rx_p2p_action_public(_adapter *adapter, union recv_frame *rframe)
7245 {
7246 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
7247 	struct wireless_dev *wdev = adapter->rtw_wdev;
7248 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
7249 	u8 *frame = get_recvframe_data(rframe);
7250 	uint frame_len = rframe->u.hdr.len;
7251 	s32 freq;
7252 	u8 ch, sch = rtw_get_oper_ch(adapter);
7253 	u8 category, action;
7254 	int type;
7255 
7256 	ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
7257 	freq = rtw_ch2freq(ch);
7258 
7259 	RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
7260 		, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
7261 	#ifdef CONFIG_P2P
7262 	type = rtw_p2p_check_frames(adapter, frame, frame_len, _FALSE);
7263 	if (type >= 0) {
7264 		switch (type) {
7265 		case P2P_GO_NEGO_CONF:
7266 			if (0) {
7267 				RTW_INFO(FUNC_ADPT_FMT" Nego confirm. state=%u, status=%u, iaddr="MAC_FMT"\n"
7268 					, FUNC_ADPT_ARG(adapter), pwdev_priv->nego_info.state, pwdev_priv->nego_info.status
7269 					, MAC_ARG(pwdev_priv->nego_info.iface_addr));
7270 			}
7271 			if (pwdev_priv->nego_info.state == 2
7272 				&& pwdev_priv->nego_info.status == 0
7273 				&& rtw_check_invalid_mac_address(pwdev_priv->nego_info.iface_addr, _FALSE) == _FALSE
7274 			) {
7275 				_adapter *intended_iface = dvobj_get_adapter_by_addr(dvobj, pwdev_priv->nego_info.iface_addr);
7276 
7277 				if (intended_iface) {
7278 					RTW_INFO(FUNC_ADPT_FMT" Nego confirm. Allow only "ADPT_FMT" to scan for 2000 ms\n"
7279 						, FUNC_ADPT_ARG(adapter), ADPT_ARG(intended_iface));
7280 					/* allow only intended_iface to do scan for 2000 ms */
7281 					rtw_mi_set_scan_deny(adapter, 2000);
7282 					rtw_clear_scan_deny(intended_iface);
7283 				}
7284 			}
7285 			break;
7286 		case P2P_PROVISION_DISC_RESP:
7287 		case P2P_INVIT_RESP:
7288 			rtw_clear_scan_deny(adapter);
7289 			#if !RTW_P2P_GROUP_INTERFACE
7290 			rtw_mi_buddy_set_scan_deny(adapter, 2000);
7291 			#endif
7292 			break;
7293 		}
7294 		goto indicate;
7295 	}
7296 	#endif
7297 	rtw_action_frame_parse(frame, frame_len, &category, &action);
7298 	RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
7299 #ifdef CONFIG_P2P
7300 indicate:
7301 #endif
7302 	#if defined(RTW_DEDICATED_P2P_DEVICE)
7303 	if (rtw_cfg80211_redirect_pd_wdev(dvobj_to_wiphy(dvobj), get_ra(frame), &wdev))
7304 		if (0)
7305 			RTW_INFO("redirect to pd_wdev:%p\n", wdev);
7306 	#endif
7307 
7308 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
7309 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7310 #else
7311 	cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
7312 #endif
7313 }
7314 
rtw_cfg80211_rx_action(_adapter * adapter,union recv_frame * rframe,const char * msg)7315 void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const char *msg)
7316 {
7317 	struct wireless_dev *wdev = adapter->rtw_wdev;
7318 	u8 *frame = get_recvframe_data(rframe);
7319 	uint frame_len = rframe->u.hdr.len;
7320 	s32 freq;
7321 	u8 ch, sch = rtw_get_oper_ch(adapter);
7322 	u8 category, action;
7323 	int type = -1;
7324 
7325 	ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
7326 	freq = rtw_ch2freq(ch);
7327 
7328 	RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
7329 		, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
7330 
7331 #ifdef CONFIG_RTW_MESH
7332 	if (MLME_IS_MESH(adapter)) {
7333 		type = rtw_mesh_check_frames_rx(adapter, frame, frame_len);
7334 		if (type >= 0)
7335 			goto indicate;
7336 	}
7337 #endif
7338 	rtw_action_frame_parse(frame, frame_len, &category, &action);
7339 	if (category == RTW_WLAN_CATEGORY_PUBLIC) {
7340 		if (action == ACT_PUBLIC_GAS_INITIAL_REQ) {
7341 			rtw_mi_set_scan_deny(adapter, 200);
7342 			rtw_mi_scan_abort(adapter, _FALSE); /*rtw_scan_abort_no_wait*/
7343 		}
7344 	}
7345 #ifdef CONFIG_RTW_MESH
7346 indicate:
7347 #endif
7348 
7349 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
7350 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7351 #else
7352 	cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
7353 #endif
7354 
7355 	if (type == -1) {
7356 		if (msg)
7357 			RTW_INFO("RTW_Rx:%s\n", msg);
7358 		else
7359 			RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
7360 	}
7361 }
7362 
7363 #ifdef CONFIG_RTW_80211K
rtw_cfg80211_rx_rrm_action(_adapter * adapter,union recv_frame * rframe)7364 void rtw_cfg80211_rx_rrm_action(_adapter *adapter, union recv_frame *rframe)
7365 {
7366 	struct wireless_dev *wdev = adapter->rtw_wdev;
7367 	u8 *frame = get_recvframe_data(rframe);
7368 	uint frame_len = rframe->u.hdr.len;
7369 	s32 freq;
7370 	u8 ch, sch = rtw_get_oper_ch(adapter);
7371 
7372 	ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
7373 	freq = rtw_ch2freq(ch);
7374 
7375 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
7376 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7377 #else
7378 	cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
7379 #endif
7380 	RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
7381 		, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
7382 }
7383 #endif /* CONFIG_RTW_80211K */
7384 
rtw_cfg80211_rx_mframe(_adapter * adapter,union recv_frame * rframe,const char * msg)7385 void rtw_cfg80211_rx_mframe(_adapter *adapter, union recv_frame *rframe, const char *msg)
7386 {
7387 	struct wireless_dev *wdev = adapter->rtw_wdev;
7388 	u8 *frame = get_recvframe_data(rframe);
7389 	uint frame_len = rframe->u.hdr.len;
7390 	s32 freq;
7391 	u8 ch, sch = rtw_get_oper_ch(adapter);
7392 
7393 	ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
7394 	freq = rtw_ch2freq(ch);
7395 
7396 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
7397 	rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
7398 #else
7399 	cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
7400 #endif
7401 
7402 	RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n", ch, sch, MAC_ARG(get_addr2_ptr(frame)));
7403 	if (!rtw_sae_preprocess(adapter, frame, frame_len, _FALSE)) {
7404 		if (msg)
7405 			RTW_INFO("RTW_Rx:%s\n", msg);
7406 		else
7407 			RTW_INFO("RTW_Rx:frame_control:0x%02x\n", le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)rframe)->frame_ctl));
7408 	}
7409 }
7410 
7411 #ifdef CONFIG_P2P
rtw_cfg80211_issue_p2p_provision_request(_adapter * padapter,const u8 * buf,size_t len)7412 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
7413 {
7414 	u16	wps_devicepassword_id = 0x0000;
7415 	uint	wps_devicepassword_id_len = 0;
7416 	u8			wpsie[255] = { 0x00 }, p2p_ie[255] = { 0x00 };
7417 	uint			p2p_ielen = 0;
7418 	uint			wpsielen = 0;
7419 	u32	devinfo_contentlen = 0;
7420 	u8	devinfo_content[64] = { 0x00 };
7421 	u16	capability = 0;
7422 	uint capability_len = 0;
7423 
7424 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7425 	u8			action = P2P_PUB_ACTION_ACTION;
7426 	u8			dialogToken = 1;
7427 	u32			p2poui = cpu_to_be32(P2POUI);
7428 	u8			oui_subtype = P2P_PROVISION_DISC_REQ;
7429 	u32			p2pielen = 0;
7430 #ifdef CONFIG_WFD
7431 	u32					wfdielen = 0;
7432 #endif
7433 
7434 	struct xmit_frame			*pmgntframe;
7435 	struct pkt_attrib			*pattrib;
7436 	unsigned char					*pframe;
7437 	struct rtw_ieee80211_hdr	*pwlanhdr;
7438 	unsigned short				*fctrl;
7439 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7440 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7441 
7442 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7443 	u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
7444 	size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
7445 
7446 
7447 	RTW_INFO("[%s] In\n", __FUNCTION__);
7448 
7449 	/* prepare for building provision_request frame	 */
7450 	_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
7451 	_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
7452 
7453 	pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
7454 
7455 	rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
7456 	wps_devicepassword_id_len = sizeof(wps_devicepassword_id);
7457 	rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
7458 	wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
7459 
7460 	switch (wps_devicepassword_id) {
7461 	case WPS_DPID_PIN:
7462 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
7463 		break;
7464 	case WPS_DPID_USER_SPEC:
7465 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
7466 		break;
7467 	case WPS_DPID_MACHINE_SPEC:
7468 		break;
7469 	case WPS_DPID_REKEY:
7470 		break;
7471 	case WPS_DPID_PBC:
7472 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
7473 		break;
7474 	case WPS_DPID_REGISTRAR_SPEC:
7475 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
7476 		break;
7477 	default:
7478 		break;
7479 	}
7480 
7481 
7482 	if (rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen)) {
7483 
7484 		devinfo_contentlen = sizeof(devinfo_content);
7485 		rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
7486 		capability_len = sizeof(capability);
7487 		rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&capability, &capability_len);
7488 
7489 	}
7490 
7491 
7492 	/* start to build provision_request frame	 */
7493 	_rtw_memset(wpsie, 0, sizeof(wpsie));
7494 	_rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
7495 	p2p_ielen = 0;
7496 
7497 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7498 	if (pmgntframe == NULL)
7499 		return;
7500 
7501 
7502 	/* update attribute */
7503 	pattrib = &pmgntframe->attrib;
7504 	update_mgntframe_attrib(padapter, pattrib);
7505 
7506 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7507 
7508 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7509 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7510 
7511 	fctrl = &(pwlanhdr->frame_ctl);
7512 	*(fctrl) = 0;
7513 
7514 	_rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
7515 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7516 	_rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
7517 
7518 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7519 	pmlmeext->mgnt_seq++;
7520 	set_frame_sub_type(pframe, WIFI_ACTION);
7521 
7522 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7523 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7524 
7525 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7526 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
7527 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
7528 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
7529 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
7530 
7531 
7532 	/* build_prov_disc_request_p2p_ie	 */
7533 	/*	P2P OUI */
7534 	p2pielen = 0;
7535 	p2p_ie[p2pielen++] = 0x50;
7536 	p2p_ie[p2pielen++] = 0x6F;
7537 	p2p_ie[p2pielen++] = 0x9A;
7538 	p2p_ie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7539 
7540 	/*	Commented by Albert 20110301 */
7541 	/*	According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
7542 	/*	1. P2P Capability */
7543 	/*	2. Device Info */
7544 	/*	3. Group ID ( When joining an operating P2P Group ) */
7545 
7546 	/*	P2P Capability ATTR */
7547 	/*	Type:	 */
7548 	p2p_ie[p2pielen++] = P2P_ATTR_CAPABILITY;
7549 
7550 	/*	Length: */
7551 	/* *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); */
7552 	RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
7553 	p2pielen += 2;
7554 
7555 	/*	Value: */
7556 	/*	Device Capability Bitmap, 1 byte */
7557 	/*	Group Capability Bitmap, 1 byte */
7558 	_rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
7559 	p2pielen += 2;
7560 
7561 
7562 	/*	Device Info ATTR */
7563 	/*	Type: */
7564 	p2p_ie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7565 
7566 	/*	Length: */
7567 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
7568 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7569 	/* *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); */
7570 	RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
7571 	p2pielen += 2;
7572 
7573 	/*	Value: */
7574 	_rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
7575 	p2pielen += devinfo_contentlen;
7576 
7577 
7578 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
7579 	/* p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr); */
7580 	/* pframe += p2pielen; */
7581 	pattrib->pktlen += p2p_ielen;
7582 
7583 	wpsielen = 0;
7584 	/*	WPS OUI */
7585 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7586 	wpsielen += 4;
7587 
7588 	/*	WPS version */
7589 	/*	Type: */
7590 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7591 	wpsielen += 2;
7592 
7593 	/*	Length: */
7594 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7595 	wpsielen += 2;
7596 
7597 	/*	Value: */
7598 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7599 
7600 	/*	Config Method */
7601 	/*	Type: */
7602 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7603 	wpsielen += 2;
7604 
7605 	/*	Length: */
7606 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7607 	wpsielen += 2;
7608 
7609 	/*	Value: */
7610 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
7611 	wpsielen += 2;
7612 
7613 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
7614 
7615 
7616 #ifdef CONFIG_WFD
7617 	wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
7618 	pframe += wfdielen;
7619 	pattrib->pktlen += wfdielen;
7620 #endif
7621 
7622 	pattrib->last_txcmdsz = pattrib->pktlen;
7623 
7624 	/* dump_mgntframe(padapter, pmgntframe); */
7625 	if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
7626 		RTW_INFO("%s, ack to\n", __func__);
7627 
7628 	#if 0
7629 	if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
7630 		RTW_INFO("waiting for p2p peer key-in PIN CODE\n");
7631 		rtw_msleep_os(15000); /* 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req. */
7632 	}
7633 	#endif
7634 
7635 }
7636 
7637 #ifdef CONFIG_RTW_80211R
cfg80211_rtw_update_ft_ies(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_update_ft_ies_params * ftie)7638 static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy,
7639 	struct net_device *ndev,
7640 	struct cfg80211_update_ft_ies_params *ftie)
7641 {
7642 	_adapter *padapter = NULL;
7643 	struct mlme_priv *pmlmepriv = NULL;
7644 	struct ft_roam_info *pft_roam = NULL;
7645 	_irqL irqL;
7646 	u8 *p;
7647 	u8 *pie = NULL;
7648 	u32 ie_len = 0;
7649 
7650 	if (ndev == NULL)
7651 		return  -EINVAL;
7652 
7653 	padapter = (_adapter *)rtw_netdev_priv(ndev);
7654 	pmlmepriv = &(padapter->mlmepriv);
7655 	pft_roam = &(pmlmepriv->ft_roam);
7656 
7657 	p = (u8 *)ftie->ie;
7658 	if (ftie->ie_len <= sizeof(pft_roam->updated_ft_ies)) {
7659 		_enter_critical_bh(&pmlmepriv->lock, &irqL);
7660 		_rtw_memcpy(pft_roam->updated_ft_ies, ftie->ie, ftie->ie_len);
7661 		pft_roam->updated_ft_ies_len = ftie->ie_len;
7662 		_exit_critical_bh(&pmlmepriv->lock, &irqL);
7663 	} else {
7664 		RTW_ERR("FTIEs parsing fail!\n");
7665 		return -EINVAL;
7666 	}
7667 
7668 	if (rtw_ft_roam_status(padapter, RTW_FT_AUTHENTICATED_STA)) {
7669 		RTW_PRINT("auth success, start reassoc\n");
7670 		rtw_ft_lock_set_status(padapter, RTW_FT_ASSOCIATING_STA, &irqL);
7671 		start_clnt_assoc(padapter);
7672 	}
7673 
7674 	return 0;
7675 }
7676 #endif
7677 #endif /* CONFIG_P2P */
7678 
rtw_cfg80211_set_is_roch(_adapter * adapter,bool val)7679 inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val)
7680 {
7681 	adapter->rochinfo.is_ro_ch = val;
7682 	rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
7683 }
7684 
rtw_cfg80211_get_is_roch(_adapter * adapter)7685 inline bool rtw_cfg80211_get_is_roch(_adapter *adapter)
7686 {
7687 	return adapter->rochinfo.is_ro_ch;
7688 }
7689 
rtw_cfg80211_is_ro_ch_once(_adapter * adapter)7690 inline bool rtw_cfg80211_is_ro_ch_once(_adapter *adapter)
7691 {
7692 	return adapter->rochinfo.last_ro_ch_time ? 1 : 0;
7693 }
7694 
rtw_cfg80211_set_last_ro_ch_time(_adapter * adapter)7695 inline void rtw_cfg80211_set_last_ro_ch_time(_adapter *adapter)
7696 {
7697 	adapter->rochinfo.last_ro_ch_time = rtw_get_current_time();
7698 
7699 	if (!adapter->rochinfo.last_ro_ch_time)
7700 		adapter->rochinfo.last_ro_ch_time++;
7701 }
7702 
rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter * adapter)7703 inline s32 rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter *adapter)
7704 {
7705 	return rtw_get_passing_time_ms(adapter->rochinfo.last_ro_ch_time);
7706 }
7707 
cfg80211_rtw_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,struct ieee80211_channel * channel,enum nl80211_channel_type channel_type,unsigned int duration,u64 * cookie)7708 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
7709 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7710 	struct wireless_dev *wdev,
7711 #else
7712 	struct net_device *ndev,
7713 #endif
7714 	struct ieee80211_channel *channel,
7715 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7716 	enum nl80211_channel_type channel_type,
7717 #endif
7718 	unsigned int duration, u64 *cookie)
7719 {
7720 	s32 err = 0;
7721 	u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
7722 	_adapter *padapter = NULL;
7723 	struct rtw_wdev_priv *pwdev_priv;
7724 	struct roch_info *prochinfo;
7725 #ifdef CONFIG_P2P
7726 	struct wifidirect_info *pwdinfo;
7727 #ifdef CONFIG_CONCURRENT_MODE
7728 	u8 is_p2p_find = _FALSE;
7729 #endif
7730 #endif
7731 
7732 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7733 	#if defined(RTW_DEDICATED_P2P_DEVICE)
7734 	if (wdev == wiphy_to_pd_wdev(wiphy))
7735 		padapter = wiphy_to_adapter(wiphy);
7736 	else
7737 	#endif
7738 	if (wdev_to_ndev(wdev))
7739 		padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
7740 	else {
7741 		err = -EINVAL;
7742 		goto exit;
7743 	}
7744 #else
7745 	struct wireless_dev *wdev;
7746 
7747 	if (ndev == NULL) {
7748 		err = -EINVAL;
7749 		goto exit;
7750 	}
7751 	padapter = (_adapter *)rtw_netdev_priv(ndev);
7752 	wdev = ndev_to_wdev(ndev);
7753 #endif
7754 
7755 	pwdev_priv = adapter_wdev_data(padapter);
7756 	prochinfo = &padapter->rochinfo;
7757 #ifdef CONFIG_P2P
7758 	pwdinfo = &padapter->wdinfo;
7759 #ifdef CONFIG_CONCURRENT_MODE
7760 	is_p2p_find = (duration < (pwdinfo->ext_listen_interval)) ? _TRUE : _FALSE;
7761 #endif
7762 #endif
7763 
7764 	*cookie = ATOMIC_INC_RETURN(&prochinfo->ro_ch_cookie_gen);
7765 
7766 	RTW_INFO(FUNC_ADPT_FMT"%s ch:%u duration:%d, cookie:0x%llx\n"
7767 		, FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
7768 		, remain_ch, duration, *cookie);
7769 
7770 	if (rtw_chset_search_ch(adapter_to_chset(padapter), remain_ch) < 0) {
7771 		RTW_WARN(FUNC_ADPT_FMT" invalid ch:%u\n", FUNC_ADPT_ARG(padapter), remain_ch);
7772 		err = -EFAULT;
7773 		goto exit;
7774 	}
7775 
7776 #ifdef CONFIG_MP_INCLUDED
7777 	if (rtw_mp_mode_check(padapter)) {
7778 		RTW_INFO("MP mode block remain_on_channel request\n");
7779 		err = -EFAULT;
7780 		goto exit;
7781 	}
7782 #endif
7783 
7784 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
7785 		err = -EFAULT;
7786 		goto exit;
7787 	}
7788 
7789 	rtw_scan_abort(padapter);
7790 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P)
7791 	/*don't scan_abort during p2p_listen.*/
7792 	if (is_p2p_find)
7793 		rtw_mi_buddy_scan_abort(padapter, _TRUE);
7794 #endif /* defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) */
7795 
7796 	if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
7797 		_cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer);
7798 		rtw_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK);
7799 	}
7800 
7801 #ifdef CONFIG_P2P
7802 	/* if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) */
7803 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
7804 		#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P)
7805 		&& ((padapter->iface_id == padapter->registrypriv.sel_p2p_iface))
7806 		#endif
7807 	) {
7808 		rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
7809 		padapter->wdinfo.listen_channel = remain_ch;
7810 		RTW_INFO(FUNC_ADPT_FMT" init listen_channel %u\n"
7811 			, FUNC_ADPT_ARG(padapter), padapter->wdinfo.listen_channel);
7812 	} else if (rtw_p2p_chk_state(pwdinfo , P2P_STATE_LISTEN)
7813 		&& (time_after_eq(rtw_get_current_time(), pwdev_priv->probe_resp_ie_update_time)
7814 			&& rtw_get_passing_time_ms(pwdev_priv->probe_resp_ie_update_time) < 50)
7815 	) {
7816 		if (padapter->wdinfo.listen_channel != remain_ch) {
7817 			padapter->wdinfo.listen_channel = remain_ch;
7818 			RTW_INFO(FUNC_ADPT_FMT" update listen_channel %u\n"
7819 				, FUNC_ADPT_ARG(padapter), padapter->wdinfo.listen_channel);
7820 		}
7821 	} else {
7822 		rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
7823 #ifdef CONFIG_DEBUG_CFG80211
7824 		RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
7825 #endif
7826 	}
7827 
7828 	rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
7829 #endif /* CONFIG_P2P */
7830 
7831 	#ifdef RTW_ROCH_DURATION_ENLARGE
7832 	if (duration < 400)
7833 		duration = duration * 3; /* extend from exper */
7834 	#endif
7835 
7836 #if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P)
7837 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
7838 		if (is_p2p_find) /* p2p_find , duration<1000 */
7839 			duration = duration + pwdinfo->ext_listen_interval;
7840 	}
7841 #endif /* defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) */
7842 
7843 	rtw_cfg80211_set_is_roch(padapter, _TRUE);
7844 	prochinfo->ro_ch_wdev = wdev;
7845 	prochinfo->remain_on_ch_cookie = *cookie;
7846 	rtw_cfg80211_set_last_ro_ch_time(padapter);
7847 	_rtw_memcpy(&prochinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
7848 	#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7849 	prochinfo->remain_on_ch_type = channel_type;
7850 	#endif
7851 	prochinfo->restore_channel = rtw_get_oper_ch(padapter);
7852 
7853 	rtw_roch_cmd(padapter, *cookie, wdev, channel, prochinfo->remain_on_ch_type,
7854 		duration, RTW_CMDF_WAIT_ACK);
7855 
7856 	rtw_cfg80211_ready_on_channel(wdev, *cookie, channel, channel_type, duration, GFP_KERNEL);
7857 exit:
7858 	return err;
7859 }
7860 
cfg80211_rtw_cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)7861 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
7862 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7863 	struct wireless_dev *wdev,
7864 #else
7865 	struct net_device *ndev,
7866 #endif
7867 	u64 cookie)
7868 {
7869 	s32 err = 0;
7870 	_adapter *padapter;
7871 	struct rtw_wdev_priv *pwdev_priv;
7872 	struct roch_info *prochinfo;
7873 #ifdef CONFIG_P2P
7874 	struct wifidirect_info *pwdinfo;
7875 #endif
7876 
7877 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7878 	#if defined(RTW_DEDICATED_P2P_DEVICE)
7879 	if (wdev == wiphy_to_pd_wdev(wiphy))
7880 		padapter = wiphy_to_adapter(wiphy);
7881 	else
7882 	#endif
7883 	if (wdev_to_ndev(wdev))
7884 		padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
7885 	else {
7886 		err = -EINVAL;
7887 		goto exit;
7888 	}
7889 #else
7890 	struct wireless_dev *wdev;
7891 
7892 	if (ndev == NULL) {
7893 		err = -EINVAL;
7894 		goto exit;
7895 	}
7896 	padapter = (_adapter *)rtw_netdev_priv(ndev);
7897 	wdev = ndev_to_wdev(ndev);
7898 #endif
7899 
7900 	pwdev_priv = adapter_wdev_data(padapter);
7901 	prochinfo = &padapter->rochinfo;
7902 #ifdef CONFIG_P2P
7903 	pwdinfo = &padapter->wdinfo;
7904 #endif
7905 
7906 	RTW_INFO(FUNC_ADPT_FMT"%s cookie:0x%llx\n"
7907 		, FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
7908 		, cookie);
7909 
7910 	if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
7911 		_cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer);
7912 		rtw_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK);
7913 	}
7914 
7915 exit:
7916 	return err;
7917 }
7918 
7919 #ifdef CONFIG_P2P
rtw_cfg80211_iface_has_p2p_group_cap(_adapter * adapter)7920 inline int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter)
7921 {
7922 #if RTW_P2P_GROUP_INTERFACE
7923 	if (is_primary_adapter(adapter))
7924 		return 0;
7925 #endif
7926 	return 1;
7927 }
7928 
rtw_cfg80211_is_p2p_scan(_adapter * adapter)7929 inline int rtw_cfg80211_is_p2p_scan(_adapter *adapter)
7930 {
7931 #if RTW_P2P_GROUP_INTERFACE
7932 	if (rtw_cfg80211_iface_has_p2p_group_cap(adapter))
7933 #endif
7934 	{
7935 		struct wifidirect_info *wdinfo = &adapter->wdinfo;
7936 
7937 		return rtw_p2p_chk_state(wdinfo, P2P_STATE_SCAN)
7938 			|| rtw_p2p_chk_state(wdinfo, P2P_STATE_FIND_PHASE_SEARCH);
7939 	}
7940 
7941 #if RTW_P2P_GROUP_INTERFACE
7942 	#if defined(RTW_DEDICATED_P2P_DEVICE)
7943 	if (wiphy_to_pd_wdev(adapter_to_wiphy(adapter))) /* pd_wdev exist */
7944 		return rtw_cfg80211_is_scan_by_pd_wdev(adapter);
7945 	#endif
7946 	{
7947 		/*
7948 		* For 2 RTW_P2P_GROUP_INTERFACE cases:
7949 		* 1. RTW_DEDICATED_P2P_DEVICE defined but upper layer don't use pd_wdev or
7950 		* 2. RTW_DEDICATED_P2P_DEVICE not defined
7951 		*/
7952 		struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
7953 		_irqL irqL;
7954 		int is_p2p_scan = 0;
7955 
7956 		_enter_critical_bh(&wdev_data->scan_req_lock, &irqL);
7957 		if (wdev_data->scan_request
7958 			&& wdev_data->scan_request->n_ssids
7959 			&& wdev_data->scan_request->ssids
7960 			&& wdev_data->scan_request->ie
7961 		) {
7962 			if (_rtw_memcmp(wdev_data->scan_request->ssids[0].ssid, "DIRECT-", 7)
7963 				&& rtw_get_p2p_ie((u8 *)wdev_data->scan_request->ie, wdev_data->scan_request->ie_len, NULL, NULL))
7964 				is_p2p_scan = 1;
7965 		}
7966 		_exit_critical_bh(&wdev_data->scan_req_lock, &irqL);
7967 
7968 		return is_p2p_scan;
7969 	}
7970 #endif
7971 }
7972 
7973 #if defined(RTW_DEDICATED_P2P_DEVICE)
rtw_pd_iface_alloc(struct wiphy * wiphy,const char * name,struct wireless_dev ** pd_wdev)7974 int rtw_pd_iface_alloc(struct wiphy *wiphy, const char *name, struct wireless_dev **pd_wdev)
7975 {
7976 	struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
7977 	struct wireless_dev *wdev = NULL;
7978 	struct rtw_netdev_priv_indicator *npi;
7979 	_adapter *primary_adpt = wiphy_to_adapter(wiphy);
7980 	int ret = 0;
7981 
7982 	if (wiphy_data->pd_wdev) {
7983 		RTW_WARN(FUNC_WIPHY_FMT" pd_wdev already exists\n", FUNC_WIPHY_ARG(wiphy));
7984 		ret = -EBUSY;
7985 		goto exit;
7986 	}
7987 
7988 	wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
7989 	if (!wdev) {
7990 		RTW_WARN(FUNC_WIPHY_FMT" allocate wdev fail\n", FUNC_WIPHY_ARG(wiphy));
7991 		ret = -ENOMEM;
7992 		goto exit;
7993 	}
7994 
7995 	wdev->wiphy = wiphy;
7996 	wdev->iftype = NL80211_IFTYPE_P2P_DEVICE;
7997 	_rtw_memcpy(wdev->address, adapter_mac_addr(primary_adpt), ETH_ALEN);
7998 
7999 	wiphy_data->pd_wdev = wdev;
8000 	*pd_wdev = wdev;
8001 
8002 	RTW_INFO(FUNC_WIPHY_FMT" pd_wdev:%p, addr="MAC_FMT" added\n"
8003 		, FUNC_WIPHY_ARG(wiphy), wdev, MAC_ARG(wdev_address(wdev)));
8004 
8005 exit:
8006 	if (ret && wdev) {
8007 		rtw_mfree((u8 *)wdev, sizeof(struct wireless_dev));
8008 		wdev = NULL;
8009 	}
8010 
8011 	return ret;
8012 }
8013 
rtw_pd_iface_free(struct wiphy * wiphy)8014 void rtw_pd_iface_free(struct wiphy *wiphy)
8015 {
8016 	struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
8017 	struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
8018 	u8 rtnl_lock_needed;
8019 
8020 	if (!wiphy_data->pd_wdev)
8021 		goto exit;
8022 
8023 	RTW_INFO(FUNC_WIPHY_FMT" pd_wdev:%p, addr="MAC_FMT"\n"
8024 		, FUNC_WIPHY_ARG(wiphy), wiphy_data->pd_wdev
8025 		, MAC_ARG(wdev_address(wiphy_data->pd_wdev)));
8026 
8027 	rtnl_lock_needed = rtw_rtnl_lock_needed(dvobj);
8028 	if (rtnl_lock_needed)
8029 		rtnl_lock();
8030 	cfg80211_unregister_wdev(wiphy_data->pd_wdev);
8031 	if (rtnl_lock_needed)
8032 		rtnl_unlock();
8033 
8034 	rtw_mfree((u8 *)wiphy_data->pd_wdev, sizeof(struct wireless_dev));
8035 	wiphy_data->pd_wdev = NULL;
8036 
8037 exit:
8038 	return;
8039 }
8040 
cfg80211_rtw_start_p2p_device(struct wiphy * wiphy,struct wireless_dev * wdev)8041 static int cfg80211_rtw_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
8042 {
8043 	_adapter *adapter = wiphy_to_adapter(wiphy);
8044 
8045 	RTW_INFO(FUNC_WIPHY_FMT" wdev=%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
8046 
8047 	rtw_p2p_enable(adapter, P2P_ROLE_DEVICE);
8048 	return 0;
8049 }
8050 
cfg80211_rtw_stop_p2p_device(struct wiphy * wiphy,struct wireless_dev * wdev)8051 static void cfg80211_rtw_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
8052 {
8053 	_adapter *adapter = wiphy_to_adapter(wiphy);
8054 
8055 	RTW_INFO(FUNC_WIPHY_FMT" wdev=%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
8056 
8057 	if (rtw_cfg80211_is_p2p_scan(adapter))
8058 		rtw_scan_abort(adapter);
8059 
8060 	rtw_p2p_enable(adapter, P2P_ROLE_DISABLE);
8061 }
8062 
rtw_cfg80211_redirect_pd_wdev(struct wiphy * wiphy,u8 * ra,struct wireless_dev ** wdev)8063 inline int rtw_cfg80211_redirect_pd_wdev(struct wiphy *wiphy, u8 *ra, struct wireless_dev **wdev)
8064 {
8065 	struct wireless_dev *pd_wdev = wiphy_to_pd_wdev(wiphy);
8066 
8067 	if (pd_wdev && pd_wdev != *wdev
8068 		&& _rtw_memcmp(wdev_address(pd_wdev), ra, ETH_ALEN) == _TRUE
8069 	) {
8070 		*wdev = pd_wdev;
8071 		return 1;
8072 	}
8073 	return 0;
8074 }
8075 
rtw_cfg80211_is_scan_by_pd_wdev(_adapter * adapter)8076 inline int rtw_cfg80211_is_scan_by_pd_wdev(_adapter *adapter)
8077 {
8078 	struct wiphy *wiphy = adapter_to_wiphy(adapter);
8079 	struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
8080 	struct wireless_dev *wdev = NULL;
8081 	_irqL irqL;
8082 
8083 	_enter_critical_bh(&wdev_data->scan_req_lock, &irqL);
8084 	if (wdev_data->scan_request)
8085 		wdev = wdev_data->scan_request->wdev;
8086 	_exit_critical_bh(&wdev_data->scan_req_lock, &irqL);
8087 
8088 	if (wdev && wdev == wiphy_to_pd_wdev(wiphy))
8089 		return 1;
8090 
8091 	return 0;
8092 }
8093 #endif /* RTW_DEDICATED_P2P_DEVICE */
8094 #endif /* CONFIG_P2P */
8095 
rtw_cfg80211_set_is_mgmt_tx(_adapter * adapter,u8 val)8096 inline void rtw_cfg80211_set_is_mgmt_tx(_adapter *adapter, u8 val)
8097 {
8098 	struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
8099 
8100 	wdev_priv->is_mgmt_tx = val;
8101 	rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
8102 }
8103 
rtw_cfg80211_get_is_mgmt_tx(_adapter * adapter)8104 inline u8 rtw_cfg80211_get_is_mgmt_tx(_adapter *adapter)
8105 {
8106 	struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
8107 
8108 	return wdev_priv->is_mgmt_tx;
8109 }
8110 
_cfg80211_rtw_mgmt_tx(_adapter * padapter,u8 tx_ch,u8 no_cck,const u8 * buf,size_t len,int wait_ack)8111 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack)
8112 {
8113 	struct xmit_frame	*pmgntframe;
8114 	struct pkt_attrib	*pattrib;
8115 	unsigned char	*pframe;
8116 	int ret = _FAIL;
8117 	bool ack = _TRUE;
8118 	struct rtw_ieee80211_hdr *pwlanhdr;
8119 #if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
8120 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
8121 #endif
8122 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
8123 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8124 	u8 u_ch = rtw_mi_get_union_chan(padapter);
8125 	u8 leave_op = 0;
8126 	struct roch_info *prochinfo = &padapter->rochinfo;
8127 #if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
8128 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
8129 #endif
8130 
8131 	rtw_cfg80211_set_is_mgmt_tx(padapter, 1);
8132 
8133 #ifdef CONFIG_BT_COEXIST
8134 	rtw_btcoex_ScanNotify(padapter, _TRUE);
8135 #endif
8136 
8137 #ifdef CONFIG_P2P
8138 	if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
8139 		#ifdef CONFIG_CONCURRENT_MODE
8140 		if (!check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
8141 			RTW_INFO("%s, extend ro ch time\n", __func__);
8142 			_set_timer(&padapter->rochinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
8143 		}
8144 		#endif /* CONFIG_CONCURRENT_MODE */
8145 	}
8146 #endif /* CONFIG_P2P */
8147 
8148 #ifdef CONFIG_MCC_MODE
8149 	if (MCC_EN(padapter)) {
8150 		if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
8151 			/* don't set channel, issue frame directly */
8152 			goto issue_mgmt_frame;
8153 	}
8154 #endif /* CONFIG_MCC_MODE */
8155 
8156 	if (rtw_mi_check_status(padapter, MI_LINKED)
8157 		&& tx_ch != u_ch
8158 	) {
8159 		rtw_leave_opch(padapter);
8160 		leave_op = 1;
8161 	}
8162 
8163 	if (tx_ch != rtw_get_oper_ch(padapter))
8164 		set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
8165 #ifdef CONFIG_MCC_MODE
8166 issue_mgmt_frame:
8167 #endif
8168 	/* starting alloc mgmt frame to dump it */
8169 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8170 	if (pmgntframe == NULL) {
8171 		/* ret = -ENOMEM; */
8172 		ret = _FAIL;
8173 		goto exit;
8174 	}
8175 
8176 	/* update attribute */
8177 	pattrib = &pmgntframe->attrib;
8178 	update_mgntframe_attrib(padapter, pattrib);
8179 
8180 	if (no_cck && IS_CCK_RATE(pattrib->rate)) {
8181 		/* force OFDM 6M rate*/
8182 		pattrib->rate = MGN_6M;
8183 		pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
8184 	}
8185 
8186 	pattrib->retry_ctrl = _FALSE;
8187 
8188 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8189 
8190 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8191 
8192 	_rtw_memcpy(pframe, (void *)buf, len);
8193 	pattrib->pktlen = len;
8194 
8195 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8196 	/* update seq number */
8197 	pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
8198 	pattrib->seqnum = pmlmeext->mgnt_seq;
8199 	pmlmeext->mgnt_seq++;
8200 
8201 #ifdef CONFIG_P2P
8202 	rtw_xframe_chk_wfd_ie(pmgntframe);
8203 #endif /* CONFIG_P2P */
8204 
8205 	pattrib->last_txcmdsz = pattrib->pktlen;
8206 
8207 	if (wait_ack) {
8208 		if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) {
8209 			ack = _FALSE;
8210 			ret = _FAIL;
8211 
8212 #ifdef CONFIG_DEBUG_CFG80211
8213 			RTW_INFO("%s, ack == _FAIL\n", __func__);
8214 #endif
8215 		} else {
8216 
8217 #ifdef CONFIG_XMIT_ACK
8218 			if (!MLME_IS_MESH(padapter)) /* TODO: remove this sleep for all mode */
8219 				rtw_msleep_os(50);
8220 #endif
8221 #ifdef CONFIG_DEBUG_CFG80211
8222 			RTW_INFO("%s, ack=%d, ok!\n", __func__, ack);
8223 #endif
8224 			ret = _SUCCESS;
8225 		}
8226 	} else {
8227 		dump_mgntframe(padapter, pmgntframe);
8228 		ret = _SUCCESS;
8229 	}
8230 
8231 exit:
8232 	if (rtw_cfg80211_get_is_roch(padapter)
8233 		&& !rtw_roch_stay_in_cur_chan(padapter)
8234 		&& prochinfo->remain_on_ch_channel.hw_value != u_ch
8235 	) {
8236 		/* roch is ongoing, switch back to rch */
8237 		if (prochinfo->remain_on_ch_channel.hw_value != tx_ch)
8238 			set_channel_bwmode(padapter, prochinfo->remain_on_ch_channel.hw_value
8239 				, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
8240 	} else if (leave_op) {
8241 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
8242 			u8 u_bw = rtw_mi_get_union_bw(padapter);
8243 			u8 u_offset = rtw_mi_get_union_offset(padapter);
8244 
8245 			set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
8246 		}
8247 		rtw_back_opch(padapter);
8248 	}
8249 
8250 	rtw_cfg80211_set_is_mgmt_tx(padapter, 0);
8251 
8252 #ifdef CONFIG_BT_COEXIST
8253 	rtw_btcoex_ScanNotify(padapter, _FALSE);
8254 #endif
8255 
8256 #ifdef CONFIG_DEBUG_CFG80211
8257 	RTW_INFO("%s, ret=%d\n", __func__, ret);
8258 #endif
8259 
8260 	return ret;
8261 
8262 }
8263 
rtw_mgnt_tx_handler(_adapter * adapter,u8 * buf)8264 u8 rtw_mgnt_tx_handler(_adapter *adapter, u8 *buf)
8265 {
8266 	u8 rst = H2C_CMD_FAIL;
8267 	struct mgnt_tx_parm *mgnt_parm = (struct mgnt_tx_parm *)buf;
8268 
8269 	if (_cfg80211_rtw_mgmt_tx(adapter, mgnt_parm->tx_ch, mgnt_parm->no_cck,
8270 		mgnt_parm->buf, mgnt_parm->len, mgnt_parm->wait_ack) == _SUCCESS)
8271 		rst = H2C_SUCCESS;
8272 
8273 	return rst;
8274 }
8275 
cfg80211_rtw_mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct ieee80211_channel * chan,bool offchan,enum nl80211_channel_type channel_type,bool channel_type_valid,unsigned int wait,const u8 * buf,size_t len,bool no_cck,bool dont_wait_for_ack,u64 * cookie)8276 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
8277 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8278 	struct wireless_dev *wdev,
8279 #else
8280 	struct net_device *ndev,
8281 #endif
8282 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE)
8283 	struct ieee80211_channel *chan,
8284 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
8285 	bool offchan,
8286 	#endif
8287 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
8288 	enum nl80211_channel_type channel_type,
8289 	#endif
8290 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
8291 	bool channel_type_valid,
8292 	#endif
8293 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
8294 	unsigned int wait,
8295 	#endif
8296 	const u8 *buf, size_t len,
8297 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
8298 	bool no_cck,
8299 	#endif
8300 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
8301 	bool dont_wait_for_ack,
8302 	#endif
8303 #else
8304 	struct cfg80211_mgmt_tx_params *params,
8305 #endif
8306 	u64 *cookie)
8307 {
8308 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE)
8309 	struct ieee80211_channel *chan = params->chan;
8310 	const u8 *buf = params->buf;
8311 	size_t len = params->len;
8312 	bool no_cck = params->no_cck;
8313 #endif
8314 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
8315 	bool no_cck = 0;
8316 #endif
8317 	int ret = 0;
8318 	u8 tx_ret;
8319 	int wait_ack = 1;
8320 	const u8 *dump_buf = buf;
8321 	size_t dump_len = len;
8322 	u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
8323 	u32 dump_cnt = 0;
8324 	u32 sleep_ms = 0;
8325 	u32 retry_guarantee_ms = 0;
8326 	bool ack = _TRUE;
8327 	u8 tx_ch;
8328 	u8 category, action;
8329 	u8 frame_styp;
8330 #ifdef CONFIG_P2P
8331 	u8 is_p2p = 0;
8332 #endif
8333 	int type = (-1);
8334 	systime start = rtw_get_current_time();
8335 	_adapter *padapter;
8336 	struct dvobj_priv *dvobj;
8337 	struct rtw_wdev_priv *pwdev_priv;
8338 	struct rf_ctl_t *rfctl;
8339 
8340 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8341 	#if defined(RTW_DEDICATED_P2P_DEVICE)
8342 	if (wdev == wiphy_to_pd_wdev(wiphy))
8343 		padapter = wiphy_to_adapter(wiphy);
8344 	else
8345 	#endif
8346 	if (wdev_to_ndev(wdev))
8347 		padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
8348 	else {
8349 		ret = -EINVAL;
8350 		goto exit;
8351 	}
8352 #else
8353 	struct wireless_dev *wdev;
8354 
8355 	if (ndev == NULL) {
8356 		ret = -EINVAL;
8357 		goto exit;
8358 	}
8359 	padapter = (_adapter *)rtw_netdev_priv(ndev);
8360 	wdev = ndev_to_wdev(ndev);
8361 #endif
8362 
8363 	if (chan == NULL) {
8364 		ret = -EINVAL;
8365 		goto exit;
8366 	}
8367 
8368 	rfctl = adapter_to_rfctl(padapter);
8369 	tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
8370 	if (IS_CH_WAITING(rfctl)) {
8371 		#ifdef CONFIG_DFS_MASTER
8372 		if (_rtw_rfctl_overlap_radar_detect_ch(rfctl, tx_ch, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
8373 			ret = -EINVAL;
8374 			goto exit;
8375 		}
8376 		#endif
8377 	}
8378 
8379 	dvobj = adapter_to_dvobj(padapter);
8380 	pwdev_priv = adapter_wdev_data(padapter);
8381 
8382 	/* cookie generation */
8383 	*cookie = pwdev_priv->mgmt_tx_cookie++;
8384 
8385 #ifdef CONFIG_DEBUG_CFG80211
8386 	RTW_INFO(FUNC_ADPT_FMT"%s len=%zu, ch=%d"
8387 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
8388 		", ch_type=%d"
8389 		#endif
8390 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
8391 		", channel_type_valid=%d"
8392 		#endif
8393 		"\n", FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
8394 		, len, tx_ch
8395 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
8396 		, channel_type
8397 		#endif
8398 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
8399 		, channel_type_valid
8400 		#endif
8401 	);
8402 #endif /* CONFIG_DEBUG_CFG80211 */
8403 
8404 	/* indicate ack before issue frame to avoid racing with rsp frame */
8405 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
8406 	rtw_cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, GFP_KERNEL);
8407 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 36))
8408 	cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
8409 #endif
8410 
8411 	frame_styp = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl) & IEEE80211_FCTL_STYPE;
8412 	if (IEEE80211_STYPE_PROBE_RESP == frame_styp) {
8413 #ifdef CONFIG_DEBUG_CFG80211
8414 		RTW_INFO("RTW_Tx: probe_resp tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
8415 #endif /* CONFIG_DEBUG_CFG80211 */
8416 		wait_ack = 0;
8417 		goto dump;
8418 	}
8419 	else if (frame_styp == RTW_IEEE80211_STYPE_AUTH) {
8420 		int retval = 0;
8421 
8422 		RTW_INFO("RTW_Tx:tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
8423 
8424 		retval = rtw_sae_preprocess(padapter, buf, len, _TRUE);
8425 		if (retval == 2)
8426 			goto exit;
8427 		if (retval == 0)
8428 			RTW_INFO("RTW_Tx:AUTH\n");
8429 		dump_limit = 1;
8430 		goto dump;
8431 	}
8432 
8433 	if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
8434 		RTW_INFO(FUNC_ADPT_FMT" frame_control:0x%02x\n", FUNC_ADPT_ARG(padapter),
8435 			le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
8436 		goto exit;
8437 	}
8438 
8439 	RTW_INFO("RTW_Tx:tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
8440 #ifdef CONFIG_P2P
8441 	type = rtw_p2p_check_frames(padapter, buf, len, _TRUE);
8442 	if (type >= 0) {
8443 		is_p2p = 1;
8444 		no_cck = 1; /* force no CCK for P2P frames */
8445 		goto dump;
8446 	}
8447 #endif
8448 #ifdef CONFIG_RTW_MESH
8449 	if (MLME_IS_MESH(padapter)) {
8450 		type = rtw_mesh_check_frames_tx(padapter, &dump_buf, &dump_len);
8451 		if (type >= 0) {
8452 			dump_limit = 1;
8453 			goto dump;
8454 		}
8455 	}
8456 #endif
8457 	if (category == RTW_WLAN_CATEGORY_PUBLIC) {
8458 		RTW_INFO("RTW_Tx:%s\n", action_public_str(action));
8459 		switch (action) {
8460 		case ACT_PUBLIC_GAS_INITIAL_REQ:
8461 		case ACT_PUBLIC_GAS_INITIAL_RSP:
8462 			sleep_ms = 50;
8463 			retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS;
8464 			break;
8465 		}
8466 	}
8467 #ifdef CONFIG_RTW_80211K
8468 	else if (category == RTW_WLAN_CATEGORY_RADIO_MEAS)
8469 		RTW_INFO("RTW_Tx: RRM Action\n");
8470 #endif
8471 	else
8472 		RTW_INFO("RTW_Tx:category(%u), action(%u)\n", category, action);
8473 
8474 dump:
8475 
8476 	rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
8477 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
8478 		ret = -EFAULT;
8479 		goto cancel_ps_deny;
8480 	}
8481 
8482 	while (1) {
8483 		dump_cnt++;
8484 
8485 		rtw_mi_set_scan_deny(padapter, 1000);
8486 		rtw_mi_scan_abort(padapter, _TRUE);
8487 		tx_ret = rtw_mgnt_tx_cmd(padapter, tx_ch, no_cck, dump_buf, dump_len, wait_ack, RTW_CMDF_WAIT_ACK);
8488 		if (tx_ret == _SUCCESS
8489 			|| (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms))
8490 			break;
8491 
8492 		if (sleep_ms > 0)
8493 			rtw_msleep_os(sleep_ms);
8494 	}
8495 
8496 	if (tx_ret != _SUCCESS || dump_cnt > 1) {
8497 		RTW_INFO(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
8498 			tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
8499 	}
8500 
8501 #ifdef CONFIG_P2P
8502 	if (is_p2p) {
8503 		switch (type) {
8504 		case P2P_GO_NEGO_CONF:
8505 			if (0) {
8506 				RTW_INFO(FUNC_ADPT_FMT" Nego confirm. state=%u, status=%u, iaddr="MAC_FMT"\n"
8507 					, FUNC_ADPT_ARG(padapter), pwdev_priv->nego_info.state, pwdev_priv->nego_info.status
8508 					, MAC_ARG(pwdev_priv->nego_info.iface_addr));
8509 			}
8510 			if (pwdev_priv->nego_info.state == 2
8511 				&& pwdev_priv->nego_info.status == 0
8512 				&& rtw_check_invalid_mac_address(pwdev_priv->nego_info.iface_addr, _FALSE) == _FALSE
8513 			) {
8514 				_adapter *intended_iface = dvobj_get_adapter_by_addr(dvobj, pwdev_priv->nego_info.iface_addr);
8515 
8516 				if (intended_iface) {
8517 					RTW_INFO(FUNC_ADPT_FMT" Nego confirm. Allow only "ADPT_FMT" to scan for 2000 ms\n"
8518 						, FUNC_ADPT_ARG(padapter), ADPT_ARG(intended_iface));
8519 					/* allow only intended_iface to do scan for 2000 ms */
8520 					rtw_mi_set_scan_deny(padapter, 2000);
8521 					rtw_clear_scan_deny(intended_iface);
8522 				}
8523 			}
8524 			break;
8525 		case P2P_INVIT_RESP:
8526 			if (pwdev_priv->invit_info.flags & BIT(0)
8527 				&& pwdev_priv->invit_info.status == 0
8528 			) {
8529 				rtw_clear_scan_deny(padapter);
8530 				RTW_INFO(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
8531 					FUNC_ADPT_ARG(padapter));
8532 				#if !RTW_P2P_GROUP_INTERFACE
8533 				rtw_mi_buddy_set_scan_deny(padapter, 5000);
8534 				#endif
8535 				rtw_pwr_wakeup_ex(padapter, 5000);
8536 			}
8537 			break;
8538 		}
8539 	}
8540 #endif /* CONFIG_P2P */
8541 
8542 cancel_ps_deny:
8543 	rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
8544 
8545 	if (dump_buf != buf)
8546 		rtw_mfree((u8 *)dump_buf, dump_len);
8547 exit:
8548 	return ret;
8549 }
8550 
8551 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0))
cfg80211_rtw_mgmt_frame_register(struct wiphy * wiphy,struct wireless_dev * wdev,u16 frame_type,bool reg)8552 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
8553 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8554 	struct wireless_dev *wdev,
8555 #else
8556 	struct net_device *ndev,
8557 #endif
8558 	u16 frame_type, bool reg)
8559 {
8560 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8561 	struct net_device *ndev = wdev_to_ndev(wdev);
8562 #endif
8563 	_adapter *adapter;
8564 	struct rtw_wdev_priv *pwdev_priv;
8565 
8566 	if (ndev == NULL)
8567 		goto exit;
8568 
8569 	adapter = (_adapter *)rtw_netdev_priv(ndev);
8570 	pwdev_priv = adapter_wdev_data(adapter);
8571 
8572 #ifdef CONFIG_DEBUG_CFG80211
8573 	RTW_INFO(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
8574 		frame_type, reg);
8575 #endif
8576 
8577 	switch (frame_type) {
8578 	case IEEE80211_STYPE_AUTH: /* 0x00B0 */
8579 		if (reg > 0)
8580 			SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH);
8581 		else
8582 			CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH);
8583 		break;
8584 	case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */
8585 		if (reg > 0)
8586 			SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ);
8587 		else
8588 			CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ);
8589 		break;
8590 #ifdef not_yet
8591 	case IEEE80211_STYPE_ACTION: /* 0x00D0 */
8592 		if (reg > 0)
8593 			SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION);
8594 		else
8595 			CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION);
8596 		break;
8597 #endif
8598 	default:
8599 		break;
8600 	}
8601 
8602 exit:
8603 	return;
8604 }
8605 #else
cfg80211_rtw_update_mgmt_frame_register(struct wiphy * wiphy,struct wireless_dev * wdev,struct mgmt_frame_regs * upd)8606 static void cfg80211_rtw_update_mgmt_frame_register(
8607 	struct wiphy *wiphy,
8608 	struct wireless_dev *wdev,
8609 	struct mgmt_frame_regs *upd)
8610 {
8611 	struct net_device *ndev;
8612 	_adapter *padapter;
8613 	struct rtw_wdev_priv *pwdev_priv;
8614 	u32 rtw_stypes_mask = 0;
8615 	u32 rtw_mstypes_mask = 0;
8616 
8617 	ndev = wdev_to_ndev(wdev);
8618 
8619 	if (ndev == NULL)
8620 		goto exit;
8621 
8622 	padapter = (_adapter *)rtw_netdev_priv(ndev);
8623 	pwdev_priv = adapter_wdev_data(padapter);
8624 
8625 	/* Driver only supports Auth and Probe request */
8626 	rtw_stypes_mask = BIT(IEEE80211_STYPE_AUTH >> 4) |
8627 			  BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
8628 
8629 #ifdef CONFIG_DEBUG_CFG80211
8630 	RTW_INFO(FUNC_ADPT_FMT " global_stypes:0x%08x interface_stypes:0x%08x\n",
8631 		FUNC_ADPT_ARG(padapter), upd->global_stypes, upd->interface_stypes);
8632 	RTW_INFO(FUNC_ADPT_FMT " global_mcast_stypes:0x%08x interface_mcast_stypes:0x%08x\n",
8633 		FUNC_ADPT_ARG(padapter), upd->global_mcast_stypes, upd->interface_mcast_stypes);
8634 	RTW_INFO(FUNC_ADPT_FMT " old_regs:0x%08x new_regs:0x%08x\n",
8635 		FUNC_ADPT_ARG(padapter), pwdev_priv->mgmt_regs,
8636 		(upd->interface_stypes & rtw_stypes_mask));
8637 #endif
8638 	if (pwdev_priv->mgmt_regs !=
8639 			(upd->interface_stypes & rtw_stypes_mask)) {
8640 		pwdev_priv->mgmt_regs = (upd->interface_stypes & rtw_stypes_mask);
8641 	}
8642 
8643 exit:
8644 	return;
8645 }
8646 #endif
8647 
8648 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
cfg80211_rtw_tdls_mgmt(struct wiphy * wiphy,struct net_device * ndev,const u8 * peer,u8 action_code,u8 dialog_token,u16 status_code,u32 peer_capability,bool initiator,const u8 * buf,size_t len)8649 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
8650 	struct net_device *ndev,
8651 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
8652 	const u8 *peer,
8653 #else
8654 	u8 *peer,
8655 #endif
8656 	u8 action_code,
8657 	u8 dialog_token,
8658 	u16 status_code,
8659 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
8660 	u32 peer_capability,
8661 #endif
8662 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
8663 	bool initiator,
8664 #endif
8665 	const u8 *buf,
8666 	size_t len)
8667 {
8668 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
8669 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8670 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8671 	int ret = 0;
8672 	struct tdls_txmgmt txmgmt;
8673 
8674 	if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
8675 		RTW_INFO("Discard tdls action:%d, since hal doesn't support tdls\n", action_code);
8676 		goto discard;
8677 	}
8678 
8679 	if (rtw_is_tdls_enabled(padapter) == _FALSE) {
8680 		RTW_INFO("TDLS is not enabled\n");
8681 		goto discard;
8682 	}
8683 
8684 	if (rtw_tdls_is_driver_setup(padapter)) {
8685 		RTW_INFO("Discard tdls action:%d, let driver to set up direct link\n", action_code);
8686 		goto discard;
8687 	}
8688 
8689 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
8690 	_rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
8691 	txmgmt.action_code = action_code;
8692 	txmgmt.dialog_token = dialog_token;
8693 	txmgmt.status_code = status_code;
8694 	txmgmt.len = len;
8695 	txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
8696 	if (txmgmt.buf == NULL) {
8697 		ret = -ENOMEM;
8698 		goto bad;
8699 	}
8700 	_rtw_memcpy(txmgmt.buf, (void *)buf, txmgmt.len);
8701 
8702 	/* Debug purpose */
8703 #if 1
8704 	RTW_INFO("%s %d\n", __FUNCTION__, __LINE__);
8705 	RTW_INFO("peer:"MAC_FMT", action code:%d, dialog:%d, status code:%d\n",
8706 		MAC_ARG(txmgmt.peer), txmgmt.action_code,
8707 		txmgmt.dialog_token, txmgmt.status_code);
8708 	if (txmgmt.len > 0) {
8709 		int i = 0;
8710 		for (; i < len; i++)
8711 			printk("%02x ", *(txmgmt.buf + i));
8712 		RTW_INFO("len:%d\n", (u32)txmgmt.len);
8713 	}
8714 #endif
8715 
8716 	switch (txmgmt.action_code) {
8717 	case TDLS_SETUP_REQUEST:
8718 		issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
8719 		break;
8720 	case TDLS_SETUP_RESPONSE:
8721 		issue_tdls_setup_rsp(padapter, &txmgmt);
8722 		break;
8723 	case TDLS_SETUP_CONFIRM:
8724 		issue_tdls_setup_cfm(padapter, &txmgmt);
8725 		break;
8726 	case TDLS_TEARDOWN:
8727 		issue_tdls_teardown(padapter, &txmgmt, _TRUE);
8728 		break;
8729 	case TDLS_DISCOVERY_REQUEST:
8730 		issue_tdls_dis_req(padapter, &txmgmt);
8731 		break;
8732 	case TDLS_DISCOVERY_RESPONSE:
8733 		issue_tdls_dis_rsp(padapter, &txmgmt, pmlmeinfo->enc_algo ? _TRUE : _FALSE);
8734 		break;
8735 	}
8736 
8737 bad:
8738 	if (txmgmt.buf)
8739 		rtw_mfree(txmgmt.buf, txmgmt.len);
8740 
8741 discard:
8742 	return ret;
8743 }
8744 
cfg80211_rtw_tdls_oper(struct wiphy * wiphy,struct net_device * ndev,const u8 * peer,enum nl80211_tdls_operation oper)8745 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
8746 	struct net_device *ndev,
8747 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
8748 	const u8 *peer,
8749 #else
8750 	u8 *peer,
8751 #endif
8752 	enum nl80211_tdls_operation oper)
8753 {
8754 	_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
8755 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
8756 	struct tdls_txmgmt	txmgmt;
8757 	struct sta_info *ptdls_sta = NULL;
8758 
8759 	RTW_INFO(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
8760 
8761 	if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
8762 		RTW_INFO("Discard tdls oper:%d, since hal doesn't support tdls\n", oper);
8763 		return 0;
8764 	}
8765 
8766 	if (rtw_is_tdls_enabled(padapter) == _FALSE) {
8767 		RTW_INFO("TDLS is not enabled\n");
8768 		return 0;
8769 	}
8770 
8771 #ifdef CONFIG_LPS
8772 	rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0);
8773 #endif /* CONFIG_LPS */
8774 
8775 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
8776 	if (peer)
8777 		_rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
8778 
8779 	if (rtw_tdls_is_driver_setup(padapter)) {
8780 		/* these two cases are done by driver itself */
8781 		if (oper == NL80211_TDLS_ENABLE_LINK || oper == NL80211_TDLS_DISABLE_LINK)
8782 			return 0;
8783 	}
8784 
8785 	switch (oper) {
8786 	case NL80211_TDLS_DISCOVERY_REQ:
8787 		issue_tdls_dis_req(padapter, &txmgmt);
8788 		break;
8789 	case NL80211_TDLS_SETUP:
8790 #ifdef CONFIG_WFD
8791 		if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
8792 			if (padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
8793 				issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
8794 			else
8795 				RTW_INFO("[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__);
8796 		} else
8797 #endif /* CONFIG_WFD */
8798 		{
8799 			issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
8800 		}
8801 		break;
8802 	case NL80211_TDLS_TEARDOWN:
8803 		ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
8804 		if (ptdls_sta != NULL) {
8805 			txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
8806 			issue_tdls_teardown(padapter, &txmgmt, _TRUE);
8807 		} else
8808 			RTW_INFO("TDLS peer not found\n");
8809 		break;
8810 	case NL80211_TDLS_ENABLE_LINK:
8811 		RTW_INFO(FUNC_NDEV_FMT", NL80211_TDLS_ENABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
8812 		ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), (u8 *)peer);
8813 		if (ptdls_sta != NULL) {
8814 			rtw_tdls_set_link_established(padapter, _TRUE);
8815 			ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
8816 			ptdls_sta->state |= WIFI_ASOC_STATE;
8817 			rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED);
8818 		}
8819 		break;
8820 	case NL80211_TDLS_DISABLE_LINK:
8821 		RTW_INFO(FUNC_NDEV_FMT", NL80211_TDLS_DISABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
8822 		ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), (u8 *)peer);
8823 		if (ptdls_sta != NULL) {
8824 			rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
8825 			rtw_tdls_cmd(padapter, (u8 *)peer, TDLS_TEARDOWN_STA_LOCALLY_POST);
8826 		}
8827 		break;
8828 	}
8829 	return 0;
8830 }
8831 #endif /* CONFIG_TDLS */
8832 
8833 #if defined(CONFIG_RTW_MESH) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
8834 
8835 #if DBG_RTW_CFG80211_MESH_CONF
8836 #define LEGACY_RATES_STR_LEN (RTW_G_RATES_NUM * 5 + 1)
get_legacy_rates_str(struct wiphy * wiphy,enum nl80211_band band,u32 mask,char * buf)8837 int get_legacy_rates_str(struct wiphy *wiphy, enum nl80211_band band, u32 mask, char *buf)
8838 {
8839 	int i;
8840 	int cnt = 0;
8841 
8842 	for (i = 0; i < wiphy->bands[band]->n_bitrates; i++) {
8843 		if (mask & BIT(i)) {
8844 			cnt += snprintf(buf + cnt, LEGACY_RATES_STR_LEN - cnt -1, "%d.%d "
8845 				, wiphy->bands[band]->bitrates[i].bitrate / 10
8846 				, wiphy->bands[band]->bitrates[i].bitrate % 10);
8847 			if (cnt >= LEGACY_RATES_STR_LEN - 1)
8848 				break;
8849 		}
8850 	}
8851 
8852 	return cnt;
8853 }
8854 
dump_mesh_setup(void * sel,struct wiphy * wiphy,const struct mesh_setup * setup)8855 void dump_mesh_setup(void *sel, struct wiphy *wiphy, const struct mesh_setup *setup)
8856 {
8857 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8858 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
8859 	struct cfg80211_chan_def *chdef = (struct cfg80211_chan_def *)(&setup->chandef);
8860 #endif
8861 	struct ieee80211_channel *chan;
8862 #endif
8863 
8864 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
8865 	chan = (struct ieee80211_channel *)chdef->chan;
8866 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8867 	chan = (struct ieee80211_channel *)setup->channel;
8868 #endif
8869 
8870 	RTW_PRINT_SEL(sel, "mesh_id:\"%s\", len:%u\n", setup->mesh_id, setup->mesh_id_len);
8871 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8872 	RTW_PRINT_SEL(sel, "sync_method:%u\n", setup->sync_method);
8873 #endif
8874 	RTW_PRINT_SEL(sel, "path_sel_proto:%u, path_metric:%u\n", setup->path_sel_proto, setup->path_metric);
8875 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8876 	RTW_PRINT_SEL(sel, "auth_id:%u\n", setup->auth_id);
8877 #endif
8878 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
8879 	if (setup->ie && setup->ie_len) {
8880 		RTW_PRINT_SEL(sel, "ie:%p, len:%u\n", setup->ie, setup->ie_len);
8881 		dump_ies(RTW_DBGDUMP, setup->ie, setup->ie_len);
8882 	}
8883 #else
8884 	if (setup->vendor_ie && setup->vendor_ie_len) {
8885 		RTW_PRINT_SEL(sel, "ie:%p, len:%u\n", setup->vendor_ie, setup->vendor_ie_len);
8886 		dump_ies(RTW_DBGDUMP, setup->vendor_ie, setup->vendor_ie_len);
8887 	}
8888 #endif
8889 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
8890 	RTW_PRINT_SEL(sel, "is_authenticated:%d, is_secure:%d\n", setup->is_authenticated, setup->is_secure);
8891 #endif
8892 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
8893 	RTW_PRINT_SEL(sel, "user_mpm:%d\n", setup->user_mpm);
8894 #endif
8895 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
8896 	RTW_PRINT_SEL(sel, "dtim_period:%u, beacon_interval:%u\n", setup->dtim_period, setup->beacon_interval);
8897 #endif
8898 
8899 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8900 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
8901 	RTW_PRINT_SEL(sel, "center_freq:%u, ch:%u, width:%s, cfreq1:%u, cfreq2:%u\n"
8902 		, chan->center_freq, chan->hw_value, nl80211_chan_width_str(chdef->width), chdef->center_freq1, chdef->center_freq2);
8903 #else
8904 	RTW_PRINT_SEL(sel, "center_freq:%u, ch:%u, channel_type:%s\n"
8905 		, chan->center_freq, chan->hw_value, nl80211_channel_type_str(setup->channel_type));
8906 #endif
8907 #endif
8908 
8909 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
8910 	if (setup->mcast_rate[chan->band]) {
8911 		RTW_PRINT_SEL(sel, "mcast_rate:%d.%d\n"
8912 			, wiphy->bands[chan->band]->bitrates[setup->mcast_rate[chan->band] - 1].bitrate / 10
8913 			, wiphy->bands[chan->band]->bitrates[setup->mcast_rate[chan->band] - 1].bitrate % 10
8914 		);
8915 	}
8916 #endif
8917 
8918 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8919 	if (setup->basic_rates) {
8920 		char buf[LEGACY_RATES_STR_LEN] = {0};
8921 
8922 		get_legacy_rates_str(wiphy, chan->band, setup->basic_rates, buf);
8923 		RTW_PRINT_SEL(sel, "basic_rates:%s\n", buf);
8924 	}
8925 #endif
8926 
8927 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
8928 	if (setup->beacon_rate.control[chan->band].legacy) {
8929 		char buf[LEGACY_RATES_STR_LEN] = {0};
8930 
8931 		get_legacy_rates_str(wiphy, chan->band, setup->beacon_rate.control[chan->band].legacy, buf);
8932 		RTW_PRINT_SEL(sel, "beacon_rate.legacy:%s\n", buf);
8933 	}
8934 	if (*((u32 *)&(setup->beacon_rate.control[chan->band].ht_mcs[0]))
8935 		|| *((u32 *)&(setup->beacon_rate.control[chan->band].ht_mcs[4]))
8936 		|| *((u16 *)&(setup->beacon_rate.control[chan->band].ht_mcs[8]))
8937 	) {
8938 		RTW_PRINT_SEL(sel, "beacon_rate.ht_mcs:"HT_RX_MCS_BMP_FMT"\n"
8939 			, HT_RX_MCS_BMP_ARG(setup->beacon_rate.control[chan->band].ht_mcs));
8940 	}
8941 
8942 	if (setup->beacon_rate.control[chan->band].vht_mcs[0]
8943 		|| setup->beacon_rate.control[chan->band].vht_mcs[1]
8944 		|| setup->beacon_rate.control[chan->band].vht_mcs[2]
8945 		|| setup->beacon_rate.control[chan->band].vht_mcs[3]
8946 	) {
8947 		int i;
8948 
8949 		for (i = 0; i < 4; i++) {/* parsing up to 4SS */
8950 			u16 mcs_mask = setup->beacon_rate.control[chan->band].vht_mcs[i];
8951 
8952 			RTW_PRINT_SEL(sel, "beacon_rate.vht_mcs[%d]:%s\n", i
8953 				, mcs_mask == 0x00FF ? "0~7" : mcs_mask == 0x01FF ? "0~8" : mcs_mask == 0x03FF ? "0~9" : "invalid");
8954 		}
8955 	}
8956 
8957 	if (setup->beacon_rate.control[chan->band].gi) {
8958 		RTW_PRINT_SEL(sel, "beacon_rate.gi:%s\n"
8959 			, setup->beacon_rate.control[chan->band].gi == NL80211_TXRATE_FORCE_SGI ? "SGI" :
8960 				setup->beacon_rate.control[chan->band].gi == NL80211_TXRATE_FORCE_LGI ? "LGI" : "invalid"
8961 		);
8962 	}
8963 #endif
8964 }
8965 
dump_mesh_config(void * sel,const struct mesh_config * conf)8966 void dump_mesh_config(void *sel, const struct mesh_config *conf)
8967 {
8968 	RTW_PRINT_SEL(sel, "dot11MeshRetryTimeout:%u\n", conf->dot11MeshRetryTimeout);
8969 	RTW_PRINT_SEL(sel, "dot11MeshConfirmTimeout:%u\n", conf->dot11MeshConfirmTimeout);
8970 	RTW_PRINT_SEL(sel, "dot11MeshHoldingTimeout:%u\n", conf->dot11MeshHoldingTimeout);
8971 	RTW_PRINT_SEL(sel, "dot11MeshMaxPeerLinks:%u\n", conf->dot11MeshMaxPeerLinks);
8972 	RTW_PRINT_SEL(sel, "dot11MeshMaxRetries:%u\n", conf->dot11MeshMaxRetries);
8973 	RTW_PRINT_SEL(sel, "dot11MeshTTL:%u\n", conf->dot11MeshTTL);
8974 	RTW_PRINT_SEL(sel, "element_ttl:%u\n", conf->element_ttl);
8975 	RTW_PRINT_SEL(sel, "auto_open_plinks:%d\n", conf->auto_open_plinks);
8976 
8977 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8978 	RTW_PRINT_SEL(sel, "dot11MeshNbrOffsetMaxNeighbor:%u\n", conf->dot11MeshNbrOffsetMaxNeighbor);
8979 #endif
8980 
8981 	RTW_PRINT_SEL(sel, "dot11MeshHWMPmaxPREQretries:%u\n", conf->dot11MeshHWMPmaxPREQretries);
8982 	RTW_PRINT_SEL(sel, "path_refresh_time:%u\n", conf->path_refresh_time);
8983 	RTW_PRINT_SEL(sel, "min_discovery_timeout:%u\n", conf->min_discovery_timeout);
8984 	RTW_PRINT_SEL(sel, "dot11MeshHWMPactivePathTimeout:%u\n", conf->dot11MeshHWMPactivePathTimeout);
8985 	RTW_PRINT_SEL(sel, "dot11MeshHWMPpreqMinInterval:%u\n", conf->dot11MeshHWMPpreqMinInterval);
8986 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
8987 	RTW_PRINT_SEL(sel, "dot11MeshHWMPperrMinInterval:%u\n", conf->dot11MeshHWMPperrMinInterval);
8988 #endif
8989 	RTW_PRINT_SEL(sel, "dot11MeshHWMPnetDiameterTraversalTime:%u\n", conf->dot11MeshHWMPnetDiameterTraversalTime);
8990 	RTW_PRINT_SEL(sel, "dot11MeshHWMPRootMode:%u\n", conf->dot11MeshHWMPRootMode);
8991 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
8992 	RTW_PRINT_SEL(sel, "dot11MeshHWMPRannInterval:%u\n", conf->dot11MeshHWMPRannInterval);
8993 	RTW_PRINT_SEL(sel, "dot11MeshGateAnnouncementProtocol:%d\n", conf->dot11MeshGateAnnouncementProtocol);
8994 #endif
8995 
8996 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
8997 	RTW_PRINT_SEL(sel, "dot11MeshForwarding:%d\n", conf->dot11MeshForwarding);
8998 	RTW_PRINT_SEL(sel, "rssi_threshold:%d\n", conf->rssi_threshold);
8999 #endif
9000 
9001 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
9002 	RTW_PRINT_SEL(sel, "ht_opmode:0x%04x\n", conf->ht_opmode);
9003 #endif
9004 
9005 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9006 	RTW_PRINT_SEL(sel, "dot11MeshHWMPactivePathToRootTimeout:%u\n", conf->dot11MeshHWMPactivePathToRootTimeout);
9007 	RTW_PRINT_SEL(sel, "dot11MeshHWMProotInterval:%u\n", conf->dot11MeshHWMProotInterval);
9008 	RTW_PRINT_SEL(sel, "dot11MeshHWMPconfirmationInterval:%u\n", conf->dot11MeshHWMPconfirmationInterval);
9009 #endif
9010 
9011 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
9012 	RTW_PRINT_SEL(sel, "power_mode:%s\n", nl80211_mesh_power_mode_str(conf->power_mode));
9013 	RTW_PRINT_SEL(sel, "dot11MeshAwakeWindowDuration:%u\n", conf->dot11MeshAwakeWindowDuration);
9014 #endif
9015 
9016 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
9017 	RTW_PRINT_SEL(sel, "plink_timeout:%u\n", conf->plink_timeout);
9018 #endif
9019 }
9020 #endif /* DBG_RTW_CFG80211_MESH_CONF */
9021 
rtw_cfg80211_mesh_info_set_profile(struct rtw_mesh_info * minfo,const struct mesh_setup * setup)9022 static void rtw_cfg80211_mesh_info_set_profile(struct rtw_mesh_info *minfo, const struct mesh_setup *setup)
9023 {
9024 	_rtw_memcpy(minfo->mesh_id, setup->mesh_id, setup->mesh_id_len);
9025 	minfo->mesh_id_len = setup->mesh_id_len;
9026 	minfo->mesh_pp_id = setup->path_sel_proto;
9027 	minfo->mesh_pm_id = setup->path_metric;
9028 	minfo->mesh_cc_id = 0;
9029 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
9030 	minfo->mesh_sp_id = setup->sync_method;
9031 #endif
9032 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
9033 	minfo->mesh_auth_id = setup->auth_id;
9034 #else
9035 	if (setup->is_authenticated) {
9036 		u8 *rsn_ie;
9037 		sint rsn_ie_len;
9038 		struct rsne_info info;
9039 		u8 *akm;
9040 		u8 AKM_SUITE_SAE[4] = {0x00, 0x0F, 0xAC, 0x08};
9041 
9042 		rsn_ie = rtw_get_ie(setup->ie, WLAN_EID_RSN, &rsn_ie_len, setup->ie_len);
9043 		if (!rsn_ie || !rsn_ie_len) {
9044 			rtw_warn_on(1);
9045 			return;
9046 		}
9047 
9048 		if (rtw_rsne_info_parse(rsn_ie, rsn_ie_len + 2, &info) != _SUCCESS) {
9049 			rtw_warn_on(1);
9050 			return;
9051 		}
9052 
9053 		if (!info.akm_list || !info.akm_cnt) {
9054 			rtw_warn_on(1);
9055 			return;
9056 		}
9057 
9058 		akm = info.akm_list;
9059 		while (akm < info.akm_list + info.akm_cnt * 4) {
9060 			if (_rtw_memcmp(akm, AKM_SUITE_SAE, 4) == _TRUE) {
9061 				minfo->mesh_auth_id = 0x01;
9062 				break;
9063 			}
9064 		}
9065 
9066 		if (!minfo->mesh_auth_id) {
9067 			rtw_warn_on(1);
9068 			return;
9069 		}
9070 	}
9071 #endif
9072 }
9073 
chk_mesh_attr(enum nl80211_meshconf_params parm,u32 mask)9074 static inline bool chk_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
9075 {
9076 	return (mask >> (parm - 1)) & 0x1;
9077 }
9078 
rtw_cfg80211_mesh_cfg_set(_adapter * adapter,const struct mesh_config * conf,u32 mask)9079 static void rtw_cfg80211_mesh_cfg_set(_adapter *adapter, const struct mesh_config *conf, u32 mask)
9080 {
9081 	struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
9082 
9083 #if 0 /* driver MPM */
9084 	if (chk_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask));
9085 	if (chk_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask));
9086 	if (chk_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask));
9087 	if (chk_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask));
9088 	if (chk_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask));
9089 #endif
9090 
9091 	if (chk_mesh_attr(NL80211_MESHCONF_TTL, mask))
9092 		mcfg->dot11MeshTTL = conf->dot11MeshTTL;
9093 	if (chk_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
9094 		mcfg->element_ttl = conf->element_ttl;
9095 
9096 #if 0 /* driver MPM */
9097 	if (chk_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask));
9098 #endif
9099 
9100 #if 0 /* TBD: synchronization */
9101 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
9102 	if (chk_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask));
9103 #endif
9104 #endif
9105 
9106 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
9107 		mcfg->dot11MeshHWMPmaxPREQretries = conf->dot11MeshHWMPmaxPREQretries;
9108 	if (chk_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
9109 		mcfg->path_refresh_time = conf->path_refresh_time;
9110 	if (chk_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
9111 		mcfg->min_discovery_timeout = conf->min_discovery_timeout;
9112 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
9113 		mcfg->dot11MeshHWMPactivePathTimeout = conf->dot11MeshHWMPactivePathTimeout;
9114 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
9115 		mcfg->dot11MeshHWMPpreqMinInterval = conf->dot11MeshHWMPpreqMinInterval;
9116 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
9117 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, mask))
9118 		mcfg->dot11MeshHWMPperrMinInterval = conf->dot11MeshHWMPperrMinInterval;
9119 #endif
9120 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, mask))
9121 		mcfg->dot11MeshHWMPnetDiameterTraversalTime = conf->dot11MeshHWMPnetDiameterTraversalTime;
9122 
9123 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask))
9124 		mcfg->dot11MeshHWMPRootMode = conf->dot11MeshHWMPRootMode;
9125 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
9126 	if (chk_mesh_attr(NL80211_MESHCONF_GATE_ANNOUNCEMENTS, mask))
9127 		mcfg->dot11MeshGateAnnouncementProtocol = conf->dot11MeshGateAnnouncementProtocol;
9128 	/* our current gate annc implementation rides on root annc with gate annc bit in PREQ flags */
9129 	if (mcfg->dot11MeshGateAnnouncementProtocol
9130 		&& mcfg->dot11MeshHWMPRootMode <= RTW_IEEE80211_ROOTMODE_ROOT
9131 	) {
9132 		mcfg->dot11MeshHWMPRootMode = RTW_IEEE80211_PROACTIVE_RANN;
9133 		RTW_INFO(ADPT_FMT" enable PROACTIVE_RANN becaue gate annc is needed\n", ADPT_ARG(adapter));
9134 	}
9135 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
9136 		mcfg->dot11MeshHWMPRannInterval = conf->dot11MeshHWMPRannInterval;
9137 #endif
9138 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
9139 	if (chk_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
9140 		mcfg->dot11MeshForwarding = conf->dot11MeshForwarding;
9141 
9142 	if (chk_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask))
9143 		mcfg->rssi_threshold = conf->rssi_threshold;
9144 #endif
9145 
9146 #if 0 /* controlled by driver */
9147 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
9148 	if (chk_mesh_attr(NL80211_MESHCONF_HT_OPMODE, mask));
9149 #endif
9150 #endif
9151 
9152 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9153 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
9154 		mcfg->dot11MeshHWMPactivePathToRootTimeout = conf->dot11MeshHWMPactivePathToRootTimeout;
9155 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
9156 		mcfg->dot11MeshHWMProotInterval = conf->dot11MeshHWMProotInterval;
9157 	if (chk_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
9158 		mcfg->dot11MeshHWMPconfirmationInterval = conf->dot11MeshHWMPconfirmationInterval;
9159 #endif
9160 
9161 #if 0 /* TBD */
9162 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
9163 	if (chk_mesh_attr(NL80211_MESHCONF_POWER_MODE, mask));
9164 	if (chk_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask));
9165 #endif
9166 #endif
9167 
9168 #if 0 /* driver MPM */
9169 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
9170 	if (chk_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask));
9171 #endif
9172 #endif
9173 }
9174 
rtw_cfg80211_construct_mesh_beacon_ies(struct wiphy * wiphy,_adapter * adapter,const struct mesh_config * conf,const struct mesh_setup * setup,uint * ies_len)9175 u8 *rtw_cfg80211_construct_mesh_beacon_ies(struct wiphy *wiphy, _adapter *adapter
9176 	, const struct mesh_config *conf, const struct mesh_setup *setup
9177 	, uint *ies_len)
9178 {
9179 	struct rtw_mesh_info *minfo = &adapter->mesh_info;
9180 	struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
9181 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9182 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
9183 	struct cfg80211_chan_def *chdef = (struct cfg80211_chan_def *)(&setup->chandef);
9184 #endif
9185 	struct ieee80211_channel *chan;
9186 	u8 ch, bw, offset;
9187 #endif
9188 	uint len;
9189 	u8 n_bitrates;
9190 	u8 ht = 0;
9191 	u8 vht = 0;
9192 	u8 *rsn_ie = NULL;
9193 	sint rsn_ie_len = 0;
9194 	u8 *ies = NULL, *c;
9195 	u8 supported_rates[RTW_G_RATES_NUM] = {0};
9196 	int i;
9197 
9198 	*ies_len = 0;
9199 
9200 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
9201 	chan = (struct ieee80211_channel *)chdef->chan;
9202 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9203 	chan = (struct ieee80211_channel *)setup->channel;
9204 #endif
9205 
9206 	n_bitrates = wiphy->bands[chan->band]->n_bitrates;
9207 
9208 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9209 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
9210 	rtw_get_chbw_from_cfg80211_chan_def(chdef, &ht, &ch, &bw, &offset);
9211 #else
9212 	rtw_get_chbw_from_nl80211_channel_type(chan, setup->channel_type, &ht, &ch, &bw, &offset);
9213 #endif
9214 	if (!ch)
9215 		goto exit;
9216 
9217 #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9218 	vht = ht && ch > 14 && bw >= CHANNEL_WIDTH_80; /* VHT40/VHT20? */
9219 #endif
9220 
9221 	RTW_INFO(FUNC_ADPT_FMT" => ch:%u,%u,%u, ht:%u, vht:%u\n"
9222 		, FUNC_ADPT_ARG(adapter), ch, bw, offset, ht, vht);
9223 #endif
9224 
9225 	rsn_ie = rtw_get_ie(setup->ie, WLAN_EID_RSN, &rsn_ie_len, setup->ie_len);
9226 	if (rsn_ie && !rsn_ie_len) {
9227 		rtw_warn_on(1);
9228 		rsn_ie = NULL;
9229 	}
9230 
9231 	len = _BEACON_IE_OFFSET_
9232 		+ 2 /* 0-length SSID */
9233 		+ (n_bitrates >= 8 ? 8 : n_bitrates) + 2 /* Supported Rates */
9234 		+ 3 /* DS parameter set */
9235 		+ 6 /* TIM  */
9236 		+ (n_bitrates > 8 ? n_bitrates - 8 + 2 : 0) /* Extended Supported Rates */
9237 		+ (rsn_ie ? rsn_ie_len + 2 : 0) /* RSN */
9238 		#if defined(CONFIG_80211N_HT)
9239 		+ (ht ? HT_CAP_IE_LEN + 2 + HT_OP_IE_LEN + 2 : 0) /* HT */
9240 		#endif
9241 		#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9242 		+ (vht ? VHT_CAP_IE_LEN + 2 + VHT_OP_IE_LEN + 2 : 0) /* VHT */
9243 		#endif
9244 		+ minfo->mesh_id_len + 2 /* Mesh ID */
9245 		+ 9 /* Mesh configuration */
9246 		;
9247 
9248 	ies = rtw_zmalloc(len);
9249 	if (!ies)
9250 		goto exit;
9251 
9252 	/* timestamp */
9253 	c = ies + 8;
9254 
9255 	/* beacon interval */
9256 	RTW_PUT_LE16(c , setup->beacon_interval);
9257 	c += 2;
9258 
9259 	/* capability */
9260 	if (rsn_ie)
9261 		*((u16 *)c) |= cpu_to_le16(cap_Privacy);
9262 	c += 2;
9263 
9264 	/* SSID */
9265 	c = rtw_set_ie(c, WLAN_EID_SSID, 0, NULL, NULL);
9266 
9267 	/* Supported Rates */
9268 	for (i = 0; i < n_bitrates; i++) {
9269 		supported_rates[i] = wiphy->bands[chan->band]->bitrates[i].bitrate / 5;
9270 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
9271 		if (setup->basic_rates & BIT(i))
9272 		#else
9273 		if (rtw_is_basic_rate_mix(supported_rates[i]))
9274 		#endif
9275 			supported_rates[i] |= IEEE80211_BASIC_RATE_MASK;
9276 	}
9277 	c = rtw_set_ie(c, WLAN_EID_SUPP_RATES, (n_bitrates >= 8 ? 8 : n_bitrates), supported_rates, NULL);
9278 
9279 	/* DS parameter set */
9280 	c = rtw_set_ie(c, WLAN_EID_DS_PARAMS, 1, &ch, NULL);
9281 
9282 	/* TIM */
9283 	*c = WLAN_EID_TIM;
9284 	*(c + 1) = 4;
9285 	c += 6;
9286 	//c = rtw_set_ie(c, _TIM_IE_, 4, NULL, NULL);
9287 
9288 	/* Extended Supported Rates */
9289 	if (n_bitrates > 8)
9290 		c = rtw_set_ie(c, WLAN_EID_EXT_SUPP_RATES, n_bitrates - 8, supported_rates + 8, NULL);
9291 
9292 	/* RSN */
9293 	if (rsn_ie)
9294 		c = rtw_set_ie(c, WLAN_EID_RSN, rsn_ie_len, rsn_ie + 2, NULL);
9295 
9296 #if defined(CONFIG_80211N_HT)
9297 	if (ht) {
9298 		struct ieee80211_sta_ht_cap *sta_ht_cap = &wiphy->bands[chan->band]->ht_cap;
9299 		u8 ht_cap[HT_CAP_IE_LEN];
9300 		u8 ht_op[HT_OP_IE_LEN];
9301 
9302 		_rtw_memset(ht_cap, 0, HT_CAP_IE_LEN);
9303 		_rtw_memset(ht_op, 0, HT_OP_IE_LEN);
9304 
9305 		/* WLAN_EID_HT_CAP */
9306 		RTW_PUT_LE16(HT_CAP_ELE_CAP_INFO(ht_cap), sta_ht_cap->cap);
9307 		SET_HT_CAP_ELE_MAX_AMPDU_LEN_EXP(ht_cap, sta_ht_cap->ampdu_factor);
9308 		SET_HT_CAP_ELE_MIN_MPDU_S_SPACE(ht_cap, sta_ht_cap->ampdu_density);
9309 		_rtw_memcpy(HT_CAP_ELE_SUP_MCS_SET(ht_cap), &sta_ht_cap->mcs, 16);
9310 		c = rtw_set_ie(c, WLAN_EID_HT_CAP, HT_CAP_IE_LEN, ht_cap, NULL);
9311 
9312 		/* WLAN_EID_HT_OPERATION */
9313 		SET_HT_OP_ELE_PRI_CHL(ht_op, ch);
9314 		switch (offset) {
9315 		case HAL_PRIME_CHNL_OFFSET_LOWER:
9316 			SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op, SCA);
9317 			break;
9318 		case HAL_PRIME_CHNL_OFFSET_UPPER:
9319 			SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op, SCB);
9320 			break;
9321 		case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
9322 		default:
9323 			SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op, SCN);
9324 			break;
9325 		}
9326 		if (bw >= CHANNEL_WIDTH_40)
9327 			SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op, 1);
9328 		else
9329 			SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op, 0);
9330 		c = rtw_set_ie(c, WLAN_EID_HT_OPERATION, HT_OP_IE_LEN, ht_op, NULL);
9331 	}
9332 #endif /* defined(CONFIG_80211N_HT) */
9333 
9334 #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9335 	if (vht) {
9336 		struct ieee80211_sta_vht_cap *sta_vht_cap = &wiphy->bands[chan->band]->vht_cap;
9337 		u8 vht_cap[VHT_CAP_IE_LEN];
9338 		u8 vht_op[VHT_OP_IE_LEN];
9339 		u8 cch = rtw_get_center_ch(ch, bw, offset);
9340 
9341 		_rtw_memset(vht_op, 0, VHT_OP_IE_LEN);
9342 
9343 		/* WLAN_EID_VHT_CAPABILITY */
9344 		_rtw_memcpy(vht_cap, &sta_vht_cap->cap, 4);
9345 		_rtw_memcpy(vht_cap + 4, &sta_vht_cap->vht_mcs, 8);
9346 		c = rtw_set_ie(c, WLAN_EID_VHT_CAPABILITY, VHT_CAP_IE_LEN, vht_cap, NULL);
9347 
9348 		/* WLAN_EID_VHT_OPERATION */
9349 		if (bw < CHANNEL_WIDTH_80) {
9350 			SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op, 0);
9351 			SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op, 0);
9352 			SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op, 0);
9353 		} else if (bw == CHANNEL_WIDTH_80) {
9354 			SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op, 1);
9355 			SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op, cch);
9356 			SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op, 0);
9357 		} else {
9358 			RTW_ERR(FUNC_ADPT_FMT" unsupported BW:%u\n", FUNC_ADPT_ARG(adapter), bw);
9359 			rtw_warn_on(1);
9360 			rtw_mfree(ies, len);
9361 			goto exit;
9362 		}
9363 
9364 		/* Hard code 1 stream, MCS0-7 is a min Basic VHT MCS rates */
9365 		vht_op[3] = 0xfc;
9366 		vht_op[4] = 0xff;
9367 		c = rtw_set_ie(c, WLAN_EID_VHT_OPERATION, VHT_OP_IE_LEN, vht_op, NULL);
9368 	}
9369 #endif /* defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
9370 
9371 	/* Mesh ID */
9372 	c = rtw_set_ie_mesh_id(c, NULL, minfo->mesh_id, minfo->mesh_id_len);
9373 
9374 	/* Mesh configuration */
9375 	c = rtw_set_ie_mesh_config(c, NULL
9376 		, minfo->mesh_pp_id
9377 		, minfo->mesh_pm_id
9378 		, minfo->mesh_cc_id
9379 		, minfo->mesh_sp_id
9380 		, minfo->mesh_auth_id
9381 		, 0, 0, 0
9382 		, 1
9383 		, 0, 0
9384 		, mcfg->dot11MeshForwarding
9385 		, 0, 0, 0
9386 	);
9387 
9388 #if DBG_RTW_CFG80211_MESH_CONF
9389 	RTW_INFO(FUNC_ADPT_FMT" ies_len:%u\n", FUNC_ADPT_ARG(adapter), len);
9390 	dump_ies(RTW_DBGDUMP, ies + _BEACON_IE_OFFSET_, len - _BEACON_IE_OFFSET_);
9391 #endif
9392 
9393 exit:
9394 	if (ies)
9395 		*ies_len = len;
9396 	return ies;
9397 }
9398 
cfg80211_rtw_get_mesh_config(struct wiphy * wiphy,struct net_device * dev,struct mesh_config * conf)9399 static int cfg80211_rtw_get_mesh_config(struct wiphy *wiphy, struct net_device *dev
9400 	, struct mesh_config *conf)
9401 {
9402 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9403 	struct rtw_mesh_cfg *mesh_cfg = &adapter->mesh_cfg;
9404 	int ret = 0;
9405 
9406 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
9407 
9408 	/* driver MPM */
9409 	conf->dot11MeshRetryTimeout = 0;
9410 	conf->dot11MeshConfirmTimeout = 0;
9411 	conf->dot11MeshHoldingTimeout = 0;
9412 	conf->dot11MeshMaxPeerLinks = mesh_cfg->max_peer_links;
9413 	conf->dot11MeshMaxRetries = 0;
9414 
9415 	conf->dot11MeshTTL = mesh_cfg->dot11MeshTTL;
9416 	conf->element_ttl = mesh_cfg->element_ttl;
9417 
9418 	/* driver MPM */
9419 	conf->auto_open_plinks = 0;
9420 
9421 	/* TBD: synchronization */
9422 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
9423 	conf->dot11MeshNbrOffsetMaxNeighbor = 0;
9424 #endif
9425 
9426 	conf->dot11MeshHWMPmaxPREQretries = mesh_cfg->dot11MeshHWMPmaxPREQretries;
9427 	conf->path_refresh_time = mesh_cfg->path_refresh_time;
9428 	conf->min_discovery_timeout = mesh_cfg->min_discovery_timeout;
9429 	conf->dot11MeshHWMPactivePathTimeout = mesh_cfg->dot11MeshHWMPactivePathTimeout;
9430 	conf->dot11MeshHWMPpreqMinInterval = mesh_cfg->dot11MeshHWMPpreqMinInterval;
9431 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
9432 	conf->dot11MeshHWMPperrMinInterval = mesh_cfg->dot11MeshHWMPperrMinInterval;
9433 #endif
9434 	conf->dot11MeshHWMPnetDiameterTraversalTime = mesh_cfg->dot11MeshHWMPnetDiameterTraversalTime;
9435 	conf->dot11MeshHWMPRootMode = mesh_cfg->dot11MeshHWMPRootMode;
9436 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
9437 	conf->dot11MeshHWMPRannInterval = mesh_cfg->dot11MeshHWMPRannInterval;
9438 #endif
9439 	conf->dot11MeshGateAnnouncementProtocol = mesh_cfg->dot11MeshGateAnnouncementProtocol;
9440 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
9441 	conf->dot11MeshForwarding = mesh_cfg->dot11MeshForwarding;
9442 	conf->rssi_threshold = mesh_cfg->rssi_threshold;
9443 #endif
9444 
9445 	/* TBD */
9446 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
9447 	conf->ht_opmode = 0xffff;
9448 #endif
9449 
9450 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9451 	conf->dot11MeshHWMPactivePathToRootTimeout = mesh_cfg->dot11MeshHWMPactivePathToRootTimeout;
9452 	conf->dot11MeshHWMProotInterval = mesh_cfg->dot11MeshHWMProotInterval;
9453 	conf->dot11MeshHWMPconfirmationInterval = mesh_cfg->dot11MeshHWMPconfirmationInterval;
9454 #endif
9455 
9456 	/* TBD: power save */
9457 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
9458 	conf->power_mode = NL80211_MESH_POWER_ACTIVE;
9459 	conf->dot11MeshAwakeWindowDuration = 0;
9460 #endif
9461 
9462 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
9463 	conf->plink_timeout = mesh_cfg->plink_timeout;
9464 #endif
9465 
9466 	return ret;
9467 }
9468 
rtw_mbss_info_change_notify(_adapter * adapter,bool minfo_changed,bool need_work)9469 static void rtw_mbss_info_change_notify(_adapter *adapter, bool minfo_changed, bool need_work)
9470 {
9471 	if (need_work)
9472 		rtw_mesh_work(&adapter->mesh_work);
9473 }
9474 
cfg80211_rtw_update_mesh_config(struct wiphy * wiphy,struct net_device * dev,u32 mask,const struct mesh_config * nconf)9475 static int cfg80211_rtw_update_mesh_config(struct wiphy *wiphy, struct net_device *dev
9476 	, u32 mask, const struct mesh_config *nconf)
9477 {
9478 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9479 	int ret = 0;
9480 	bool minfo_changed = _FALSE, need_work = _FALSE;
9481 
9482 	RTW_INFO(FUNC_ADPT_FMT" mask:0x%08x\n", FUNC_ADPT_ARG(adapter), mask);
9483 
9484 	rtw_cfg80211_mesh_cfg_set(adapter, nconf, mask);
9485 	update_beacon(adapter, WLAN_EID_MESH_CONFIG, NULL, _TRUE, 0);
9486 #if CONFIG_RTW_MESH_CTO_MGATE_CARRIER
9487 	if (rtw_mesh_cto_mgate_required(adapter))
9488 		rtw_netif_carrier_off(adapter->pnetdev);
9489 	else
9490 		rtw_netif_carrier_on(adapter->pnetdev);
9491 #endif
9492 	need_work = rtw_ieee80211_mesh_root_setup(adapter);
9493 
9494 	rtw_mbss_info_change_notify(adapter, minfo_changed, need_work);
9495 
9496 	return ret;
9497 }
9498 
cfg80211_rtw_join_mesh(struct wiphy * wiphy,struct net_device * dev,const struct mesh_config * conf,const struct mesh_setup * setup)9499 static int cfg80211_rtw_join_mesh(struct wiphy *wiphy, struct net_device *dev,
9500 	const struct mesh_config *conf, const struct mesh_setup *setup)
9501 {
9502 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9503 	u8 *ies = NULL;
9504 	uint ies_len;
9505 	int ret = 0;
9506 
9507 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
9508 
9509 #if DBG_RTW_CFG80211_MESH_CONF
9510 	RTW_INFO(FUNC_ADPT_FMT" mesh_setup:\n", FUNC_ADPT_ARG(adapter));
9511 	dump_mesh_setup(RTW_DBGDUMP, wiphy, setup);
9512 	RTW_INFO(FUNC_ADPT_FMT" mesh_config:\n", FUNC_ADPT_ARG(adapter));
9513 	dump_mesh_config(RTW_DBGDUMP, conf);
9514 #endif
9515 
9516 	if (rtw_cfg80211_sync_iftype(adapter) != _SUCCESS) {
9517 		ret = -ENOTSUPP;
9518 		goto exit;
9519 	}
9520 
9521 	/* initialization */
9522 	rtw_mesh_init_mesh_info(adapter);
9523 
9524 	/* apply cfg80211 settings*/
9525 	rtw_cfg80211_mesh_info_set_profile(&adapter->mesh_info, setup);
9526 	rtw_cfg80211_mesh_cfg_set(adapter, conf, 0xFFFFFFFF);
9527 
9528 	/* apply cfg80211 settings (join only) */
9529 	rtw_mesh_cfg_init_max_peer_links(adapter, conf->dot11MeshMaxPeerLinks);
9530 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
9531 	rtw_mesh_cfg_init_plink_timeout(adapter, conf->plink_timeout);
9532 	#endif
9533 
9534 	rtw_ieee80211_mesh_root_setup(adapter);
9535 
9536 	ies = rtw_cfg80211_construct_mesh_beacon_ies(wiphy, adapter, conf, setup, &ies_len);
9537 	if (!ies) {
9538 		ret = -EINVAL;
9539 		goto exit;
9540 	}
9541 
9542 	/* start mbss */
9543 	if (rtw_check_beacon_data(adapter, ies,  ies_len) != _SUCCESS) {
9544 		ret = -EINVAL;
9545 		goto exit;
9546 	}
9547 
9548 	rtw_mesh_work(&adapter->mesh_work);
9549 
9550 exit:
9551 	if (ies)
9552 		rtw_mfree(ies, ies_len);
9553 	if (ret)
9554 		rtw_mesh_deinit_mesh_info(adapter);
9555 
9556 	return ret;
9557 }
9558 
cfg80211_rtw_leave_mesh(struct wiphy * wiphy,struct net_device * dev)9559 static int cfg80211_rtw_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
9560 {
9561 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9562 	int ret = 0;
9563 
9564 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
9565 
9566 	rtw_mesh_deinit_mesh_info(adapter);
9567 
9568 	rtw_stop_ap_cmd(adapter, RTW_CMDF_WAIT_ACK);
9569 
9570 	return ret;
9571 }
9572 
cfg80211_rtw_add_mpath(struct wiphy * wiphy,struct net_device * dev,const u8 * dst,const u8 * next_hop)9573 static int cfg80211_rtw_add_mpath(struct wiphy *wiphy, struct net_device *dev
9574 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
9575 	, const u8 *dst, const u8 *next_hop
9576 	#else
9577 	, u8 *dst, u8 *next_hop
9578 	#endif
9579 )
9580 {
9581 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9582 	struct sta_priv *stapriv = &adapter->stapriv;
9583 	struct sta_info *sta;
9584 	struct rtw_mesh_path *mpath;
9585 	int ret = 0;
9586 
9587 	rtw_rcu_read_lock();
9588 
9589 	sta = rtw_get_stainfo(stapriv, next_hop);
9590 	if (!sta) {
9591 		ret = -ENOENT;
9592 		goto exit;
9593 	}
9594 
9595 	mpath = rtw_mesh_path_add(adapter, dst);
9596 	if (!mpath) {
9597 		ret = -ENOENT;
9598 		goto exit;
9599 	}
9600 
9601 	rtw_mesh_path_fix_nexthop(mpath, sta);
9602 
9603 exit:
9604 	rtw_rcu_read_unlock();
9605 
9606 	return ret;
9607 }
9608 
cfg80211_rtw_del_mpath(struct wiphy * wiphy,struct net_device * dev,const u8 * dst)9609 static int cfg80211_rtw_del_mpath(struct wiphy *wiphy, struct net_device *dev
9610 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
9611 	, const u8 *dst
9612 	#else
9613 	, u8 *dst
9614 	#endif
9615 )
9616 {
9617 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9618 	int ret = 0;
9619 
9620 	if (dst) {
9621 		if (rtw_mesh_path_del(adapter, dst)) {
9622 			ret = -ENOENT;
9623 			goto exit;
9624 		}
9625 	} else {
9626 		rtw_mesh_path_flush_by_iface(adapter);
9627 	}
9628 
9629 exit:
9630 	return ret;
9631 }
9632 
cfg80211_rtw_change_mpath(struct wiphy * wiphy,struct net_device * dev,const u8 * dst,const u8 * next_hop)9633 static int cfg80211_rtw_change_mpath(struct wiphy *wiphy, struct net_device *dev
9634 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
9635 	, const u8 *dst, const u8 *next_hop
9636 	#else
9637 	, u8 *dst, u8 *next_hop
9638 	#endif
9639 )
9640 {
9641 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9642 	struct sta_priv *stapriv = &adapter->stapriv;
9643 	struct sta_info *sta;
9644 	struct rtw_mesh_path *mpath;
9645 	int ret = 0;
9646 
9647 	rtw_rcu_read_lock();
9648 
9649 	sta = rtw_get_stainfo(stapriv, next_hop);
9650 	if (!sta) {
9651 		ret = -ENOENT;
9652 		goto exit;
9653 	}
9654 
9655 	mpath = rtw_mesh_path_lookup(adapter, dst);
9656 	if (!mpath) {
9657 		ret = -ENOENT;
9658 		goto exit;
9659 	}
9660 
9661 	rtw_mesh_path_fix_nexthop(mpath, sta);
9662 
9663 exit:
9664 	rtw_rcu_read_unlock();
9665 
9666 	return ret;
9667 }
9668 
rtw_cfg80211_mpath_set_pinfo(struct rtw_mesh_path * mpath,u8 * next_hop,struct mpath_info * pinfo)9669 static void rtw_cfg80211_mpath_set_pinfo(struct rtw_mesh_path *mpath, u8 *next_hop, struct mpath_info *pinfo)
9670 {
9671 	struct sta_info *next_hop_sta = rtw_rcu_dereference(mpath->next_hop);
9672 
9673 	if (next_hop_sta)
9674 		_rtw_memcpy(next_hop, next_hop_sta->cmn.mac_addr, ETH_ALEN);
9675 	else
9676 		_rtw_memset(next_hop, 0, ETH_ALEN);
9677 
9678 	_rtw_memset(pinfo, 0, sizeof(*pinfo));
9679 
9680 	pinfo->generation = mpath->adapter->mesh_info.mesh_paths_generation;
9681 
9682 	pinfo->filled = 0
9683 		| MPATH_INFO_FRAME_QLEN
9684 		| MPATH_INFO_SN
9685 		| MPATH_INFO_METRIC
9686 		| MPATH_INFO_EXPTIME
9687 		| MPATH_INFO_DISCOVERY_TIMEOUT
9688 		| MPATH_INFO_DISCOVERY_RETRIES
9689 		| MPATH_INFO_FLAGS
9690 		;
9691 
9692 	pinfo->frame_qlen = mpath->frame_queue_len;
9693 	pinfo->sn = mpath->sn;
9694 	pinfo->metric = mpath->metric;
9695 	if (rtw_time_after(mpath->exp_time, rtw_get_current_time()))
9696 		pinfo->exptime = rtw_get_remaining_time_ms(mpath->exp_time);
9697 	pinfo->discovery_timeout = rtw_systime_to_ms(mpath->discovery_timeout);
9698 	pinfo->discovery_retries = mpath->discovery_retries;
9699 	if (mpath->flags & RTW_MESH_PATH_ACTIVE)
9700 		pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
9701 	if (mpath->flags & RTW_MESH_PATH_RESOLVING)
9702 		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
9703 	if (mpath->flags & RTW_MESH_PATH_SN_VALID)
9704 		pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
9705 	if (mpath->flags & RTW_MESH_PATH_FIXED)
9706 		pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
9707 	if (mpath->flags & RTW_MESH_PATH_RESOLVED)
9708 		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;
9709 }
9710 
cfg80211_rtw_get_mpath(struct wiphy * wiphy,struct net_device * dev,u8 * dst,u8 * next_hop,struct mpath_info * pinfo)9711 static int cfg80211_rtw_get_mpath(struct wiphy *wiphy, struct net_device *dev, u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
9712 {
9713 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9714 	struct rtw_mesh_path *mpath;
9715 	int ret = 0;
9716 
9717 	rtw_rcu_read_lock();
9718 
9719 	mpath = rtw_mesh_path_lookup(adapter, dst);
9720 	if (!mpath) {
9721 		ret = -ENOENT;
9722 		goto exit;
9723 	}
9724 
9725 	rtw_cfg80211_mpath_set_pinfo(mpath, next_hop, pinfo);
9726 
9727 exit:
9728 	rtw_rcu_read_unlock();
9729 
9730 	return ret;
9731 }
9732 
cfg80211_rtw_dump_mpath(struct wiphy * wiphy,struct net_device * dev,int idx,u8 * dst,u8 * next_hop,struct mpath_info * pinfo)9733 static int cfg80211_rtw_dump_mpath(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
9734 {
9735 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9736 	struct rtw_mesh_path *mpath;
9737 	int ret = 0;
9738 
9739 	rtw_rcu_read_lock();
9740 
9741 	mpath = rtw_mesh_path_lookup_by_idx(adapter, idx);
9742 	if (!mpath) {
9743 		ret = -ENOENT;
9744 		goto exit;
9745 	}
9746 
9747 	_rtw_memcpy(dst, mpath->dst, ETH_ALEN);
9748 	rtw_cfg80211_mpath_set_pinfo(mpath, next_hop, pinfo);
9749 
9750 exit:
9751 	rtw_rcu_read_unlock();
9752 
9753 	return ret;
9754 }
9755 
9756 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
rtw_cfg80211_mpp_set_pinfo(struct rtw_mesh_path * mpath,u8 * mpp,struct mpath_info * pinfo)9757 static void rtw_cfg80211_mpp_set_pinfo(struct rtw_mesh_path *mpath, u8 *mpp, struct mpath_info *pinfo)
9758 {
9759 	_rtw_memcpy(mpp, mpath->mpp, ETH_ALEN);
9760 
9761 	_rtw_memset(pinfo, 0, sizeof(*pinfo));
9762 	pinfo->generation = mpath->adapter->mesh_info.mpp_paths_generation;
9763 }
9764 
cfg80211_rtw_get_mpp(struct wiphy * wiphy,struct net_device * dev,u8 * dst,u8 * mpp,struct mpath_info * pinfo)9765 static int cfg80211_rtw_get_mpp(struct wiphy *wiphy, struct net_device *dev, u8 *dst, u8 *mpp, struct mpath_info *pinfo)
9766 {
9767 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9768 	struct rtw_mesh_path *mpath;
9769 	int ret = 0;
9770 
9771 	rtw_rcu_read_lock();
9772 
9773 	mpath = rtw_mpp_path_lookup(adapter, dst);
9774 	if (!mpath) {
9775 		ret = -ENOENT;
9776 		goto exit;
9777 	}
9778 
9779 	rtw_cfg80211_mpp_set_pinfo(mpath, mpp, pinfo);
9780 
9781 exit:
9782 	rtw_rcu_read_unlock();
9783 
9784 	return ret;
9785 }
9786 
cfg80211_rtw_dump_mpp(struct wiphy * wiphy,struct net_device * dev,int idx,u8 * dst,u8 * mpp,struct mpath_info * pinfo)9787 static int cfg80211_rtw_dump_mpp(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *mpp, struct mpath_info *pinfo)
9788 {
9789 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9790 	struct rtw_mesh_path *mpath;
9791 	int ret = 0;
9792 
9793 	rtw_rcu_read_lock();
9794 
9795 	mpath = rtw_mpp_path_lookup_by_idx(adapter, idx);
9796 	if (!mpath) {
9797 		ret = -ENOENT;
9798 		goto exit;
9799 	}
9800 
9801 	_rtw_memcpy(dst, mpath->dst, ETH_ALEN);
9802 	rtw_cfg80211_mpp_set_pinfo(mpath, mpp, pinfo);
9803 
9804 exit:
9805 	rtw_rcu_read_unlock();
9806 
9807 	return ret;
9808 }
9809 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
9810 
9811 #endif /* defined(CONFIG_RTW_MESH) */
9812 
9813 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
cfg80211_rtw_sched_scan_start(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_sched_scan_request * request)9814 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
9815 		struct net_device *dev,
9816 		struct cfg80211_sched_scan_request *request)
9817 {
9818 
9819 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9820 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
9821 	struct cfg80211_ssid *ssids;
9822 	int n_ssids = 0;
9823 	int interval = 0;
9824 	int i = 0;
9825 	u8 ret;
9826 
9827 	if (padapter->bup == _FALSE) {
9828 		RTW_INFO("%s: net device is down.\n", __func__);
9829 		return -EIO;
9830 	}
9831 
9832 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE ||
9833 		check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE  ||
9834 		check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) {
9835 		RTW_INFO("%s: device is busy.\n", __func__);
9836 		rtw_scan_abort(padapter);
9837 	}
9838 
9839 	if (request == NULL) {
9840 		RTW_INFO("%s: invalid cfg80211_requests parameters.\n", __func__);
9841 		return -EINVAL;
9842 	}
9843 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
9844 
9845 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
9846 	interval = request->scan_plans->interval;
9847 #else
9848 	interval = request->interval;
9849 #endif
9850 	n_ssids = request->n_match_sets;
9851 	ssids = (struct cfg80211_ssid *)rtw_zmalloc(n_ssids * sizeof(struct cfg80211_ssid));
9852 	if(ssids == NULL) {
9853 		RTW_ERR("Fail to allocate ssids for PNO\n");
9854 		return -ENOMEM;
9855 	}
9856 	for (i=0;i<request->n_match_sets;i++) {
9857 			ssids[i].ssid_len = request->match_sets[i].ssid.ssid_len;
9858 			memcpy(ssids[i].ssid, request->match_sets[i].ssid.ssid,
9859 					request->match_sets[i].ssid.ssid_len);
9860 	}
9861 #else
9862 	interval = request->interval;
9863 	n_ssids = request->n_ssids;
9864 	ssids = request->ssids;
9865 #endif
9866 ret = rtw_android_cfg80211_pno_setup(dev, ssids,
9867 			n_ssids, interval);
9868 	if (ret < 0) {
9869 		RTW_INFO("%s ret: %d\n", __func__, ret);
9870 		goto exit;
9871 	}
9872 
9873 	ret = rtw_android_pno_enable(dev, _TRUE);
9874 	if (ret < 0) {
9875 		RTW_INFO("%s ret: %d\n", __func__, ret);
9876 		goto exit;
9877 	}
9878 exit:
9879 	return ret;
9880 }
9881 
cfg80211_rtw_sched_scan_stop(struct wiphy * wiphy,struct net_device * dev,u64 reqid)9882 static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
9883 		struct net_device *dev
9884 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
9885 		, u64 reqid
9886 #endif
9887 )
9888 {
9889 	return rtw_android_pno_enable(dev, _FALSE);
9890 }
9891 
cfg80211_rtw_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wow)9892 int	cfg80211_rtw_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) {
9893 	RTW_DBG("==> %s\n",__func__);
9894 	RTW_DBG("<== %s\n",__func__);
9895 	return 0;
9896 }
9897 
cfg80211_rtw_resume(struct wiphy * wiphy)9898 int	cfg80211_rtw_resume(struct wiphy *wiphy) {
9899 
9900 	_adapter *padapter;
9901 	struct pwrctrl_priv *pwrpriv;
9902 	struct mlme_priv *pmlmepriv;
9903 	struct sitesurvey_parm parm;
9904 	int i, len;
9905 
9906 	padapter = wiphy_to_adapter(wiphy);
9907 	pwrpriv = adapter_to_pwrctl(padapter);
9908 	pmlmepriv = &padapter->mlmepriv;
9909 
9910 	RTW_DBG("==> %s\n",__func__);
9911 	if (pwrpriv->wowlan_last_wake_reason == RX_PNO) {
9912 
9913 		struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
9914 		_irqL irqL;
9915 		int PNOWakeupScanWaitCnt = 0;
9916 
9917 		rtw_cfg80211_disconnected(padapter->rtw_wdev, 0, NULL, 0, 1, GFP_ATOMIC);
9918 
9919 		rtw_init_sitesurvey_parm(padapter, &parm);
9920 		for (i=0;i<pwrpriv->pnlo_info->ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
9921 			len = pwrpriv->pno_ssid_list->node[i].SSID_len;
9922 			_rtw_memcpy(&parm.ssid[i].Ssid, pwrpriv->pno_ssid_list->node[i].SSID, len);
9923 			parm.ssid[i].SsidLength = len;
9924 		}
9925 		parm.ssid_num = pwrpriv->pnlo_info->ssid_num;
9926 
9927 		_enter_critical_bh(&pmlmepriv->lock, &irqL);
9928 		//This modification fix PNO wakeup reconnect issue with hidden SSID AP.
9929 		//rtw_sitesurvey_cmd(padapter, NULL);
9930 		rtw_sitesurvey_cmd(padapter, &parm);
9931 		_exit_critical_bh(&pmlmepriv->lock, &irqL);
9932 
9933 		for (PNOWakeupScanWaitCnt = 0; PNOWakeupScanWaitCnt < 10; PNOWakeupScanWaitCnt++) {
9934 			if(check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _FALSE)
9935 				break;
9936 			rtw_msleep_os(1000);
9937 		}
9938 
9939 		_enter_critical_bh(&pmlmepriv->lock, &irqL);
9940 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
9941 		cfg80211_sched_scan_results(padapter->rtw_wdev->wiphy, 0);
9942 #else
9943 		cfg80211_sched_scan_results(padapter->rtw_wdev->wiphy);
9944 #endif
9945 		_exit_critical_bh(&pmlmepriv->lock, &irqL);
9946 
9947 	}
9948 	RTW_DBG("<== %s\n",__func__);
9949 	return 0;
9950 
9951 }
9952 #endif /* CONFIG_PNO_SUPPORT */
9953 
9954 #ifdef CONFIG_80211N_HT
rtw_cfg80211_init_ht_capab_ex(_adapter * padapter,struct ieee80211_sta_ht_cap * ht_cap,BAND_TYPE band,u8 rf_type)9955 static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter
9956 	, struct ieee80211_sta_ht_cap *ht_cap, BAND_TYPE band, u8 rf_type)
9957 {
9958 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
9959 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
9960 	struct ht_priv		*phtpriv = &pmlmepriv->htpriv;
9961 	u8 stbc_rx_enable = _FALSE;
9962 
9963 	rtw_ht_use_default_setting(padapter);
9964 
9965 	/* RX LDPC */
9966 	if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX))
9967 		ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING;
9968 
9969 	/* TX STBC */
9970 	if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX))
9971 		ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
9972 
9973 	/* RX STBC */
9974 	if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
9975 		/*rtw_rx_stbc 0: disable, bit(0):enable 2.4g, bit(1):enable 5g*/
9976 		if (band == BAND_ON_2_4G)
9977 			stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(0)) ? _TRUE : _FALSE;
9978 		if (band == BAND_ON_5G)
9979 			stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(1)) ? _TRUE : _FALSE;
9980 
9981 		if (stbc_rx_enable) {
9982 			switch (rf_type) {
9983 			case RF_1T1R:
9984 				ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/*RX STBC One spatial stream*/
9985 				break;
9986 
9987 			case RF_2T2R:
9988 			case RF_1T2R:
9989 				ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
9990 				break;
9991 			case RF_3T3R:
9992 			case RF_3T4R:
9993 			case RF_4T4R:
9994 				ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
9995 				break;
9996 			default:
9997 				RTW_INFO("[warning] rf_type %d is not expected\n", rf_type);
9998 				break;
9999 			}
10000 		}
10001 	}
10002 }
10003 
rtw_cfg80211_init_ht_capab(_adapter * padapter,struct ieee80211_sta_ht_cap * ht_cap,BAND_TYPE band,u8 rf_type)10004 static void rtw_cfg80211_init_ht_capab(_adapter *padapter
10005 	, struct ieee80211_sta_ht_cap *ht_cap, BAND_TYPE band, u8 rf_type)
10006 {
10007 	struct registry_priv *regsty = &padapter->registrypriv;
10008 	u8 rx_nss = 0;
10009 
10010 	if (!regsty->ht_enable || !is_supported_ht(regsty->wireless_mode))
10011 		return;
10012 
10013 	ht_cap->ht_supported = 1;
10014 
10015 	ht_cap->cap = IEEE80211_HT_CAP_MAX_AMSDU;
10016 
10017 	if (TEST_FLAG(regsty->short_gi, BIT0))
10018 		ht_cap->cap |= IEEE80211_HT_CAP_SGI_20;
10019 	if (hal_is_bw_support(padapter, CHANNEL_WIDTH_40)
10020 		&& ((band == BAND_ON_2_4G && REGSTY_IS_BW_2G_SUPPORT(regsty, CHANNEL_WIDTH_40))
10021 			|| (band == BAND_ON_5G && REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)))
10022 	) {
10023 		ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
10024 		if (band == BAND_ON_2_4G)
10025 			ht_cap->cap |= IEEE80211_HT_CAP_DSSSCCK40;
10026 		if (TEST_FLAG(regsty->short_gi, BIT1))
10027 			ht_cap->cap |= IEEE80211_HT_CAP_SGI_40;
10028 	}
10029 
10030 	rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type);
10031 
10032 	/*
10033 	 *Maximum length of AMPDU that the STA can receive.
10034 	 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
10035 	 */
10036 	ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
10037 
10038 	/*Minimum MPDU start spacing , */
10039 	ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
10040 
10041 	ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
10042 
10043 	rx_nss = GET_HAL_RX_NSS(padapter);
10044 	switch (rx_nss) {
10045 	case 1:
10046 		ht_cap->mcs.rx_mask[0] = 0xFF;
10047 		break;
10048 	case 2:
10049 		ht_cap->mcs.rx_mask[0] = 0xFF;
10050 		ht_cap->mcs.rx_mask[1] = 0xFF;
10051 		break;
10052 	case 3:
10053 		ht_cap->mcs.rx_mask[0] = 0xFF;
10054 		ht_cap->mcs.rx_mask[1] = 0xFF;
10055 		ht_cap->mcs.rx_mask[2] = 0xFF;
10056 		break;
10057 	case 4:
10058 		ht_cap->mcs.rx_mask[0] = 0xFF;
10059 		ht_cap->mcs.rx_mask[1] = 0xFF;
10060 		ht_cap->mcs.rx_mask[2] = 0xFF;
10061 		ht_cap->mcs.rx_mask[3] = 0xFF;
10062 		break;
10063 	default:
10064 		rtw_warn_on(1);
10065 		RTW_INFO("%s, error rf_type=%d, rx_nss=%d\n", __func__, rf_type, rx_nss);
10066 	};
10067 
10068 	ht_cap->mcs.rx_highest = cpu_to_le16(
10069 		rtw_ht_mcs_rate(hal_is_bw_support(padapter, CHANNEL_WIDTH_40)
10070 			, hal_is_bw_support(padapter, CHANNEL_WIDTH_40) ? ht_cap->cap & IEEE80211_HT_CAP_SGI_40 : ht_cap->cap & IEEE80211_HT_CAP_SGI_20
10071 			, ht_cap->mcs.rx_mask) / 10);
10072 }
10073 #endif /* CONFIG_80211N_HT */
10074 
10075 #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
rtw_cfg80211_init_vht_capab(_adapter * padapter,struct ieee80211_sta_vht_cap * sta_vht_cap,BAND_TYPE band,u8 rf_type)10076 static void rtw_cfg80211_init_vht_capab(_adapter *padapter
10077 	, struct ieee80211_sta_vht_cap *sta_vht_cap, BAND_TYPE band, u8 rf_type)
10078 {
10079 	struct registry_priv *regsty = &padapter->registrypriv;
10080 	u8 vht_cap_ie[2 + 12] = {0};
10081 
10082 	if (!REGSTY_IS_11AC_ENABLE(regsty) || !is_supported_vht(regsty->wireless_mode))
10083 		return;
10084 
10085 	rtw_vht_use_default_setting(padapter);
10086 	rtw_build_vht_cap_ie(padapter, vht_cap_ie);
10087 
10088 	sta_vht_cap->vht_supported = 1;
10089 
10090 	_rtw_memcpy(&sta_vht_cap->cap, vht_cap_ie + 2, 4);
10091 	_rtw_memcpy(&sta_vht_cap->vht_mcs, vht_cap_ie + 2 + 4, 8);
10092 }
10093 #endif /* defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
10094 
rtw_cfg80211_init_wdev_data(_adapter * padapter)10095 void rtw_cfg80211_init_wdev_data(_adapter *padapter)
10096 {
10097 #ifdef CONFIG_CONCURRENT_MODE
10098 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
10099 
10100 	ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
10101 #endif
10102 }
10103 
rtw_cfg80211_init_wiphy_band(_adapter * padapter,struct wiphy * wiphy)10104 static int rtw_cfg80211_init_wiphy_band(_adapter *padapter, struct wiphy *wiphy)
10105 {
10106 	u8 rf_type;
10107 	struct ieee80211_supported_band *band;
10108 	int ret = _FAIL;
10109 
10110 	rf_type = GET_HAL_RFPATH(padapter);
10111 	RTW_INFO("%s:rf_type=%d\n", __func__, rf_type);
10112 
10113 	if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
10114 		band = wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(BAND_ON_2_4G);
10115 		if (!band)
10116 			goto exit;
10117 		rtw_2g_channels_init(band->channels);
10118 		rtw_2g_rates_init(band->bitrates);
10119 		#if defined(CONFIG_80211N_HT)
10120 		rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_2_4G, rf_type);
10121 		#endif
10122 	}
10123 #if CONFIG_IEEE80211_BAND_5GHZ
10124 	if (is_supported_5g(padapter->registrypriv.wireless_mode)) {
10125 		band = wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(BAND_ON_5G);
10126 		if (!band) {
10127 			if (wiphy->bands[NL80211_BAND_2GHZ]) {
10128 				rtw_spt_band_free(wiphy->bands[NL80211_BAND_2GHZ]);
10129 				wiphy->bands[NL80211_BAND_2GHZ] = NULL;
10130 			}
10131 			goto exit;
10132 		}
10133 		rtw_5g_channels_init(band->channels);
10134 		rtw_5g_rates_init(band->bitrates);
10135 		#if defined(CONFIG_80211N_HT)
10136 		rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_5G, rf_type);
10137 		#endif
10138 		#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
10139 		rtw_cfg80211_init_vht_capab(padapter, &band->vht_cap, BAND_ON_5G, rf_type);
10140 		#endif
10141 	}
10142 #endif
10143 
10144 	ret = _SUCCESS;
10145 
10146 exit:
10147 	return ret;
10148 }
10149 
10150 #if !defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
rtw_cfg80211_update_wiphy_max_txpower(_adapter * adapter,struct wiphy * wiphy)10151 void rtw_cfg80211_update_wiphy_max_txpower(_adapter *adapter, struct wiphy *wiphy)
10152 {
10153 	struct ieee80211_supported_band *band;
10154 	struct ieee80211_channel *channel;
10155 	s16 max_txpwr;
10156 	int i;
10157 
10158 	if (IsSupported24G(adapter->registrypriv.wireless_mode)) {
10159 		band = wiphy->bands[NL80211_BAND_2GHZ];
10160 		if (band) {
10161 			max_txpwr = phy_get_txpwr_by_rate_total_max_mbm(adapter, BAND_ON_2_4G, 1, 1);
10162 			if (max_txpwr != UNSPECIFIED_MBM) {
10163 				for (i = 0; i < band->n_channels; i++) {
10164 					channel = &band->channels[i];
10165 					channel->max_power = max_txpwr / MBM_PDBM;
10166 				}
10167 			}
10168 		}
10169 	}
10170 #if CONFIG_IEEE80211_BAND_5GHZ
10171 	if (is_supported_5g(adapter->registrypriv.wireless_mode)) {
10172 		band = wiphy->bands[NL80211_BAND_5GHZ];
10173 		if (band) {
10174 			max_txpwr = phy_get_txpwr_by_rate_total_max_mbm(adapter, BAND_ON_5G, 1, 1);
10175 			if (max_txpwr != UNSPECIFIED_MBM) {
10176 				for (i = 0; i < band->n_channels; i++) {
10177 					channel = &band->channels[i];
10178 					channel->max_power = max_txpwr / MBM_PDBM;
10179 				}
10180 			}
10181 		}
10182 	}
10183 #endif
10184 }
10185 #endif /* defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) */
10186 
10187 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && defined(RTW_SINGLE_WIPHY) && (CONFIG_IFACE_NUMBER >= 2)
10188 struct ieee80211_iface_limit rtw_limits[] = {
10189 	{
10190 		.max = CONFIG_IFACE_NUMBER,
10191 		.types = BIT(NL80211_IFTYPE_STATION)
10192 			#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
10193 			| BIT(NL80211_IFTYPE_P2P_CLIENT)
10194 			#endif
10195 	},
10196 	#ifdef CONFIG_AP_MODE
10197 	{
10198 		.max = rtw_min(CONFIG_IFACE_NUMBER, CONFIG_LIMITED_AP_NUM),
10199 		.types = BIT(NL80211_IFTYPE_AP)
10200 			#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
10201 			| BIT(NL80211_IFTYPE_P2P_GO)
10202 			#endif
10203 	},
10204 	#endif
10205 	#if defined(RTW_DEDICATED_P2P_DEVICE)
10206 	{
10207 		.max = 1,
10208 		.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
10209 	},
10210 	#endif
10211 	#if defined(CONFIG_RTW_MESH)
10212 	{
10213 		.max = 1,
10214 		.types = BIT(NL80211_IFTYPE_MESH_POINT)
10215 	},
10216 	#endif
10217 };
10218 
10219 struct ieee80211_iface_combination rtw_combinations[] = {
10220 	{
10221 		.limits = rtw_limits,
10222 		.n_limits = ARRAY_SIZE(rtw_limits),
10223 		#if defined(RTW_DEDICATED_P2P_DEVICE)
10224 		.max_interfaces = CONFIG_IFACE_NUMBER + 1,
10225 		#else
10226 		.max_interfaces = CONFIG_IFACE_NUMBER,
10227 		#endif
10228 		.num_different_channels = 1,
10229 	},
10230 };
10231 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */
10232 
rtw_cfg80211_init_wiphy(_adapter * adapter,struct wiphy * wiphy)10233 static int rtw_cfg80211_init_wiphy(_adapter *adapter, struct wiphy *wiphy)
10234 {
10235 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10236 	struct registry_priv *regsty = dvobj_to_regsty(dvobj);
10237 	int ret = _FAIL;
10238 
10239 	/* copy mac_addr to wiphy */
10240 	_rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(adapter), ETH_ALEN);
10241 
10242 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
10243 
10244 	wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
10245 	wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
10246 	wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
10247 
10248 #if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
10249 	wiphy->max_acl_mac_addrs = NUM_ACL;
10250 #endif
10251 
10252 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
10253 	wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
10254 #endif
10255 
10256 	wiphy->interface_modes =	BIT(NL80211_IFTYPE_STATION)
10257 								#ifdef CONFIG_AP_MODE
10258 								| BIT(NL80211_IFTYPE_ADHOC) /* todo : AD-HOC task group will refine it */
10259 								| BIT(NL80211_IFTYPE_AP)
10260 								#endif
10261 								#ifdef CONFIG_WIFI_MONITOR
10262 								| BIT(NL80211_IFTYPE_MONITOR)
10263 								#endif
10264 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
10265 								| BIT(NL80211_IFTYPE_P2P_CLIENT)
10266 								| BIT(NL80211_IFTYPE_P2P_GO)
10267 								#if defined(RTW_DEDICATED_P2P_DEVICE)
10268 								| BIT(NL80211_IFTYPE_P2P_DEVICE)
10269 								#endif
10270 #endif
10271 #ifdef CONFIG_RTW_MESH
10272 								| BIT(NL80211_IFTYPE_MESH_POINT) /* 2.6.26 */
10273 #endif
10274 								;
10275 
10276 #if !defined(RTW_SINGLE_WIPHY) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P)
10277 	if (adapter->iface_id != adapter->registrypriv.sel_p2p_iface) {
10278 		wiphy->interface_modes &= ~(BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT));
10279 		RTW_INFO("%s iface_id:%d- don't set p2p capability\n", __func__, adapter->iface_id);
10280 	}
10281 #endif
10282 
10283 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
10284 	wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
10285 #endif
10286 
10287 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
10288 	#ifdef CONFIG_WIFI_MONITOR
10289 	wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
10290 	#endif
10291 #endif
10292 
10293 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && defined(RTW_SINGLE_WIPHY) && (CONFIG_IFACE_NUMBER >= 2)
10294 	wiphy->iface_combinations = rtw_combinations;
10295 	wiphy->n_iface_combinations = ARRAY_SIZE(rtw_combinations);
10296 #endif
10297 
10298 	wiphy->cipher_suites = rtw_cipher_suites;
10299 
10300 	/* Todo refine */
10301 	if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_EXTRA_SEC))
10302 		wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
10303 	else {
10304 #ifdef CONFIG_IEEE80211W
10305 		/* remove hardware not support cipher */
10306 		wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites) - 6;
10307 #else
10308 		wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
10309 #endif
10310 	}
10311 
10312 	if (rtw_cfg80211_init_wiphy_band(adapter, wiphy) != _SUCCESS) {
10313 		RTW_ERR("rtw_cfg80211_init_wiphy_band fail\n");
10314 		goto exit;
10315 	}
10316 	#if !defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
10317 	rtw_cfg80211_update_wiphy_max_txpower(adapter, wiphy);
10318 	#endif
10319 
10320 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0))
10321 	wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
10322 #endif
10323 
10324 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
10325 	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
10326 	wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
10327 	/* remove WIPHY_FLAG_OFFCHAN_TX, because we not support this feature */
10328 	/* wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; */
10329 #endif
10330 
10331 #if (KERNEL_VERSION(3, 2, 0) <= LINUX_VERSION_CODE)
10332 	wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
10333 #endif
10334 
10335 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
10336 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
10337  	wiphy->max_sched_scan_reqs = 1;
10338 #else
10339   	wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
10340 #endif
10341 #ifdef CONFIG_PNO_SUPPORT
10342 	wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
10343 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
10344 	wiphy->max_match_sets = MAX_PNO_LIST_COUNT;
10345 #endif
10346 #endif
10347 #endif
10348 
10349 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
10350 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0))
10351 	wiphy->wowlan = wowlan_stub;
10352 #else
10353 	wiphy->wowlan = &wowlan_stub;
10354 #endif
10355 #endif
10356 
10357 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
10358 	wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
10359 #ifndef CONFIG_TDLS_DRIVER_SETUP
10360 	wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;	/* Driver handles key exchange */
10361 	wiphy->flags |= NL80211_ATTR_HT_CAPABILITY;
10362 #endif /* CONFIG_TDLS_DRIVER_SETUP */
10363 #endif /* CONFIG_TDLS */
10364 
10365 #ifdef CONFIG_LPS
10366 		wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
10367 #else
10368 		wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
10369 #endif
10370 
10371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
10372 	/* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */
10373 #endif
10374 
10375 #ifdef CONFIG_RTW_WDS
10376 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
10377 	wiphy->flags |= WIPHY_FLAG_4ADDR_AP;
10378 	wiphy->flags |= WIPHY_FLAG_4ADDR_STATION;
10379 	#endif
10380 #endif
10381 
10382 #ifdef CONFIG_RTW_MESH
10383 	wiphy->flags |= 0
10384 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
10385 		| WIPHY_FLAG_IBSS_RSN
10386 		#endif
10387 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
10388 		| WIPHY_FLAG_MESH_AUTH
10389 		#endif
10390 		;
10391 
10392 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
10393 	wiphy->features |= 0
10394 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
10395 		| NL80211_FEATURE_USERSPACE_MPM
10396 		#endif
10397 		;
10398 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */
10399 #endif /* CONFIG_RTW_MESH */
10400 
10401 #if defined(CONFIG_RTW_80211K) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
10402 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM);
10403 #endif
10404 
10405 #if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
10406 	wiphy->features |= NL80211_FEATURE_SAE;
10407 #endif
10408 
10409 #ifdef CONFIG_RTW_SCAN_RAND
10410 	#if (KERNEL_VERSION(3, 19, 0) <= LINUX_VERSION_CODE)
10411 	wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
10412 	#endif
10413 #endif
10414 
10415 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
10416 #ifdef CONFIG_WIFI_MONITOR
10417 	/* Currently only for Monitor debugging */
10418 	wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
10419 #endif
10420 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */
10421 
10422 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
10423 	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
10424 #endif
10425 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
10426 	wiphy->max_num_csa_counters = MAX_CSA_CNT;
10427 #endif
10428 
10429 	ret = _SUCCESS;
10430 
10431 exit:
10432 	return ret;
10433 }
10434 
10435 #ifdef CONFIG_RFKILL_POLL
rtw_cfg80211_init_rfkill(struct wiphy * wiphy)10436 void rtw_cfg80211_init_rfkill(struct wiphy *wiphy)
10437 {
10438 	wiphy_rfkill_set_hw_state(wiphy, 0);
10439 	wiphy_rfkill_start_polling(wiphy);
10440 }
10441 
rtw_cfg80211_deinit_rfkill(struct wiphy * wiphy)10442 void rtw_cfg80211_deinit_rfkill(struct wiphy *wiphy)
10443 {
10444 	wiphy_rfkill_stop_polling(wiphy);
10445 }
10446 
cfg80211_rtw_rfkill_poll(struct wiphy * wiphy)10447 static void cfg80211_rtw_rfkill_poll(struct wiphy *wiphy)
10448 {
10449 	_adapter *padapter = NULL;
10450 	bool blocked = _FALSE;
10451 	u8 valid = 0;
10452 
10453 	padapter = wiphy_to_adapter(wiphy);
10454 
10455 	if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
10456 		/*RTW_INFO("cfg80211_rtw_rfkill_poll: device is removed!\n");*/
10457 		return;
10458 	}
10459 
10460 	blocked = rtw_hal_rfkill_poll(padapter, &valid);
10461 	/*RTW_INFO("cfg80211_rtw_rfkill_poll: valid=%d, blocked=%d\n",
10462 			valid, blocked);*/
10463 
10464 	if (valid)
10465 		wiphy_rfkill_set_hw_state(wiphy, blocked);
10466 }
10467 #endif
10468 
10469 #if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
10470 
10471 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
10472 #define SURVEY_INFO_TIME			SURVEY_INFO_CHANNEL_TIME
10473 #define SURVEY_INFO_TIME_BUSY		SURVEY_INFO_CHANNEL_TIME_BUSY
10474 #define SURVEY_INFO_TIME_EXT_BUSY	SURVEY_INFO_CHANNEL_TIME_EXT_BUSY
10475 #define SURVEY_INFO_TIME_RX			SURVEY_INFO_CHANNEL_TIME_RX
10476 #define SURVEY_INFO_TIME_TX			SURVEY_INFO_CHANNEL_TIME_TX
10477 #endif
10478 
10479 #ifdef CONFIG_RTW_ACS
rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter,int idx,struct survey_info * pinfo)10480 static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, struct survey_info *pinfo)
10481 {
10482 	s8 noise = -50;			/*channel noise in dBm. This and all following fields are optional */
10483 	u64 time = SURVEY_TO;	/*amount of time in ms the radio was turn on (on the channel)*/
10484 	u64 time_busy = 0;		/*amount of time the primary channel was sensed busy*/
10485 	u8 chan = (u8)idx;
10486 
10487 	if ((idx < 0) || (pinfo == NULL))
10488 		return;
10489 
10490 	pinfo->filled  = SURVEY_INFO_NOISE_DBM
10491 		#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
10492 		| SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY
10493 		#endif
10494 		;
10495 
10496 	time_busy = rtw_acs_get_clm_ratio_by_ch_idx(padapter, chan);
10497 	noise = rtw_acs_get_nhm_noise_pwr_by_ch_idx(padapter, chan);
10498 	/* RTW_INFO("%s: ch-idx:%d time=%llu(ms), time_busy=%llu(ms), noise=%d(dbm)\n", __func__, idx, time, time_busy, noise); */
10499 
10500 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
10501 	#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
10502 	pinfo->channel_time = time;
10503 	pinfo->channel_time_busy = time_busy;
10504 	#else
10505 	pinfo->time = time;
10506 	pinfo->time_busy = time_busy;
10507 	#endif
10508 #endif
10509 	pinfo->noise = noise;
10510 }
10511 #endif /* CONFIG_RTW_ACS */
10512 
rtw_hostapd_acs_dump_survey(struct wiphy * wiphy,struct net_device * netdev,int idx,struct survey_info * info)10513 static int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, int idx, struct survey_info *info)
10514 {
10515 	PADAPTER padapter = (_adapter *)rtw_netdev_priv(netdev);
10516 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
10517 	RT_CHANNEL_INFO *pch_set = rfctl->channel_set;
10518 	u8 max_chan_nums = rfctl->max_chan_nums;
10519 	u32 freq = 0;
10520 	u8 ret = 0;
10521 	u16 channel = 0;
10522 
10523 	if (!netdev || !info) {
10524 		RTW_INFO("%s: invial parameters.\n", __func__);
10525 		return -EINVAL;
10526 	}
10527 
10528 	_rtw_memset(info, 0, sizeof(struct survey_info));
10529 	if (padapter->bup == _FALSE) {
10530 		RTW_INFO("%s: net device is down.\n", __func__);
10531 		return -EIO;
10532 	}
10533 
10534 	if (idx >= max_chan_nums)
10535 		return -ENOENT;
10536 
10537 	channel = pch_set[idx].ChannelNum;
10538 	freq = rtw_ch2freq(channel);
10539 	info->channel = ieee80211_get_channel(wiphy, freq);
10540 	/* RTW_INFO("%s: channel %d, freq %d\n", __func__, channel, freq); */
10541 
10542 	if (!info->channel)
10543 		return -EINVAL;
10544 
10545 	if (info->channel->flags == IEEE80211_CHAN_DISABLED)
10546 		return ret;
10547 
10548 #ifdef CONFIG_RTW_ACS
10549 	rtw_cfg80211_set_survey_info_with_clm(padapter, idx, info);
10550 #else
10551 	RTW_ERR("%s: unknown acs operation!\n", __func__);
10552 #endif
10553 
10554 	return ret;
10555 }
10556 #endif /* defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */
10557 
10558 #if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \
10559     || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH)
cfg80211_rtw_external_auth(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_external_auth_params * params)10560 int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev,
10561 	struct cfg80211_external_auth_params *params)
10562 {
10563 	PADAPTER padapter = (_adapter *)rtw_netdev_priv(dev);
10564 
10565 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(dev));
10566 
10567 	rtw_cfg80211_external_auth_status(wiphy, dev,
10568 		(struct rtw_external_auth_params *)params);
10569 
10570 	return 0;
10571 }
10572 #endif
10573 
rtw_cfg80211_external_auth_status(struct wiphy * wiphy,struct net_device * dev,struct rtw_external_auth_params * params)10574 void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *dev,
10575 	struct rtw_external_auth_params *params)
10576 {
10577 	PADAPTER padapter = (_adapter *)rtw_netdev_priv(dev);
10578 	struct security_priv *psecuritypriv = &padapter->securitypriv;
10579 	struct sta_priv *pstapriv = &padapter->stapriv;
10580 	struct sta_info	*psta = NULL;
10581 	u8 *buf = NULL;
10582 	u32 len = 0;
10583 	_irqL irqL;
10584 
10585 	RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(dev));
10586 
10587 	RTW_INFO("SAE: action: %u, status: %u\n", params->action, params->status);
10588 	if (params->status == WLAN_STATUS_SUCCESS) {
10589 		RTW_INFO("bssid: "MAC_FMT"\n", MAC_ARG(params->bssid));
10590 		RTW_INFO("SSID: [%s]\n",
10591 			((params->ssid.ssid_len == 0) ? "" : (char *)params->ssid.ssid));
10592 		RTW_INFO("suite: 0x%08x\n", params->key_mgmt_suite);
10593 	}
10594 
10595 	psta = rtw_get_stainfo(pstapriv, params->bssid);
10596 	if (psta && (params->status == WLAN_STATUS_SUCCESS)) {
10597 #ifdef CONFIG_AP_MODE
10598 		/* AP mode */
10599 		RTW_INFO("station match\n");
10600 
10601 		psta->state &= ~WIFI_FW_AUTH_NULL;
10602 		psta->state |= WIFI_FW_AUTH_SUCCESS;
10603 		psta->expire_to = padapter->stapriv.assoc_to;
10604 
10605 		/* ToDo: Kernel v5.1 pmkid is pointer */
10606 		/* RTW_INFO_DUMP("PMKID:", params->pmkid, PMKID_LEN); */
10607 		_rtw_set_pmksa(dev, params->bssid, params->pmkid);
10608 
10609 		_enter_critical_bh(&psta->lock, &irqL);
10610 		if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) {
10611 			buf =  rtw_zmalloc(psta->auth_len);
10612 			if (buf) {
10613 				_rtw_memcpy(buf, psta->pauth_frame, psta->auth_len);
10614 				len = psta->auth_len;
10615 			}
10616 
10617 			rtw_mfree(psta->pauth_frame, psta->auth_len);
10618 			psta->pauth_frame = NULL;
10619 			psta->auth_len = 0;
10620 		}
10621 		_exit_critical_bh(&psta->lock, &irqL);
10622 
10623 		if (buf) {
10624 			struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10625 			/* send the SAE auth Confirm */
10626 
10627 			rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
10628 			if (_SUCCESS == rtw_pwr_wakeup(padapter)) {
10629 				rtw_mi_set_scan_deny(padapter, 1000);
10630 				rtw_mi_scan_abort(padapter, _TRUE);
10631 
10632 				RTW_INFO("SAE: Tx auth Confirm\n");
10633 				rtw_mgnt_tx_cmd(padapter, pmlmeext->cur_channel, 1, buf, len, 0, RTW_CMDF_DIRECTLY);
10634 
10635 			}
10636 			rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
10637 
10638 			rtw_mfree(buf, len);
10639 			buf = NULL;
10640 			len = 0;
10641 		}
10642 #endif
10643 	} else if (psta && (params->status == WLAN_STATUS_UNSPECIFIED_FAILURE)) {
10644 #ifdef CONFIG_AP_MODE
10645 		rtw_cfg80211_indicate_sta_disassoc(padapter, psta->cmn.mac_addr, WLAN_STATUS_UNSPECIFIED_FAILURE);
10646 #endif
10647 	} else {
10648 		/* STA mode */
10649 		psecuritypriv->extauth_status = params->status;
10650 	}
10651 }
10652 
10653 #ifdef CONFIG_AP_MODE
check_channel(_adapter * padapter,u8 ch,u8 bw,u8 offset)10654 static int check_channel(_adapter* padapter,u8 ch, u8 bw, u8 offset) {
10655 	int ret = _SUCCESS;
10656 	u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(padapter);
10657 	u8 u_ch, u_bw, u_offset;
10658 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
10659 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
10660 	struct	mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10661 
10662 	u_ch = rtw_mi_get_union_chan(padapter);
10663 	u_bw = rtw_mi_get_union_bw(padapter);
10664 	u_offset = rtw_mi_get_union_offset(padapter);
10665 
10666 	if (rtw_chset_search_ch(rfctl->channel_set, ch) < 0
10667 		|| rtw_chset_is_ch_non_ocp(rfctl->channel_set, ch)) {
10668 		ret = _FAIL;
10669 		RTW_INFO("ch not legal %d,%d,%d\n", ch, bw, offset);
10670 	} else if(pmlmeext->cur_channel == ch && pmlmeext->cur_bwmode == bw && pmlmeext->cur_ch_offset == offset) {
10671 		/* channel, bandwidth, offset doesn't change */
10672 		ret = _FAIL;
10673 		RTW_INFO("ch same, skip switching %d,%d,%d ==> %d,%d,%d  (union:%d,%d,%d)\n",
10674 		 pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, ch, bw, offset, u_ch, u_bw, u_offset);
10675 	} else if((u_ch != ch || (offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE && u_offset != offset)) && ifbmp_s) {
10676 		ret = _FAIL;
10677 		RTW_INFO("must follow STA's ch, %d,%d,%d ==> %d,%d,%d  (union:%d,%d,%d)\n",
10678 		 pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, ch, bw, offset, u_ch, u_bw, u_offset);
10679 	} else {
10680 		RTW_INFO("channel switch.%d,%d,%d ==> %d,%d,%d  (union:%d,%d,%d)\n",
10681 		 pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, ch, bw, offset, u_ch, u_bw, u_offset);
10682 	}
10683 	return ret;
10684 }
10685 
10686 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
cfg80211_rtw_channel_switch(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_csa_settings * params)10687 static int cfg80211_rtw_channel_switch(struct wiphy *wiphy,
10688 				struct net_device *dev,
10689 				struct cfg80211_csa_settings *params)
10690 {
10691 	_adapter *padapter = NULL;
10692 	struct dvobj_priv *dvobj = NULL;
10693 	PNDIS_802_11_VARIABLE_IEs	pIE;
10694 	u8 *ies;
10695 	u8 mode = 0, count = 0, bw = CHANNEL_WIDTH_20, ch = 0, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE, ht = 0, vht = 0, ifbmp = 0, enable = 1;
10696 	u32 i, ies_len;
10697 	struct rf_ctl_t *rfctl;
10698 
10699 	padapter = (_adapter *)rtw_netdev_priv(dev);
10700 	dvobj = adapter_to_dvobj(padapter);
10701 	rfctl = dvobj_to_rfctl(dvobj);
10702 
10703 	ifbmp = rtw_mi_get_ap_mesh_ifbmp(padapter);
10704 
10705 	if(params && params->chandef.chan) {
10706 
10707 		rtw_get_chbw_from_cfg80211_chan_def(&params->chandef, &ht, &ch, &bw, &offset);
10708 
10709 		if (check_channel(padapter, ch, bw, offset) == _FAIL)
10710 			return -EINVAL;
10711 
10712 		if (!ch) {
10713 			RTW_INFO(" => ch:%u invalid\n", ch);
10714 			return -EINVAL;
10715 		}
10716 
10717 		/* return error code when switch process is running */
10718 		if(rfctl->ap_csa_en == AP_SWITCH_CH_CSA || rfctl->ap_csa_en == STA_RX_CSA
10719 			|| rfctl->ap_csa_en == CSA_STA_JOINBSS)
10720 			return -EINVAL;
10721 
10722 		/* todo, disable vht or something */
10723 		vht = ht && ch > 14 && bw >= CHANNEL_WIDTH_80;
10724 		RTW_INFO(" => ch:%u,%u,%u, ht:%u, vht:%u\n", ch, bw, offset, ht, vht);
10725 
10726 		if(params->beacon_csa.tail) {
10727 			/* dump_ies(RTW_DBGDUMP, (char *) params->beacon_csa.tail, params->beacon_csa.tail_len); */
10728 			ies = (u8 *)params->beacon_csa.tail;
10729 			ies_len = params->beacon_csa.tail_len;
10730 			for (i = 0; i + 1 < ies_len;) {
10731 				pIE = (PNDIS_802_11_VARIABLE_IEs)(ies + i);
10732 
10733 				switch (pIE->ElementID) {
10734 				case WLAN_EID_CHANNEL_SWITCH:
10735 					mode = *(pIE->data);
10736 					ch = *(pIE->data + 1);
10737 					count = *(pIE->data + 2);
10738 					RTW_INFO("CSA IE, mode=%d, ch=%d, count=%d\n", mode, ch, count);
10739 					break;
10740 				default:
10741 					break;
10742 				}
10743 				i += (pIE->Length + 2);
10744 			}
10745 
10746 			if (count == 0) {
10747 				RTW_INFO("CSA count should not be 0\n");
10748 				return -EINVAL;
10749 			}
10750 
10751 			if (ifbmp && count > 0) {
10752 				rfctl->ap_csa_en = AP_SWITCH_CH_CSA;
10753 				rfctl->ap_csa_ch = ch;
10754 				rfctl->ap_csa_switch_cnt = count;
10755 				rfctl->ap_csa_ch_offset = offset;
10756 				rfctl->ap_csa_ch_width = bw;
10757 				rtw_set_ap_csa_cmd(padapter);
10758 			}
10759 		}
10760 	}
10761 
10762 	return 0;
10763 }
10764 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) */
10765 #endif /* CONFIG_AP_MODE */
10766 
10767 static struct cfg80211_ops rtw_cfg80211_ops = {
10768 	.change_virtual_intf = cfg80211_rtw_change_iface,
10769 	.add_key = cfg80211_rtw_add_key,
10770 	.get_key = cfg80211_rtw_get_key,
10771 	.del_key = cfg80211_rtw_del_key,
10772 	.set_default_key = cfg80211_rtw_set_default_key,
10773 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
10774 	.set_default_mgmt_key = cfg80211_rtw_set_default_mgmt_key,
10775 #endif
10776 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
10777 	.set_rekey_data = cfg80211_rtw_set_rekey_data,
10778 #endif /*CONFIG_GTK_OL*/
10779 	.get_station = cfg80211_rtw_get_station,
10780 	.scan = cfg80211_rtw_scan,
10781 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
10782 	.abort_scan = cfg80211_rtw_abort_scan,
10783 #endif
10784 	.set_wiphy_params = cfg80211_rtw_set_wiphy_params,
10785 	.connect = cfg80211_rtw_connect,
10786 	.disconnect = cfg80211_rtw_disconnect,
10787 	.join_ibss = cfg80211_rtw_join_ibss,
10788 	.leave_ibss = cfg80211_rtw_leave_ibss,
10789 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
10790 	.set_tx_power = cfg80211_rtw_set_txpower,
10791 	.get_tx_power = cfg80211_rtw_get_txpower,
10792 #endif
10793 	.set_power_mgmt = cfg80211_rtw_set_power_mgmt,
10794 	.set_pmksa = cfg80211_rtw_set_pmksa,
10795 	.del_pmksa = cfg80211_rtw_del_pmksa,
10796 	.flush_pmksa = cfg80211_rtw_flush_pmksa,
10797 
10798 	.add_virtual_intf = cfg80211_rtw_add_virtual_intf,
10799 	.del_virtual_intf = cfg80211_rtw_del_virtual_intf,
10800 
10801 #ifdef CONFIG_AP_MODE
10802 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
10803 	.add_beacon = cfg80211_rtw_add_beacon,
10804 	.set_beacon = cfg80211_rtw_set_beacon,
10805 	.del_beacon = cfg80211_rtw_del_beacon,
10806 #else
10807 	.start_ap = cfg80211_rtw_start_ap,
10808 	.change_beacon = cfg80211_rtw_change_beacon,
10809 	.stop_ap = cfg80211_rtw_stop_ap,
10810 #endif
10811 
10812 #if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
10813 	.set_mac_acl = cfg80211_rtw_set_mac_acl,
10814 #endif
10815 
10816 	.add_station = cfg80211_rtw_add_station,
10817 	.del_station = cfg80211_rtw_del_station,
10818 	.change_station = cfg80211_rtw_change_station,
10819 	.dump_station = cfg80211_rtw_dump_station,
10820 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
10821 	.change_bss = cfg80211_rtw_change_bss,
10822 #endif
10823 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
10824 	.set_txq_params = cfg80211_rtw_set_txq_params,
10825 #endif
10826 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
10827 	.set_channel = cfg80211_rtw_set_channel,
10828 #endif
10829 	/* .auth = cfg80211_rtw_auth, */
10830 	/* .assoc = cfg80211_rtw_assoc,	 */
10831 #endif /* CONFIG_AP_MODE */
10832 
10833 #if defined(CONFIG_RTW_MESH) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
10834 	.get_mesh_config = cfg80211_rtw_get_mesh_config,
10835 	.update_mesh_config = cfg80211_rtw_update_mesh_config,
10836 	.join_mesh = cfg80211_rtw_join_mesh,
10837 	.leave_mesh = cfg80211_rtw_leave_mesh,
10838 	.add_mpath = cfg80211_rtw_add_mpath,
10839 	.del_mpath = cfg80211_rtw_del_mpath,
10840 	.change_mpath = cfg80211_rtw_change_mpath,
10841 	.get_mpath = cfg80211_rtw_get_mpath,
10842 	.dump_mpath = cfg80211_rtw_dump_mpath,
10843 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
10844 	.get_mpp = cfg80211_rtw_get_mpp,
10845 	.dump_mpp = cfg80211_rtw_dump_mpp,
10846 	#endif
10847 #endif
10848 
10849 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
10850 	.set_monitor_channel = cfg80211_rtw_set_monitor_channel,
10851 #endif
10852 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
10853 	.get_channel = cfg80211_rtw_get_channel,
10854 #endif
10855 
10856 	.remain_on_channel = cfg80211_rtw_remain_on_channel,
10857 	.cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
10858 
10859 #if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
10860 	.start_p2p_device = cfg80211_rtw_start_p2p_device,
10861 	.stop_p2p_device = cfg80211_rtw_stop_p2p_device,
10862 #endif
10863 
10864 #ifdef CONFIG_RTW_80211R
10865 	.update_ft_ies = cfg80211_rtw_update_ft_ies,
10866 #endif
10867 
10868 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
10869 	.mgmt_tx = cfg80211_rtw_mgmt_tx,
10870 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0))
10871 	.mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
10872 #else
10873 	.update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_register,
10874 #endif
10875 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
10876 	.action = cfg80211_rtw_mgmt_tx,
10877 #endif
10878 
10879 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
10880 	.tdls_mgmt = cfg80211_rtw_tdls_mgmt,
10881 	.tdls_oper = cfg80211_rtw_tdls_oper,
10882 #endif /* CONFIG_TDLS */
10883 
10884 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
10885 	.sched_scan_start = cfg80211_rtw_sched_scan_start,
10886 	.sched_scan_stop = cfg80211_rtw_sched_scan_stop,
10887 	.suspend = cfg80211_rtw_suspend,
10888 	.resume = cfg80211_rtw_resume,
10889 #endif /* CONFIG_PNO_SUPPORT */
10890 #ifdef CONFIG_RFKILL_POLL
10891 	.rfkill_poll = cfg80211_rtw_rfkill_poll,
10892 #endif
10893 #if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
10894 	.dump_survey = rtw_hostapd_acs_dump_survey,
10895 #endif
10896 #if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \
10897     || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH)
10898 	.external_auth = cfg80211_rtw_external_auth,
10899 #endif
10900 #ifdef CONFIG_AP_MODE
10901 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
10902 	.channel_switch = cfg80211_rtw_channel_switch,
10903 #endif
10904 #endif /* #ifdef CONFIG_AP_MODE */
10905 };
10906 
rtw_wiphy_alloc(_adapter * padapter,struct device * dev)10907 struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev)
10908 {
10909 	struct wiphy *wiphy;
10910 	struct rtw_wiphy_data *wiphy_data;
10911 
10912 	/* wiphy */
10913 	wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wiphy_data));
10914 	if (!wiphy) {
10915 		RTW_ERR("Couldn't allocate wiphy device\n");
10916 		goto exit;
10917 	}
10918 	set_wiphy_dev(wiphy, dev);
10919 
10920 	/* wiphy_data */
10921 	wiphy_data = rtw_wiphy_priv(wiphy);
10922 	wiphy_data->dvobj = adapter_to_dvobj(padapter);
10923 #ifndef RTW_SINGLE_WIPHY
10924 	wiphy_data->adapter = padapter;
10925 #endif
10926 	wiphy_data->txpwr_total_lmt_mbm = UNSPECIFIED_MBM;
10927 	wiphy_data->txpwr_total_target_mbm = UNSPECIFIED_MBM;
10928 
10929 	rtw_regd_init(wiphy);
10930 
10931 	if (rtw_cfg80211_init_wiphy(padapter, wiphy) != _SUCCESS) {
10932 		rtw_wiphy_free(wiphy);
10933 		wiphy = NULL;
10934 		goto exit;
10935 	}
10936 
10937 	RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10938 
10939 exit:
10940 	return wiphy;
10941 }
10942 
rtw_wiphy_free(struct wiphy * wiphy)10943 void rtw_wiphy_free(struct wiphy *wiphy)
10944 {
10945 	if (!wiphy)
10946 		return;
10947 
10948 	RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10949 
10950 	rtw_regd_deinit(wiphy);
10951 
10952 	if (wiphy->bands[NL80211_BAND_2GHZ]) {
10953 		rtw_spt_band_free(wiphy->bands[NL80211_BAND_2GHZ]);
10954 		wiphy->bands[NL80211_BAND_2GHZ] = NULL;
10955 	}
10956 	if (wiphy->bands[NL80211_BAND_5GHZ]) {
10957 		rtw_spt_band_free(wiphy->bands[NL80211_BAND_5GHZ]);
10958 		wiphy->bands[NL80211_BAND_5GHZ] = NULL;
10959 	}
10960 
10961 	wiphy_free(wiphy);
10962 }
10963 
rtw_wiphy_register(struct wiphy * wiphy)10964 int rtw_wiphy_register(struct wiphy *wiphy)
10965 {
10966 	struct get_chplan_resp *chplan;
10967 	int ret;
10968 
10969 	RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10970 
10971 #if ( (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \
10972      || defined(RTW_VENDOR_EXT_SUPPORT) )
10973 	rtw_cfgvendor_attach(wiphy);
10974 #endif
10975 
10976 	ret = wiphy_register(wiphy);
10977 	if (ret != 0) {
10978 		RTW_INFO(FUNC_WIPHY_FMT" wiphy_register() return %d\n", FUNC_WIPHY_ARG(wiphy), ret);
10979 		goto exit;
10980 	}
10981 
10982 	rtw_chset_hook_os_channels(dvobj_to_rfctl(wiphy_to_dvobj(wiphy)));
10983 
10984 	if (rtw_get_chplan_cmd(wiphy_to_adapter(wiphy), RTW_CMDF_DIRECTLY, &chplan) == _SUCCESS)
10985 		rtw_regd_change_complete_sync(wiphy, chplan, 1);
10986 	else
10987 		rtw_warn_on(1);
10988 
10989 exit:
10990 	return ret;
10991 }
10992 
rtw_wiphy_unregister(struct wiphy * wiphy)10993 void rtw_wiphy_unregister(struct wiphy *wiphy)
10994 {
10995 	RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10996 
10997 #if ( (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \
10998      || defined(RTW_VENDOR_EXT_SUPPORT) )
10999 	rtw_cfgvendor_detach(wiphy);
11000 #endif
11001 
11002 	#if defined(RTW_DEDICATED_P2P_DEVICE)
11003 	rtw_pd_iface_free(wiphy);
11004 	#endif
11005 
11006 	return wiphy_unregister(wiphy);
11007 }
11008 
rtw_wdev_alloc(_adapter * padapter,struct wiphy * wiphy)11009 int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy)
11010 {
11011 	int ret = 0;
11012 	struct net_device *pnetdev = padapter->pnetdev;
11013 	struct wireless_dev *wdev;
11014 	struct rtw_wdev_priv *pwdev_priv;
11015 
11016 	RTW_INFO("%s(padapter=%p)\n", __func__, padapter);
11017 
11018 	/*  wdev */
11019 	wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
11020 	if (!wdev) {
11021 		RTW_INFO("Couldn't allocate wireless device\n");
11022 		ret = -ENOMEM;
11023 		goto exit;
11024 	}
11025 	wdev->wiphy = wiphy;
11026 	wdev->netdev = pnetdev;
11027 	wdev->iftype = NL80211_IFTYPE_STATION;
11028 	padapter->rtw_wdev = wdev;
11029 	pnetdev->ieee80211_ptr = wdev;
11030 
11031 	/* init pwdev_priv */
11032 	pwdev_priv = adapter_wdev_data(padapter);
11033 	pwdev_priv->rtw_wdev = wdev;
11034 	pwdev_priv->pmon_ndev = NULL;
11035 	pwdev_priv->ifname_mon[0] = '\0';
11036 	pwdev_priv->padapter = padapter;
11037 	pwdev_priv->scan_request = NULL;
11038 	_rtw_spinlock_init(&pwdev_priv->scan_req_lock);
11039 	pwdev_priv->connect_req = NULL;
11040 	_rtw_spinlock_init(&pwdev_priv->connect_req_lock);
11041 
11042 	pwdev_priv->p2p_enabled = _FALSE;
11043 	pwdev_priv->probe_resp_ie_update_time = rtw_get_current_time();
11044 	pwdev_priv->provdisc_req_issued = _FALSE;
11045 	rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
11046 	rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
11047 
11048 	pwdev_priv->bandroid_scan = _FALSE;
11049 
11050 	_rtw_mutex_init(&pwdev_priv->roch_mutex);
11051 
11052 #ifdef CONFIG_CONCURRENT_MODE
11053 	ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
11054 #endif
11055 
11056 #ifdef CONFIG_RTW_CFGVENDOR_RSSIMONITOR
11057         pwdev_priv->rssi_monitor_enable = 0;
11058         pwdev_priv->rssi_monitor_max = 0;
11059         pwdev_priv->rssi_monitor_min = 0;
11060 #endif
11061 
11062 
11063 exit:
11064 	return ret;
11065 }
11066 
rtw_wdev_free(struct wireless_dev * wdev)11067 void rtw_wdev_free(struct wireless_dev *wdev)
11068 {
11069 	if (!wdev)
11070 		return;
11071 
11072 	RTW_INFO("%s(wdev=%p)\n", __func__, wdev);
11073 
11074 	if (wdev_to_ndev(wdev)) {
11075 		_adapter *adapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
11076 		struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
11077 		_irqL irqL;
11078 
11079 		_rtw_spinlock_free(&wdev_priv->scan_req_lock);
11080 
11081 		_enter_critical_bh(&wdev_priv->connect_req_lock, &irqL);
11082 		rtw_wdev_free_connect_req(wdev_priv);
11083 		_exit_critical_bh(&wdev_priv->connect_req_lock, &irqL);
11084 		_rtw_spinlock_free(&wdev_priv->connect_req_lock);
11085 
11086 		_rtw_mutex_free(&wdev_priv->roch_mutex);
11087 	}
11088 
11089 	rtw_mfree((u8 *)wdev, sizeof(struct wireless_dev));
11090 }
11091 
rtw_wdev_unregister(struct wireless_dev * wdev)11092 void rtw_wdev_unregister(struct wireless_dev *wdev)
11093 {
11094 	struct net_device *ndev;
11095 	_adapter *adapter;
11096 	struct rtw_wdev_priv *pwdev_priv;
11097 
11098 	if (!wdev)
11099 		return;
11100 
11101 	RTW_INFO("%s(wdev=%p)\n", __func__, wdev);
11102 
11103 	ndev = wdev_to_ndev(wdev);
11104 	if (!ndev)
11105 		return;
11106 
11107 	adapter = (_adapter *)rtw_netdev_priv(ndev);
11108 	pwdev_priv = adapter_wdev_data(adapter);
11109 
11110 	rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
11111 
11112 	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) || defined(COMPAT_KERNEL_RELEASE)
11113 	if (wdev->current_bss) {
11114 		RTW_INFO(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter));
11115 		rtw_cfg80211_indicate_disconnect(adapter, 0, 1);
11116 	}
11117 	#endif
11118 
11119 	if (pwdev_priv->pmon_ndev) {
11120 		RTW_INFO("%s, unregister monitor interface\n", __func__);
11121 		unregister_netdev(pwdev_priv->pmon_ndev);
11122 	}
11123 }
11124 
rtw_cfg80211_ndev_res_alloc(_adapter * adapter)11125 int rtw_cfg80211_ndev_res_alloc(_adapter *adapter)
11126 {
11127 	int ret = _FAIL;
11128 
11129 #if !defined(RTW_SINGLE_WIPHY)
11130 	struct wiphy *wiphy;
11131 	struct device *dev = dvobj_to_dev(adapter_to_dvobj(adapter));
11132 
11133 	wiphy = rtw_wiphy_alloc(adapter, dev);
11134 	if (wiphy == NULL)
11135 		goto exit;
11136 
11137 	adapter->wiphy = wiphy;
11138 #endif
11139 
11140 	if (rtw_wdev_alloc(adapter, adapter_to_wiphy(adapter)) == 0)
11141 		ret = _SUCCESS;
11142 
11143 #if !defined(RTW_SINGLE_WIPHY)
11144 	if (ret != _SUCCESS) {
11145 		rtw_wiphy_free(wiphy);
11146 		adapter->wiphy = NULL;
11147 	}
11148 
11149 exit:
11150 #endif
11151 
11152 	return ret;
11153 }
11154 
rtw_cfg80211_ndev_res_free(_adapter * adapter)11155 void rtw_cfg80211_ndev_res_free(_adapter *adapter)
11156 {
11157 	rtw_wdev_free(adapter->rtw_wdev);
11158 	adapter->rtw_wdev = NULL;
11159 #if !defined(RTW_SINGLE_WIPHY)
11160 	rtw_wiphy_free(adapter_to_wiphy(adapter));
11161 	adapter->wiphy = NULL;
11162 #endif
11163 }
11164 
11165 
rtw_cfg80211_ndev_res_register(_adapter * adapter)11166 int rtw_cfg80211_ndev_res_register(_adapter *adapter)
11167 {
11168 #if !defined(RTW_SINGLE_WIPHY)
11169 	int ret = _FAIL;
11170 
11171 	if (rtw_wiphy_register(adapter_to_wiphy(adapter)) < 0) {
11172 		RTW_INFO("%s rtw_wiphy_register fail for if%d\n", __func__, (adapter->iface_id + 1));
11173 		goto exit;
11174 	}
11175 
11176 	#ifdef CONFIG_RFKILL_POLL
11177 	rtw_cfg80211_init_rfkill(adapter_to_wiphy(adapter));
11178 	#endif
11179 
11180 	ret = _SUCCESS;
11181 
11182 exit:
11183 	return ret;
11184 #else
11185 	return _SUCCESS;
11186 #endif
11187 }
11188 
rtw_cfg80211_ndev_res_unregister(_adapter * adapter)11189 void rtw_cfg80211_ndev_res_unregister(_adapter *adapter)
11190 {
11191 	rtw_wdev_unregister(adapter->rtw_wdev);
11192 }
11193 
rtw_cfg80211_dev_res_alloc(struct dvobj_priv * dvobj)11194 int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj)
11195 {
11196 	int ret = _FAIL;
11197 
11198 #if defined(RTW_SINGLE_WIPHY)
11199 	struct wiphy *wiphy;
11200 	struct device *dev = dvobj_to_dev(dvobj);
11201 
11202 	wiphy = rtw_wiphy_alloc(dvobj_get_primary_adapter(dvobj), dev);
11203 	if (wiphy == NULL)
11204 		return ret;
11205 
11206 	dvobj->wiphy = wiphy;
11207 #endif
11208 
11209 	ret = _SUCCESS;
11210 	return ret;
11211 }
11212 
rtw_cfg80211_dev_res_free(struct dvobj_priv * dvobj)11213 void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj)
11214 {
11215 #if defined(RTW_SINGLE_WIPHY)
11216 	rtw_wiphy_free(dvobj_to_wiphy(dvobj));
11217 	dvobj->wiphy = NULL;
11218 #endif
11219 }
11220 
rtw_cfg80211_dev_res_register(struct dvobj_priv * dvobj)11221 int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj)
11222 {
11223 	int ret = _FAIL;
11224 
11225 #if defined(RTW_SINGLE_WIPHY)
11226 	if (rtw_wiphy_register(dvobj_to_wiphy(dvobj)) != 0)
11227 		return ret;
11228 
11229 #ifdef CONFIG_RFKILL_POLL
11230 	rtw_cfg80211_init_rfkill(dvobj_to_wiphy(dvobj));
11231 #endif
11232 #endif
11233 
11234 	ret = _SUCCESS;
11235 
11236 	return ret;
11237 }
11238 
rtw_cfg80211_dev_res_unregister(struct dvobj_priv * dvobj)11239 void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj)
11240 {
11241 #if defined(RTW_SINGLE_WIPHY)
11242 #ifdef CONFIG_RFKILL_POLL
11243 	rtw_cfg80211_deinit_rfkill(dvobj_to_wiphy(dvobj));
11244 #endif
11245 	rtw_wiphy_unregister(dvobj_to_wiphy(dvobj));
11246 #endif
11247 }
11248 
rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(struct dvobj_priv * dvobj)11249 s16 rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(struct dvobj_priv *dvobj)
11250 {
11251 	struct rtw_wiphy_data *wiphy_data;
11252 	s16 mbm = UNSPECIFIED_MBM;
11253 
11254 	/* TODO: input radio index to choose corresponding wiphy(s) */
11255 
11256 #if defined(RTW_SINGLE_WIPHY)
11257 	wiphy_data = rtw_wiphy_priv(dvobj_to_wiphy(dvobj));
11258 	mbm = wiphy_data->txpwr_total_lmt_mbm;
11259 #else
11260 	struct wiphy *wiphy;
11261 	int i;
11262 
11263 	for (i = 0; i < dvobj->iface_nums; i++) {
11264 		if (!dvobj->padapters[i])
11265 			continue;
11266 		wiphy = dvobj->padapters[i]->wiphy;
11267 		if (!wiphy)
11268 			continue;
11269 		wiphy_data = rtw_wiphy_priv(wiphy);
11270 		if (wiphy_data->txpwr_total_lmt_mbm == UNSPECIFIED_MBM)
11271 			continue;
11272 		if (mbm > wiphy_data->txpwr_total_lmt_mbm)
11273 			mbm = wiphy_data->txpwr_total_lmt_mbm;
11274 	}
11275 #endif
11276 
11277 	return mbm;
11278 }
11279 
rtw_cfg80211_dev_get_total_txpwr_target_mbm(struct dvobj_priv * dvobj)11280 s16 rtw_cfg80211_dev_get_total_txpwr_target_mbm(struct dvobj_priv *dvobj)
11281 {
11282 	struct rtw_wiphy_data *wiphy_data;
11283 	s16 mbm = UNSPECIFIED_MBM;
11284 
11285 	/* TODO: input radio index to choose corresponding wiphy(s) */
11286 
11287 #if defined(RTW_SINGLE_WIPHY)
11288 	wiphy_data = rtw_wiphy_priv(dvobj_to_wiphy(dvobj));
11289 	mbm = wiphy_data->txpwr_total_target_mbm;
11290 #else
11291 	struct wiphy *wiphy;
11292 	int i;
11293 
11294 	for (i = 0; i < dvobj->iface_nums; i++) {
11295 		if (!dvobj->padapters[i])
11296 			continue;
11297 		wiphy = dvobj->padapters[i]->wiphy;
11298 		if (!wiphy)
11299 			continue;
11300 		wiphy_data = rtw_wiphy_priv(wiphy);
11301 		if (wiphy_data->txpwr_total_target_mbm == UNSPECIFIED_MBM)
11302 			continue;
11303 		if (mbm > wiphy_data->txpwr_total_target_mbm)
11304 			mbm = wiphy_data->txpwr_total_target_mbm;
11305 	}
11306 #endif
11307 
11308 	return mbm;
11309 }
11310 #endif /* CONFIG_IOCTL_CFG80211 */
11311