1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _IOCTL_CFG80211_C_
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <rtw_ioctl.h>
26 #include <rtw_ioctl_set.h>
27 #include <rtw_ioctl_query.h>
28 #include <xmit_osdep.h>
30 #ifdef CONFIG_IOCTL_CFG80211
32 #include "ioctl_cfg80211.h"
34 #define RTW_MAX_MGMT_TX_CNT (8)
36 #define RTW_SCAN_IE_LEN_MAX 2304
37 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 //ms
38 #define RTW_MAX_NUM_PMKIDS 4
40 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
42 static const u32 rtw_cipher_suites
[] = {
43 WLAN_CIPHER_SUITE_WEP40
,
44 WLAN_CIPHER_SUITE_WEP104
,
45 WLAN_CIPHER_SUITE_TKIP
,
46 WLAN_CIPHER_SUITE_CCMP
,
47 #ifdef CONFIG_IEEE80211W
48 WLAN_CIPHER_SUITE_AES_CMAC
,
49 #endif //CONFIG_IEEE80211W
52 #define RATETAB_ENT(_rate, _rateid, _flags) \
55 .hw_value = (_rateid), \
59 #define CHAN2G(_channel, _freq, _flags) { \
60 .band = NL80211_BAND_2GHZ, \
61 .center_freq = (_freq), \
62 .hw_value = (_channel), \
64 .max_antenna_gain = 0, \
68 #define CHAN5G(_channel, _flags) { \
69 .band = NL80211_BAND_5GHZ, \
70 .center_freq = 5000 + (5 * (_channel)), \
71 .hw_value = (_channel), \
73 .max_antenna_gain = 0, \
77 static struct ieee80211_rate rtw_rates
[] = {
78 RATETAB_ENT(10, 0x1, 0),
79 RATETAB_ENT(20, 0x2, 0),
80 RATETAB_ENT(55, 0x4, 0),
81 RATETAB_ENT(110, 0x8, 0),
82 RATETAB_ENT(60, 0x10, 0),
83 RATETAB_ENT(90, 0x20, 0),
84 RATETAB_ENT(120, 0x40, 0),
85 RATETAB_ENT(180, 0x80, 0),
86 RATETAB_ENT(240, 0x100, 0),
87 RATETAB_ENT(360, 0x200, 0),
88 RATETAB_ENT(480, 0x400, 0),
89 RATETAB_ENT(540, 0x800, 0),
92 #define rtw_a_rates (rtw_rates + 4)
93 #define RTW_A_RATES_NUM 8
94 #define rtw_g_rates (rtw_rates + 0)
95 #define RTW_G_RATES_NUM 12
97 #define RTW_2G_CHANNELS_NUM 14
98 #define RTW_5G_CHANNELS_NUM 37
100 static struct ieee80211_channel rtw_2ghz_channels
[] = {
117 static struct ieee80211_channel rtw_5ghz_a_channels
[] = {
118 CHAN5G(34, 0), CHAN5G(36, 0),
119 CHAN5G(38, 0), CHAN5G(40, 0),
120 CHAN5G(42, 0), CHAN5G(44, 0),
121 CHAN5G(46, 0), CHAN5G(48, 0),
122 CHAN5G(52, 0), CHAN5G(56, 0),
123 CHAN5G(60, 0), CHAN5G(64, 0),
124 CHAN5G(100, 0), CHAN5G(104, 0),
125 CHAN5G(108, 0), CHAN5G(112, 0),
126 CHAN5G(116, 0), CHAN5G(120, 0),
127 CHAN5G(124, 0), CHAN5G(128, 0),
128 CHAN5G(132, 0), CHAN5G(136, 0),
129 CHAN5G(140, 0), CHAN5G(149, 0),
130 CHAN5G(153, 0), CHAN5G(157, 0),
131 CHAN5G(161, 0), CHAN5G(165, 0),
132 CHAN5G(184, 0), CHAN5G(188, 0),
133 CHAN5G(192, 0), CHAN5G(196, 0),
134 CHAN5G(200, 0), CHAN5G(204, 0),
135 CHAN5G(208, 0), CHAN5G(212, 0),
140 void rtw_2g_channels_init(struct ieee80211_channel
*channels
)
142 _rtw_memcpy((void*)channels
, (void*)rtw_2ghz_channels
,
143 sizeof(struct ieee80211_channel
)*RTW_2G_CHANNELS_NUM
147 void rtw_5g_channels_init(struct ieee80211_channel
*channels
)
149 _rtw_memcpy((void*)channels
, (void*)rtw_5ghz_a_channels
,
150 sizeof(struct ieee80211_channel
)*RTW_5G_CHANNELS_NUM
154 void rtw_2g_rates_init(struct ieee80211_rate
*rates
)
156 _rtw_memcpy(rates
, rtw_g_rates
,
157 sizeof(struct ieee80211_rate
)*RTW_G_RATES_NUM
161 void rtw_5g_rates_init(struct ieee80211_rate
*rates
)
163 _rtw_memcpy(rates
, rtw_a_rates
,
164 sizeof(struct ieee80211_rate
)*RTW_A_RATES_NUM
168 struct ieee80211_supported_band
*rtw_spt_band_alloc(
169 enum nl80211_band band
172 struct ieee80211_supported_band
*spt_band
= NULL
;
173 int n_channels
, n_bitrates
;
175 if(band
== NL80211_BAND_2GHZ
)
177 n_channels
= RTW_2G_CHANNELS_NUM
;
178 n_bitrates
= RTW_G_RATES_NUM
;
180 else if(band
== NL80211_BAND_5GHZ
)
182 n_channels
= RTW_5G_CHANNELS_NUM
;
183 n_bitrates
= RTW_A_RATES_NUM
;
190 spt_band
= (struct ieee80211_supported_band
*)rtw_zmalloc(
191 sizeof(struct ieee80211_supported_band
)
192 + sizeof(struct ieee80211_channel
)*n_channels
193 + sizeof(struct ieee80211_rate
)*n_bitrates
198 spt_band
->channels
= (struct ieee80211_channel
*)(((u8
*)spt_band
)+sizeof(struct ieee80211_supported_band
));
199 spt_band
->bitrates
= (struct ieee80211_rate
*)(((u8
*)spt_band
->channels
)+sizeof(struct ieee80211_channel
)*n_channels
);
200 spt_band
->band
= band
;
201 spt_band
->n_channels
= n_channels
;
202 spt_band
->n_bitrates
= n_bitrates
;
204 if(band
== NL80211_BAND_2GHZ
)
206 rtw_2g_channels_init(spt_band
->channels
);
207 rtw_2g_rates_init(spt_band
->bitrates
);
209 else if(band
== NL80211_BAND_5GHZ
)
211 rtw_5g_channels_init(spt_band
->channels
);
212 rtw_5g_rates_init(spt_band
->bitrates
);
222 void rtw_spt_band_free(struct ieee80211_supported_band
*spt_band
)
229 if(spt_band
->band
== NL80211_BAND_2GHZ
)
231 size
= sizeof(struct ieee80211_supported_band
)
232 + sizeof(struct ieee80211_channel
)*RTW_2G_CHANNELS_NUM
233 + sizeof(struct ieee80211_rate
)*RTW_G_RATES_NUM
;
235 else if(spt_band
->band
== NL80211_BAND_5GHZ
)
237 size
= sizeof(struct ieee80211_supported_band
)
238 + sizeof(struct ieee80211_channel
)*RTW_5G_CHANNELS_NUM
239 + sizeof(struct ieee80211_rate
)*RTW_A_RATES_NUM
;
245 rtw_mfree((u8
*)spt_band
, size
);
248 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
249 static const struct ieee80211_txrx_stypes
250 rtw_cfg80211_default_mgmt_stypes
[NUM_NL80211_IFTYPES
] = {
251 [NL80211_IFTYPE_ADHOC
] = {
253 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4)
255 [NL80211_IFTYPE_STATION
] = {
257 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
258 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
260 [NL80211_IFTYPE_AP
] = {
262 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
263 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
264 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
265 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
266 BIT(IEEE80211_STYPE_AUTH
>> 4) |
267 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
268 BIT(IEEE80211_STYPE_ACTION
>> 4)
270 [NL80211_IFTYPE_AP_VLAN
] = {
273 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
274 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
275 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
276 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
277 BIT(IEEE80211_STYPE_AUTH
>> 4) |
278 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
279 BIT(IEEE80211_STYPE_ACTION
>> 4)
281 [NL80211_IFTYPE_P2P_CLIENT
] = {
283 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
284 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
286 [NL80211_IFTYPE_P2P_GO
] = {
288 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
289 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
290 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
291 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
292 BIT(IEEE80211_STYPE_AUTH
>> 4) |
293 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
294 BIT(IEEE80211_STYPE_ACTION
>> 4)
299 static int rtw_ieee80211_channel_to_frequency(int chan
, int band
)
301 /* see 802.11 17.3.8.3.2 and Annex J
302 * there are overlapping channel numbers in 5GHz and 2GHz bands */
304 if (band
== NL80211_BAND_5GHZ
) {
305 if (chan
>= 182 && chan
<= 196)
306 return 4000 + chan
* 5;
308 return 5000 + chan
* 5;
309 } else { /* NL80211_BAND_2GHZ */
313 return 2407 + chan
* 5;
315 return 0; /* not supported */
319 #define MAX_BSSINFO_LEN 1000
320 static int rtw_cfg80211_inform_bss(_adapter
*padapter
, struct wlan_network
*pnetwork
)
323 struct ieee80211_channel
*notify_channel
;
324 struct cfg80211_bss
*bss
;
325 //struct ieee80211_supported_band *band;
328 u64 notify_timestamp
;
329 u16 notify_capability
;
335 size_t len
,bssinf_len
=0;
336 struct rtw_ieee80211_hdr
*pwlanhdr
;
337 unsigned short *fctrl
;
338 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
340 struct wireless_dev
*wdev
= padapter
->rtw_wdev
;
341 struct wiphy
*wiphy
= wdev
->wiphy
;
342 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
345 //DBG_8192C("%s\n", __func__);
347 bssinf_len
= pnetwork
->network
.IELength
+sizeof (struct rtw_ieee80211_hdr_3addr
);
348 if(bssinf_len
> MAX_BSSINFO_LEN
){
349 DBG_871X("%s IE Length too long > %d byte \n",__FUNCTION__
,MAX_BSSINFO_LEN
);
353 //To reduce PBC Overlap rate
354 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
355 if(wdev_to_priv(wdev
)->scan_request
!= NULL
)
357 u8
*psr
=NULL
, sr
= 0;
358 NDIS_802_11_SSID
*pssid
= &pnetwork
->network
.Ssid
;
359 struct cfg80211_scan_request
*request
= wdev_to_priv(wdev
)->scan_request
;
360 struct cfg80211_ssid
*ssids
= request
->ssids
;
364 wpsie
= rtw_get_wps_ie(pnetwork
->network
.IEs
+_FIXED_IE_LENGTH_
, pnetwork
->network
.IELength
-_FIXED_IE_LENGTH_
, NULL
, &wpsielen
);
366 if(wpsie
&& wpsielen
>0)
367 psr
= rtw_get_wps_attr_content(wpsie
, wpsielen
, WPS_ATTR_SELECTED_REGISTRAR
, (u8
*)(&sr
), NULL
);
371 if(request
->n_ssids
== 1 && request
->n_channels
== 1) // it means under processing WPS
373 DBG_8192C("ssid=%s, len=%d\n", pssid
->Ssid
, pssid
->SsidLength
);
375 if(pssid
->SsidLength
== ssids
[0].ssid_len
&&
376 _rtw_memcmp(pssid
->Ssid
, ssids
[0].ssid
, ssids
[0].ssid_len
))
378 DBG_871X("%s, got sr and ssid match!\n", __func__
);
386 WLAN_BSSID_EX
*pselect_network
= &pnetwork
->network
;
387 struct cfg80211_bss
*pselect_bss
= NULL
;
388 struct ieee80211_channel
*notify_channel
= NULL
;
391 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__
);
393 if (pselect_network
->Configuration
.DSConfig
<= RTW_CH_MAX_2G_CHANNEL
)
394 freq
= rtw_ieee80211_channel_to_frequency(pselect_network
->Configuration
.DSConfig
, NL80211_BAND_2GHZ
);
396 freq
= rtw_ieee80211_channel_to_frequency(pselect_network
->Configuration
.DSConfig
, NL80211_BAND_5GHZ
);
398 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
399 pselect_bss
= cfg80211_get_bss(wiphy
, NULL
/*notify_channel*/,
400 pselect_network
->MacAddress
, pselect_network
->Ssid
.Ssid
,
401 pselect_network
->Ssid
.SsidLength
, 0/*WLAN_CAPABILITY_ESS*/,
402 0/*WLAN_CAPABILITY_ESS*/);
406 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__
);
408 cfg80211_unlink_bss(wiphy
, pselect_bss
);
409 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
410 cfg80211_put_bss(wiphy
, pselect_bss
);
412 cfg80211_put_bss(pselect_bss
);
423 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
425 channel
= pnetwork
->network
.Configuration
.DSConfig
;
426 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
427 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
429 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
431 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
433 //rtw_get_timestampe_from_ie()
434 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
436 notify_interval
= le16_to_cpu(*(u16
*)rtw_get_beacon_interval_from_ie(pnetwork
->network
.IEs
));
437 notify_capability
= le16_to_cpu(*(u16
*)rtw_get_capability_from_ie(pnetwork
->network
.IEs
));
440 notify_ie
= pnetwork
->network
.IEs
+_FIXED_IE_LENGTH_
;
441 notify_ielen
= pnetwork
->network
.IELength
-_FIXED_IE_LENGTH_
;
443 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
444 if ( check_fwstate(pmlmepriv
, _FW_LINKED
)== _TRUE
&&
445 is_same_network(&pmlmepriv
->cur_network
.network
, &pnetwork
->network
)) {
446 notify_signal
= 100*translate_percentage_to_dbm(padapter
->recvpriv
.signal_strength
);//dbm
448 notify_signal
= 100*translate_percentage_to_dbm(pnetwork
->network
.PhyInfo
.SignalStrength
);//dbm
452 DBG_8192C("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
453 pnetwork->network.MacAddress[0], pnetwork->network.MacAddress[1], pnetwork->network.MacAddress[2],
454 pnetwork->network.MacAddress[3], pnetwork->network.MacAddress[4], pnetwork->network.MacAddress[5]);
455 DBG_8192C("Channel: %d(%d)\n", channel, freq);
456 DBG_8192C("Capability: %X\n", notify_capability);
457 DBG_8192C("Beacon interval: %d\n", notify_interval);
458 DBG_8192C("Signal: %d\n", notify_signal);
459 DBG_8192C("notify_timestamp: %#018llx\n", notify_timestamp);
462 buf
= rtw_zmalloc(MAX_BSSINFO_LEN
);
465 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pbuf
;
466 fctrl
= &(pwlanhdr
->frame_ctl
);
469 SetSeqNum(pwlanhdr
, 0/*pmlmeext->mgnt_seq*/);
470 //pmlmeext->mgnt_seq++;
472 if (pnetwork
->network
.Reserved
[0] == 1) { // WIFI_BEACON
473 _rtw_memcpy(pwlanhdr
->addr1
, bc_addr
, ETH_ALEN
);
474 SetFrameSubType(pbuf
, WIFI_BEACON
);
476 _rtw_memcpy(pwlanhdr
->addr1
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
477 SetFrameSubType(pbuf
, WIFI_PROBERSP
);
480 _rtw_memcpy(pwlanhdr
->addr2
, pnetwork
->network
.MacAddress
, ETH_ALEN
);
481 _rtw_memcpy(pwlanhdr
->addr3
, pnetwork
->network
.MacAddress
, ETH_ALEN
);
484 pbuf
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
485 len
= sizeof (struct rtw_ieee80211_hdr_3addr
);
487 _rtw_memcpy(pbuf
, pnetwork
->network
.IEs
, pnetwork
->network
.IELength
);
488 len
+= pnetwork
->network
.IELength
;
490 rtw_mfree(buf
, MAX_BSSINFO_LEN
);
493 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
495 // DBG_8192C("%s, got p2p_ie\n", __func__);
501 bss
= cfg80211_inform_bss_frame(wiphy
, notify_channel
, (struct ieee80211_mgmt
*)buf
,
502 len
, notify_signal
, GFP_ATOMIC
);
505 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)pnetwork
->network
.MacAddress
,
506 notify_timestamp
, notify_capability
, notify_interval
, notify_ie
,
507 notify_ielen
, notify_signal
, GFP_ATOMIC
/*GFP_KERNEL*/);
510 if (unlikely(!bss
)) {
511 DBG_8192C("rtw_cfg80211_inform_bss error\n");
515 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
516 #ifndef COMPAT_KERNEL_RELEASE
517 //patch for cfg80211, update beacon ies to information_elements
518 if (pnetwork
->network
.Reserved
[0] == 1) { // WIFI_BEACON
520 if(bss
->len_information_elements
!= bss
->len_beacon_ies
)
522 bss
->information_elements
= bss
->beacon_ies
;
523 bss
->len_information_elements
= bss
->len_beacon_ies
;
526 #endif //COMPAT_KERNEL_RELEASE
527 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
531 if( bss->information_elements == bss->proberesp_ies)
533 if( bss->len_information_elements != bss->len_proberesp_ies)
535 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
539 else if(bss->len_information_elements < bss->len_beacon_ies)
541 bss->information_elements = bss->beacon_ies;
542 bss->len_information_elements = bss->len_beacon_ies;
547 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
548 cfg80211_put_bss(wiphy
, bss
);
550 cfg80211_put_bss(bss
);
559 Check the given bss is valid by kernel API cfg80211_get_bss()
560 @padapter : the given adapter
562 return _TRUE if bss is valid, _FALSE for not found.
564 int rtw_cfg80211_check_bss(_adapter
*padapter
)
566 WLAN_BSSID_EX
*pnetwork
= &(padapter
->mlmeextpriv
.mlmext_info
.network
);
567 struct cfg80211_bss
*bss
= NULL
;
568 struct ieee80211_channel
*notify_channel
= NULL
;
571 if (!(pnetwork
) || !(padapter
->rtw_wdev
))
574 if (pnetwork
->Configuration
.DSConfig
<= RTW_CH_MAX_2G_CHANNEL
)
575 freq
= rtw_ieee80211_channel_to_frequency(pnetwork
->Configuration
.DSConfig
, NL80211_BAND_2GHZ
);
577 freq
= rtw_ieee80211_channel_to_frequency(pnetwork
->Configuration
.DSConfig
, NL80211_BAND_5GHZ
);
579 notify_channel
= ieee80211_get_channel(padapter
->rtw_wdev
->wiphy
, freq
);
580 bss
= cfg80211_get_bss(padapter
->rtw_wdev
->wiphy
, notify_channel
,
581 pnetwork
->MacAddress
, pnetwork
->Ssid
.Ssid
,
582 pnetwork
->Ssid
.SsidLength
,
583 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
584 WLAN_CAPABILITY_ESS
, WLAN_CAPABILITY_ESS
);
586 IEEE80211_BSS_TYPE_ESS
, IEEE80211_PRIVACY_ANY
);
592 void rtw_cfg80211_indicate_connect(_adapter
*padapter
)
594 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
595 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
596 struct wireless_dev
*pwdev
= padapter
->rtw_wdev
;
598 struct wifidirect_info
*pwdinfo
= &(padapter
->wdinfo
);
600 struct cfg80211_bss
*bss
= NULL
;
602 DBG_871X(FUNC_ADPT_FMT
"\n", FUNC_ADPT_ARG(padapter
));
603 if (pwdev
->iftype
!= NL80211_IFTYPE_STATION
604 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
605 && pwdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
611 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
615 if(pwdinfo
->driver_interface
== DRIVER_CFG80211
)
617 if(!rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
619 rtw_p2p_set_pre_state(pwdinfo
, rtw_p2p_state(pwdinfo
));
620 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
621 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
622 DBG_8192C("%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
));
627 #ifdef CONFIG_LAYER2_ROAMING
628 if (rtw_to_roaming(padapter
) > 0) {
629 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
630 struct wiphy
*wiphy
= pwdev
->wiphy
;
631 struct ieee80211_channel
*notify_channel
;
633 u16 channel
= cur_network
->network
.Configuration
.DSConfig
;
635 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
636 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
638 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
640 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
643 DBG_871X("%s call cfg80211_roamed\n", __FUNCTION__
);
644 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
646 struct cfg80211_roam_info roam_info
= {
647 .channel
= notify_channel
,
648 .bssid
= cur_network
->network
.MacAddress
,
649 .req_ie
= pmlmepriv
->assoc_req
+sizeof(struct rtw_ieee80211_hdr_3addr
)+2,
650 .req_ie_len
= pmlmepriv
->assoc_req_len
-sizeof(struct rtw_ieee80211_hdr_3addr
)-2,
651 .resp_ie
= pmlmepriv
->assoc_rsp
+sizeof(struct rtw_ieee80211_hdr_3addr
)+6,
652 .resp_ie_len
= pmlmepriv
->assoc_rsp_len
-sizeof(struct rtw_ieee80211_hdr_3addr
)-6,
654 cfg80211_roamed(padapter
->pnetdev
, &roam_info
, GFP_ATOMIC
);
657 cfg80211_roamed(padapter
->pnetdev
658 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
661 , cur_network
->network
.MacAddress
662 , pmlmepriv
->assoc_req
+sizeof(struct rtw_ieee80211_hdr_3addr
)+2
663 , pmlmepriv
->assoc_req_len
-sizeof(struct rtw_ieee80211_hdr_3addr
)-2
664 , pmlmepriv
->assoc_rsp
+sizeof(struct rtw_ieee80211_hdr_3addr
)+6
665 , pmlmepriv
->assoc_rsp_len
-sizeof(struct rtw_ieee80211_hdr_3addr
)-6
672 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev
->sme_state
);
673 cfg80211_connect_result(padapter
->pnetdev
, cur_network
->network
.MacAddress
674 , pmlmepriv
->assoc_req
+sizeof(struct rtw_ieee80211_hdr_3addr
)+2
675 , pmlmepriv
->assoc_req_len
-sizeof(struct rtw_ieee80211_hdr_3addr
)-2
676 , pmlmepriv
->assoc_rsp
+sizeof(struct rtw_ieee80211_hdr_3addr
)+6
677 , pmlmepriv
->assoc_rsp_len
-sizeof(struct rtw_ieee80211_hdr_3addr
)-6
678 , WLAN_STATUS_SUCCESS
, GFP_ATOMIC
);
679 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev
->sme_state
);
683 void rtw_cfg80211_indicate_disconnect(_adapter
*padapter
)
685 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
686 struct wireless_dev
*pwdev
= padapter
->rtw_wdev
;
688 struct wifidirect_info
*pwdinfo
= &(padapter
->wdinfo
);
691 DBG_871X(FUNC_ADPT_FMT
"\n", FUNC_ADPT_ARG(padapter
));
693 if (pwdev
->iftype
!= NL80211_IFTYPE_STATION
694 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
695 && pwdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
701 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
705 if( pwdinfo
->driver_interface
== DRIVER_CFG80211
)
707 if(!rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
709 _cancel_timer_ex( &pwdinfo
->find_phase_timer
);
710 _cancel_timer_ex( &pwdinfo
->restore_p2p_state_timer
);
711 _cancel_timer_ex( &pwdinfo
->pre_tx_scan_timer
);
713 rtw_p2p_set_state(pwdinfo
, rtw_p2p_pre_state(pwdinfo
));
714 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
716 DBG_8192C("%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
));
721 if (!padapter
->mlmepriv
.not_indic_disco
) {
722 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev
->sme_state
);
724 if (check_fwstate(pmlmepriv
, WIFI_UNDER_LINKING
)) {
725 cfg80211_connect_result(padapter
->pnetdev
, NULL
, NULL
, 0, NULL
, 0,
726 WLAN_STATUS_UNSPECIFIED_FAILURE
, GFP_ATOMIC
/*GFP_KERNEL*/);
728 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)
729 cfg80211_disconnected(padapter
->pnetdev
, 0, NULL
, 0, GFP_ATOMIC
);
731 cfg80211_disconnected(padapter
->pnetdev
, 0, NULL
, 0, false, GFP_ATOMIC
);
735 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev
->sme_state
);
740 #ifdef CONFIG_AP_MODE
741 static u8
set_pairwise_key(_adapter
*padapter
, struct sta_info
*psta
)
743 struct cmd_obj
* ph2c
;
744 struct set_stakey_parm
*psetstakey_para
;
745 struct cmd_priv
*pcmdpriv
=&padapter
->cmdpriv
;
748 ph2c
= (struct cmd_obj
*)rtw_zmalloc(sizeof(struct cmd_obj
));
754 psetstakey_para
= (struct set_stakey_parm
*)rtw_zmalloc(sizeof(struct set_stakey_parm
));
755 if(psetstakey_para
==NULL
){
756 rtw_mfree((u8
*) ph2c
, sizeof(struct cmd_obj
));
761 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
764 psetstakey_para
->algorithm
= (u8
)psta
->dot118021XPrivacy
;
766 _rtw_memcpy(psetstakey_para
->addr
, psta
->hwaddr
, ETH_ALEN
);
768 _rtw_memcpy(psetstakey_para
->key
, &psta
->dot118021x_UncstKey
, 16);
771 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
779 static int set_group_key(_adapter
*padapter
, u8
*key
, u8 alg
, int keyid
)
782 struct cmd_obj
* pcmd
;
783 struct setkey_parm
*psetkeyparm
;
784 struct cmd_priv
*pcmdpriv
=&(padapter
->cmdpriv
);
787 DBG_8192C("%s\n", __FUNCTION__
);
789 pcmd
= (struct cmd_obj
*)rtw_zmalloc(sizeof(struct cmd_obj
));
794 psetkeyparm
=(struct setkey_parm
*)rtw_zmalloc(sizeof(struct setkey_parm
));
795 if(psetkeyparm
==NULL
){
796 rtw_mfree((unsigned char *)pcmd
, sizeof(struct cmd_obj
));
801 _rtw_memset(psetkeyparm
, 0, sizeof(struct setkey_parm
));
803 psetkeyparm
->keyid
=(u8
)keyid
;
805 padapter
->securitypriv
.key_mask
|= BIT(psetkeyparm
->keyid
);
807 psetkeyparm
->algorithm
= alg
;
809 psetkeyparm
->set_tx
= 1;
827 _rtw_memcpy(&(psetkeyparm
->key
[0]), key
, keylen
);
829 pcmd
->cmdcode
= _SetKey_CMD_
;
830 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
831 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
836 _rtw_init_listhead(&pcmd
->list
);
838 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
847 static int set_wep_key(_adapter
*padapter
, u8
*key
, u8 keylen
, int keyid
)
863 return set_group_key(padapter
, key
, alg
, keyid
);
867 static int rtw_cfg80211_ap_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
870 u32 wep_key_idx
, wep_key_len
,wep_total_len
;
871 struct sta_info
*psta
= NULL
, *pbcmc_sta
= NULL
;
872 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(dev
);
873 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
874 struct security_priv
* psecuritypriv
=&(padapter
->securitypriv
);
875 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
877 DBG_8192C("%s\n", __FUNCTION__
);
879 param
->u
.crypt
.err
= 0;
880 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
882 //sizeof(struct ieee_param) = 64 bytes;
883 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
884 if (param_len
!= sizeof(struct ieee_param
) + param
->u
.crypt
.key_len
)
890 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
891 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
892 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
894 if (param
->u
.crypt
.idx
>= WEP_KEYS
)
902 psta
= rtw_get_stainfo(pstapriv
, param
->sta_addr
);
906 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
911 if (strcmp(param
->u
.crypt
.alg
, "none") == 0 && (psta
==NULL
))
913 //todo:clear default encryption keys
915 DBG_8192C("clear default encryption keys, keyid=%d\n", param
->u
.crypt
.idx
);
921 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0 && (psta
==NULL
))
923 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
925 wep_key_idx
= param
->u
.crypt
.idx
;
926 wep_key_len
= param
->u
.crypt
.key_len
;
928 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx
, wep_key_len
);
930 if((wep_key_idx
>= WEP_KEYS
) || (wep_key_len
<=0))
938 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
941 if (psecuritypriv
->bWepDefaultKeyIdxSet
== 0)
943 //wep default key has not been set, so use this key index as default key.
945 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
946 psecuritypriv
->dot11PrivacyAlgrthm
=_WEP40_
;
947 psecuritypriv
->dot118021XGrpPrivacy
=_WEP40_
;
949 if(wep_key_len
== 13)
951 psecuritypriv
->dot11PrivacyAlgrthm
=_WEP104_
;
952 psecuritypriv
->dot118021XGrpPrivacy
=_WEP104_
;
955 psecuritypriv
->dot11PrivacyKeyIndex
= wep_key_idx
;
958 _rtw_memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), param
->u
.crypt
.key
, wep_key_len
);
960 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = wep_key_len
;
962 set_wep_key(padapter
, param
->u
.crypt
.key
, wep_key_len
, wep_key_idx
);
969 if(!psta
&& check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) // //group key
971 if(param
->u
.crypt
.set_tx
== 0) //group key
973 if(strcmp(param
->u
.crypt
.alg
, "WEP") == 0)
975 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__
);
977 _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
));
979 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
980 if(param
->u
.crypt
.key_len
==13)
982 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
986 else if(strcmp(param
->u
.crypt
.alg
, "TKIP") == 0)
988 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__
);
990 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
992 _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
));
994 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
996 _rtw_memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
997 _rtw_memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
999 psecuritypriv
->busetkipkey
= _TRUE
;
1002 else if(strcmp(param
->u
.crypt
.alg
, "CCMP") == 0)
1004 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__
);
1006 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
1008 _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
));
1012 DBG_8192C("%s, set group_key, none\n", __FUNCTION__
);
1014 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1017 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
1019 psecuritypriv
->binstallGrpkey
= _TRUE
;
1021 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;//!!!
1023 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
1025 pbcmc_sta
=rtw_get_bcmc_stainfo(padapter
);
1028 pbcmc_sta
->ieee8021x_blocked
= _FALSE
;
1029 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;//rx will use bmc_sta's dot118021XPrivacy
1038 if(psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
&& psta
) // psk/802_1x
1040 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1042 if(param
->u
.crypt
.set_tx
==1) //pairwise key
1044 _rtw_memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
>16 ?16:param
->u
.crypt
.key_len
));
1046 if(strcmp(param
->u
.crypt
.alg
, "WEP") == 0)
1048 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__
);
1050 psta
->dot118021XPrivacy
= _WEP40_
;
1051 if(param
->u
.crypt
.key_len
==13)
1053 psta
->dot118021XPrivacy
= _WEP104_
;
1056 else if(strcmp(param
->u
.crypt
.alg
, "TKIP") == 0)
1058 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__
);
1060 psta
->dot118021XPrivacy
= _TKIP_
;
1062 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
1064 _rtw_memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
1065 _rtw_memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
1067 psecuritypriv
->busetkipkey
= _TRUE
;
1070 else if(strcmp(param
->u
.crypt
.alg
, "CCMP") == 0)
1073 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__
);
1075 psta
->dot118021XPrivacy
= _AES_
;
1079 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__
);
1081 psta
->dot118021XPrivacy
= _NO_PRIVACY_
;
1084 set_pairwise_key(padapter
, psta
);
1086 psta
->ieee8021x_blocked
= _FALSE
;
1088 psta
->bpairwise_key_installed
= _TRUE
;
1093 if(strcmp(param
->u
.crypt
.alg
, "WEP") == 0)
1095 _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
));
1097 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
1098 if(param
->u
.crypt
.key_len
==13)
1100 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
1103 else if(strcmp(param
->u
.crypt
.alg
, "TKIP") == 0)
1105 psecuritypriv
->dot118021XGrpPrivacy
= _TKIP_
;
1107 _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
));
1109 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
1111 _rtw_memcpy(psecuritypriv
->dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[16]), 8);
1112 _rtw_memcpy(psecuritypriv
->dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
, &(param
->u
.crypt
.key
[24]), 8);
1114 psecuritypriv
->busetkipkey
= _TRUE
;
1117 else if(strcmp(param
->u
.crypt
.alg
, "CCMP") == 0)
1119 psecuritypriv
->dot118021XGrpPrivacy
= _AES_
;
1121 _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
));
1125 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
1128 psecuritypriv
->dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
1130 psecuritypriv
->binstallGrpkey
= _TRUE
;
1132 psecuritypriv
->dot11PrivacyAlgrthm
= psecuritypriv
->dot118021XGrpPrivacy
;//!!!
1134 set_group_key(padapter
, param
->u
.crypt
.key
, psecuritypriv
->dot118021XGrpPrivacy
, param
->u
.crypt
.idx
);
1136 pbcmc_sta
=rtw_get_bcmc_stainfo(padapter
);
1139 pbcmc_sta
->ieee8021x_blocked
= _FALSE
;
1140 pbcmc_sta
->dot118021XPrivacy
= psecuritypriv
->dot118021XGrpPrivacy
;//rx will use bmc_sta's dot118021XPrivacy
1156 static int rtw_cfg80211_set_encryption(struct net_device
*dev
, struct ieee_param
*param
, u32 param_len
)
1159 u32 wep_key_idx
, wep_key_len
,wep_total_len
;
1160 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(dev
);
1161 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1162 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1164 struct wifidirect_info
* pwdinfo
= &padapter
->wdinfo
;
1169 DBG_8192C("%s\n", __func__
);
1171 param
->u
.crypt
.err
= 0;
1172 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
1174 if (param_len
< (u32
) ((u8
*) param
->u
.crypt
.key
- (u8
*) param
) + param
->u
.crypt
.key_len
)
1180 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
1181 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
1182 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff)
1184 if (param
->u
.crypt
.idx
>= WEP_KEYS
1185 #ifdef CONFIG_IEEE80211W
1186 && param
->u
.crypt
.idx
> BIP_MAX_KEYID
1187 #endif //CONFIG_IEEE80211W
1198 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0)
1200 RT_TRACE(_module_rtl871x_ioctl_os_c
,_drv_err_
,("wpa_set_encryption, crypt.alg = WEP\n"));
1201 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
1203 wep_key_idx
= param
->u
.crypt
.idx
;
1204 wep_key_len
= param
->u
.crypt
.key_len
;
1206 if ((wep_key_idx
> WEP_KEYS
) || (wep_key_len
<= 0))
1212 if (psecuritypriv
->bWepDefaultKeyIdxSet
== 0)
1214 //wep default key has not been set, so use this key index as default key.
1216 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
1218 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
1219 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP40_
;
1220 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
1224 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP104_
;
1225 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
1228 psecuritypriv
->dot11PrivacyKeyIndex
= wep_key_idx
;
1231 _rtw_memcpy(&(psecuritypriv
->dot11DefKey
[wep_key_idx
].skey
[0]), param
->u
.crypt
.key
, wep_key_len
);
1233 psecuritypriv
->dot11DefKeylen
[wep_key_idx
] = wep_key_len
;
1235 rtw_set_key(padapter
, psecuritypriv
, wep_key_idx
, 0);
1240 if(padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) // 802_1x
1242 struct sta_info
* psta
,*pbcmc_sta
;
1243 struct sta_priv
* pstapriv
= &padapter
->stapriv
;
1245 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
1247 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_MP_STATE
) == _TRUE
) //sta mode
1249 psta
= rtw_get_stainfo(pstapriv
, get_bssid(pmlmepriv
));
1251 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1252 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__
);
1256 //Jeff: don't disable ieee8021x_blocked while clearing key
1257 if (strcmp(param
->u
.crypt
.alg
, "none") != 0)
1258 psta
->ieee8021x_blocked
= _FALSE
;
1261 if((padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption2Enabled
)||
1262 (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption3Enabled
))
1264 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
1267 if(param
->u
.crypt
.set_tx
==1)//pairwise key
1270 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__
);
1272 _rtw_memcpy(psta
->dot118021x_UncstKey
.skey
, param
->u
.crypt
.key
, (param
->u
.crypt
.key_len
>16 ?16:param
->u
.crypt
.key_len
));
1274 if(strcmp(param
->u
.crypt
.alg
, "TKIP") == 0)//set mic key
1276 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1277 _rtw_memcpy(psta
->dot11tkiptxmickey
.skey
, &(param
->u
.crypt
.key
[16]), 8);
1278 _rtw_memcpy(psta
->dot11tkiprxmickey
.skey
, &(param
->u
.crypt
.key
[24]), 8);
1280 padapter
->securitypriv
.busetkipkey
=_FALSE
;
1281 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1284 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1285 DBG_871X(" ~~~~set sta key:unicastkey\n");
1287 rtw_setstakey_cmd(padapter
, (unsigned char *)psta
, _TRUE
);
1291 if(strcmp(param
->u
.crypt
.alg
, "TKIP") == 0 || strcmp(param
->u
.crypt
.alg
, "CCMP") == 0)
1293 _rtw_memcpy(padapter
->securitypriv
.dot118021XGrpKey
[param
->u
.crypt
.idx
].skey
, param
->u
.crypt
.key
,(param
->u
.crypt
.key_len
>16 ?16:param
->u
.crypt
.key_len
));
1294 _rtw_memcpy(padapter
->securitypriv
.dot118021XGrptxmickey
[param
->u
.crypt
.idx
].skey
,&(param
->u
.crypt
.key
[16]),8);
1295 _rtw_memcpy(padapter
->securitypriv
.dot118021XGrprxmickey
[param
->u
.crypt
.idx
].skey
,&(param
->u
.crypt
.key
[24]),8);
1296 padapter
->securitypriv
.binstallGrpkey
= _TRUE
;
1297 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1298 DBG_871X(" ~~~~set sta key:groupkey\n");
1300 padapter
->securitypriv
.dot118021XGrpKeyid
= param
->u
.crypt
.idx
;
1302 rtw_set_key(padapter
,&padapter
->securitypriv
,param
->u
.crypt
.idx
, 1);
1304 #ifdef CONFIG_IEEE80211W
1305 else if(strcmp(param
->u
.crypt
.alg
, "BIP") == 0)
1308 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
1309 //save the IGTK key, length 16 bytes
1310 _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
));
1311 /*DBG_871X("IGTK key below:\n");
1312 for(no=0;no<16;no++)
1313 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1315 padapter
->securitypriv
.dot11wBIPKeyid
= param
->u
.crypt
.idx
;
1316 padapter
->securitypriv
.binstallBIPkey
= _TRUE
;
1317 DBG_871X(" ~~~~set sta key:IGKT\n");
1319 #endif //CONFIG_IEEE80211W
1322 if(pwdinfo
->driver_interface
== DRIVER_CFG80211
)
1324 if(rtw_p2p_chk_state(pwdinfo
, P2P_STATE_PROVISIONING_ING
))
1326 rtw_p2p_set_state(pwdinfo
, P2P_STATE_PROVISIONING_DONE
);
1334 pbcmc_sta
=rtw_get_bcmc_stainfo(padapter
);
1337 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1341 //Jeff: don't disable ieee8021x_blocked while clearing key
1342 if (strcmp(param
->u
.crypt
.alg
, "none") != 0)
1343 pbcmc_sta
->ieee8021x_blocked
= _FALSE
;
1345 if((padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption2Enabled
)||
1346 (padapter
->securitypriv
.ndisencryptstatus
== Ndis802_11Encryption3Enabled
))
1348 pbcmc_sta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
1352 else if(check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) //adhoc mode
1359 DBG_8192C("%s, ret=%d\n", __func__
, ret
);
1366 static int cfg80211_rtw_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1367 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1368 u8 key_index
, bool pairwise
, const u8
*mac_addr
,
1369 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1370 u8 key_index
, const u8
*mac_addr
,
1371 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1372 struct key_params
*params
)
1376 struct ieee_param
*param
= NULL
;
1378 struct wireless_dev
*rtw_wdev
= wiphy_to_wdev(wiphy
);
1379 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
1380 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1382 DBG_871X(FUNC_NDEV_FMT
" adding key for %pM\n", FUNC_NDEV_ARG(ndev
), mac_addr
);
1383 DBG_871X("cipher=0x%x\n", params
->cipher
);
1384 DBG_871X("key_len=0x%x\n", params
->key_len
);
1385 DBG_871X("seq_len=0x%x\n", params
->seq_len
);
1386 DBG_871X("key_index=%d\n", key_index
);
1387 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1388 DBG_871X("pairwise=%d\n", pairwise
);
1389 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1391 param_len
= sizeof(struct ieee_param
) + params
->key_len
;
1392 param
= (struct ieee_param
*)rtw_malloc(param_len
);
1396 _rtw_memset(param
, 0, param_len
);
1398 param
->cmd
= IEEE_CMD_SET_ENCRYPTION
;
1399 _rtw_memset(param
->sta_addr
, 0xff, ETH_ALEN
);
1401 switch (params
->cipher
) {
1402 case IW_AUTH_CIPHER_NONE
:
1407 case WLAN_CIPHER_SUITE_WEP40
:
1408 case WLAN_CIPHER_SUITE_WEP104
:
1411 case WLAN_CIPHER_SUITE_TKIP
:
1414 case WLAN_CIPHER_SUITE_CCMP
:
1417 #ifdef CONFIG_IEEE80211W
1418 case WLAN_CIPHER_SUITE_AES_CMAC
:
1421 #endif //CONFIG_IEEE80211W
1426 strncpy((char *)param
->u
.crypt
.alg
, alg_name
, IEEE_CRYPT_ALG_NAME_LEN
);
1429 if (!mac_addr
|| is_broadcast_ether_addr(mac_addr
))
1431 param
->u
.crypt
.set_tx
= 0; //for wpa/wpa2 group key
1433 param
->u
.crypt
.set_tx
= 1; //for wpa/wpa2 pairwise key
1437 //param->u.crypt.idx = key_index - 1;
1438 param
->u
.crypt
.idx
= key_index
;
1440 if (params
->seq_len
&& params
->seq
)
1442 _rtw_memcpy(param
->u
.crypt
.seq
, params
->seq
, params
->seq_len
);
1445 if(params
->key_len
&& params
->key
)
1447 param
->u
.crypt
.key_len
= params
->key_len
;
1448 _rtw_memcpy(param
->u
.crypt
.key
, params
->key
, params
->key_len
);
1451 if(check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == _TRUE
)
1453 ret
= rtw_cfg80211_set_encryption(ndev
, param
, param_len
);
1455 else if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
1457 #ifdef CONFIG_AP_MODE
1459 _rtw_memcpy(param
->sta_addr
, (void*)mac_addr
, ETH_ALEN
);
1461 ret
= rtw_cfg80211_ap_set_encryption(ndev
, param
, param_len
);
1466 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv
->fw_state
, rtw_wdev
->iftype
);
1472 rtw_mfree((u8
*)param
, param_len
);
1479 static int cfg80211_rtw_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1480 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1481 u8 key_index
, bool pairwise
, const u8
*mac_addr
,
1482 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1483 u8 key_index
, const u8
*mac_addr
,
1484 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1486 void (*callback
)(void *cookie
,
1487 struct key_params
*))
1490 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
1491 struct iwm_key
*key
= &iwm
->keys
[key_index
];
1492 struct key_params params
;
1494 IWM_DBG_WEXT(iwm
, DBG
, "Getting key %d\n", key_index
);
1496 memset(¶ms
, 0, sizeof(params
));
1498 params
.cipher
= key
->cipher
;
1499 params
.key_len
= key
->key_len
;
1500 params
.seq_len
= key
->seq_len
;
1501 params
.seq
= key
->seq
;
1502 params
.key
= key
->key
;
1504 callback(cookie
, ¶ms
);
1506 return key
->key_len
? 0 : -ENOENT
;
1508 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
1512 static int cfg80211_rtw_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1513 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1514 u8 key_index
, bool pairwise
, const u8
*mac_addr
)
1515 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1516 u8 key_index
, const u8
*mac_addr
)
1517 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1519 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(ndev
);
1520 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1522 DBG_871X(FUNC_NDEV_FMT
" key_index=%d\n", FUNC_NDEV_ARG(ndev
), key_index
);
1524 if (key_index
== psecuritypriv
->dot11PrivacyKeyIndex
)
1526 //clear the flag of wep default key set.
1527 psecuritypriv
->bWepDefaultKeyIdxSet
= 0;
1533 static int cfg80211_rtw_set_default_key(struct wiphy
*wiphy
,
1534 struct net_device
*ndev
, u8 key_index
1535 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1536 , bool unicast
, bool multicast
1540 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(ndev
);
1541 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1543 DBG_871X(FUNC_NDEV_FMT
" key_index=%d"
1544 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1545 ", unicast=%d, multicast=%d"
1547 ".\n", FUNC_NDEV_ARG(ndev
), key_index
1548 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1549 , unicast
, multicast
1553 if ((key_index
< WEP_KEYS
) && ((psecuritypriv
->dot11PrivacyAlgrthm
== _WEP40_
) || (psecuritypriv
->dot11PrivacyAlgrthm
== _WEP104_
))) //set wep default key
1555 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
1557 psecuritypriv
->dot11PrivacyKeyIndex
= key_index
;
1559 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP40_
;
1560 psecuritypriv
->dot118021XGrpPrivacy
= _WEP40_
;
1561 if (psecuritypriv
->dot11DefKeylen
[key_index
] == 13)
1563 psecuritypriv
->dot11PrivacyAlgrthm
= _WEP104_
;
1564 psecuritypriv
->dot118021XGrpPrivacy
= _WEP104_
;
1567 psecuritypriv
->bWepDefaultKeyIdxSet
= 1; //set the flag to represent that wep default key has been set
1574 static int cfg80211_rtw_get_station(struct wiphy
*wiphy
,
1575 struct net_device
*ndev
,
1576 const u8
*mac
, struct station_info
*sinfo
)
1579 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
1580 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1581 struct sta_info
*psta
= NULL
;
1582 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1587 DBG_871X(FUNC_NDEV_FMT
" mac==%p\n", FUNC_NDEV_ARG(ndev
), mac
);
1592 psta
= rtw_get_stainfo(pstapriv
, mac
);
1594 DBG_8192C("%s, sta_info is null\n", __func__
);
1599 #ifdef CONFIG_DEBUG_CFG80211
1600 DBG_871X(FUNC_NDEV_FMT
" mac="MAC_FMT
"\n", FUNC_NDEV_ARG(ndev
), MAC_ARG(mac
));
1603 //for infra./P2PClient mode
1604 if( check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)
1605 && check_fwstate(pmlmepriv
, _FW_LINKED
)
1608 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1610 if (_rtw_memcmp(mac
, cur_network
->network
.MacAddress
, ETH_ALEN
) == _FALSE
) {
1611 DBG_871X("%s, mismatch bssid="MAC_FMT
"\n", __func__
, MAC_ARG(cur_network
->network
.MacAddress
));
1616 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
1617 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
1619 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1621 sinfo
->signal
= translate_percentage_to_dbm(padapter
->recvpriv
.signal_strength
);
1623 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
1624 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BITRATE
);
1626 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1628 sinfo
->txrate
.legacy
= rtw_get_cur_max_rate(padapter
);
1630 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
1631 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_PACKETS
);
1633 sinfo
->filled
|= STATION_INFO_RX_PACKETS
;
1635 sinfo
->rx_packets
= sta_rx_data_pkts(psta
);
1637 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0))
1638 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_PACKETS
);
1640 sinfo
->filled
|= STATION_INFO_TX_PACKETS
;
1642 sinfo
->tx_packets
= psta
->sta_stats
.tx_pkts
;
1646 //for Ad-Hoc/AP mode
1647 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)
1648 ||check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)
1649 ||check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1650 && check_fwstate(pmlmepriv
, _FW_LINKED
)
1653 //TODO: should acquire station info...
1660 extern int netdev_open(struct net_device
*pnetdev
);
1661 #ifdef CONFIG_CONCURRENT_MODE
1662 extern int netdev_if2_open(struct net_device
*pnetdev
);
1666 enum nl80211_iftype {
1667 NL80211_IFTYPE_UNSPECIFIED,
1668 NL80211_IFTYPE_ADHOC, //1
1669 NL80211_IFTYPE_STATION, //2
1670 NL80211_IFTYPE_AP, //3
1671 NL80211_IFTYPE_AP_VLAN,
1673 NL80211_IFTYPE_MONITOR, //6
1674 NL80211_IFTYPE_MESH_POINT,
1675 NL80211_IFTYPE_P2P_CLIENT, //8
1676 NL80211_IFTYPE_P2P_GO, //9
1678 NUM_NL80211_IFTYPES,
1679 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
1682 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1683 static int cfg80211_rtw_change_iface(struct wiphy
*wiphy
,
1684 struct net_device
*ndev
,
1685 enum nl80211_iftype type
,
1686 struct vif_params
*params
)
1688 static int cfg80211_rtw_change_iface(struct wiphy
*wiphy
,
1689 struct net_device
*ndev
,
1690 enum nl80211_iftype type
, u32
*flags
,
1691 struct vif_params
*params
)
1694 enum nl80211_iftype old_type
;
1695 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType
;
1696 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
1697 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1698 struct wireless_dev
*rtw_wdev
= wiphy_to_wdev(wiphy
);
1699 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1701 _queue
*queue
= &pmlmepriv
->scanned_queue
;
1703 struct wifidirect_info
*pwdinfo
= &(padapter
->wdinfo
);
1708 if (adapter_to_dvobj(padapter
)->processing_dev_remove
== _TRUE
) {
1713 #ifdef CONFIG_CONCURRENT_MODE
1714 if(padapter
->adapter_type
== SECONDARY_ADAPTER
)
1716 DBG_871X(FUNC_NDEV_FMT
" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev
));
1717 if(netdev_if2_open(ndev
) != 0) {
1722 else if(padapter
->adapter_type
== PRIMARY_ADAPTER
)
1723 #endif //CONFIG_CONCURRENT_MODE
1725 DBG_871X(FUNC_NDEV_FMT
" call netdev_open\n", FUNC_NDEV_ARG(ndev
));
1726 if(netdev_open(ndev
) != 0) {
1732 if(_FAIL
== rtw_pwr_wakeup(padapter
)) {
1737 old_type
= rtw_wdev
->iftype
;
1738 DBG_871X(FUNC_NDEV_FMT
" old_iftype=%d, new_iftype=%d\n",
1739 FUNC_NDEV_ARG(ndev
), old_type
, type
);
1741 if(old_type
!= type
)
1744 pmlmeext
->action_public_rxseq
= 0xffff;
1745 pmlmeext
->action_public_dialog_token
= 0xff;
1749 case NL80211_IFTYPE_ADHOC
:
1750 networkType
= Ndis802_11IBSS
;
1752 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1753 case NL80211_IFTYPE_P2P_CLIENT
:
1755 case NL80211_IFTYPE_STATION
:
1756 networkType
= Ndis802_11Infrastructure
;
1758 if(pwdinfo
->driver_interface
== DRIVER_CFG80211
)
1760 if(change
&& rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
1762 _cancel_timer_ex( &pwdinfo
->find_phase_timer
);
1763 _cancel_timer_ex( &pwdinfo
->restore_p2p_state_timer
);
1764 _cancel_timer_ex( &pwdinfo
->pre_tx_scan_timer
);
1766 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
1767 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
1768 rtw_p2p_set_state(pwdinfo
, rtw_p2p_pre_state(pwdinfo
));
1770 DBG_8192C("%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
));
1775 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1776 case NL80211_IFTYPE_P2P_GO
:
1778 case NL80211_IFTYPE_AP
:
1779 networkType
= Ndis802_11APMode
;
1781 if(pwdinfo
->driver_interface
== DRIVER_CFG80211
)
1783 if(change
&& !rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
1785 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
1786 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
1795 rtw_wdev
->iftype
= type
;
1797 _enter_critical_bh(&pmlmepriv
->lock
, &irqL
);
1798 _enter_critical_bh(&queue
->lock
, &irqL
);
1800 if (rtw_set_802_11_infrastructure_mode(padapter
, networkType
) ==_FALSE
)
1802 rtw_wdev
->iftype
= old_type
;
1804 _exit_critical_bh(&queue
->lock
, &irqL
);
1805 _exit_critical_bh(&pmlmepriv
->lock
, &irqL
);
1808 _exit_critical_bh(&queue
->lock
, &irqL
);
1809 _exit_critical_bh(&pmlmepriv
->lock
, &irqL
);
1811 rtw_setopmode_cmd(padapter
, networkType
);
1818 void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv
*pwdev_priv
, bool aborted
)
1822 _enter_critical_bh(&pwdev_priv
->scan_req_lock
, &irqL
);
1823 if(pwdev_priv
->scan_request
!= NULL
)
1825 //struct cfg80211_scan_request *scan_request = pwdev_priv->scan_request;
1827 #ifdef CONFIG_DEBUG_CFG80211
1828 DBG_871X("%s with scan req\n", __FUNCTION__
);
1831 //avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
1832 //if(scan_request == wiphy_to_dev(scan_request->wiphy)->scan_req)
1833 if(pwdev_priv
->scan_request
->wiphy
!= pwdev_priv
->rtw_wdev
->wiphy
)
1835 DBG_8192C("error wiphy compare\n");
1839 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
1840 cfg80211_scan_done(pwdev_priv
->scan_request
, aborted
);
1842 struct cfg80211_scan_info info
= {
1846 cfg80211_scan_done(pwdev_priv
->scan_request
, &info
);
1850 pwdev_priv
->scan_request
= NULL
;
1853 #ifdef CONFIG_DEBUG_CFG80211
1854 DBG_871X("%s without scan req\n", __FUNCTION__
);
1857 _exit_critical_bh(&pwdev_priv
->scan_req_lock
, &irqL
);
1860 void rtw_cfg80211_surveydone_event_callback(_adapter
*padapter
)
1863 _list
*plist
, *phead
;
1864 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1865 _queue
*queue
= &(pmlmepriv
->scanned_queue
);
1866 struct wlan_network
*pnetwork
= NULL
;
1868 u32 wait_for_surveydone
;
1871 struct wifidirect_info
* pwdinfo
= &padapter
->wdinfo
;
1873 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
1874 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
1876 #ifdef CONFIG_DEBUG_CFG80211
1877 DBG_8192C("%s\n", __func__
);
1880 _enter_critical_bh(&(pmlmepriv
->scanned_queue
.lock
), &irqL
);
1882 phead
= get_list_head(queue
);
1883 plist
= get_next(phead
);
1887 if (rtw_end_of_queue_search(phead
,plist
)== _TRUE
)
1890 pnetwork
= LIST_CONTAINOR(plist
, struct wlan_network
, list
);
1892 //report network only if the current channel set contains the channel to which this network belongs
1893 if(rtw_ch_set_search_ch(padapter
->mlmeextpriv
.channel_set
, pnetwork
->network
.Configuration
.DSConfig
) >= 0
1894 && rtw_mlme_band_check(padapter
, pnetwork
->network
.Configuration
.DSConfig
) == _TRUE
1895 && _TRUE
== rtw_validate_ssid(&(pnetwork
->network
.Ssid
))
1898 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
1899 rtw_cfg80211_inform_bss(padapter
, pnetwork
);
1902 plist
= get_next(plist
);
1906 _exit_critical_bh(&(pmlmepriv
->scanned_queue
.lock
), &irqL
);
1908 //call this after other things have been done
1909 rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter
->rtw_wdev
), _FALSE
);
1912 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter
*padapter
, char *buf
, int len
)
1921 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1923 #ifdef CONFIG_DEBUG_CFG80211
1924 DBG_8192C("%s, ielen=%d\n", __func__
, len
);
1929 if((wps_ie
= rtw_get_wps_ie(buf
, len
, NULL
, &wps_ielen
)))
1931 #ifdef CONFIG_DEBUG_CFG80211
1932 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen
);
1935 if(pmlmepriv
->wps_probe_req_ie
)
1937 u32 free_len
= pmlmepriv
->wps_probe_req_ie_len
;
1938 pmlmepriv
->wps_probe_req_ie_len
= 0;
1939 rtw_mfree(pmlmepriv
->wps_probe_req_ie
, free_len
);
1940 pmlmepriv
->wps_probe_req_ie
= NULL
;
1943 pmlmepriv
->wps_probe_req_ie
= rtw_malloc(wps_ielen
);
1944 if ( pmlmepriv
->wps_probe_req_ie
== NULL
) {
1945 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
1949 _rtw_memcpy(pmlmepriv
->wps_probe_req_ie
, wps_ie
, wps_ielen
);
1950 pmlmepriv
->wps_probe_req_ie_len
= wps_ielen
;
1957 if((p2p_ie
=rtw_get_p2p_ie(buf
, len
, NULL
, &p2p_ielen
)))
1959 struct wifidirect_info
*wdinfo
= &padapter
->wdinfo
;
1960 u32 attr_contentlen
= 0;
1961 u8 listen_ch_attr
[5];
1963 #ifdef CONFIG_DEBUG_CFG80211
1964 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen
);
1967 if(pmlmepriv
->p2p_probe_req_ie
)
1969 u32 free_len
= pmlmepriv
->p2p_probe_req_ie_len
;
1970 pmlmepriv
->p2p_probe_req_ie_len
= 0;
1971 rtw_mfree(pmlmepriv
->p2p_probe_req_ie
, free_len
);
1972 pmlmepriv
->p2p_probe_req_ie
= NULL
;
1975 pmlmepriv
->p2p_probe_req_ie
= rtw_malloc(p2p_ielen
);
1976 if ( pmlmepriv
->p2p_probe_req_ie
== NULL
) {
1977 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
1981 _rtw_memcpy(pmlmepriv
->p2p_probe_req_ie
, p2p_ie
, p2p_ielen
);
1982 pmlmepriv
->p2p_probe_req_ie_len
= p2p_ielen
;
1984 if(rtw_get_p2p_attr_content(p2p_ie
, p2p_ielen
, P2P_ATTR_LISTEN_CH
, (u8
*)listen_ch_attr
, (uint
*) &attr_contentlen
)
1985 && attr_contentlen
== 5)
1987 if (wdinfo
->listen_channel
!= listen_ch_attr
[4]) {
1988 DBG_871X(FUNC_ADPT_FMT
" listen channel - country:%c%c%c, class:%u, ch:%u\n",
1989 FUNC_ADPT_ARG(padapter
), listen_ch_attr
[0], listen_ch_attr
[1], listen_ch_attr
[2],
1990 listen_ch_attr
[3], listen_ch_attr
[4]);
1991 wdinfo
->listen_channel
= listen_ch_attr
[4];
2001 if(rtw_get_wfd_ie(buf
, len
, NULL
, &wfd_ielen
))
2003 #ifdef CONFIG_DEBUG_CFG80211
2004 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen
);
2007 if(pmlmepriv
->wfd_probe_req_ie
)
2009 u32 free_len
= pmlmepriv
->wfd_probe_req_ie_len
;
2010 pmlmepriv
->wfd_probe_req_ie_len
= 0;
2011 rtw_mfree(pmlmepriv
->wfd_probe_req_ie
, free_len
);
2012 pmlmepriv
->wfd_probe_req_ie
= NULL
;
2015 pmlmepriv
->wfd_probe_req_ie
= rtw_malloc(wfd_ielen
);
2016 if ( pmlmepriv
->wfd_probe_req_ie
== NULL
) {
2017 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
2021 rtw_get_wfd_ie(buf
, len
, pmlmepriv
->wfd_probe_req_ie
, &pmlmepriv
->wfd_probe_req_ie_len
);
2031 static int cfg80211_rtw_scan(struct wiphy
*wiphy
2032 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2033 , struct net_device
*ndev
2035 , struct cfg80211_scan_request
*request
)
2038 u8 _status
= _FALSE
;
2040 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
2041 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2042 NDIS_802_11_SSID ssid
[RTW_SSID_SCAN_AMOUNT
];
2043 struct rtw_ieee80211_channel ch
[RTW_CHANNEL_SCAN_AMOUNT
];
2050 u8 survey_times_for_one_ch
=6;
2052 struct wifidirect_info
*pwdinfo
= &(padapter
->wdinfo
);
2054 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
2055 struct cfg80211_ssid
*ssids
= request
->ssids
;
2056 int social_channel
= 0, j
= 0;
2057 bool need_indicate_scan_done
= _FALSE
;
2058 #ifdef CONFIG_CONCURRENT_MODE
2059 PADAPTER pbuddy_adapter
= NULL
;
2060 struct mlme_priv
*pbuddy_mlmepriv
= NULL
;
2061 #endif //CONFIG_CONCURRENT_MODE
2063 //#ifdef CONFIG_DEBUG_CFG80211
2064 DBG_871X(FUNC_ADPT_FMT
"\n", FUNC_ADPT_ARG(padapter
));
2067 #ifdef CONFIG_CONCURRENT_MODE
2068 if (padapter
->pbuddy_adapter
) {
2069 pbuddy_adapter
= padapter
->pbuddy_adapter
;
2070 pbuddy_mlmepriv
= &(pbuddy_adapter
->mlmepriv
);
2072 #endif //CONFIG_CONCURRENT_MODE
2074 #ifdef CONFIG_MP_INCLUDED
2075 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
)
2082 _enter_critical_bh(&pwdev_priv
->scan_req_lock
, &irqL
);
2083 pwdev_priv
->scan_request
= request
;
2084 _exit_critical_bh(&pwdev_priv
->scan_req_lock
, &irqL
);
2086 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
2088 #ifdef CONFIG_DEBUG_CFG80211
2089 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__
);
2092 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
|_FW_UNDER_SURVEY
|_FW_UNDER_LINKING
) == _TRUE
)
2094 DBG_8192C("%s, fwstate=0x%x\n", __func__
, pmlmepriv
->fw_state
);
2096 if(check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
))
2098 DBG_8192C("AP mode process WPS \n");
2101 need_indicate_scan_done
= _TRUE
;
2102 goto check_need_indicate_scan_done
;
2106 if(_FAIL
== rtw_pwr_wakeup(padapter
)) {
2107 need_indicate_scan_done
= _TRUE
;
2108 goto check_need_indicate_scan_done
;
2112 if( pwdinfo
->driver_interface
== DRIVER_CFG80211
)
2114 if(ssids
->ssid
!= NULL
2115 && _rtw_memcmp(ssids
->ssid
, "DIRECT-", 7)
2116 && rtw_get_p2p_ie((u8
*)request
->ie
, request
->ie_len
, NULL
, NULL
)
2119 if(rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
2121 u32 initialgain
= 0x30;
2122 rtw_p2p_enable(padapter
, P2P_ROLE_DEVICE
);
2123 wdev_to_priv(padapter
->rtw_wdev
)->p2p_enabled
= _TRUE
;
2124 padapter
->HalFunc
.SetHwRegHandler(padapter
, HW_VAR_INITIAL_GAIN
, (u8
*)&(initialgain
));
2125 padapter
->HalFunc
.SetHwRegHandler(padapter
, HW_VAR_INITIAL_GAIN
, (u8
*)&(initialgain
));
2129 rtw_p2p_set_pre_state(pwdinfo
, rtw_p2p_state(pwdinfo
));
2130 #ifdef CONFIG_DEBUG_CFG80211
2131 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__
, rtw_p2p_role(pwdinfo
), rtw_p2p_state(pwdinfo
));
2134 rtw_p2p_set_state(pwdinfo
, P2P_STATE_LISTEN
);
2136 if(request
->n_channels
== 3 &&
2137 request
->channels
[0]->hw_value
== 1 &&
2138 request
->channels
[1]->hw_value
== 6 &&
2139 request
->channels
[2]->hw_value
== 11
2148 if(request
->ie
&& request
->ie_len
>0)
2150 rtw_cfg80211_set_probe_req_wpsp2pie(padapter
, (u8
*)request
->ie
, request
->ie_len
);
2153 if (pmlmepriv
->LinkDetectInfo
.bBusyTraffic
== _TRUE
)
2155 DBG_8192C("%s, bBusyTraffic == _TRUE\n", __func__
);
2156 need_indicate_scan_done
= _TRUE
;
2157 goto check_need_indicate_scan_done
;
2159 if (rtw_is_scan_deny(padapter
)){
2160 DBG_871X(FUNC_ADPT_FMT
": scan deny\n", FUNC_ADPT_ARG(padapter
));
2161 need_indicate_scan_done
= _TRUE
;
2162 goto check_need_indicate_scan_done
;
2165 #ifdef CONFIG_CONCURRENT_MODE
2166 if(pbuddy_mlmepriv
&& (pbuddy_mlmepriv
->LinkDetectInfo
.bBusyTraffic
== _TRUE
))
2168 DBG_8192C("%s, bBusyTraffic == _TRUE at buddy_intf\n", __func__
);
2169 need_indicate_scan_done
= _TRUE
;
2170 goto check_need_indicate_scan_done
;
2172 #endif //CONFIG_CONCURRENT_MODE
2174 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
|_FW_UNDER_LINKING
) == _TRUE
)
2176 DBG_8192C("%s, fwstate=0x%x\n", __func__
, pmlmepriv
->fw_state
);
2177 need_indicate_scan_done
= _TRUE
;
2178 goto check_need_indicate_scan_done
;
2181 #ifdef CONFIG_CONCURRENT_MODE
2182 if (check_buddy_fwstate(padapter
,
2183 _FW_UNDER_SURVEY
|_FW_UNDER_LINKING
|WIFI_UNDER_WPS
) == _TRUE
)
2185 if(check_buddy_fwstate(padapter
, _FW_UNDER_SURVEY
))
2187 DBG_8192C("scanning_via_buddy_intf\n");
2188 pmlmepriv
->scanning_via_buddy_intf
= _TRUE
;
2191 DBG_8192C("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv
->fw_state
);
2193 need_indicate_scan_done
= _TRUE
;
2194 goto check_need_indicate_scan_done
;
2200 if( pwdinfo
->driver_interface
== DRIVER_CFG80211
)
2202 if(!rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
) && !rtw_p2p_chk_state(pwdinfo
, P2P_STATE_IDLE
))
2204 rtw_p2p_set_state(pwdinfo
, P2P_STATE_FIND_PHASE_SEARCH
);
2205 rtw_free_network_queue(padapter
, _TRUE
);
2207 if(social_channel
== 0)
2208 rtw_p2p_findphase_ex_set(pwdinfo
, P2P_FINDPHASE_EX_NONE
);
2210 rtw_p2p_findphase_ex_set(pwdinfo
, P2P_FINDPHASE_EX_SOCIAL_LAST
);
2216 _rtw_memset(ssid
, 0, sizeof(NDIS_802_11_SSID
)*RTW_SSID_SCAN_AMOUNT
);
2217 //parsing request ssids, n_ssids
2218 for (i
= 0; i
< request
->n_ssids
&& i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
2219 #ifdef CONFIG_DEBUG_CFG80211
2220 DBG_8192C("ssid=%s, len=%d\n", ssids
[i
].ssid
, ssids
[i
].ssid_len
);
2222 _rtw_memcpy(ssid
[i
].Ssid
, ssids
[i
].ssid
, ssids
[i
].ssid_len
);
2223 ssid
[i
].SsidLength
= ssids
[i
].ssid_len
;
2227 /* parsing channels, n_channels */
2228 _rtw_memset(ch
, 0, sizeof(struct rtw_ieee80211_channel
)*RTW_CHANNEL_SCAN_AMOUNT
);
2229 for (i
=0;i
<request
->n_channels
&& i
<RTW_CHANNEL_SCAN_AMOUNT
;i
++) {
2230 #ifdef CONFIG_DEBUG_CFG80211
2231 DBG_871X(FUNC_ADPT_FMT CHAN_FMT
"\n", FUNC_ADPT_ARG(padapter
), CHAN_ARG(request
->channels
[i
]));
2233 ch
[i
].hw_value
= request
->channels
[i
]->hw_value
;
2234 ch
[i
].flags
= request
->channels
[i
]->flags
;
2237 _enter_critical_bh(&pmlmepriv
->lock
, &irqL
);
2238 if (request
->n_channels
== 1) {
2239 for(i
=1;i
<survey_times_for_one_ch
;i
++)
2240 _rtw_memcpy(&ch
[i
], &ch
[0], sizeof(struct rtw_ieee80211_channel
));
2241 _status
= rtw_sitesurvey_cmd(padapter
, ssid
, RTW_SSID_SCAN_AMOUNT
, ch
, survey_times_for_one_ch
);
2242 } else if (request
->n_channels
== 2) {
2243 _rtw_memcpy(&ch
[3], &ch
[1], sizeof(struct rtw_ieee80211_channel
));
2244 for(i
=1;i
<survey_times
;i
++) {
2245 _rtw_memcpy(&ch
[i
], &ch
[0], sizeof(struct rtw_ieee80211_channel
));
2246 _rtw_memcpy(&ch
[i
+3], &ch
[3], sizeof(struct rtw_ieee80211_channel
));
2248 _status
= rtw_sitesurvey_cmd(padapter
, ssid
, RTW_SSID_SCAN_AMOUNT
, ch
, survey_times
* 2);
2250 _status
= rtw_sitesurvey_cmd(padapter
, ssid
, RTW_SSID_SCAN_AMOUNT
, NULL
, 0);
2252 _exit_critical_bh(&pmlmepriv
->lock
, &irqL
);
2255 if(_status
== _FALSE
)
2260 check_need_indicate_scan_done
:
2261 if(need_indicate_scan_done
)
2262 rtw_cfg80211_surveydone_event_callback(padapter
);
2270 static int cfg80211_rtw_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
2273 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
2275 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
2276 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
2279 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
2281 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
2283 iwm
->conf
.rts_threshold
);
2288 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
2289 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
2292 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
2294 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
2296 iwm
->conf
.frag_threshold
);
2301 DBG_8192C("%s\n", __func__
);
2305 static int cfg80211_rtw_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
2306 struct cfg80211_ibss_params
*params
)
2309 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
2310 struct ieee80211_channel
*chan
= params
->channel
;
2312 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
2315 /* UMAC doesn't support creating or joining an IBSS network
2316 * with specified bssid. */
2320 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
2321 iwm
->umac_profile
->ibss
.band
= chan
->band
;
2322 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
2323 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
2324 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
2326 return iwm_send_mlme_profile(iwm
);
2328 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
2332 static int cfg80211_rtw_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
2335 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
2337 if (iwm
->umac_profile_active
)
2338 return iwm_invalidate_mlme_profile(iwm
);
2340 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
2344 static int rtw_cfg80211_set_wpa_version(struct security_priv
*psecuritypriv
, u32 wpa_version
)
2346 DBG_8192C("%s, wpa_version=%d\n", __func__
, wpa_version
);
2349 psecuritypriv
->ndisauthtype
= Ndis802_11AuthModeOpen
;
2354 if (wpa_version
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
2356 psecuritypriv
->ndisauthtype
= Ndis802_11AuthModeWPAPSK
;
2360 if (wpa_version & NL80211_WPA_VERSION_2)
2362 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2370 static int rtw_cfg80211_set_auth_type(struct security_priv
*psecuritypriv
,
2371 enum nl80211_auth_type sme_auth_type
)
2373 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__
, sme_auth_type
);
2376 switch (sme_auth_type
) {
2377 case NL80211_AUTHTYPE_AUTOMATIC
:
2379 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_Auto
;
2382 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
2384 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
2386 if(psecuritypriv
->ndisauthtype
>Ndis802_11AuthModeWPA
)
2387 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
2390 case NL80211_AUTHTYPE_SHARED_KEY
:
2392 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_Shared
;
2394 psecuritypriv
->ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2399 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
;
2407 static int rtw_cfg80211_set_cipher(struct security_priv
*psecuritypriv
, u32 cipher
, bool ucast
)
2409 u32 ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
2411 u32
*profile_cipher
= ucast
? &psecuritypriv
->dot11PrivacyAlgrthm
:
2412 &psecuritypriv
->dot118021XGrpPrivacy
;
2414 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__
, ucast
, cipher
);
2418 *profile_cipher
= _NO_PRIVACY_
;
2419 psecuritypriv
->ndisencryptstatus
= ndisencryptstatus
;
2424 case IW_AUTH_CIPHER_NONE
:
2425 *profile_cipher
= _NO_PRIVACY_
;
2426 ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
2428 case WLAN_CIPHER_SUITE_WEP40
:
2429 *profile_cipher
= _WEP40_
;
2430 ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2432 case WLAN_CIPHER_SUITE_WEP104
:
2433 *profile_cipher
= _WEP104_
;
2434 ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2436 case WLAN_CIPHER_SUITE_TKIP
:
2437 *profile_cipher
= _TKIP_
;
2438 ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
2440 case WLAN_CIPHER_SUITE_CCMP
:
2441 *profile_cipher
= _AES_
;
2442 ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
2445 DBG_8192C("Unsupported cipher: 0x%x\n", cipher
);
2451 psecuritypriv
->ndisencryptstatus
= ndisencryptstatus
;
2453 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
2454 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2460 static int rtw_cfg80211_set_key_mgt(struct security_priv
*psecuritypriv
, u32 key_mgt
)
2462 DBG_8192C("%s, key_mgt=0x%x\n", __func__
, key_mgt
);
2464 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
2465 //*auth_type = UMAC_AUTH_TYPE_8021X;
2466 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
2467 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
2468 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
2470 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt
);
2477 static int rtw_cfg80211_set_wpa_ie(_adapter
*padapter
, const u8
*pie
, size_t ielen
)
2479 u8
*buf
=NULL
, *pos
=NULL
;
2481 int group_cipher
= 0, pairwise_cipher
= 0;
2486 u8 null_addr
[]= {0,0,0,0,0,0};
2488 if (pie
== NULL
|| !ielen
) {
2489 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
2490 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
2494 if (ielen
> MAX_WPA_IE_LEN
+MAX_WPS_IE_LEN
+MAX_P2P_IE_LEN
) {
2499 buf
= rtw_zmalloc(ielen
);
2505 _rtw_memcpy(buf
, pie
, ielen
);
2510 DBG_8192C("set wpa_ie(length:%zu):\n", ielen
);
2511 for(i
=0;i
<ielen
;i
=i
+8)
2512 DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf
[i
],buf
[i
+1],buf
[i
+2],buf
[i
+3],buf
[i
+4],buf
[i
+5],buf
[i
+6],buf
[i
+7]);
2516 if(ielen
< RSN_HEADER_LEN
){
2517 RT_TRACE(_module_rtl871x_ioctl_os_c
,_drv_err_
,("Ie len too short %d\n", ielen
));
2522 pwpa
= rtw_get_wpa_ie(buf
, &wpa_ielen
, ielen
);
2523 if(pwpa
&& wpa_ielen
>0)
2525 if(rtw_parse_wpa_ie(pwpa
, wpa_ielen
+2, &group_cipher
, &pairwise_cipher
) == _SUCCESS
)
2527 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
2528 padapter
->securitypriv
.ndisauthtype
=Ndis802_11AuthModeWPAPSK
;
2529 _rtw_memcpy(padapter
->securitypriv
.supplicant_ie
, &pwpa
[0], wpa_ielen
+2);
2531 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen
);
2535 pwpa2
= rtw_get_wpa2_ie(buf
, &wpa2_ielen
, ielen
);
2536 if(pwpa2
&& wpa2_ielen
>0)
2538 if(rtw_parse_wpa2_ie(pwpa2
, wpa2_ielen
+2, &group_cipher
, &pairwise_cipher
) == _SUCCESS
)
2540 padapter
->securitypriv
.dot11AuthAlgrthm
= dot11AuthAlgrthm_8021X
;
2541 padapter
->securitypriv
.ndisauthtype
=Ndis802_11AuthModeWPA2PSK
;
2542 _rtw_memcpy(padapter
->securitypriv
.supplicant_ie
, &pwpa2
[0], wpa2_ielen
+2);
2544 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen
);
2548 if (group_cipher
== 0)
2550 group_cipher
= WPA_CIPHER_NONE
;
2552 if (pairwise_cipher
== 0)
2554 pairwise_cipher
= WPA_CIPHER_NONE
;
2557 switch(group_cipher
)
2559 case WPA_CIPHER_NONE
:
2560 padapter
->securitypriv
.dot118021XGrpPrivacy
=_NO_PRIVACY_
;
2561 padapter
->securitypriv
.ndisencryptstatus
=Ndis802_11EncryptionDisabled
;
2563 case WPA_CIPHER_WEP40
:
2564 padapter
->securitypriv
.dot118021XGrpPrivacy
=_WEP40_
;
2565 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2567 case WPA_CIPHER_TKIP
:
2568 padapter
->securitypriv
.dot118021XGrpPrivacy
=_TKIP_
;
2569 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
2571 case WPA_CIPHER_CCMP
:
2572 padapter
->securitypriv
.dot118021XGrpPrivacy
=_AES_
;
2573 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
2575 case WPA_CIPHER_WEP104
:
2576 padapter
->securitypriv
.dot118021XGrpPrivacy
=_WEP104_
;
2577 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2581 switch(pairwise_cipher
)
2583 case WPA_CIPHER_NONE
:
2584 padapter
->securitypriv
.dot11PrivacyAlgrthm
=_NO_PRIVACY_
;
2585 padapter
->securitypriv
.ndisencryptstatus
=Ndis802_11EncryptionDisabled
;
2587 case WPA_CIPHER_WEP40
:
2588 padapter
->securitypriv
.dot11PrivacyAlgrthm
=_WEP40_
;
2589 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2591 case WPA_CIPHER_TKIP
:
2592 padapter
->securitypriv
.dot11PrivacyAlgrthm
=_TKIP_
;
2593 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption2Enabled
;
2595 case WPA_CIPHER_CCMP
:
2596 padapter
->securitypriv
.dot11PrivacyAlgrthm
=_AES_
;
2597 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption3Enabled
;
2599 case WPA_CIPHER_WEP104
:
2600 padapter
->securitypriv
.dot11PrivacyAlgrthm
=_WEP104_
;
2601 padapter
->securitypriv
.ndisencryptstatus
= Ndis802_11Encryption1Enabled
;
2605 {/* handle wps_ie */
2609 wps_ie
= rtw_get_wps_ie(buf
, ielen
, NULL
, &wps_ielen
);
2610 if (wps_ie
&& wps_ielen
> 0) {
2611 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen
);
2612 padapter
->securitypriv
.wps_ie_len
= wps_ielen
<MAX_WPS_IE_LEN
?wps_ielen
:MAX_WPS_IE_LEN
;
2613 _rtw_memcpy(padapter
->securitypriv
.wps_ie
, wps_ie
, padapter
->securitypriv
.wps_ie_len
);
2614 set_fwstate(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
2616 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
2621 {//check p2p_ie for assoc req;
2624 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2626 if((p2p_ie
=rtw_get_p2p_ie(buf
, ielen
, NULL
, &p2p_ielen
)))
2628 #ifdef CONFIG_DEBUG_CFG80211
2629 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__
, p2p_ielen
);
2632 if(pmlmepriv
->p2p_assoc_req_ie
)
2634 u32 free_len
= pmlmepriv
->p2p_assoc_req_ie_len
;
2635 pmlmepriv
->p2p_assoc_req_ie_len
= 0;
2636 rtw_mfree(pmlmepriv
->p2p_assoc_req_ie
, free_len
);
2637 pmlmepriv
->p2p_assoc_req_ie
= NULL
;
2640 pmlmepriv
->p2p_assoc_req_ie
= rtw_malloc(p2p_ielen
);
2641 if ( pmlmepriv
->p2p_assoc_req_ie
== NULL
) {
2642 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
2645 _rtw_memcpy(pmlmepriv
->p2p_assoc_req_ie
, p2p_ie
, p2p_ielen
);
2646 pmlmepriv
->p2p_assoc_req_ie_len
= p2p_ielen
;
2652 {//check wfd_ie for assoc req;
2655 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
2657 if(rtw_get_wfd_ie(buf
, ielen
, NULL
, &wfd_ielen
))
2659 #ifdef CONFIG_DEBUG_CFG80211
2660 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__
, wfd_ielen
);
2663 if(pmlmepriv
->wfd_assoc_req_ie
)
2665 u32 free_len
= pmlmepriv
->wfd_assoc_req_ie_len
;
2666 pmlmepriv
->wfd_assoc_req_ie_len
= 0;
2667 rtw_mfree(pmlmepriv
->wfd_assoc_req_ie
, free_len
);
2668 pmlmepriv
->wfd_assoc_req_ie
= NULL
;
2671 pmlmepriv
->wfd_assoc_req_ie
= rtw_malloc(wfd_ielen
);
2672 if ( pmlmepriv
->wfd_assoc_req_ie
== NULL
) {
2673 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
2676 rtw_get_wfd_ie(buf
, ielen
, pmlmepriv
->wfd_assoc_req_ie
, &pmlmepriv
->wfd_assoc_req_ie_len
);
2681 //TKIP and AES disallow multicast packets until installing group key
2682 if(padapter
->securitypriv
.dot11PrivacyAlgrthm
== _TKIP_
2683 || padapter
->securitypriv
.dot11PrivacyAlgrthm
== _TKIP_WTMIC_
2684 || padapter
->securitypriv
.dot11PrivacyAlgrthm
== _AES_
)
2685 //WPS open need to enable multicast
2686 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
2687 rtw_hal_set_hwreg(padapter
, HW_VAR_OFF_RCR_AM
, null_addr
);
2689 RT_TRACE(_module_rtl871x_ioctl_os_c
, _drv_info_
,
2690 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
2691 pairwise_cipher
, padapter
->securitypriv
.ndisencryptstatus
, padapter
->securitypriv
.ndisauthtype
));
2695 rtw_mfree(buf
, ielen
);
2697 _clr_fwstate_(&padapter
->mlmepriv
, WIFI_UNDER_WPS
);
2701 static int cfg80211_rtw_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
2702 struct cfg80211_connect_params
*sme
)
2707 struct wlan_network
*pnetwork
= NULL
;
2708 NDIS_802_11_AUTHENTICATION_MODE authmode
;
2709 NDIS_802_11_SSID ndis_ssid
;
2710 u8
*dst_ssid
, *src_ssid
;
2711 u8
*dst_bssid
, *src_bssid
;
2712 //u8 matched_by_bssid=_FALSE;
2713 //u8 matched_by_ssid=_FALSE;
2715 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
2716 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2717 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
2718 _queue
*queue
= &pmlmepriv
->scanned_queue
;
2720 DBG_871X("=>"FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
2721 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
2722 sme
->privacy
, sme
->key
, sme
->key_len
, sme
->key_idx
);
2725 if(wdev_to_priv(padapter
->rtw_wdev
)->block
== _TRUE
)
2728 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__
);
2732 #ifdef CONFIG_PLATFORM_MSTAR
2733 printk("MStar Android!\n");
2734 if((wdev_to_priv(padapter
->rtw_wdev
))->bandroid_scan
== _FALSE
)
2737 struct wifidirect_info
*pwdinfo
= &(padapter
->wdinfo
);
2738 if(rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
2742 printk("Android hasn't attached yet!\n");
2748 if(_FAIL
== rtw_pwr_wakeup(padapter
)) {
2753 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
2758 #ifdef CONFIG_CONCURRENT_MODE
2759 if (check_buddy_fwstate(padapter
, _FW_UNDER_LINKING
) == _TRUE
) {
2760 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__
);
2764 if (check_buddy_fwstate(padapter
, _FW_UNDER_SURVEY
) == _TRUE
) {
2765 rtw_scan_abort(padapter
->pbuddy_adapter
);
2769 if (!sme
->ssid
|| !sme
->ssid_len
)
2775 if (sme
->ssid_len
> IW_ESSID_MAX_SIZE
){
2781 _rtw_memset(&ndis_ssid
, 0, sizeof(NDIS_802_11_SSID
));
2782 ndis_ssid
.SsidLength
= sme
->ssid_len
;
2783 _rtw_memcpy(ndis_ssid
.Ssid
, sme
->ssid
, sme
->ssid_len
);
2785 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid
.Ssid
, sme
->ssid_len
);
2789 DBG_8192C("bssid="MAC_FMT
"\n", MAC_ARG(sme
->bssid
));
2792 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
) == _TRUE
) {
2794 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__
, pmlmepriv
->fw_state
);
2797 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
) == _TRUE
) {
2798 rtw_scan_abort(padapter
);
2801 psecuritypriv
->ndisencryptstatus
= Ndis802_11EncryptionDisabled
;
2802 psecuritypriv
->dot11PrivacyAlgrthm
= _NO_PRIVACY_
;
2803 psecuritypriv
->dot118021XGrpPrivacy
= _NO_PRIVACY_
;
2804 psecuritypriv
->dot11AuthAlgrthm
= dot11AuthAlgrthm_Open
; //open system
2805 psecuritypriv
->ndisauthtype
= Ndis802_11AuthModeOpen
;
2808 ret
= rtw_cfg80211_set_wpa_version(psecuritypriv
, sme
->crypto
.wpa_versions
);
2812 ret
= rtw_cfg80211_set_auth_type(psecuritypriv
, sme
->auth_type
);
2816 DBG_8192C("%s, ie_len=%zu\n", __func__
, sme
->ie_len
);
2818 ret
= rtw_cfg80211_set_wpa_ie(padapter
, sme
->ie
, sme
->ie_len
);
2822 if (sme
->crypto
.n_ciphers_pairwise
) {
2823 ret
= rtw_cfg80211_set_cipher(psecuritypriv
, sme
->crypto
.ciphers_pairwise
[0], _TRUE
);
2828 //For WEP Shared auth
2829 if((psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_Shared
2830 || psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_Auto
) && sme
->key
2833 u32 wep_key_idx
, wep_key_len
,wep_total_len
;
2834 NDIS_802_11_WEP
*pwep
= NULL
;
2835 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__
);
2837 wep_key_idx
= sme
->key_idx
;
2838 wep_key_len
= sme
->key_len
;
2840 if (sme
->key_idx
> WEP_KEYS
) {
2845 if (wep_key_len
> 0)
2847 wep_key_len
= wep_key_len
<= 5 ? 5 : 13;
2848 wep_total_len
= wep_key_len
+ FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
);
2849 pwep
=(NDIS_802_11_WEP
*) rtw_malloc(wep_total_len
);
2851 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
2856 _rtw_memset(pwep
, 0, wep_total_len
);
2858 pwep
->KeyLength
= wep_key_len
;
2859 pwep
->Length
= wep_total_len
;
2863 padapter
->securitypriv
.dot11PrivacyAlgrthm
=_WEP104_
;
2864 padapter
->securitypriv
.dot118021XGrpPrivacy
=_WEP104_
;
2872 pwep
->KeyIndex
= wep_key_idx
;
2873 pwep
->KeyIndex
|= 0x80000000;
2875 _rtw_memcpy(pwep
->KeyMaterial
, (void *)sme
->key
, pwep
->KeyLength
);
2877 if(rtw_set_802_11_add_wep(padapter
, pwep
) == (u8
)_FAIL
)
2883 rtw_mfree((u8
*)pwep
,wep_total_len
);
2890 ret
= rtw_cfg80211_set_cipher(psecuritypriv
, sme
->crypto
.cipher_group
, _FALSE
);
2894 if (sme
->crypto
.n_akm_suites
) {
2895 ret
= rtw_cfg80211_set_key_mgt(psecuritypriv
, sme
->crypto
.akm_suites
[0]);
2900 authmode
= psecuritypriv
->ndisauthtype
;
2901 rtw_set_802_11_authentication_mode(padapter
, authmode
);
2903 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2905 if (rtw_set_802_11_connect(padapter
, sme
->bssid
, &ndis_ssid
) == _FALSE
) {
2910 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv
->dot11AuthAlgrthm
, psecuritypriv
->dot11PrivacyAlgrthm
, psecuritypriv
->dot118021XGrpPrivacy
);
2914 DBG_8192C("<=%s, ret %d\n",__FUNCTION__
, ret
);
2919 static int cfg80211_rtw_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
2922 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
2924 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
2926 rtw_set_roaming(padapter
, 0);
2928 if(check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))
2930 rtw_scan_abort(padapter
);
2931 LeaveAllPowerSaveMode(padapter
);
2932 rtw_disassoc_cmd(padapter
, 500, _FALSE
);
2934 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__
);
2936 padapter
->mlmepriv
.not_indic_disco
= _TRUE
;
2937 rtw_indicate_disconnect(padapter
);
2938 padapter
->mlmepriv
.not_indic_disco
= _FALSE
;
2940 rtw_free_assoc_resources(padapter
, 1);
2946 static int cfg80211_rtw_set_txpower(struct wiphy
*wiphy
,
2947 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2948 struct wireless_dev
*wdev
,
2950 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
2951 enum nl80211_tx_power_setting type
, int mbm
)
2953 enum tx_power_setting type
, int dbm
)
2957 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
2961 case NL80211_TX_POWER_AUTOMATIC
:
2963 case NL80211_TX_POWER_FIXED
:
2964 if (mbm
< 0 || (mbm
% 100))
2967 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
2970 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
2971 CFG_TX_PWR_LIMIT_USR
,
2972 MBM_TO_DBM(mbm
) * 2);
2976 return iwm_tx_power_trigger(iwm
);
2978 IWM_ERR(iwm
, "Unsupported power type: %d\n", type
);
2982 DBG_8192C("%s\n", __func__
);
2986 static int cfg80211_rtw_get_txpower(struct wiphy
*wiphy
,
2987 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2988 struct wireless_dev
*wdev
,
2992 //_adapter *padapter = wiphy_to_adapter(wiphy);
2994 DBG_8192C("%s\n", __func__
);
3001 inline bool rtw_cfg80211_pwr_mgmt(_adapter
*adapter
)
3003 struct rtw_wdev_priv
*rtw_wdev_priv
= wdev_to_priv(adapter
->rtw_wdev
);
3004 return rtw_wdev_priv
->power_mgmt
;
3007 static int cfg80211_rtw_set_power_mgmt(struct wiphy
*wiphy
,
3008 struct net_device
*ndev
,
3009 bool enabled
, int timeout
)
3011 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
3012 struct rtw_wdev_priv
*rtw_wdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
3014 DBG_871X(FUNC_NDEV_FMT
" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev
),
3017 rtw_wdev_priv
->power_mgmt
= enabled
;
3021 LPS_Leave(padapter
);
3027 static int cfg80211_rtw_set_pmksa(struct wiphy
*wiphy
,
3028 struct net_device
*netdev
,
3029 struct cfg80211_pmksa
*pmksa
)
3031 u8 index
,blInserted
= _FALSE
;
3032 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
3033 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
3034 u8 strZeroMacAddress
[ ETH_ALEN
] = { 0x00 };
3036 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(netdev
));
3038 if ( _rtw_memcmp( pmksa
->bssid
, strZeroMacAddress
, ETH_ALEN
) == _TRUE
)
3043 blInserted
= _FALSE
;
3046 for(index
=0 ; index
<NUM_PMKID_CACHE
; index
++)
3048 if( _rtw_memcmp( psecuritypriv
->PMKIDList
[index
].Bssid
, pmksa
->bssid
, ETH_ALEN
) ==_TRUE
)
3049 { // BSSID is matched, the same AP => rewrite with new PMKID.
3050 DBG_871X(FUNC_NDEV_FMT
" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(netdev
));
3052 _rtw_memcpy( psecuritypriv
->PMKIDList
[index
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3053 psecuritypriv
->PMKIDList
[index
].bUsed
= _TRUE
;
3054 psecuritypriv
->PMKIDIndex
= index
+1;
3063 DBG_871X(FUNC_NDEV_FMT
" Use the new entry index = %d for this PMKID.\n",
3064 FUNC_NDEV_ARG(netdev
), psecuritypriv
->PMKIDIndex
);
3066 _rtw_memcpy(psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].Bssid
, pmksa
->bssid
, ETH_ALEN
);
3067 _rtw_memcpy(psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3069 psecuritypriv
->PMKIDList
[psecuritypriv
->PMKIDIndex
].bUsed
= _TRUE
;
3070 psecuritypriv
->PMKIDIndex
++ ;
3071 if(psecuritypriv
->PMKIDIndex
==16)
3073 psecuritypriv
->PMKIDIndex
=0;
3080 static int cfg80211_rtw_del_pmksa(struct wiphy
*wiphy
,
3081 struct net_device
*netdev
,
3082 struct cfg80211_pmksa
*pmksa
)
3084 u8 index
, bMatched
= _FALSE
;
3085 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
3086 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
3088 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(netdev
));
3090 for(index
=0 ; index
<NUM_PMKID_CACHE
; index
++)
3092 if( _rtw_memcmp( psecuritypriv
->PMKIDList
[index
].Bssid
, pmksa
->bssid
, ETH_ALEN
) ==_TRUE
)
3093 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
3094 _rtw_memset( psecuritypriv
->PMKIDList
[index
].Bssid
, 0x00, ETH_ALEN
);
3095 _rtw_memset( psecuritypriv
->PMKIDList
[index
].PMKID
, 0x00, WLAN_PMKID_LEN
);
3096 psecuritypriv
->PMKIDList
[index
].bUsed
= _FALSE
;
3102 if(_FALSE
== bMatched
)
3104 DBG_871X(FUNC_NDEV_FMT
" do not have matched BSSID\n"
3105 , FUNC_NDEV_ARG(netdev
));
3112 static int cfg80211_rtw_flush_pmksa(struct wiphy
*wiphy
,
3113 struct net_device
*netdev
)
3115 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
3116 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
3118 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(netdev
));
3120 _rtw_memset( &psecuritypriv
->PMKIDList
[ 0 ], 0x00, sizeof( RT_PMKID_LIST
) * NUM_PMKID_CACHE
);
3121 psecuritypriv
->PMKIDIndex
= 0;
3126 #ifdef CONFIG_AP_MODE
3127 void rtw_cfg80211_indicate_sta_assoc(_adapter
*padapter
, u8
*pmgmt_frame
, uint frame_len
)
3131 struct wireless_dev
*pwdev
= padapter
->rtw_wdev
;
3132 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
3133 struct net_device
*ndev
= padapter
->pnetdev
;
3135 DBG_871X(FUNC_ADPT_FMT
"\n", FUNC_ADPT_ARG(padapter
));
3137 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3139 struct station_info sinfo
;
3141 if (GetFrameSubType(pmgmt_frame
) == WIFI_ASSOCREQ
)
3142 ie_offset
= _ASOCREQ_IE_OFFSET_
;
3143 else // WIFI_REASSOCREQ
3144 ie_offset
= _REASOCREQ_IE_OFFSET_
;
3147 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0))
3148 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
3150 sinfo
.assoc_req_ies
= pmgmt_frame
+ WLAN_HDR_A3_LEN
+ ie_offset
;
3151 sinfo
.assoc_req_ies_len
= frame_len
- WLAN_HDR_A3_LEN
- ie_offset
;
3152 cfg80211_new_sta(ndev
, GetAddr2Ptr(pmgmt_frame
), &sinfo
, GFP_ATOMIC
);
3154 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3155 channel
= pmlmeext
->cur_channel
;
3156 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
3157 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
3159 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
3161 #ifdef COMPAT_KERNEL_RELEASE
3162 rtw_cfg80211_rx_mgmt(padapter
, freq
, 0, pmgmt_frame
, frame_len
, GFP_ATOMIC
);
3163 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3164 rtw_cfg80211_rx_mgmt(padapter
, freq
, 0, pmgmt_frame
, frame_len
, GFP_ATOMIC
);
3165 #else //COMPAT_KERNEL_RELEASE
3167 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
3168 #ifndef CONFIG_PLATFORM_MSTAR
3169 pwdev
->iftype
= NL80211_IFTYPE_STATION
;
3170 #endif //CONFIG_PLATFORM_MSTAR
3171 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev
->iftype
);
3172 rtw_cfg80211_send_rx_assoc(padapter
, NULL
, pmgmt_frame
, frame_len
);
3173 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev
->iftype
);
3174 pwdev
->iftype
= NL80211_IFTYPE_AP
;
3175 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3177 #endif //COMPAT_KERNEL_RELEASE
3178 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3182 void rtw_cfg80211_indicate_sta_disassoc(_adapter
*padapter
, unsigned char *da
, unsigned short reason
)
3188 struct rtw_ieee80211_hdr
*pwlanhdr
;
3189 unsigned short *fctrl
;
3190 u8 mgmt_buf
[128] = {0};
3191 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
3192 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
3193 struct net_device
*ndev
= padapter
->pnetdev
;
3195 DBG_871X(FUNC_ADPT_FMT
"\n", FUNC_ADPT_ARG(padapter
));
3197 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3198 cfg80211_del_sta(ndev
, da
, GFP_ATOMIC
);
3199 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3200 channel
= pmlmeext
->cur_channel
;
3201 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
3202 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
3204 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
3206 pmgmt_frame
= mgmt_buf
;
3207 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pmgmt_frame
;
3209 fctrl
= &(pwlanhdr
->frame_ctl
);
3212 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3213 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3214 _rtw_memcpy(pwlanhdr
->addr1
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
3215 _rtw_memcpy(pwlanhdr
->addr2
, da
, ETH_ALEN
);
3216 _rtw_memcpy(pwlanhdr
->addr3
, get_my_bssid(&(pmlmeinfo
->network
)), ETH_ALEN
);
3218 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3219 pmlmeext
->mgnt_seq
++;
3220 SetFrameSubType(pmgmt_frame
, WIFI_DEAUTH
);
3222 pmgmt_frame
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
3223 frame_len
= sizeof(struct rtw_ieee80211_hdr_3addr
);
3225 reason
= cpu_to_le16(reason
);
3226 pmgmt_frame
= rtw_set_fixed_ie(pmgmt_frame
, _RSON_CODE_
, (unsigned char *)&reason
, &frame_len
);
3228 #ifdef COMPAT_KERNEL_RELEASE
3229 rtw_cfg80211_rx_mgmt(padapter
, freq
, 0, mgmt_buf
, frame_len
, GFP_ATOMIC
);
3230 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3231 rtw_cfg80211_rx_mgmt(padapter
, freq
, 0, mgmt_buf
, frame_len
, GFP_ATOMIC
);
3232 #else //COMPAT_KERNEL_RELEASE
3233 cfg80211_send_disassoc(padapter
->pnetdev
, mgmt_buf
, frame_len
);
3234 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
3235 #endif //COMPAT_KERNEL_RELEASE
3236 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3239 static int rtw_cfg80211_monitor_if_open(struct net_device
*ndev
)
3243 DBG_8192C("%s\n", __func__
);
3248 static int rtw_cfg80211_monitor_if_close(struct net_device
*ndev
)
3252 DBG_8192C("%s\n", __func__
);
3257 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff
*skb
, struct net_device
*ndev
)
3262 int dot11_hdr_len
= 24;
3264 unsigned char *pdata
;
3266 unsigned char src_mac_addr
[6];
3267 unsigned char dst_mac_addr
[6];
3268 struct ieee80211_hdr
*dot11_hdr
;
3269 struct ieee80211_radiotap_header
*rtap_hdr
;
3270 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(ndev
);
3272 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3275 rtw_mstat_update(MSTAT_TYPE_SKB
, MSTAT_ALLOC_SUCCESS
, skb
->truesize
);
3277 if (unlikely(skb
->len
< sizeof(struct ieee80211_radiotap_header
)))
3280 rtap_hdr
= (struct ieee80211_radiotap_header
*)skb
->data
;
3281 if (unlikely(rtap_hdr
->it_version
))
3284 rtap_len
= ieee80211_get_radiotap_len(skb
->data
);
3285 if (unlikely(skb
->len
< rtap_len
))
3290 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len
);
3294 /* Skip the ratio tap header */
3295 skb_pull(skb
, rtap_len
);
3297 dot11_hdr
= (struct ieee80211_hdr
*)skb
->data
;
3298 frame_ctl
= le16_to_cpu(dot11_hdr
->frame_control
);
3299 /* Check if the QoS bit is set */
3300 if ((frame_ctl
& RTW_IEEE80211_FCTL_FTYPE
) == RTW_IEEE80211_FTYPE_DATA
) {
3301 /* Check if this ia a Wireless Distribution System (WDS) frame
3302 * which has 4 MAC addresses
3304 if (dot11_hdr
->frame_control
& 0x0080)
3306 if ((dot11_hdr
->frame_control
& 0x0300) == 0x0300)
3309 memcpy(dst_mac_addr
, dot11_hdr
->addr1
, sizeof(dst_mac_addr
));
3310 memcpy(src_mac_addr
, dot11_hdr
->addr2
, sizeof(src_mac_addr
));
3312 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
3313 * for two MAC addresses
3315 skb_pull(skb
, dot11_hdr_len
+ qos_len
+ snap_len
- sizeof(src_mac_addr
) * 2);
3316 pdata
= (unsigned char*)skb
->data
;
3317 memcpy(pdata
, dst_mac_addr
, sizeof(dst_mac_addr
));
3318 memcpy(pdata
+ sizeof(dst_mac_addr
), src_mac_addr
, sizeof(src_mac_addr
));
3320 DBG_8192C("should be eapol packet\n");
3322 /* Use the real net device to transmit the packet */
3323 ret
= _rtw_xmit_entry(skb
, padapter
->pnetdev
);
3328 else if ((frame_ctl
& (RTW_IEEE80211_FCTL_FTYPE
|RTW_IEEE80211_FCTL_STYPE
))
3329 == (RTW_IEEE80211_FTYPE_MGMT
|RTW_IEEE80211_STYPE_ACTION
)
3332 //only for action frames
3333 struct xmit_frame
*pmgntframe
;
3334 struct pkt_attrib
*pattrib
;
3335 unsigned char *pframe
;
3336 //u8 category, action, OUI_Subtype, dialogToken=0;
3337 //unsigned char *frame_body;
3338 struct rtw_ieee80211_hdr
*pwlanhdr
;
3339 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
3340 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
3341 u8
*buf
= skb
->data
;
3343 u8 category
, action
;
3346 if (rtw_action_frame_parse(buf
, len
, &category
, &action
) == _FALSE
) {
3347 DBG_8192C(FUNC_NDEV_FMT
" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev
),
3348 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr
*)buf
)->frame_ctl
));
3352 DBG_8192C("RTW_Tx:da="MAC_FMT
" via "FUNC_NDEV_FMT
"\n",
3353 MAC_ARG(GetAddr1Ptr(buf
)), FUNC_NDEV_ARG(ndev
));
3355 if((type
= rtw_p2p_check_frames(padapter
, buf
, len
, _TRUE
)) >= 0)
3358 if (category
== RTW_WLAN_CATEGORY_PUBLIC
)
3359 DBG_871X("RTW_Tx:%s\n", action_public_str(action
));
3361 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category
, action
);
3364 //starting alloc mgmt frame to dump it
3365 if ((pmgntframe
= alloc_mgtxmitframe(pxmitpriv
)) == NULL
)
3371 pattrib
= &pmgntframe
->attrib
;
3372 update_mgntframe_attrib(padapter
, pattrib
);
3373 pattrib
->retry_ctrl
= _FALSE
;
3375 _rtw_memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3377 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3379 _rtw_memcpy(pframe
, (void*)buf
, len
);
3383 struct wifi_display_info
*pwfd_info
;
3385 pwfd_info
= padapter
->wdinfo
.wfd_info
;
3387 if ( _TRUE
== pwfd_info
->wfd_enable
)
3389 rtw_append_wfd_ie( padapter
, pframe
, &len
);
3392 #endif // CONFIG_WFD
3393 pattrib
->pktlen
= len
;
3395 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
3397 pmlmeext
->mgnt_seq
= GetSequence(pwlanhdr
);
3398 pattrib
->seqnum
= pmlmeext
->mgnt_seq
;
3399 pmlmeext
->mgnt_seq
++;
3402 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3404 dump_mgntframe(padapter
, pmgntframe
);
3409 DBG_8192C("frame_ctl=0x%x\n", frame_ctl
& (RTW_IEEE80211_FCTL_FTYPE
|RTW_IEEE80211_FCTL_STYPE
));
3421 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device
*ndev
)
3423 DBG_8192C("%s\n", __func__
);
3426 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device
*ndev
, void *addr
)
3430 DBG_8192C("%s\n", __func__
);
3435 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3436 static const struct net_device_ops rtw_cfg80211_monitor_if_ops
= {
3437 .ndo_open
= rtw_cfg80211_monitor_if_open
,
3438 .ndo_stop
= rtw_cfg80211_monitor_if_close
,
3439 .ndo_start_xmit
= rtw_cfg80211_monitor_if_xmit_entry
,
3440 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
3441 .ndo_set_multicast_list
= rtw_cfg80211_monitor_if_set_multicast_list
,
3443 .ndo_set_mac_address
= rtw_cfg80211_monitor_if_set_mac_address
,
3447 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
3448 static int rtw_cfg80211_add_monitor_if(_adapter
*padapter
, char *name
, unsigned char name_assign_type
, struct net_device
**ndev
)
3450 static int rtw_cfg80211_add_monitor_if(_adapter
*padapter
, char *name
, struct net_device
**ndev
)
3454 struct net_device
* mon_ndev
= NULL
;
3455 struct wireless_dev
* mon_wdev
= NULL
;
3456 struct rtw_netdev_priv_indicator
*pnpi
;
3457 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
3460 DBG_871X(FUNC_ADPT_FMT
" without specific name\n", FUNC_ADPT_ARG(padapter
));
3465 if (pwdev_priv
->pmon_ndev
) {
3466 DBG_871X(FUNC_ADPT_FMT
" monitor interface exist: "NDEV_FMT
"\n",
3467 FUNC_ADPT_ARG(padapter
), NDEV_ARG(pwdev_priv
->pmon_ndev
));
3472 mon_ndev
= alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator
));
3474 DBG_871X(FUNC_ADPT_FMT
" allocate ndev fail\n", FUNC_ADPT_ARG(padapter
));
3479 mon_ndev
->type
= ARPHRD_IEEE80211_RADIOTAP
;
3480 strncpy(mon_ndev
->name
, name
, IFNAMSIZ
);
3481 mon_ndev
->name
[IFNAMSIZ
- 1] = 0;
3482 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
3483 mon_ndev
->name_assign_type
= name_assign_type
;
3485 mon_ndev
->needs_free_netdev
= true;
3486 mon_ndev
->priv_destructor
= rtw_ndev_destructor
;
3488 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3489 mon_ndev
->netdev_ops
= &rtw_cfg80211_monitor_if_ops
;
3491 mon_ndev
->open
= rtw_cfg80211_monitor_if_open
;
3492 mon_ndev
->stop
= rtw_cfg80211_monitor_if_close
;
3493 mon_ndev
->hard_start_xmit
= rtw_cfg80211_monitor_if_xmit_entry
;
3494 mon_ndev
->set_mac_address
= rtw_cfg80211_monitor_if_set_mac_address
;
3497 pnpi
= netdev_priv(mon_ndev
);
3498 pnpi
->priv
= padapter
;
3499 pnpi
->sizeof_priv
= sizeof(_adapter
);
3502 mon_wdev
= (struct wireless_dev
*)rtw_zmalloc(sizeof(struct wireless_dev
));
3504 DBG_871X(FUNC_ADPT_FMT
" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter
));
3509 mon_wdev
->wiphy
= padapter
->rtw_wdev
->wiphy
;
3510 mon_wdev
->netdev
= mon_ndev
;
3511 mon_wdev
->iftype
= NL80211_IFTYPE_MONITOR
;
3512 mon_ndev
->ieee80211_ptr
= mon_wdev
;
3514 ret
= register_netdevice(mon_ndev
);
3519 *ndev
= pwdev_priv
->pmon_ndev
= mon_ndev
;
3520 _rtw_memcpy(pwdev_priv
->ifname_mon
, name
, IFNAMSIZ
+1);
3523 if (ret
&& mon_wdev
) {
3524 rtw_mfree((u8
*)mon_wdev
, sizeof(struct wireless_dev
));
3528 if (ret
&& mon_ndev
) {
3529 free_netdev(mon_ndev
);
3530 *ndev
= mon_ndev
= NULL
;
3536 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3537 static struct wireless_dev
*
3538 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3539 static struct net_device
*
3543 cfg80211_rtw_add_virtual_intf(
3544 struct wiphy
*wiphy
,
3545 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
3550 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
3551 unsigned char name_assign_type
,
3553 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
3554 enum nl80211_iftype type
, struct vif_params
*params
)
3556 enum nl80211_iftype type
, u32
*flags
, struct vif_params
*params
)
3560 struct net_device
* ndev
= NULL
;
3561 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
3563 DBG_871X(FUNC_ADPT_FMT
" wiphy:%s, name:%s, type:%d\n",
3564 FUNC_ADPT_ARG(padapter
), wiphy_name(wiphy
), name
, type
);
3567 case NL80211_IFTYPE_ADHOC
:
3568 case NL80211_IFTYPE_AP_VLAN
:
3569 case NL80211_IFTYPE_WDS
:
3570 case NL80211_IFTYPE_MESH_POINT
:
3573 case NL80211_IFTYPE_MONITOR
:
3574 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0))
3575 ret
= rtw_cfg80211_add_monitor_if(padapter
, (char *)name
, name_assign_type
, &ndev
);
3577 ret
= rtw_cfg80211_add_monitor_if(padapter
, (char *)name
, &ndev
);
3581 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3582 case NL80211_IFTYPE_P2P_CLIENT
:
3584 case NL80211_IFTYPE_STATION
:
3588 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3589 case NL80211_IFTYPE_P2P_GO
:
3591 case NL80211_IFTYPE_AP
:
3596 DBG_871X("Unsupported interface type\n");
3600 DBG_871X(FUNC_ADPT_FMT
" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter
), ndev
, ret
);
3602 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3603 return ndev
? ndev
->ieee80211_ptr
: ERR_PTR(ret
);
3604 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3605 return ndev
? ndev
: ERR_PTR(ret
);
3611 static int cfg80211_rtw_del_virtual_intf(struct wiphy
*wiphy
,
3612 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3613 struct wireless_dev
*wdev
3615 struct net_device
*ndev
3619 struct rtw_wdev_priv
*pwdev_priv
= (struct rtw_wdev_priv
*)wiphy_priv(wiphy
);
3620 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3621 struct net_device
*ndev
;
3622 ndev
= wdev
? wdev
->netdev
: NULL
;
3628 unregister_netdevice(ndev
);
3630 if (ndev
== pwdev_priv
->pmon_ndev
) {
3631 pwdev_priv
->pmon_ndev
= NULL
;
3632 pwdev_priv
->ifname_mon
[0] = '\0';
3633 DBG_871X(FUNC_NDEV_FMT
" remove monitor interface\n", FUNC_NDEV_ARG(ndev
));
3640 static int rtw_add_beacon(_adapter
*adapter
, const u8
*head
, size_t head_len
, const u8
*tail
, size_t tail_len
)
3644 uint len
, wps_ielen
=0;
3647 u8 got_p2p_ie
= _FALSE
;
3648 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
3649 //struct sta_priv *pstapriv = &padapter->stapriv;
3652 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__
, head_len
, tail_len
);
3655 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) != _TRUE
)
3662 pbuf
= rtw_zmalloc(head_len
+tail_len
);
3667 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3669 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
3670 // pstapriv->max_num_sta = NUM_STA;
3673 _rtw_memcpy(pbuf
, (void *)head
+24, head_len
-24);// 24=beacon header len.
3674 _rtw_memcpy(pbuf
+head_len
-24, (void *)tail
, tail_len
);
3676 len
= head_len
+tail_len
-24;
3678 //check wps ie if inclued
3679 if(rtw_get_wps_ie(pbuf
+_FIXED_IE_LENGTH_
, len
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
))
3680 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen
);
3683 //check p2p ie if inclued
3684 if( adapter
->wdinfo
.driver_interface
== DRIVER_CFG80211
)
3686 //check p2p if enable
3687 if(rtw_get_p2p_ie(pbuf
+_FIXED_IE_LENGTH_
, len
-_FIXED_IE_LENGTH_
, NULL
, &p2p_ielen
))
3689 struct mlme_ext_priv
*pmlmeext
= &adapter
->mlmeextpriv
;
3690 struct wifidirect_info
*pwdinfo
= &(adapter
->wdinfo
);
3692 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen
);
3695 if(rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3697 DBG_8192C("Enable P2P function for the first time\n");
3698 rtw_p2p_enable(adapter
, P2P_ROLE_GO
);
3699 wdev_to_priv(adapter
->rtw_wdev
)->p2p_enabled
= _TRUE
;
3703 _cancel_timer_ex( &pwdinfo
->find_phase_timer
);
3704 _cancel_timer_ex( &pwdinfo
->restore_p2p_state_timer
);
3705 _cancel_timer_ex( &pwdinfo
->pre_tx_scan_timer
);
3707 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen
);
3709 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
3710 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3711 pwdinfo
->intent
= 15;
3715 #endif // CONFIG_P2P
3717 /* pbss_network->IEs will not include p2p_ie, wfd ie */
3718 rtw_ies_remove_ie(pbuf
, &len
, _BEACON_IE_OFFSET_
, _VENDOR_SPECIFIC_IE_
, P2P_OUI
, 4);
3719 rtw_ies_remove_ie(pbuf
, &len
, _BEACON_IE_OFFSET_
, _VENDOR_SPECIFIC_IE_
, WFD_OUI
, 4);
3721 if (rtw_check_beacon_data(adapter
, pbuf
, len
) == _SUCCESS
)
3724 //check p2p if enable
3725 if(got_p2p_ie
== _TRUE
)
3727 struct mlme_ext_priv
*pmlmeext
= &adapter
->mlmeextpriv
;
3728 struct wifidirect_info
*pwdinfo
= &(adapter
->wdinfo
);
3729 pwdinfo
->operating_channel
= pmlmeext
->cur_channel
;
3740 rtw_mfree(pbuf
, head_len
+tail_len
);
3745 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
3746 static int cfg80211_rtw_add_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3747 struct beacon_parameters
*info
)
3750 _adapter
*adapter
= wiphy_to_adapter(wiphy
);
3752 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3753 ret
= rtw_add_beacon(adapter
, info
->head
, info
->head_len
, info
->tail
, info
->tail_len
);
3758 static int cfg80211_rtw_set_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3759 struct beacon_parameters
*info
)
3761 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
3762 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
3764 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3766 pmlmeext
->bstart_bss
= _TRUE
;
3768 cfg80211_rtw_add_beacon(wiphy
, ndev
, info
);
3773 static int cfg80211_rtw_del_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
)
3775 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3780 static int cfg80211_rtw_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3781 struct cfg80211_ap_settings
*settings
)
3784 _adapter
*adapter
= wiphy_to_adapter(wiphy
);
3786 DBG_871X(FUNC_NDEV_FMT
" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev
),
3787 settings
->hidden_ssid
, settings
->auth_type
);
3789 ret
= rtw_add_beacon(adapter
, settings
->beacon
.head
, settings
->beacon
.head_len
,
3790 settings
->beacon
.tail
, settings
->beacon
.tail_len
);
3792 adapter
->mlmeextpriv
.mlmext_info
.hidden_ssid_mode
= settings
->hidden_ssid
;
3794 if (settings
->ssid
&& settings
->ssid_len
) {
3795 WLAN_BSSID_EX
*pbss_network
= &adapter
->mlmepriv
.cur_network
.network
;
3796 WLAN_BSSID_EX
*pbss_network_ext
= &adapter
->mlmeextpriv
.mlmext_info
.network
;
3799 DBG_871X(FUNC_ADPT_FMT
" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter
),
3800 settings
->ssid
, settings
->ssid_len
,
3801 pbss_network
->Ssid
.Ssid
, pbss_network
->Ssid
.SsidLength
);
3803 _rtw_memcpy(pbss_network
->Ssid
.Ssid
, (void *)settings
->ssid
, settings
->ssid_len
);
3804 pbss_network
->Ssid
.SsidLength
= settings
->ssid_len
;
3805 _rtw_memcpy(pbss_network_ext
->Ssid
.Ssid
, (void *)settings
->ssid
, settings
->ssid_len
);
3806 pbss_network_ext
->Ssid
.SsidLength
= settings
->ssid_len
;
3809 DBG_871X(FUNC_ADPT_FMT
" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter
),
3810 pbss_network
->Ssid
.Ssid
, pbss_network
->Ssid
.SsidLength
,
3811 pbss_network_ext
->Ssid
.Ssid
, pbss_network_ext
->Ssid
.SsidLength
);
3817 static int cfg80211_rtw_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3818 struct cfg80211_beacon_data
*info
)
3821 _adapter
*adapter
= wiphy_to_adapter(wiphy
);
3823 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3825 ret
= rtw_add_beacon(adapter
, info
->head
, info
->head_len
, info
->tail
, info
->tail_len
);
3830 static int cfg80211_rtw_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3832 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3836 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
3838 static int cfg80211_rtw_add_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3839 const u8
*mac
, struct station_parameters
*params
)
3841 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3846 static int cfg80211_rtw_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3847 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
3849 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0))
3852 struct station_del_parameters
*params
)
3854 const u8
*mac
= params
->mac
;
3858 _list
*phead
, *plist
;
3859 u8 updated
= _FALSE
;
3860 struct sta_info
*psta
= NULL
;
3861 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(ndev
);
3862 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
3863 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3865 DBG_871X("+"FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3867 if(check_fwstate(pmlmepriv
, (_FW_LINKED
|WIFI_AP_STATE
)) != _TRUE
)
3869 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__
);
3876 DBG_8192C("flush all sta, and cam_entry\n");
3878 flush_all_cam_entry(padapter
); //clear CAM
3880 ret
= rtw_sta_flush(padapter
);
3886 DBG_8192C("free sta macaddr =" MAC_FMT
"\n", MAC_ARG(mac
));
3888 if (mac
[0] == 0xff && mac
[1] == 0xff &&
3889 mac
[2] == 0xff && mac
[3] == 0xff &&
3890 mac
[4] == 0xff && mac
[5] == 0xff)
3896 _enter_critical_bh(&pstapriv
->asoc_list_lock
, &irqL
);
3898 phead
= &pstapriv
->asoc_list
;
3899 plist
= get_next(phead
);
3902 while ((rtw_end_of_queue_search(phead
, plist
)) == _FALSE
)
3904 psta
= LIST_CONTAINOR(plist
, struct sta_info
, asoc_list
);
3906 plist
= get_next(plist
);
3908 if(_rtw_memcmp(mac
, psta
->hwaddr
, ETH_ALEN
))
3910 if(psta
->dot8021xalg
== 1 && psta
->bpairwise_key_installed
== _FALSE
)
3912 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__
);
3916 DBG_8192C("free psta=%p, aid=%d\n", psta
, psta
->aid
);
3918 rtw_list_delete(&psta
->asoc_list
);
3919 pstapriv
->asoc_list_cnt
--;
3921 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3922 updated
= ap_free_sta(padapter
, psta
, _TRUE
, WLAN_REASON_DEAUTH_LEAVING
);
3923 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3934 _exit_critical_bh(&pstapriv
->asoc_list_lock
, &irqL
);
3936 associated_clients_update(padapter
, updated
);
3938 DBG_871X("-"FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3944 static int cfg80211_rtw_change_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3945 const u8
*mac
, struct station_parameters
*params
)
3947 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3952 static int cfg80211_rtw_dump_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3953 int idx
, u8
*mac
, struct station_info
*sinfo
)
3955 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3957 //TODO: dump scanned queue
3962 static int cfg80211_rtw_change_bss(struct wiphy
*wiphy
, struct net_device
*ndev
,
3963 struct bss_parameters
*params
)
3967 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3969 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
3970 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
3971 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
3972 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
3974 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
3975 for(i=0; i<params->basic_rates_len; i++)
3977 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
3985 static int cfg80211_rtw_set_channel(struct wiphy
*wiphy
3986 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3987 , struct net_device
*ndev
3989 , struct ieee80211_channel
*chan
, enum nl80211_channel_type channel_type
)
3991 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3992 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
3998 static int cfg80211_rtw_auth(struct wiphy
*wiphy
, struct net_device
*ndev
,
3999 struct cfg80211_auth_request
*req
)
4001 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
4006 static int cfg80211_rtw_assoc(struct wiphy
*wiphy
, struct net_device
*ndev
,
4007 struct cfg80211_assoc_request
*req
)
4009 DBG_871X(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(ndev
));
4013 #endif //CONFIG_AP_MODE
4015 void rtw_cfg80211_rx_action_p2p(_adapter
*padapter
, u8
*pmgmt_frame
, uint frame_len
)
4020 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
4021 u8 category
, action
;
4023 channel
= rtw_get_oper_ch(padapter
);
4025 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel
);
4027 type
= rtw_p2p_check_frames(padapter
, pmgmt_frame
, frame_len
, _FALSE
);
4031 rtw_action_frame_parse(pmgmt_frame
, frame_len
, &category
, &action
);
4032 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category
, action
);
4035 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
4036 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
4038 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
4040 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4041 rtw_cfg80211_rx_mgmt(padapter
, freq
, 0, pmgmt_frame
, frame_len
, GFP_ATOMIC
);
4043 cfg80211_rx_action(padapter
->pnetdev
, freq
, pmgmt_frame
, frame_len
, GFP_ATOMIC
);
4047 void rtw_cfg80211_rx_p2p_action_public(_adapter
*padapter
, u8
*pmgmt_frame
, uint frame_len
)
4052 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
4053 u8 category
, action
;
4055 channel
= rtw_get_oper_ch(padapter
);
4057 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel
);
4059 type
= rtw_p2p_check_frames(padapter
, pmgmt_frame
, frame_len
, _FALSE
);
4062 case P2P_GO_NEGO_CONF
:
4063 case P2P_PROVISION_DISC_RESP
:
4064 case P2P_INVIT_RESP
:
4065 rtw_set_scan_deny(padapter
, 2000);
4066 rtw_clear_scan_deny(padapter
);
4071 rtw_action_frame_parse(pmgmt_frame
, frame_len
, &category
, &action
);
4072 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category
, action
);
4075 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
4076 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
4078 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
4080 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4081 rtw_cfg80211_rx_mgmt(padapter
, freq
, 0, pmgmt_frame
, frame_len
, GFP_ATOMIC
);
4083 cfg80211_rx_action(padapter
->pnetdev
, freq
, pmgmt_frame
, frame_len
, GFP_ATOMIC
);
4087 void rtw_cfg80211_rx_action(_adapter
*adapter
, u8
*frame
, uint frame_len
, const char*msg
)
4091 struct mlme_ext_priv
*pmlmeext
= &(adapter
->mlmeextpriv
);
4092 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(adapter
->rtw_wdev
);
4093 u8 category
, action
;
4095 channel
= rtw_get_oper_ch(adapter
);
4097 rtw_action_frame_parse(frame
, frame_len
, &category
, &action
);
4099 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel
);
4101 DBG_871X("RTW_Rx:%s\n", msg
);
4103 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category
, action
);
4105 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
4106 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_2GHZ
);
4108 freq
= rtw_ieee80211_channel_to_frequency(channel
, NL80211_BAND_5GHZ
);
4110 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4111 rtw_cfg80211_rx_mgmt(adapter
, freq
, 0, frame
, frame_len
, GFP_ATOMIC
);
4113 cfg80211_rx_action(adapter
->pnetdev
, freq
, frame
, frame_len
, GFP_ATOMIC
);
4119 void rtw_cfg80211_issue_p2p_provision_request(_adapter
*padapter
, const u8
*buf
, size_t len
)
4121 u16 wps_devicepassword_id
= 0x0000;
4122 uint wps_devicepassword_id_len
= 0;
4123 u8 wpsie
[ 255 ] = { 0x00 }, p2p_ie
[ 255 ] = { 0x00 };
4126 u32 devinfo_contentlen
= 0;
4127 u8 devinfo_content
[64] = { 0x00 };
4129 uint capability_len
= 0;
4131 unsigned char category
= RTW_WLAN_CATEGORY_PUBLIC
;
4132 u8 action
= P2P_PUB_ACTION_ACTION
;
4134 u32 p2poui
= cpu_to_be32(P2POUI
);
4135 u8 oui_subtype
= P2P_PROVISION_DISC_REQ
;
4141 struct xmit_frame
*pmgntframe
;
4142 struct pkt_attrib
*pattrib
;
4143 unsigned char *pframe
;
4144 struct rtw_ieee80211_hdr
*pwlanhdr
;
4145 unsigned short *fctrl
;
4146 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
4147 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
4148 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4150 struct wifidirect_info
*pwdinfo
= &(padapter
->wdinfo
);
4151 u8
*frame_body
= (unsigned char *)(buf
+ sizeof(struct rtw_ieee80211_hdr_3addr
));
4152 size_t frame_body_len
= len
- sizeof(struct rtw_ieee80211_hdr_3addr
);
4155 DBG_871X( "[%s] In\n", __FUNCTION__
);
4157 //prepare for building provision_request frame
4158 _rtw_memcpy(pwdinfo
->tx_prov_disc_info
.peerIFAddr
, GetAddr1Ptr(buf
), ETH_ALEN
);
4159 _rtw_memcpy(pwdinfo
->tx_prov_disc_info
.peerDevAddr
, GetAddr1Ptr(buf
), ETH_ALEN
);
4161 pwdinfo
->tx_prov_disc_info
.wps_config_method_request
= WPS_CM_PUSH_BUTTON
;
4163 rtw_get_wps_ie( frame_body
+ _PUBLIC_ACTION_IE_OFFSET_
, frame_body_len
- _PUBLIC_ACTION_IE_OFFSET_
, wpsie
, &wpsielen
);
4164 rtw_get_wps_attr_content( wpsie
, wpsielen
, WPS_ATTR_DEVICE_PWID
, (u8
*) &wps_devicepassword_id
, &wps_devicepassword_id_len
);
4165 wps_devicepassword_id
= be16_to_cpu( wps_devicepassword_id
);
4167 switch(wps_devicepassword_id
)
4170 pwdinfo
->tx_prov_disc_info
.wps_config_method_request
= WPS_CM_LABEL
;
4172 case WPS_DPID_USER_SPEC
:
4173 pwdinfo
->tx_prov_disc_info
.wps_config_method_request
= WPS_CM_DISPLYA
;
4175 case WPS_DPID_MACHINE_SPEC
:
4177 case WPS_DPID_REKEY
:
4180 pwdinfo
->tx_prov_disc_info
.wps_config_method_request
= WPS_CM_PUSH_BUTTON
;
4182 case WPS_DPID_REGISTRAR_SPEC
:
4183 pwdinfo
->tx_prov_disc_info
.wps_config_method_request
= WPS_CM_KEYPAD
;
4190 if ( rtw_get_p2p_ie( frame_body
+ _PUBLIC_ACTION_IE_OFFSET_
, frame_body_len
- _PUBLIC_ACTION_IE_OFFSET_
, p2p_ie
, &p2p_ielen
) )
4193 rtw_get_p2p_attr_content( p2p_ie
, p2p_ielen
, P2P_ATTR_DEVICE_INFO
, devinfo_content
, &devinfo_contentlen
);
4194 rtw_get_p2p_attr_content( p2p_ie
, p2p_ielen
, P2P_ATTR_CAPABILITY
, (u8
*)&capability
, &capability_len
);
4199 //start to build provision_request frame
4200 _rtw_memset(wpsie
, 0, sizeof(wpsie
));
4201 _rtw_memset(p2p_ie
, 0, sizeof(p2p_ie
));
4204 if ((pmgntframe
= alloc_mgtxmitframe(pxmitpriv
)) == NULL
)
4211 pattrib
= &pmgntframe
->attrib
;
4212 update_mgntframe_attrib(padapter
, pattrib
);
4214 _rtw_memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
4216 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
4217 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
4219 fctrl
= &(pwlanhdr
->frame_ctl
);
4222 _rtw_memcpy(pwlanhdr
->addr1
, pwdinfo
->tx_prov_disc_info
.peerDevAddr
, ETH_ALEN
);
4223 _rtw_memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
4224 _rtw_memcpy(pwlanhdr
->addr3
, pwdinfo
->tx_prov_disc_info
.peerDevAddr
, ETH_ALEN
);
4226 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
4227 pmlmeext
->mgnt_seq
++;
4228 SetFrameSubType(pframe
, WIFI_ACTION
);
4230 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
4231 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
4233 pframe
= rtw_set_fixed_ie(pframe
, 1, &(category
), &(pattrib
->pktlen
));
4234 pframe
= rtw_set_fixed_ie(pframe
, 1, &(action
), &(pattrib
->pktlen
));
4235 pframe
= rtw_set_fixed_ie(pframe
, 4, (unsigned char *) &(p2poui
), &(pattrib
->pktlen
));
4236 pframe
= rtw_set_fixed_ie(pframe
, 1, &(oui_subtype
), &(pattrib
->pktlen
));
4237 pframe
= rtw_set_fixed_ie(pframe
, 1, &(dialogToken
), &(pattrib
->pktlen
));
4240 //build_prov_disc_request_p2p_ie
4243 p2p_ie
[ p2pielen
++ ] = 0x50;
4244 p2p_ie
[ p2pielen
++ ] = 0x6F;
4245 p2p_ie
[ p2pielen
++ ] = 0x9A;
4246 p2p_ie
[ p2pielen
++ ] = 0x09; // WFA P2P v1.0
4248 // Commented by Albert 20110301
4249 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
4250 // 1. P2P Capability
4252 // 3. Group ID ( When joining an operating P2P Group )
4254 // P2P Capability ATTR
4256 p2p_ie
[ p2pielen
++ ] = P2P_ATTR_CAPABILITY
;
4259 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4260 RTW_PUT_LE16(p2p_ie
+ p2pielen
, 0x0002);
4264 // Device Capability Bitmap, 1 byte
4265 // Group Capability Bitmap, 1 byte
4266 _rtw_memcpy(p2p_ie
+ p2pielen
, &capability
, 2);
4272 p2p_ie
[ p2pielen
++ ] = P2P_ATTR_DEVICE_INFO
;
4275 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4276 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4277 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4278 RTW_PUT_LE16(p2p_ie
+ p2pielen
, devinfo_contentlen
);
4282 _rtw_memcpy(p2p_ie
+ p2pielen
, devinfo_content
, devinfo_contentlen
);
4283 p2pielen
+= devinfo_contentlen
;
4286 pframe
= rtw_set_ie(pframe
, _VENDOR_SPECIFIC_IE_
, p2pielen
, (unsigned char *) p2p_ie
, &p2p_ielen
);
4287 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
4288 //pframe += p2pielen;
4289 pattrib
->pktlen
+= p2p_ielen
;
4293 *(u32
*) ( wpsie
) = cpu_to_be32( WPSOUI
);
4298 *(u16
*) ( wpsie
+ wpsielen
) = cpu_to_be16( WPS_ATTR_VER1
);
4302 *(u16
*) ( wpsie
+ wpsielen
) = cpu_to_be16( 0x0001 );
4306 wpsie
[wpsielen
++] = WPS_VERSION_1
; // Version 1.0
4310 *(u16
*) ( wpsie
+ wpsielen
) = cpu_to_be16( WPS_ATTR_CONF_METHOD
);
4314 *(u16
*) ( wpsie
+ wpsielen
) = cpu_to_be16( 0x0002 );
4318 *(u16
*) ( wpsie
+ wpsielen
) = cpu_to_be16( pwdinfo
->tx_prov_disc_info
.wps_config_method_request
);
4321 pframe
= rtw_set_ie(pframe
, _VENDOR_SPECIFIC_IE_
, wpsielen
, (unsigned char *) wpsie
, &pattrib
->pktlen
);
4325 wfdielen
= build_provdisc_req_wfd_ie(pwdinfo
, pframe
);
4327 pattrib
->pktlen
+= wfdielen
;
4330 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
4332 //dump_mgntframe(padapter, pmgntframe);
4333 if (dump_mgntframe_and_wait_ack(padapter
, pmgntframe
) != _SUCCESS
)
4334 DBG_8192C("%s, ack to\n", __func__
);
4336 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4338 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
4339 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
4344 static s32
cfg80211_rtw_remain_on_channel(struct wiphy
*wiphy
,
4345 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4346 struct wireless_dev
*wdev
,
4348 struct net_device
*ndev
,
4350 struct ieee80211_channel
* channel
,
4351 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4352 enum nl80211_channel_type channel_type
,
4354 unsigned int duration
, u64
*cookie
)
4357 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
4358 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
4359 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4360 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
4361 struct cfg80211_wifidirect_info
*pcfg80211_wdinfo
= &padapter
->cfg80211_wdinfo
;
4362 u8 remain_ch
= (u8
) ieee80211_frequency_to_channel(channel
->center_freq
);
4363 u8 ready_on_channel
= _FALSE
;
4365 DBG_871X(FUNC_ADPT_FMT
" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter
), remain_ch
, duration
);
4367 if(pcfg80211_wdinfo
->is_ro_ch
== _TRUE
)
4369 DBG_8192C("%s, cancel ro ch timer\n", __func__
);
4371 _cancel_timer_ex(&padapter
->cfg80211_wdinfo
.remain_on_ch_timer
);
4373 #ifdef CONFIG_CONCURRENT_MODE
4374 ATOMIC_SET(&pwdev_priv
->ro_ch_to
, 1);
4375 #endif //CONFIG_CONCURRENT_MODE
4377 p2p_protocol_wk_hdl(padapter
, P2P_RO_CH_WK
);
4380 pcfg80211_wdinfo
->is_ro_ch
= _TRUE
;
4382 if(_FAIL
== rtw_pwr_wakeup(padapter
)) {
4387 _rtw_memcpy(&pcfg80211_wdinfo
->remain_on_ch_channel
, channel
, sizeof(struct ieee80211_channel
));
4388 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4389 pcfg80211_wdinfo
->remain_on_ch_type
= channel_type
;
4391 pcfg80211_wdinfo
->remain_on_ch_cookie
= *cookie
;
4393 rtw_scan_abort(padapter
);
4394 #ifdef CONFIG_CONCURRENT_MODE
4395 if(rtw_buddy_adapter_up(padapter
))
4396 rtw_scan_abort(padapter
->pbuddy_adapter
);
4397 #endif //CONFIG_CONCURRENT_MODE
4399 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4400 if(rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
4402 rtw_p2p_enable(padapter
, P2P_ROLE_DEVICE
);
4403 wdev_to_priv(padapter
->rtw_wdev
)->p2p_enabled
= _TRUE
;
4407 rtw_p2p_set_pre_state(pwdinfo
, rtw_p2p_state(pwdinfo
));
4408 #ifdef CONFIG_DEBUG_CFG80211
4409 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__
, rtw_p2p_role(pwdinfo
), rtw_p2p_state(pwdinfo
));
4414 rtw_p2p_set_state(pwdinfo
, P2P_STATE_LISTEN
);
4418 duration
= duration
*3;//extend from exper.
4421 #ifdef CONFIG_CONCURRENT_MODE
4422 if(check_buddy_fwstate(padapter
, _FW_LINKED
) &&
4423 (duration
<pwdinfo
->ext_listen_interval
))
4425 duration
= duration
+ pwdinfo
->ext_listen_interval
;
4429 pcfg80211_wdinfo
->restore_channel
= rtw_get_oper_ch(padapter
);
4431 if(rtw_ch_set_search_ch(pmlmeext
->channel_set
, remain_ch
) >= 0) {
4432 #ifdef CONFIG_CONCURRENT_MODE
4433 if ( check_buddy_fwstate(padapter
, _FW_LINKED
) )
4435 PADAPTER pbuddy_adapter
= padapter
->pbuddy_adapter
;
4436 struct mlme_ext_priv
*pbuddy_mlmeext
= &pbuddy_adapter
->mlmeextpriv
;
4438 if(remain_ch
!= pbuddy_mlmeext
->cur_channel
)
4440 if(ATOMIC_READ(&pwdev_priv
->switch_ch_to
)==1 ||
4441 (remain_ch
!= pmlmeext
->cur_channel
))
4443 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__
);
4444 issue_nulldata(padapter
->pbuddy_adapter
, NULL
, 1, 3, 500);
4446 ATOMIC_SET(&pwdev_priv
->switch_ch_to
, 0);
4448 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__
, duration
-pwdinfo
->ext_listen_interval
);
4449 _set_timer(&pwdinfo
->ap_p2p_switch_timer
, duration
-pwdinfo
->ext_listen_interval
);
4453 ready_on_channel
= _TRUE
;
4454 //pmlmeext->cur_channel = remain_ch;
4455 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4457 #endif //CONFIG_CONCURRENT_MODE
4458 if(remain_ch
!= pmlmeext
->cur_channel
)
4460 ready_on_channel
= _TRUE
;
4461 //pmlmeext->cur_channel = remain_ch;
4462 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4465 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__
, remain_ch
);
4469 //call this after other things have been done
4470 #ifdef CONFIG_CONCURRENT_MODE
4471 if(ATOMIC_READ(&pwdev_priv
->ro_ch_to
)==1 ||
4472 (remain_ch
!= pmlmeext
->cur_channel
))
4474 u8 co_channel
= 0xff;
4475 ATOMIC_SET(&pwdev_priv
->ro_ch_to
, 0);
4478 if(ready_on_channel
== _TRUE
)
4480 if ( !check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) )
4481 pmlmeext
->cur_channel
= remain_ch
;
4483 #ifdef CONFIG_CONCURRENT_MODE
4484 co_channel
= rtw_get_oper_ch(padapter
);
4486 if(co_channel
!=remain_ch
)
4489 if (!padapter
->mlmepriv
.LinkDetectInfo
.bBusyTraffic
)
4490 set_channel_bwmode(padapter
, remain_ch
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
4493 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__
, duration
);
4494 _set_timer( &pcfg80211_wdinfo
->remain_on_ch_timer
, duration
);
4496 #ifdef CONFIG_CONCURRENT_MODE
4500 rtw_cfg80211_ready_on_channel(padapter
, *cookie
, channel
, channel_type
, duration
, GFP_KERNEL
);
4504 pcfg80211_wdinfo
->is_ro_ch
= _FALSE
;
4509 static s32
cfg80211_rtw_cancel_remain_on_channel(struct wiphy
*wiphy
,
4510 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4511 struct wireless_dev
*wdev
,
4513 struct net_device
*ndev
,
4518 _adapter
*padapter
= wiphy_to_adapter(wiphy
);
4519 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
4520 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
4521 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
4522 struct cfg80211_wifidirect_info
*pcfg80211_wdinfo
= &padapter
->cfg80211_wdinfo
;
4524 DBG_871X(FUNC_ADPT_FMT
"\n", FUNC_ADPT_ARG(padapter
));
4526 if (pcfg80211_wdinfo
->is_ro_ch
== _TRUE
) {
4527 DBG_8192C("%s, cancel ro ch timer\n", __func__
);
4528 _cancel_timer_ex(&padapter
->cfg80211_wdinfo
.remain_on_ch_timer
);
4529 #ifdef CONFIG_CONCURRENT_MODE
4530 ATOMIC_SET(&pwdev_priv
->ro_ch_to
, 1);
4532 p2p_protocol_wk_hdl(padapter
, P2P_RO_CH_WK
);
4536 // Disable P2P Listen State
4537 if(!rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_CLIENT
) && !rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
4539 if(!rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
4541 _cancel_timer_ex( &pwdinfo
->find_phase_timer
);
4542 _cancel_timer_ex( &pwdinfo
->restore_p2p_state_timer
);
4543 _cancel_timer_ex( &pwdinfo
->pre_tx_scan_timer
);
4545 rtw_p2p_set_state(pwdinfo
, P2P_STATE_NONE
);
4546 _rtw_memset(pwdinfo
, 0x00, sizeof(struct wifidirect_info
));
4552 rtw_p2p_set_state(pwdinfo
, rtw_p2p_pre_state(pwdinfo
));
4553 #ifdef CONFIG_DEBUG_CFG80211
4554 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__
, rtw_p2p_role(pwdinfo
), rtw_p2p_state(pwdinfo
));
4557 pcfg80211_wdinfo
->is_ro_ch
= _FALSE
;
4564 static int _cfg80211_rtw_mgmt_tx(_adapter
*padapter
, u8 tx_ch
, const u8
*buf
, size_t len
)
4566 struct xmit_frame
*pmgntframe
;
4567 struct pkt_attrib
*pattrib
;
4568 unsigned char *pframe
;
4571 struct rtw_ieee80211_hdr
*pwlanhdr
;
4572 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
4573 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
4574 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
4575 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
4576 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
4577 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4579 if(_FAIL
== rtw_pwr_wakeup(padapter
)) {
4584 rtw_set_scan_deny(padapter
, 1000);
4586 rtw_scan_abort(padapter
);
4587 #ifdef CONFIG_CONCURRENT_MODE
4588 if(rtw_buddy_adapter_up(padapter
))
4589 rtw_scan_abort(padapter
->pbuddy_adapter
);
4590 #endif /* CONFIG_CONCURRENT_MODE */
4592 if (padapter
->cfg80211_wdinfo
.is_ro_ch
== _TRUE
) {
4593 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
4594 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4595 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
4596 #ifdef CONFIG_CONCURRENT_MODE
4597 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))
4599 DBG_8192C("%s, extend ro ch time\n", __func__
);
4600 _set_timer( &padapter
->cfg80211_wdinfo
.remain_on_ch_timer
, pwdinfo
->ext_listen_period
);
4602 #endif //CONFIG_CONCURRENT_MODE
4605 #ifdef CONFIG_CONCURRENT_MODE
4606 if (check_buddy_fwstate(padapter
, _FW_LINKED
)) {
4608 PADAPTER pbuddy_adapter
= padapter
->pbuddy_adapter
;
4609 struct mlme_ext_priv
*pbuddy_mlmeext
= &pbuddy_adapter
->mlmeextpriv
;
4611 co_channel
= rtw_get_oper_ch(padapter
);
4613 if (tx_ch
!= pbuddy_mlmeext
->cur_channel
) {
4615 u16 ext_listen_period
;
4617 if (ATOMIC_READ(&pwdev_priv
->switch_ch_to
)==1) {
4618 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__
);
4619 issue_nulldata(padapter
->pbuddy_adapter
, NULL
, 1, 3, 500);
4621 ATOMIC_SET(&pwdev_priv
->switch_ch_to
, 0);
4623 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4624 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4627 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))
4629 ext_listen_period
= 500;// 500ms
4633 ext_listen_period
= pwdinfo
->ext_listen_period
;
4636 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__
, ext_listen_period
);
4637 _set_timer(&pwdinfo
->ap_p2p_switch_timer
, ext_listen_period
);
4641 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))
4642 pmlmeext
->cur_channel
= tx_ch
;
4644 if (tx_ch
!= co_channel
)
4645 set_channel_bwmode(padapter
, tx_ch
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
4647 #endif //CONFIG_CONCURRENT_MODE
4648 //if (tx_ch != pmlmeext->cur_channel) {
4649 if(tx_ch
!= rtw_get_oper_ch(padapter
)) {
4650 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))
4651 pmlmeext
->cur_channel
= tx_ch
;
4652 set_channel_bwmode(padapter
, tx_ch
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
4655 //starting alloc mgmt frame to dump it
4656 if ((pmgntframe
= alloc_mgtxmitframe(pxmitpriv
)) == NULL
)
4664 pattrib
= &pmgntframe
->attrib
;
4665 update_mgntframe_attrib(padapter
, pattrib
);
4666 pattrib
->retry_ctrl
= _FALSE
;
4668 _rtw_memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
4670 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
4672 _rtw_memcpy(pframe
, (void*)buf
, len
);
4673 pattrib
->pktlen
= len
;
4675 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
4677 pmlmeext
->mgnt_seq
= GetSequence(pwlanhdr
);
4678 pattrib
->seqnum
= pmlmeext
->mgnt_seq
;
4679 pmlmeext
->mgnt_seq
++;
4683 struct wifi_display_info
*pwfd_info
;
4685 pwfd_info
= padapter
->wdinfo
.wfd_info
;
4687 if ( _TRUE
== pwfd_info
->wfd_enable
)
4689 rtw_append_wfd_ie( padapter
, pframe
, &pattrib
->pktlen
);
4692 #endif // CONFIG_WFD
4694 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
4696 if (dump_mgntframe_and_wait_ack(padapter
, pmgntframe
) != _SUCCESS
)
4701 #ifdef CONFIG_DEBUG_CFG80211
4702 DBG_8192C("%s, ack == _FAIL\n", __func__
);
4707 #ifdef CONFIG_DEBUG_CFG80211
4708 DBG_8192C("%s, ack=%d, ok!\n", __func__
, ack
);
4715 #ifdef CONFIG_DEBUG_CFG80211
4716 DBG_8192C("%s, ret=%d\n", __func__
, ret
);
4723 static int cfg80211_rtw_mgmt_tx(struct wiphy
*wiphy
,
4724 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4725 struct wireless_dev
*wdev
,
4727 struct net_device
*ndev
,
4729 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4730 struct cfg80211_mgmt_tx_params
*params
,
4732 struct ieee80211_channel
*chan
,
4733 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4736 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4737 enum nl80211_channel_type channel_type
,
4738 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4739 bool channel_type_valid
,
4742 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4745 const u8
*buf
, size_t len
,
4746 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
4749 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
4750 bool dont_wait_for_ack
,
4755 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4756 struct ieee80211_channel
*chan
= params
->chan
;
4757 const u8
*buf
= params
->buf
;
4758 size_t len
= params
->len
;
4761 _adapter
*padapter
= (_adapter
*)wiphy_to_adapter(wiphy
);
4762 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
4765 u32 dump_limit
= RTW_MAX_MGMT_TX_CNT
;
4768 u8 tx_ch
= (u8
)ieee80211_frequency_to_channel(chan
->center_freq
);
4769 u8 category
, action
;
4771 u32 start
= rtw_get_current_time();
4773 /* cookie generation */
4774 *cookie
= (unsigned long) buf
;
4776 #ifdef CONFIG_DEBUG_CFG80211
4777 DBG_871X(FUNC_ADPT_FMT
" len=%zu, ch=%d"
4778 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4780 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4781 ", channel_type_valid=%d"
4784 "\n", FUNC_ADPT_ARG(padapter
),
4786 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4788 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4789 , channel_type_valid
4793 #endif /* CONFIG_DEBUG_CFG80211 */
4795 /* indicate ack before issue frame to avoid racing with rsp frame */
4796 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4797 rtw_cfg80211_mgmt_tx_status(padapter
, *cookie
, buf
, len
, ack
, GFP_KERNEL
);
4798 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
4799 cfg80211_action_tx_status(ndev
, *cookie
, buf
, len
, ack
, GFP_KERNEL
);
4802 if (rtw_action_frame_parse(buf
, len
, &category
, &action
) == _FALSE
) {
4803 DBG_8192C(FUNC_ADPT_FMT
" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter
),
4804 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr
*)buf
)->frame_ctl
));
4808 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT
"\n", tx_ch
, MAC_ARG(GetAddr1Ptr(buf
)));
4810 if((type
= rtw_p2p_check_frames(padapter
, buf
, len
, _TRUE
)) >= 0) {
4814 if (category
== RTW_WLAN_CATEGORY_PUBLIC
)
4815 DBG_871X("RTW_Tx:%s\n", action_public_str(action
));
4817 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category
, action
);
4822 tx_ret
= _cfg80211_rtw_mgmt_tx(padapter
, tx_ch
, buf
, len
);
4823 } while (dump_cnt
< dump_limit
&& tx_ret
!= _SUCCESS
);
4825 if (tx_ret
!= _SUCCESS
|| dump_cnt
> 1) {
4826 DBG_871X(FUNC_ADPT_FMT
" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter
),
4827 tx_ret
==_SUCCESS
?"OK":"FAIL", dump_cnt
, dump_limit
, rtw_get_passing_time_ms(start
));
4831 case P2P_GO_NEGO_CONF
:
4832 rtw_clear_scan_deny(padapter
);
4834 case P2P_INVIT_RESP
:
4835 if (pwdev_priv
->invit_info
.flags
& BIT(0)
4836 && pwdev_priv
->invit_info
.status
== 0)
4838 DBG_871X(FUNC_ADPT_FMT
" agree with invitation of persistent group\n",
4839 FUNC_ADPT_ARG(padapter
));
4840 rtw_set_scan_deny(padapter
, 5000);
4841 rtw_pwr_wakeup_ex(padapter
, 5000);
4842 rtw_clear_scan_deny(padapter
);
4851 static void cfg80211_rtw_mgmt_frame_register(struct wiphy
*wiphy
,
4852 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4853 struct wireless_dev
*wdev
,
4855 struct net_device
*ndev
,
4857 u16 frame_type
, bool reg
)
4859 _adapter
*adapter
= wiphy_to_adapter(wiphy
);
4861 #ifdef CONFIG_DEBUG_CFG80211
4862 DBG_871X(FUNC_ADPT_FMT
" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter
),
4866 if (frame_type
!= (IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_PROBE_REQ
))
4872 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device
*ndev
, char *buf
, int len
)
4878 u8 wps_oui
[8]={0x0,0x50,0xf2,0x04};
4882 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(ndev
);
4883 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
4884 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
4886 DBG_871X(FUNC_NDEV_FMT
" ielen=%d\n", FUNC_NDEV_ARG(ndev
), len
);
4890 if((wps_ie
= rtw_get_wps_ie(buf
, len
, NULL
, &wps_ielen
)))
4892 #ifdef CONFIG_DEBUG_CFG80211
4893 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen
);
4896 if(pmlmepriv
->wps_beacon_ie
)
4898 u32 free_len
= pmlmepriv
->wps_beacon_ie_len
;
4899 pmlmepriv
->wps_beacon_ie_len
= 0;
4900 rtw_mfree(pmlmepriv
->wps_beacon_ie
, free_len
);
4901 pmlmepriv
->wps_beacon_ie
= NULL
;
4904 pmlmepriv
->wps_beacon_ie
= rtw_malloc(wps_ielen
);
4905 if ( pmlmepriv
->wps_beacon_ie
== NULL
) {
4906 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
4911 _rtw_memcpy(pmlmepriv
->wps_beacon_ie
, wps_ie
, wps_ielen
);
4912 pmlmepriv
->wps_beacon_ie_len
= wps_ielen
;
4914 update_beacon(padapter
, _VENDOR_SPECIFIC_IE_
, wps_oui
, _TRUE
);
4922 if((p2p_ie
=rtw_get_p2p_ie(buf
, len
, NULL
, &p2p_ielen
)))
4924 #ifdef CONFIG_DEBUG_CFG80211
4925 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen
);
4928 if(pmlmepriv
->p2p_beacon_ie
)
4930 u32 free_len
= pmlmepriv
->p2p_beacon_ie_len
;
4931 pmlmepriv
->p2p_beacon_ie_len
= 0;
4932 rtw_mfree(pmlmepriv
->p2p_beacon_ie
, free_len
);
4933 pmlmepriv
->p2p_beacon_ie
= NULL
;
4936 pmlmepriv
->p2p_beacon_ie
= rtw_malloc(p2p_ielen
);
4937 if ( pmlmepriv
->p2p_beacon_ie
== NULL
) {
4938 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
4943 _rtw_memcpy(pmlmepriv
->p2p_beacon_ie
, p2p_ie
, p2p_ielen
);
4944 pmlmepriv
->p2p_beacon_ie_len
= p2p_ielen
;
4953 if(rtw_get_wfd_ie(buf
, len
, NULL
, &wfd_ielen
))
4955 #ifdef CONFIG_DEBUG_CFG80211
4956 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen
);
4959 if(pmlmepriv
->wfd_beacon_ie
)
4961 u32 free_len
= pmlmepriv
->wfd_beacon_ie_len
;
4962 pmlmepriv
->wfd_beacon_ie_len
= 0;
4963 rtw_mfree(pmlmepriv
->wfd_beacon_ie
, free_len
);
4964 pmlmepriv
->wfd_beacon_ie
= NULL
;
4967 pmlmepriv
->wfd_beacon_ie
= rtw_malloc(wfd_ielen
);
4968 if ( pmlmepriv
->wfd_beacon_ie
== NULL
) {
4969 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
4973 rtw_get_wfd_ie(buf
, len
, pmlmepriv
->wfd_beacon_ie
, &pmlmepriv
->wfd_beacon_ie_len
);
4977 pmlmeext
->bstart_bss
= _TRUE
;
4985 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device
*net
, char *buf
, int len
)
4994 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(net
);
4995 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
4997 #ifdef CONFIG_DEBUG_CFG80211
4998 DBG_8192C("%s, ielen=%d\n", __func__
, len
);
5003 if((wps_ie
= rtw_get_wps_ie(buf
, len
, NULL
, &wps_ielen
)))
5005 uint attr_contentlen
= 0;
5006 u16 uconfig_method
, *puconfig_method
= NULL
;
5008 #ifdef CONFIG_DEBUG_CFG80211
5009 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen
);
5012 if(check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
))
5015 rtw_get_wps_attr_content(wps_ie
, wps_ielen
, WPS_ATTR_SELECTED_REGISTRAR
, (u8
*)(&sr
), NULL
);
5019 DBG_871X("%s, got sr\n", __func__
);
5023 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
5028 if(pmlmepriv
->wps_probe_resp_ie
)
5030 u32 free_len
= pmlmepriv
->wps_probe_resp_ie_len
;
5031 pmlmepriv
->wps_probe_resp_ie_len
= 0;
5032 rtw_mfree(pmlmepriv
->wps_probe_resp_ie
, free_len
);
5033 pmlmepriv
->wps_probe_resp_ie
= NULL
;
5036 pmlmepriv
->wps_probe_resp_ie
= rtw_malloc(wps_ielen
);
5037 if ( pmlmepriv
->wps_probe_resp_ie
== NULL
) {
5038 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
5043 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
5044 if ( (puconfig_method
= (u16
*)rtw_get_wps_attr_content( wps_ie
, wps_ielen
, WPS_ATTR_CONF_METHOD
, NULL
, &attr_contentlen
)) != NULL
)
5046 #ifdef CONFIG_DEBUG_CFG80211
5047 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
5050 uconfig_method
= WPS_CM_PUSH_BUTTON
;
5051 uconfig_method
= cpu_to_be16( uconfig_method
);
5053 *puconfig_method
|= uconfig_method
;
5056 _rtw_memcpy(pmlmepriv
->wps_probe_resp_ie
, wps_ie
, wps_ielen
);
5057 pmlmepriv
->wps_probe_resp_ie_len
= wps_ielen
;
5065 if((p2p_ie
=rtw_get_p2p_ie(buf
, len
, NULL
, &p2p_ielen
)))
5068 u32 attr_contentlen
= 0;
5071 #ifdef CONFIG_DEBUG_CFG80211
5072 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen
);
5075 //Check P2P Capability ATTR
5076 if( rtw_get_p2p_attr_content( p2p_ie
, p2p_ielen
, P2P_ATTR_CAPABILITY
, (u8
*)&cap_attr
, (uint
*) &attr_contentlen
) )
5079 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
5080 cap_attr
= le16_to_cpu(cap_attr
);
5081 grp_cap
= (u8
)((cap_attr
>> 8)&0xff);
5083 is_GO
= (grp_cap
&BIT(0)) ? _TRUE
:_FALSE
;
5086 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap
);
5092 if(pmlmepriv
->p2p_probe_resp_ie
)
5094 u32 free_len
= pmlmepriv
->p2p_probe_resp_ie_len
;
5095 pmlmepriv
->p2p_probe_resp_ie_len
= 0;
5096 rtw_mfree(pmlmepriv
->p2p_probe_resp_ie
, free_len
);
5097 pmlmepriv
->p2p_probe_resp_ie
= NULL
;
5100 pmlmepriv
->p2p_probe_resp_ie
= rtw_malloc(p2p_ielen
);
5101 if ( pmlmepriv
->p2p_probe_resp_ie
== NULL
) {
5102 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
5106 _rtw_memcpy(pmlmepriv
->p2p_probe_resp_ie
, p2p_ie
, p2p_ielen
);
5107 pmlmepriv
->p2p_probe_resp_ie_len
= p2p_ielen
;
5111 if(pmlmepriv
->p2p_go_probe_resp_ie
)
5113 u32 free_len
= pmlmepriv
->p2p_go_probe_resp_ie_len
;
5114 pmlmepriv
->p2p_go_probe_resp_ie_len
= 0;
5115 rtw_mfree(pmlmepriv
->p2p_go_probe_resp_ie
, free_len
);
5116 pmlmepriv
->p2p_go_probe_resp_ie
= NULL
;
5119 pmlmepriv
->p2p_go_probe_resp_ie
= rtw_malloc(p2p_ielen
);
5120 if ( pmlmepriv
->p2p_go_probe_resp_ie
== NULL
) {
5121 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
5125 _rtw_memcpy(pmlmepriv
->p2p_go_probe_resp_ie
, p2p_ie
, p2p_ielen
);
5126 pmlmepriv
->p2p_go_probe_resp_ie_len
= p2p_ielen
;
5136 if(rtw_get_wfd_ie(buf
, len
, NULL
, &wfd_ielen
))
5138 #ifdef CONFIG_DEBUG_CFG80211
5139 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen
);
5142 if(pmlmepriv
->wfd_probe_resp_ie
)
5144 u32 free_len
= pmlmepriv
->wfd_probe_resp_ie_len
;
5145 pmlmepriv
->wfd_probe_resp_ie_len
= 0;
5146 rtw_mfree(pmlmepriv
->wfd_probe_resp_ie
, free_len
);
5147 pmlmepriv
->wfd_probe_resp_ie
= NULL
;
5150 pmlmepriv
->wfd_probe_resp_ie
= rtw_malloc(wfd_ielen
);
5151 if ( pmlmepriv
->wfd_probe_resp_ie
== NULL
) {
5152 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
5156 rtw_get_wfd_ie(buf
, len
, pmlmepriv
->wfd_probe_resp_ie
, &pmlmepriv
->wfd_probe_resp_ie_len
);
5166 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device
*net
, char *buf
, int len
)
5169 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(net
);
5170 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
5172 DBG_8192C("%s, ielen=%d\n", __func__
, len
);
5176 if(pmlmepriv
->wps_assoc_resp_ie
)
5178 u32 free_len
= pmlmepriv
->wps_assoc_resp_ie_len
;
5179 pmlmepriv
->wps_assoc_resp_ie_len
= 0;
5180 rtw_mfree(pmlmepriv
->wps_assoc_resp_ie
, free_len
);
5181 pmlmepriv
->wps_assoc_resp_ie
= NULL
;
5184 pmlmepriv
->wps_assoc_resp_ie
= rtw_malloc(len
);
5185 if ( pmlmepriv
->wps_assoc_resp_ie
== NULL
) {
5186 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__
, __LINE__
);
5190 _rtw_memcpy(pmlmepriv
->wps_assoc_resp_ie
, buf
, len
);
5191 pmlmepriv
->wps_assoc_resp_ie_len
= len
;
5198 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device
*net
, char *buf
, int len
,
5205 #ifdef CONFIG_DEBUG_CFG80211
5206 DBG_8192C("%s, ielen=%d\n", __func__
, len
);
5209 if( (rtw_get_wps_ie(buf
, len
, NULL
, &wps_ielen
) && (wps_ielen
>0))
5211 || (rtw_get_p2p_ie(buf
, len
, NULL
, &p2p_ielen
) && (p2p_ielen
>0))
5220 ret
= rtw_cfg80211_set_beacon_wpsp2pie(net
, buf
, len
);
5222 case 0x2: //PROBE_RESP
5223 ret
= rtw_cfg80211_set_probe_resp_wpsp2pie(net
, buf
, len
);
5225 case 0x4: //ASSOC_RESP
5226 ret
= rtw_cfg80211_set_assoc_resp_wpsp2pie(net
, buf
, len
);
5236 static struct cfg80211_ops rtw_cfg80211_ops
= {
5237 .change_virtual_intf
= cfg80211_rtw_change_iface
,
5238 .add_key
= cfg80211_rtw_add_key
,
5239 .get_key
= cfg80211_rtw_get_key
,
5240 .del_key
= cfg80211_rtw_del_key
,
5241 .set_default_key
= cfg80211_rtw_set_default_key
,
5242 .get_station
= cfg80211_rtw_get_station
,
5243 .scan
= cfg80211_rtw_scan
,
5244 .set_wiphy_params
= cfg80211_rtw_set_wiphy_params
,
5245 .connect
= cfg80211_rtw_connect
,
5246 .disconnect
= cfg80211_rtw_disconnect
,
5247 .join_ibss
= cfg80211_rtw_join_ibss
,
5248 .leave_ibss
= cfg80211_rtw_leave_ibss
,
5249 .set_tx_power
= cfg80211_rtw_set_txpower
,
5250 .get_tx_power
= cfg80211_rtw_get_txpower
,
5251 .set_power_mgmt
= cfg80211_rtw_set_power_mgmt
,
5252 .set_pmksa
= cfg80211_rtw_set_pmksa
,
5253 .del_pmksa
= cfg80211_rtw_del_pmksa
,
5254 .flush_pmksa
= cfg80211_rtw_flush_pmksa
,
5256 #ifdef CONFIG_AP_MODE
5257 .add_virtual_intf
= cfg80211_rtw_add_virtual_intf
,
5258 .del_virtual_intf
= cfg80211_rtw_del_virtual_intf
,
5260 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
5261 .add_beacon
= cfg80211_rtw_add_beacon
,
5262 .set_beacon
= cfg80211_rtw_set_beacon
,
5263 .del_beacon
= cfg80211_rtw_del_beacon
,
5265 .start_ap
= cfg80211_rtw_start_ap
,
5266 .change_beacon
= cfg80211_rtw_change_beacon
,
5267 .stop_ap
= cfg80211_rtw_stop_ap
,
5270 .add_station
= cfg80211_rtw_add_station
,
5271 .del_station
= cfg80211_rtw_del_station
,
5272 .change_station
= cfg80211_rtw_change_station
,
5273 .dump_station
= cfg80211_rtw_dump_station
,
5274 .change_bss
= cfg80211_rtw_change_bss
,
5275 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
5276 .set_channel
= cfg80211_rtw_set_channel
,
5278 //.auth = cfg80211_rtw_auth,
5279 //.assoc = cfg80211_rtw_assoc,
5280 #endif //CONFIG_AP_MODE
5283 .remain_on_channel
= cfg80211_rtw_remain_on_channel
,
5284 .cancel_remain_on_channel
= cfg80211_rtw_cancel_remain_on_channel
,
5287 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5288 .mgmt_tx
= cfg80211_rtw_mgmt_tx
,
5289 .mgmt_frame_register
= cfg80211_rtw_mgmt_frame_register
,
5290 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
5291 .action
= cfg80211_rtw_mgmt_tx
,
5295 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap
*ht_cap
, enum nl80211_band band
, u8 rf_type
)
5298 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
5299 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
5301 ht_cap
->ht_supported
= _TRUE
;
5303 ht_cap
->cap
= IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
5304 IEEE80211_HT_CAP_SGI_40
| IEEE80211_HT_CAP_SGI_20
|
5305 IEEE80211_HT_CAP_DSSSCCK40
| IEEE80211_HT_CAP_MAX_AMSDU
;
5308 *Maximum length of AMPDU that the STA can receive.
5309 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
5311 ht_cap
->ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
5313 /*Minimum MPDU start spacing , */
5314 ht_cap
->ampdu_density
= IEEE80211_HT_MPDU_DENSITY_16
;
5316 ht_cap
->mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
5319 *hw->wiphy->bands[NL80211_BAND_2GHZ]
5322 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
5323 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
5324 *if rx_ant >=3 rx_mask[2]=0xff;
5325 *if BW_40 rx_mask[4]=0x01;
5326 *highest supported RX rate
5328 if(rf_type
== RF_1T1R
)
5330 ht_cap
->mcs
.rx_mask
[0] = 0xFF;
5331 ht_cap
->mcs
.rx_mask
[1] = 0x00;
5332 ht_cap
->mcs
.rx_mask
[4] = 0x01;
5334 ht_cap
->mcs
.rx_highest
= MAX_BIT_RATE_40MHZ_MCS7
;
5336 else if((rf_type
== RF_1T2R
) || (rf_type
==RF_2T2R
))
5338 ht_cap
->mcs
.rx_mask
[0] = 0xFF;
5339 ht_cap
->mcs
.rx_mask
[1] = 0xFF;
5340 ht_cap
->mcs
.rx_mask
[4] = 0x01;
5342 ht_cap
->mcs
.rx_highest
= MAX_BIT_RATE_40MHZ_MCS15
;
5346 DBG_8192C("%s, error rf_type=%d\n", __func__
, rf_type
);
5351 void rtw_cfg80211_init_wiphy(_adapter
*padapter
)
5354 struct ieee80211_supported_band
*bands
;
5355 struct wireless_dev
*pwdev
= padapter
->rtw_wdev
;
5356 struct wiphy
*wiphy
= pwdev
->wiphy
;
5358 rtw_hal_get_hwreg(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
5360 DBG_8192C("%s:rf_type=%d\n", __func__
, rf_type
);
5362 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5364 bands
= wiphy
->bands
[NL80211_BAND_2GHZ
];
5366 rtw_cfg80211_init_ht_capab(&bands
->ht_cap
, NL80211_BAND_2GHZ
, rf_type
);
5369 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5371 bands
= wiphy
->bands
[NL80211_BAND_5GHZ
];
5373 rtw_cfg80211_init_ht_capab(&bands
->ht_cap
, NL80211_BAND_5GHZ
, rf_type
);
5378 struct ieee80211_iface_limit rtw_limits[] = {
5379 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
5380 | BIT(NL80211_IFTYPE_ADHOC)
5381 #ifdef CONFIG_AP_MODE
5382 | BIT(NL80211_IFTYPE_AP)
5384 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5385 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5386 | BIT(NL80211_IFTYPE_P2P_GO)
5389 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
5392 struct ieee80211_iface_combination rtw_combinations = {
5393 .limits = rtw_limits,
5394 .n_limits = ARRAY_SIZE(rtw_limits),
5395 .max_interfaces = 2,
5396 .num_different_channels = 1,
5400 static void rtw_cfg80211_preinit_wiphy(_adapter
*padapter
, struct wiphy
*wiphy
)
5403 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
5405 wiphy
->max_scan_ssids
= RTW_SSID_SCAN_AMOUNT
;
5406 wiphy
->max_scan_ie_len
= RTW_SCAN_IE_LEN_MAX
;
5407 wiphy
->max_num_pmkids
= RTW_MAX_NUM_PMKIDS
;
5409 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
5410 wiphy
->max_remain_on_channel_duration
= RTW_MAX_REMAIN_ON_CHANNEL_DURATION
;
5413 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
)
5414 | BIT(NL80211_IFTYPE_ADHOC
)
5415 #ifdef CONFIG_AP_MODE
5416 | BIT(NL80211_IFTYPE_AP
)
5417 | BIT(NL80211_IFTYPE_MONITOR
)
5419 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5420 | BIT(NL80211_IFTYPE_P2P_CLIENT
)
5421 | BIT(NL80211_IFTYPE_P2P_GO
)
5425 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5426 #ifdef CONFIG_AP_MODE
5427 wiphy
->mgmt_stypes
= rtw_cfg80211_default_mgmt_stypes
;
5428 #endif //CONFIG_AP_MODE
5431 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
5432 wiphy
->software_iftypes
|= BIT(NL80211_IFTYPE_MONITOR
);
5436 wiphy->iface_combinations = &rtw_combinations;
5437 wiphy->n_iface_combinations = 1;
5440 wiphy
->cipher_suites
= rtw_cipher_suites
;
5441 wiphy
->n_cipher_suites
= ARRAY_SIZE(rtw_cipher_suites
);
5443 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5444 wiphy
->bands
[NL80211_BAND_2GHZ
] = rtw_spt_band_alloc(NL80211_BAND_2GHZ
);
5445 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5446 wiphy
->bands
[NL80211_BAND_5GHZ
] = rtw_spt_band_alloc(NL80211_BAND_5GHZ
);
5448 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
5449 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS
;
5452 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
5453 wiphy
->flags
|= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
5454 wiphy
->flags
|= WIPHY_FLAG_OFFCHAN_TX
| WIPHY_FLAG_HAVE_AP_SME
;
5457 if(padapter
->registrypriv
.power_mgnt
!= PS_MODE_ACTIVE
)
5458 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
;
5460 wiphy
->flags
&= ~WIPHY_FLAG_PS_ON_BY_DEFAULT
;
5463 int rtw_wdev_alloc(_adapter
*padapter
, struct device
*dev
)
5466 struct wiphy
*wiphy
;
5467 struct wireless_dev
*wdev
;
5468 struct rtw_wdev_priv
*pwdev_priv
;
5469 struct net_device
*pnetdev
= padapter
->pnetdev
;
5471 DBG_8192C("%s(padapter=%p)\n", __func__
, padapter
);
5474 wiphy
= wiphy_new(&rtw_cfg80211_ops
, sizeof(struct rtw_wdev_priv
));
5476 DBG_8192C("Couldn't allocate wiphy device\n");
5480 set_wiphy_dev(wiphy
, dev
);
5481 rtw_cfg80211_preinit_wiphy(padapter
, wiphy
);
5483 ret
= wiphy_register(wiphy
);
5485 DBG_8192C("Couldn't register wiphy device\n");
5490 wdev
= (struct wireless_dev
*)rtw_zmalloc(sizeof(struct wireless_dev
));
5492 DBG_8192C("Couldn't allocate wireless device\n");
5494 goto unregister_wiphy
;
5496 wdev
->wiphy
= wiphy
;
5497 wdev
->netdev
= pnetdev
;
5499 wdev
->iftype
= NL80211_IFTYPE_STATION
; // will be init in rtw_hal_init()
5500 // Must sync with _rtw_init_mlme_priv()
5501 // pmlmepriv->fw_state = WIFI_STATION_STATE
5502 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
5503 padapter
->rtw_wdev
= wdev
;
5504 pnetdev
->ieee80211_ptr
= wdev
;
5507 pwdev_priv
= wdev_to_priv(wdev
);
5508 pwdev_priv
->rtw_wdev
= wdev
;
5509 pwdev_priv
->pmon_ndev
= NULL
;
5510 pwdev_priv
->ifname_mon
[0] = '\0';
5511 pwdev_priv
->padapter
= padapter
;
5512 pwdev_priv
->scan_request
= NULL
;
5513 _rtw_spinlock_init(&pwdev_priv
->scan_req_lock
);
5515 pwdev_priv
->p2p_enabled
= _FALSE
;
5516 pwdev_priv
->provdisc_req_issued
= _FALSE
;
5517 rtw_wdev_invit_info_init(&pwdev_priv
->invit_info
);
5518 rtw_wdev_nego_info_init(&pwdev_priv
->nego_info
);
5520 pwdev_priv
->bandroid_scan
= _FALSE
;
5522 if(padapter
->registrypriv
.power_mgnt
!= PS_MODE_ACTIVE
)
5523 pwdev_priv
->power_mgmt
= _TRUE
;
5525 pwdev_priv
->power_mgmt
= _FALSE
;
5527 #ifdef CONFIG_CONCURRENT_MODE
5528 ATOMIC_SET(&pwdev_priv
->switch_ch_to
, 1);
5529 ATOMIC_SET(&pwdev_priv
->ro_ch_to
, 1);
5534 rtw_mfree((u8
*)wdev
, sizeof(struct wireless_dev
));
5536 wiphy_unregister(wiphy
);
5544 void rtw_wdev_free(struct wireless_dev
*wdev
)
5546 struct rtw_wdev_priv
*pwdev_priv
;
5548 DBG_8192C("%s(wdev=%p)\n", __func__
, wdev
);
5553 pwdev_priv
= wdev_to_priv(wdev
);
5555 rtw_spt_band_free(wdev
->wiphy
->bands
[NL80211_BAND_2GHZ
]);
5556 rtw_spt_band_free(wdev
->wiphy
->bands
[NL80211_BAND_5GHZ
]);
5558 wiphy_free(wdev
->wiphy
);
5560 rtw_mfree((u8
*)wdev
, sizeof(struct wireless_dev
));
5563 void rtw_wdev_unregister(struct wireless_dev
*wdev
)
5565 struct rtw_wdev_priv
*pwdev_priv
;
5567 DBG_8192C("%s(wdev=%p)\n", __func__
, wdev
);
5572 pwdev_priv
= wdev_to_priv(wdev
);
5574 rtw_cfg80211_indicate_scan_done(pwdev_priv
, _TRUE
);
5576 if (pwdev_priv
->pmon_ndev
) {
5577 DBG_8192C("%s, unregister monitor interface\n", __func__
);
5578 unregister_netdev(pwdev_priv
->pmon_ndev
);
5581 wiphy_unregister(wdev
->wiphy
);
5584 #endif //CONFIG_IOCTL_CFG80211