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