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