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