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