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