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