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