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