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