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