diff --git a/Kconfig b/Kconfig deleted file mode 100644 index f87653d..0000000 --- a/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config RTL8812AU - tristate "Realtek 8812A USB WiFi" - depends on USB - ---help--- - Help message of RTL8812AU - diff --git a/Makefile b/Makefile index 7a9ce1d..1eff52e 100755 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) EXTRA_CFLAGS += -O1 #EXTRA_CFLAGS += -O3 -EXTRA_CFLAGS += -Wall -EXTRA_CFLAGS += -Wextra +#EXTRA_CFLAGS += -Wall +#EXTRA_CFLAGS += -Wextra #EXTRA_CFLAGS += -Werror #EXTRA_CFLAGS += -pedantic #EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes @@ -585,6 +585,10 @@ endif ########### HAL_RTL8814A ################################# ifeq ($(CONFIG_RTL8814A), y) +## ADD NEW VHT MP HW TX MODE ## +#EXTRA_CFLAGS += -DCONFIG_MP_VHT_HW_TX_MODE +#CONFIG_MP_VHT_HW_TX_MODE = y +########################################## RTL871X = rtl8814a ifeq ($(CONFIG_USB_HCI), y) MODULE_NAME = 8814au diff --git a/README.md b/README.md index cff7b8e..65a2015 100644 --- a/README.md +++ b/README.md @@ -143,9 +143,3 @@ at the end of file /etc/NetworkManager/NetworkManager.conf and restart NetworkMa sudo service NetworkManager restart ``` -### Other sources worth checking out -``` -new rtw88 mac80211 driver: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/log/rtw88 -wireless git: https://git.kernel.org/pub/scm/linux/kernel/git/jh/wireless.git/log/ -wireless testing git: https://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git/log/ -wpa_supplicant git: https://w1.fi/cgit/hostap/log/ diff --git a/ReleaseNotes.pdf b/ReleaseNotes.pdf index 9c27e93..e6e2b74 100644 Binary files a/ReleaseNotes.pdf and b/ReleaseNotes.pdf differ diff --git a/core/mesh/rtw_mesh.c b/core/mesh/rtw_mesh.c index 7d3a2e3..95d0f15 100644 --- a/core/mesh/rtw_mesh.c +++ b/core/mesh/rtw_mesh.c @@ -1179,33 +1179,12 @@ void rtw_mesh_adjust_chbw(u8 req_ch, u8 *req_bw, u8 *req_offset) } } -int rtw_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx) +void rtw_mesh_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx, u16 alg, u16 seq, u16 status) { - const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr); - u16 alg; - u16 seq; - u16 status; - int ret = 0; - - alg = RTW_GET_LE16(frame_body); - if (alg != 3) - goto exit; - - seq = RTW_GET_LE16(frame_body + 2); - status = RTW_GET_LE16(frame_body + 4); - - RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x\n" - , (tx == _TRUE) ? "Tx" : "Rx", alg, seq, status); - - ret = 1; - #if CONFIG_RTW_MESH_PEER_BLACKLIST if (tx && seq == 1) rtw_mesh_plink_set_peer_conf_timeout(adapter, GetAddr1Ptr(buf)); #endif - -exit: - return ret; } #if CONFIG_RTW_MPM_TX_IES_SYNC_BSS diff --git a/core/mesh/rtw_mesh.h b/core/mesh/rtw_mesh.h index 6f7f707..73694f8 100644 --- a/core/mesh/rtw_mesh.h +++ b/core/mesh/rtw_mesh.h @@ -454,7 +454,7 @@ void dump_mesh_networks(void *sel, _adapter *adapter); void rtw_mesh_adjust_chbw(u8 req_ch, u8 *req_bw, u8 *req_offset); -int rtw_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx); +void rtw_mesh_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx, u16 alg, u16 seq, u16 status); int rtw_mesh_check_frames_tx(_adapter *adapter, const u8 **buf, size_t *len); int rtw_mesh_check_frames_rx(_adapter *adapter, const u8 *buf, size_t len); diff --git a/core/rtw_ap.c b/core/rtw_ap.c index e3f0861..a03a71a 100644 --- a/core/rtw_ap.c +++ b/core/rtw_ap.c @@ -171,7 +171,7 @@ void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *d u8 bmatch = _FALSE; u8 *pie = pnetwork->IEs; u8 *p = NULL, *dst_ie = NULL, *premainder_ie = NULL, *pbackup_remainder_ie = NULL; - u32 i, offset, ielen = 0, ie_offset, remainder_ielen = 0; + u32 i, offset, ielen, ie_offset, remainder_ielen = 0; for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) { pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); @@ -1897,6 +1897,7 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) u16 cap, ht_cap = _FALSE; uint ie_len = 0; int group_cipher, pairwise_cipher; + u32 akm; u8 mfp_opt = MFP_NO; u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; int supportRateNum = 0; @@ -2057,13 +2058,14 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) psecuritypriv->wpa_psk = 0; /* wpa2 */ + akm = 0; group_cipher = 0; pairwise_cipher = 0; psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); if (p && ie_len > 0) { - if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) { + if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) { psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ @@ -2071,6 +2073,15 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) psecuritypriv->wpa2_group_cipher = group_cipher; psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; + + /* + Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC + in cfg80211_rtw_start_ap(). + if the AKM SAE in the RSN IE, we have to update the auth_type for SAE + in rtw_check_beacon_data(). + */ + if (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) + psecuritypriv->auth_type = NL80211_AUTHTYPE_SAE; #if 0 switch (group_cipher) { case WPA_CIPHER_NONE: @@ -3858,6 +3869,12 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso _enter_critical_bh(&psta->lock, &irqL); psta->state &= ~(_FW_LINKED | WIFI_UNDER_KEY_HANDSHAKE); + + if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) { + rtw_mfree(psta->pauth_frame, psta->auth_len); + psta->pauth_frame = NULL; + psta->auth_len = 0; + } _exit_critical_bh(&psta->lock, &irqL); if (!MLME_IS_MESH(padapter)) { @@ -5172,6 +5189,7 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct u8 *wpa_ie; int wpa_ie_len; int group_cipher = 0, pairwise_cipher = 0; + u32 akm = 0; u8 mfp_opt = MFP_NO; u16 status = _STATS_SUCCESSFUL_; @@ -5187,13 +5205,17 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct wpa_ie = elems->rsn_ie; wpa_ie_len = elems->rsn_ie_len; - if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) { + if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) { sta->dot8021xalg = 1;/* psk, todo:802.1x */ sta->wpa_psk |= BIT(1); sta->wpa2_group_cipher = group_cipher & sec->wpa2_group_cipher; sta->wpa2_pairwise_cipher = pairwise_cipher & sec->wpa2_pairwise_cipher; + sta->akm_suite_type = akm; + if ((CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) && (MFP_NO == mfp_opt)) + status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; + if (!sta->wpa2_group_cipher) status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; @@ -5239,6 +5261,18 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct else if (sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL) sta->flags |= WLAN_STA_MFP; + if ((sec->auth_type == NL80211_AUTHTYPE_SAE) && + (CHECK_BIT(WLAN_AKM_TYPE_SAE, sta->akm_suite_type)) && + (WLAN_AUTH_OPEN == sta->authalg)) { + /* WPA3-SAE, PMK caching */ + if (rtw_cached_pmkid(adapter, sta->cmn.mac_addr) == -1) { + RTW_INFO("SAE: No PMKSA cache entry found\n"); + status = WLAN_STATUS_INVALID_PMKID; + } else { + RTW_INFO("SAE: PMKSA cache entry found\n"); + } + } + if (status != _STATS_SUCCESSFUL_) goto exit; diff --git a/core/rtw_ieee80211.c b/core/rtw_ieee80211.c index c867197..33b05c4 100644 --- a/core/rtw_ieee80211.c +++ b/core/rtw_ieee80211.c @@ -33,14 +33,28 @@ u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; u16 RSN_VERSION_BSD = 1; -u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; -u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; + +u8 WLAN_AKM_8021X[] = {0x00, 0x0f, 0xac, 1}; +u8 WLAN_AKM_PSK[] = {0x00, 0x0f, 0xac, 2}; +u8 WLAN_AKM_FT_8021X[] = {0x00, 0x0f, 0xac, 3}; +u8 WLAN_AKM_FT_PSK[] = {0x00, 0x0f, 0xac, 4}; +u8 WLAN_AKM_8021X_SHA256[] = {0x00, 0x0f, 0xac, 5}; +u8 WLAN_AKM_PSK_SHA256[] = {0x00, 0x0f, 0xac, 6}; +u8 WLAN_AKM_TDLS[] = {0x00, 0x0f, 0xac, 7}; +u8 WLAN_AKM_SAE[] = {0x00, 0x0f, 0xac, 8}; +u8 WLAN_AKM_FT_OVER_SAE[] = {0x00, 0x0f, 0xac, 9}; +u8 WLAN_AKM_8021X_SUITE_B[] = {0x00, 0x0f, 0xac, 11}; +u8 WLAN_AKM_8021X_SUITE_B_192[] = {0x00, 0x0f, 0xac, 12}; +u8 WLAN_AKM_FILS_SHA256[] = {0x00, 0x0f, 0xac, 14}; +u8 WLAN_AKM_FILS_SHA384[] = {0x00, 0x0f, 0xac, 15}; +u8 WLAN_AKM_FT_FILS_SHA256[] = {0x00, 0x0f, 0xac, 16}; +u8 WLAN_AKM_FT_FILS_SHA384[] = {0x00, 0x0f, 0xac, 17}; /* ----------------------------------------------------------- * for adhoc-master to generate ie and provide supported-rate to fw * ----------------------------------------------------------- */ @@ -661,8 +675,44 @@ int rtw_get_wpa2_cipher_suite(u8 *s) return 0; } +u32 rtw_get_akm_suite_bitmap(u8 *s) +{ + if (_rtw_memcmp(s, WLAN_AKM_8021X, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_8021X; + if (_rtw_memcmp(s, WLAN_AKM_PSK, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_PSK; + if (_rtw_memcmp(s, WLAN_AKM_FT_8021X, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FT_8021X; + if (_rtw_memcmp(s, WLAN_AKM_FT_PSK, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FT_PSK; + if (_rtw_memcmp(s, WLAN_AKM_8021X_SHA256, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_8021X_SHA256; + if (_rtw_memcmp(s, WLAN_AKM_PSK_SHA256, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_PSK_SHA256; + if (_rtw_memcmp(s, WLAN_AKM_TDLS, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_TDLS; + if (_rtw_memcmp(s, WLAN_AKM_SAE, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_SAE; + if (_rtw_memcmp(s, WLAN_AKM_FT_OVER_SAE, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FT_OVER_SAE; + if (_rtw_memcmp(s, WLAN_AKM_8021X_SUITE_B, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_8021X_SUITE_B; + if (_rtw_memcmp(s, WLAN_AKM_8021X_SUITE_B_192, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_8021X_SUITE_B_192; + if (_rtw_memcmp(s, WLAN_AKM_FILS_SHA256, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FILS_SHA256; + if (_rtw_memcmp(s, WLAN_AKM_FILS_SHA384, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FILS_SHA384; + if (_rtw_memcmp(s, WLAN_AKM_FT_FILS_SHA256, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FT_FILS_SHA256; + if (_rtw_memcmp(s, WLAN_AKM_FT_FILS_SHA384, RSN_SELECTOR_LEN) == _TRUE) + return WLAN_AKM_TYPE_FT_FILS_SHA384; -int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) + return 0; +} + +int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, + int *pairwise_cipher, u32 *akm) { int i, ret = _SUCCESS; int left, count; @@ -721,11 +771,11 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwis return _FAIL; } - if (is_8021x) { + if (akm) { if (left >= 6) { pos += 2; if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) { - *is_8021x = 1; + *akm = WLAN_AKM_TYPE_8021X; } } } @@ -833,11 +883,11 @@ err: return _FAIL; } -int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x, u8 *mfp_opt) +int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, + int *pairwise_cipher, u32 *akm, u8 *mfp_opt) { struct rsne_info info; int i, ret = _SUCCESS; - u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01}; ret = rtw_rsne_info_parse(rsn_ie, rsn_ie_len, &info); if (ret != _SUCCESS) @@ -856,11 +906,10 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi *pairwise_cipher |= rtw_get_wpa2_cipher_suite(info.pcs_list + 4 * i); } - if (is_8021x) { - *is_8021x = 0; - /* here only check the first AKM suite */ - if (info.akm_cnt && _rtw_memcmp(SUITE_1X, info.akm_list, 4) == _TRUE) - *is_8021x = 1; + if (akm) { + *akm = 0; + for (i = 0; i < info.akm_cnt; i++) + *akm |= rtw_get_akm_suite_bitmap(info.akm_list + 4 * i); } if (mfp_opt) { @@ -2660,86 +2709,6 @@ int ieee80211_get_hdrlen(u16 fc) return hdrlen; } -int rtw_get_cipher_info(struct wlan_network *pnetwork) -{ - u32 wpa_ielen; - unsigned char *pbuf; - int group_cipher = 0, pairwise_cipher = 0, is8021x = 0; - int ret = _FAIL; - pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); - - if (pbuf && (wpa_ielen > 0)) { - if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { - - pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; - pnetwork->BcnInfo.group_cipher = group_cipher; - pnetwork->BcnInfo.is_8021x = is8021x; - ret = _SUCCESS; - } - } else { - - pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); - - if (pbuf && (wpa_ielen > 0)) { - if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x, NULL)) { - pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; - pnetwork->BcnInfo.group_cipher = group_cipher; - pnetwork->BcnInfo.is_8021x = is8021x; - ret = _SUCCESS; - } - } - } - - return ret; -} - -void rtw_get_bcn_info(struct wlan_network *pnetwork) -{ - unsigned short cap = 0; - u8 bencrypt = 0; - /* u8 wpa_ie[255],rsn_ie[255]; */ - u16 wpa_len = 0, rsn_len = 0; - struct HT_info_element *pht_info = NULL; - struct rtw_ieee80211_ht_cap *pht_cap = NULL; - unsigned int len; - unsigned char *p; - - _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); - cap = le16_to_cpu(cap); - if (cap & WLAN_CAPABILITY_PRIVACY) { - bencrypt = 1; - pnetwork->network.Privacy = 1; - } else - pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; - rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, NULL, &rsn_len, NULL, &wpa_len); - - if (rsn_len > 0) - pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2; - else if (wpa_len > 0) - pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA; - else { - if (bencrypt) - pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP; - } - rtw_get_cipher_info(pnetwork); - - /* get bwmode and ch_offset */ - /* parsing HT_CAP_IE */ - p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); - if (p && len > 0) { - pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2); - pnetwork->BcnInfo.ht_cap_info = pht_cap->cap_info; - } else - pnetwork->BcnInfo.ht_cap_info = 0; - /* parsing HT_INFO_IE */ - p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); - if (p && len > 0) { - pht_info = (struct HT_info_element *)(p + 2); - pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0]; - } else - pnetwork->BcnInfo.ht_info_infos_0 = 0; -} - u8 rtw_ht_mcsset_to_nss(u8 *supp_mcs_set) { u8 nss = 1; diff --git a/core/rtw_mlme.c b/core/rtw_mlme.c index ca7ca56..a3567a2 100644 --- a/core/rtw_mlme.c +++ b/core/rtw_mlme.c @@ -4272,7 +4272,12 @@ static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid) } -static int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent) +int rtw_cached_pmkid(_adapter *Adapter, u8 *bssid) +{ + return SecIsInPMKIDList(Adapter, bssid); +} + +int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent) { struct security_priv *sec = &adapter->securitypriv; struct rsne_info info; diff --git a/core/rtw_mlme_ext.c b/core/rtw_mlme_ext.c index 2d90209..c4af4b9 100755 --- a/core/rtw_mlme_ext.c +++ b/core/rtw_mlme_ext.c @@ -1858,7 +1858,6 @@ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) struct beacon_keys recv_beacon; update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); - rtw_get_bcn_info(&(pmlmepriv->cur_network)); /* update bcn keys */ if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { @@ -2097,9 +2096,9 @@ unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) goto auth_fail; } - if (auth_mode == 2 && - psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && - psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) + if ((auth_mode == 2) && (algorithm != WLAN_AUTH_SAE) && + (psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && + (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)) auth_mode = 0; if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */ @@ -2173,6 +2172,17 @@ unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) if (pstat->auth_seq == 0) pstat->expire_to = pstapriv->auth_to; +#ifdef CONFIG_IOCTL_CFG80211 + if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) { + if ((algorithm == WLAN_AUTH_SAE) && + (auth_mode == dot11AuthAlgrthm_8021X)) { + pstat->authalg = algorithm; + + rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL); + return _SUCCESS; + } + } +#endif /* CONFIG_IOCTL_CFG80211 */ if ((pstat->auth_seq + 1) != seq) { RTW_INFO("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", @@ -2294,6 +2304,21 @@ unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame) RTW_INFO("%s\n", __FUNCTION__); +#ifdef CONFIG_IOCTL_CFG80211 + if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) { + if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) { + if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) { + RTW_INFO("SAE: PMKSA cache entry found\n"); + goto normal; + } + rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL); + return _SUCCESS; + } + } + +normal: +#endif /* CONFIG_IOCTL_CFG80211 */ + /* check A1 matches or not */ if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN)) return _SUCCESS; @@ -2431,6 +2456,17 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) RTW_INFO("%s\n", __FUNCTION__); + if (pstat->authalg == WLAN_AUTH_SAE) { + /* WPA3-SAE */ + if (((pstat->state) & WIFI_FW_AUTH_NULL)) { + /* TODO: + Queue AssocReq and Proccess + by external auth trigger. */ + RTW_INFO("%s: wait external auth trigger\n", __func__); + return _SUCCESS; + } + } + /* check if this stat has been successfully authenticated/assocated */ if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { @@ -9152,7 +9188,18 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe); } else #endif + { +#ifdef CONFIG_IOCTL_CFG80211 + if (rtw_sec_chk_auth_alg(padapter, WLAN_AUTH_OPEN) && + rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) { + s32 entry = rtw_cached_pmkid(padapter, pmlmepriv->assoc_bssid); + + rtw_rsn_sync_pmkid(padapter, (u8 *)pIE, (pIE->Length + 2), entry); + } +#endif /* CONFIG_IOCTL_CFG80211 */ + pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen)); + } break; #ifdef CONFIG_80211N_HT case EID_HTCapability: @@ -11315,6 +11362,7 @@ void start_clnt_auth(_adapter *padapter) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); _cancel_timer_ex(&pmlmeext->link_timer); @@ -11334,6 +11382,22 @@ void start_clnt_auth(_adapter *padapter) } else #endif RTW_PRINT("start auth\n"); + +#ifdef CONFIG_IOCTL_CFG80211 + if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) { + if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) { + RTW_INFO("SAE: PMKSA cache entry found\n"); + padapter->securitypriv.auth_alg = WLAN_AUTH_OPEN; + goto no_external_auth; + } + + RTW_PRINT("SAE: start external auth\n"); + rtw_cfg80211_external_auth_request(padapter, NULL); + return; + } +no_external_auth: +#endif /* CONFIG_IOCTL_CFG80211 */ + issue_auth(padapter, NULL, 0); set_link_timer(pmlmeext, REAUTH_TO); @@ -13015,6 +13079,12 @@ void link_timer_hdl(void *ctx) pmlmeinfo->state = WIFI_FW_NULL_STATE; report_join_res(padapter, -3, WLAN_STATUS_UNSPECIFIED_FAILURE); } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) { + +#ifdef CONFIG_IOCTL_CFG80211 + if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) + return; +#endif /* CONFIG_IOCTL_CFG80211 */ + /* re-auth timer */ if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) { /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */ @@ -13193,7 +13263,6 @@ void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame) struct beacon_keys recv_beacon; update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); - rtw_get_bcn_info(&(pmlmepriv->cur_network)); /* update bcn keys */ if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { @@ -16226,11 +16295,48 @@ exit: *ch = u_ch; *bw = u_bw; *offset = u_offset; + +#if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) + { + u8 ht_option = 0; + +#ifdef CONFIG_80211N_HT + ht_option = adapter->mlmepriv.htpriv.ht_option; +#endif /* CONFIG_80211N_HT */ + + /* + when supplicant send the mlme frame, + the bss freq is updated by channel switch event. + */ + rtw_cfg80211_ch_switch_notify(adapter, + cur_ch, cur_bw, cur_ch_offset, ht_option); + } +#endif } return connect_allow == _TRUE ? _SUCCESS : _FAIL; } +void rtw_set_external_auth_status(_adapter *padapter, + const void *data, int len) +{ +#ifdef CONFIG_IOCTL_CFG80211 + struct net_device *dev = padapter->pnetdev; + struct wiphy *wiphy = adapter_to_wiphy(padapter); + struct rtw_external_auth_params params; + + /* convert data to external_auth_params */ + params.action = RTW_GET_BE32((u8 *)data); + _rtw_memcpy(¶ms.bssid, (u8 *)data + 4, ETH_ALEN); + _rtw_memcpy(¶ms.ssid.ssid, (u8 *)data + 10, WLAN_SSID_MAXLEN); + params.ssid.ssid_len = RTW_GET_BE64((u8 *)data + 42); + params.key_mgmt_suite = RTW_GET_BE32((u8 *)data + 58); + params.status = RTW_GET_BE16((u8 *)data + 62); + _rtw_memcpy(¶ms.pmkid, (u8 *)data + 64, PMKID_LEN); + + rtw_cfg80211_external_auth_status(wiphy, dev, ¶ms); +#endif /* CONFIG_IOCTL_CFG80211 */ +} u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf) { @@ -16613,3 +16719,65 @@ u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf) return H2C_SUCCESS; } + +int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx) +{ +#ifdef CONFIG_IOCTL_CFG80211 + const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr); + u16 alg; + u16 seq; + u16 status; + int ret = _FAIL; + + alg = RTW_GET_LE16(frame_body); + if (alg != WLAN_AUTH_SAE) + goto exit; + + seq = RTW_GET_LE16(frame_body + 2); + status = RTW_GET_LE16(frame_body + 4); + + RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x, mesg:%s\n", + (tx == _TRUE) ? "Tx" : "Rx", alg, seq, status, + (seq == 1) ? "Commit" : "Confirm"); + + ret = _SUCCESS; + +#ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(adapter)) { + rtw_mesh_sae_check_frames(adapter, buf, len, tx, alg, seq, status); + goto exit; + } +#endif + + if (tx && (seq == 2) && (status == 0)) { + /* quere commit frame until external auth statue update */ + struct sta_priv *pstapriv = &adapter->stapriv; + struct sta_info *psta = NULL; + _irqL irqL; + + psta = rtw_get_stainfo(pstapriv, GetAddr1Ptr(buf)); + if (psta) { + _enter_critical_bh(&psta->lock, &irqL); + if (psta->pauth_frame) { + rtw_mfree(psta->pauth_frame, psta->auth_len); + psta->pauth_frame = NULL; + psta->auth_len = 0; + } + + psta->pauth_frame = rtw_zmalloc(len); + if (psta->pauth_frame) { + _rtw_memcpy(psta->pauth_frame, buf, len); + psta->auth_len = len; + } + _exit_critical_bh(&psta->lock, &irqL); + + ret = 2; + } + } +exit: + return ret; +#else + return _SUCCESS; +#endif /* CONFIG_IOCTL_CFG80211 */ +} + diff --git a/core/rtw_wlan_util.c b/core/rtw_wlan_util.c index 9699697..fd9b7ca 100644 --- a/core/rtw_wlan_util.c +++ b/core/rtw_wlan_util.c @@ -2461,8 +2461,6 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, u16 capability; unsigned char *pos; struct rtw_ieee802_11_elems elems; - struct rtw_ieee80211_ht_cap *pht_cap = NULL; - struct HT_info_element *pht_info = NULL; _rtw_memset(recv_beacon, 0, sizeof(*recv_beacon)); @@ -2475,34 +2473,48 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) return _FALSE; - /* check bw and channel offset */ if (elems.ht_capabilities) { - if (elems.ht_capabilities_len != sizeof(*pht_cap)) + if (elems.ht_capabilities_len != 26) return _FALSE; - - pht_cap = (struct rtw_ieee80211_ht_cap *) elems.ht_capabilities; - recv_beacon->ht_cap_info = pht_cap->cap_info; } if (elems.ht_operation) { - if (elems.ht_operation_len != sizeof(*pht_info)) + if (elems.ht_operation_len != 22) return _FALSE; - - pht_info = (struct HT_info_element *) elems.ht_operation; - recv_beacon->ht_info_infos_0_sco = pht_info->infos[0] & 0x03; } - /* Checking for channel */ - if (elems.ds_params && elems.ds_params_len == sizeof(recv_beacon->bcn_channel)) - _rtw_memcpy(&recv_beacon->bcn_channel, elems.ds_params, - sizeof(recv_beacon->bcn_channel)); - else if (pht_info) - /* In 5G, some ap do not have DSSET IE checking HT info for channel */ - recv_beacon->bcn_channel = pht_info->primary_channel; - else { + if (elems.vht_capabilities) { + if (elems.vht_capabilities_len != 12) + return _FALSE; + } + + if (elems.vht_operation) { + if (elems.vht_operation_len != 5) + return _FALSE; + } + + if (rtw_ies_get_supported_rate(pos, left, recv_beacon->rate_set, &recv_beacon->rate_num) == _FAIL) + return _FALSE; + + if (cckratesonly_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE) + recv_beacon->proto_cap |= PROTO_CAP_11B; + else if (cckrates_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE) + recv_beacon->proto_cap |= PROTO_CAP_11B | PROTO_CAP_11G; + else + recv_beacon->proto_cap |= PROTO_CAP_11G; + + if (elems.ht_capabilities && elems.ht_operation) + recv_beacon->proto_cap |= PROTO_CAP_11N; + + if (elems.vht_capabilities && elems.vht_operation) + recv_beacon->proto_cap |= PROTO_CAP_11AC; + + /* check bw and channel offset */ + rtw_ies_get_chbw(pos, left, &recv_beacon->ch, &recv_beacon->bw, &recv_beacon->offset, 1, 1); + if (!recv_beacon->ch) { /* we don't find channel IE, so don't check it */ /* RTW_INFO("Oops: %s we don't find channel IE, so don't check it\n", __func__); */ - recv_beacon->bcn_channel = Adapter->mlmeextpriv.cur_channel; + recv_beacon->ch = Adapter->mlmeextpriv.cur_channel; } /* checking SSID */ @@ -2512,22 +2524,21 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, _rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len); recv_beacon->ssid_len = elems.ssid_len; - } else - ; /* means hidden ssid */ + } /* checking RSN first */ if (elems.rsn_ie && elems.rsn_ie_len) { recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2; rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2, &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher, - &recv_beacon->is_8021x, NULL); + &recv_beacon->akm, NULL); } /* checking WPA secon */ else if (elems.wpa_ie && elems.wpa_ie_len) { recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA; rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2, &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher, - &recv_beacon->is_8021x); + &recv_beacon->akm); } else if (capability & BIT(4)) recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP; @@ -2543,61 +2554,48 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, return _TRUE; } -void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon) +void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon) { u8 ssid[IW_ESSID_MAX_SIZE + 1]; _rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len); ssid[recv_beacon->ssid_len] = '\0'; - RTW_INFO("%s: ssid = %s\n", __func__, ssid); - RTW_INFO("%s: channel = %d\n", __func__, recv_beacon->bcn_channel); - RTW_INFO("%s: ht_cap = 0x%04x\n", __func__, recv_beacon->ht_cap_info); - RTW_INFO("%s: ht_info_infos_0_sco = 0x%02x\n", __func__, recv_beacon->ht_info_infos_0_sco); - RTW_INFO("%s: sec=%d, group = %x, pair = %x, 8021X = %x\n", __func__, - recv_beacon->encryp_protocol, recv_beacon->group_cipher, - recv_beacon->pairwise_cipher, recv_beacon->is_8021x); + RTW_PRINT_SEL(sel, "ssid = %s (len = %u)\n", ssid, recv_beacon->ssid_len); + RTW_PRINT_SEL(sel, "ch = %u,%u,%u\n" + , recv_beacon->ch, recv_beacon->bw, recv_beacon->offset); + RTW_PRINT_SEL(sel, "proto_cap = 0x%02x\n", recv_beacon->proto_cap); + RTW_MAP_DUMP_SEL(sel, "rate_set = " + , recv_beacon->rate_set, recv_beacon->rate_num); + RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n" + , recv_beacon->encryp_protocol, recv_beacon->group_cipher + , recv_beacon->pairwise_cipher, recv_beacon->akm); } -#define DBG_BCN_CNT + int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) { - unsigned int len; +#define BCNKEY_VERIFY_PROTO_CAP 0 +#define BCNKEY_VERIFY_WHOLE_RATE_SET 0 + u8 *pbssid = GetAddr3Ptr(pframe); struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network); + struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys; struct beacon_keys recv_beacon; + int ret = 0; if (is_client_associated_to_ap(Adapter) == _FALSE) - return _TRUE; - - len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); - - if (len > MAX_IE_SZ) { - RTW_WARN("%s IE too long for survey event\n", __func__); - return _FAIL; - } - - if (_rtw_memcmp(cur_network->network.MacAddress, pbssid, 6) == _FALSE) { - RTW_WARN("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT, - MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress)); - return _TRUE; - } + goto exit_success; if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE) - return _TRUE; /* parsing failed => broken IE */ + goto exit_success; /* parsing failed => broken IE */ #ifdef DBG_RX_BCN rtw_debug_bcn(Adapter, pframe, packet_len); #endif - /* don't care hidden ssid, use current beacon ssid directly */ - if (recv_beacon.ssid_len == 0) { - _rtw_memcpy(recv_beacon.ssid, pmlmepriv->cur_beacon_keys.ssid, - pmlmepriv->cur_beacon_keys.ssid_len); - recv_beacon.ssid_len = pmlmepriv->cur_beacon_keys.ssid_len; - } #ifdef CONFIG_BCN_CNT_CONFIRM_HDL - if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _TRUE) + if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE) pmlmepriv->new_beacon_cnts = 0; else if ((pmlmepriv->new_beacon_cnts == 0) || _rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) { @@ -2605,11 +2603,11 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) if (pmlmepriv->new_beacon_cnts == 0) { RTW_ERR("%s: cur beacon key\n", __func__); - RTW_DBG_EXPR(rtw_dump_bcn_keys(&pmlmepriv->cur_beacon_keys)); + RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon)); } RTW_DBG("%s: new beacon key\n", __func__); - RTW_DBG_EXPR(rtw_dump_bcn_keys(&recv_beacon)); + RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon)); _rtw_memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon)); pmlmepriv->new_beacon_cnts = 1; @@ -2621,45 +2619,47 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) /* if counter >= max, it means beacon is changed really */ if (pmlmepriv->new_beacon_cnts >= new_bcn_max) #else - if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _FALSE) + if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _FALSE) #endif { - /* check bw mode change only? */ - pmlmepriv->cur_beacon_keys.ht_cap_info = recv_beacon.ht_cap_info; - pmlmepriv->cur_beacon_keys.ht_info_infos_0_sco = recv_beacon.ht_info_infos_0_sco; - if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, - sizeof(recv_beacon)) == _FALSE) { - /* beacon is changed, have to do disconnect/connect */ - RTW_WARN("%s: new beacon occur!!\n", __func__); - #ifdef DBG_BCN_CNT - rtw_dump_bcn_keys(&recv_beacon); - #endif - return _FAIL; + struct beacon_keys tmp_beacon; + + RTW_INFO(FUNC_ADPT_FMT" new beacon occur!!\n", FUNC_ADPT_ARG(Adapter)); + RTW_INFO(FUNC_ADPT_FMT" cur beacon key:\n", FUNC_ADPT_ARG(Adapter)); + rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon); + RTW_INFO(FUNC_ADPT_FMT" new beacon key:\n", FUNC_ADPT_ARG(Adapter)); + rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon); + + if (!rtw_is_chbw_grouped(cur_beacon->ch, cur_beacon->bw, cur_beacon->offset + , recv_beacon.ch, recv_beacon.bw, recv_beacon.offset)) + goto exit; + + _rtw_memcpy(&tmp_beacon, cur_beacon, sizeof(tmp_beacon)); + + /* check fields excluding below */ + tmp_beacon.ch = recv_beacon.ch; + tmp_beacon.bw = recv_beacon.bw; + tmp_beacon.offset = recv_beacon.offset; + if (!BCNKEY_VERIFY_PROTO_CAP) + tmp_beacon.proto_cap = recv_beacon.proto_cap; + if (!BCNKEY_VERIFY_WHOLE_RATE_SET) { + tmp_beacon.rate_num = recv_beacon.rate_num; + _rtw_memcpy(tmp_beacon.rate_set, recv_beacon.rate_set, 12); } - #ifdef DBG_BCN_CNT - RTW_INFO("%s bw mode change\n", __func__); - RTW_INFO("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, - cur_network->BcnInfo.ht_cap_info, - cur_network->BcnInfo.ht_info_infos_0); - #endif + if (_rtw_memcmp(&tmp_beacon, &recv_beacon, sizeof(recv_beacon)) == _FALSE) + goto exit; - cur_network->BcnInfo.ht_cap_info = recv_beacon.ht_cap_info; - cur_network->BcnInfo.ht_info_infos_0 = - (cur_network->BcnInfo.ht_info_infos_0 & (~0x03)) | - recv_beacon.ht_info_infos_0_sco; - - #ifdef DBG_BCN_CNT - RTW_INFO("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, - cur_network->BcnInfo.ht_cap_info, - cur_network->BcnInfo.ht_info_infos_0); - #endif - _rtw_memcpy(&pmlmepriv->cur_beacon_keys, &recv_beacon, sizeof(recv_beacon)); + _rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon)); #ifdef CONFIG_BCN_CNT_CONFIRM_HDL pmlmepriv->new_beacon_cnts = 0; #endif } - return _SUCCESS; +exit_success: + ret = 1; + +exit: + return ret; } void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) diff --git a/dkms-install.sh b/dkms-install.sh index 656e866..7cf2e95 100755 --- a/dkms-install.sh +++ b/dkms-install.sh @@ -9,7 +9,7 @@ fi DRV_DIR="$(pwd)" DRV_NAME=rtl8812au -DRV_VERSION=5.6.4 +DRV_VERSION=5.6.4.1 cp -r ${DRV_DIR} /usr/src/${DRV_NAME}-${DRV_VERSION} diff --git a/dkms-remove.sh b/dkms-remove.sh index c0ae762..8f1d53e 100755 --- a/dkms-remove.sh +++ b/dkms-remove.sh @@ -9,7 +9,7 @@ fi DRV_DIR="$(pwd)" DRV_NAME=rtl8812au -DRV_VERSION=5.6.4 +DRV_VERSION=5.6.4.1 dkms remove ${DRV_NAME}/${DRV_VERSION} --all rm -rf /usr/src/${DRV_NAME}-${DRV_VERSION} diff --git a/dkms.conf b/dkms.conf index 38d3890..03d15a9 100644 --- a/dkms.conf +++ b/dkms.conf @@ -1,5 +1,5 @@ PACKAGE_NAME="realtek-rtl88xxau" -PACKAGE_VERSION="5.6.4~20190617" +PACKAGE_VERSION="5.6.4.1~20190622" CLEAN="'make' clean" BUILT_MODULE_NAME[0]=88XXau PROCS_NUM=`nproc` diff --git a/hal/hal_mp.c b/hal/hal_mp.c index c876a02..1af9de3 100644 --- a/hal/hal_mp.c +++ b/hal/hal_mp.c @@ -1009,8 +1009,7 @@ void mpt_SetRFPath_8812A(PADAPTER pAdapter) } switch (ulAntennaRx) { - // kimocoder edit below - u32 reg0xC50; + u32 reg0xC50 = 0; case ANTENNA_A: phy_set_bb_reg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x11); phy_set_rf_reg(pAdapter, RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/ diff --git a/hal/rtl8812a/usb/rtl8812au_xmit.c b/hal/rtl8812a/usb/rtl8812au_xmit.c index c62a13b..82e09bb 100644 --- a/hal/rtl8812a/usb/rtl8812au_xmit.c +++ b/hal/rtl8812a/usb/rtl8812au_xmit.c @@ -430,7 +430,7 @@ u32 upload_txpktbuf_8812au(_adapter *adapter, u8 *buf, u32 buflen) } rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, 0xff800000+(beacon_head<<6) + qw_addr); loop_cnt = 0; - while ((rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23) != 0) { + while ((rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23) == 1) { rtw_udelay_os(10); if (loop_cnt++ == 100) return _FALSE; diff --git a/include/autoconf.h b/include/autoconf.h index b3c5ad3..d88036b 100644 --- a/include/autoconf.h +++ b/include/autoconf.h @@ -22,7 +22,7 @@ */ #define AUTOCONF_INCLUDED #define RTL871X_MODULE_NAME "8812AU" -//#define DRV_NAME "rtl8812au" +#define DRV_NAME "rtl8812au" #define CONFIG_USB_HCI diff --git a/include/ieee80211.h b/include/ieee80211.h index c87a5b2..6fac3d2 100644 --- a/include/ieee80211.h +++ b/include/ieee80211.h @@ -142,8 +142,6 @@ extern u8 WPA_CIPHER_SUITE_WEP104[]; #define RSN_SELECTOR_LEN 4 extern u16 RSN_VERSION_BSD; -extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]; -extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; extern u8 RSN_CIPHER_SUITE_NONE[]; extern u8 RSN_CIPHER_SUITE_WEP40[]; extern u8 RSN_CIPHER_SUITE_TKIP[]; @@ -151,6 +149,39 @@ extern u8 RSN_CIPHER_SUITE_WRAP[]; extern u8 RSN_CIPHER_SUITE_CCMP[]; extern u8 RSN_CIPHER_SUITE_WEP104[]; +/* AKM suite type */ +extern u8 WLAN_AKM_8021X[]; +extern u8 WLAN_AKM_PSK[]; +extern u8 WLAN_AKM_FT_8021X[]; +extern u8 WLAN_AKM_FT_PSK[]; +extern u8 WLAN_AKM_8021X_SHA256[]; +extern u8 WLAN_AKM_PSK_SHA256[]; +extern u8 WLAN_AKM_TDLS[]; +extern u8 WLAN_AKM_SAE[]; +extern u8 WLAN_AKM_FT_OVER_SAE[]; +extern u8 WLAN_AKM_8021X_SUITE_B[]; +extern u8 WLAN_AKM_8021X_SUITE_B_192[]; +extern u8 WLAN_AKM_FILS_SHA256[]; +extern u8 WLAN_AKM_FILS_SHA384[]; +extern u8 WLAN_AKM_FT_FILS_SHA256[]; +extern u8 WLAN_AKM_FT_FILS_SHA384[]; + +#define WLAN_AKM_TYPE_8021X BIT(0) +#define WLAN_AKM_TYPE_PSK BIT(1) +#define WLAN_AKM_TYPE_FT_8021X BIT(2) +#define WLAN_AKM_TYPE_FT_PSK BIT(3) +#define WLAN_AKM_TYPE_8021X_SHA256 BIT(4) +#define WLAN_AKM_TYPE_PSK_SHA256 BIT(5) +#define WLAN_AKM_TYPE_TDLS BIT(6) +#define WLAN_AKM_TYPE_SAE BIT(7) +#define WLAN_AKM_TYPE_FT_OVER_SAE BIT(8) +#define WLAN_AKM_TYPE_8021X_SUITE_B BIT(9) +#define WLAN_AKM_TYPE_8021X_SUITE_B_192 BIT(10) +#define WLAN_AKM_TYPE_FILS_SHA256 BIT(11) +#define WLAN_AKM_TYPE_FILS_SHA384 BIT(12) +#define WLAN_AKM_TYPE_FT_FILS_SHA256 BIT(13) +#define WLAN_AKM_TYPE_FT_FILS_SHA384 BIT(14) + /* IEEE 802.11i */ #define PMKID_LEN 16 #define PMK_LEN 32 @@ -665,6 +696,7 @@ struct ieee80211_snap_hdr { /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_SAE 3 #define WLAN_AUTH_CHALLENGE_LEN 128 @@ -2070,8 +2102,8 @@ unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit); int rtw_get_wpa_cipher_suite(u8 *s); int rtw_get_wpa2_cipher_suite(u8 *s); int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len); -int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x); -int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x, u8 *mfp_opt); +int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, u32 *akm); +int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, u32 *akm, u8 *mfp_opt); int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len); @@ -2147,8 +2179,6 @@ uint rtw_is_cckratesonly_included(u8 *rate); uint rtw_get_cckrate_size(u8 *rate,u32 rate_length); int rtw_check_network_type(unsigned char *rate, int ratelen, int channel); -void rtw_get_bcn_info(struct wlan_network *pnetwork); - u8 rtw_check_invalid_mac_address(u8 *mac_addr, u8 check_local_bit); void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr); diff --git a/include/osdep_service.h b/include/osdep_service.h index 35988cc..7d13e01 100644 --- a/include/osdep_service.h +++ b/include/osdep_service.h @@ -64,6 +64,8 @@ #define BIT(x) (1 << (x)) #endif +#define CHECK_BIT(a, b) (!!((a) & (b))) + #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 diff --git a/include/rtw_android.h b/include/rtw_android.h index efc981a..f9d6b49 100644 --- a/include/rtw_android.h +++ b/include/rtw_android.h @@ -71,6 +71,7 @@ enum ANDROID_WIFI_CMD { #endif /* CONFIG_GTK_OL */ ANDROID_WIFI_CMD_P2P_DISABLE, ANDROID_WIFI_CMD_SET_AEK, + ANDROID_WIFI_CMD_EXT_AUTH_STATUS, ANDROID_WIFI_CMD_DRIVERVERSION, ANDROID_WIFI_CMD_MAX }; diff --git a/include/rtw_mlme.h b/include/rtw_mlme.h index 8f2646c..cdac712 100644 --- a/include/rtw_mlme.h +++ b/include/rtw_mlme.h @@ -529,13 +529,16 @@ enum { struct beacon_keys { u8 ssid[IW_ESSID_MAX_SIZE]; u32 ssid_len; - u8 bcn_channel; - u16 ht_cap_info; - u8 ht_info_infos_0_sco; /* bit0 & bit1 in infos[0] is second channel offset */ + u8 ch; + u8 bw; + u8 offset; + u8 proto_cap; /* PROTO_CAP_XXX */ + u8 rate_set[12]; + u8 rate_num; int encryp_protocol; int pairwise_cipher; int group_cipher; - int is_8021x; + u32 akm; }; #ifdef CONFIG_RTW_80211R #define RTW_FT_ACTION_REQ_LMT 4 @@ -1203,6 +1206,9 @@ void rtw_scan_abort_no_wait(_adapter *adapter); void rtw_scan_abort(_adapter *adapter); u32 rtw_join_abort_timeout(_adapter *adapter, u32 timeout_ms); +int rtw_cached_pmkid(_adapter *Adapter, u8 *bssid); +int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent); + extern int rtw_restruct_sec_ie(_adapter *adapter, u8 *out_ie); #ifdef CONFIG_WMMPS_STA void rtw_uapsd_use_default_setting(_adapter *padapter); diff --git a/include/rtw_mlme_ext.h b/include/rtw_mlme_ext.h index f198489..49fcaa9 100644 --- a/include/rtw_mlme_ext.h +++ b/include/rtw_mlme_ext.h @@ -276,6 +276,10 @@ enum TDLS_option { #endif /* CONFIG_TDLS */ +#ifndef NL80211_AUTHTYPE_SAE +#define NL80211_AUTHTYPE_SAE 4 +#endif + /* * Usage: * When one iface acted as AP mode and the other iface is STA mode and scanning, @@ -679,6 +683,8 @@ void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch); void Set_MSR(_adapter *padapter, u8 type); +void rtw_set_external_auth_status(_adapter *padapter, const void *data, int len); + u8 rtw_get_oper_ch(_adapter *adapter); void rtw_set_oper_ch(_adapter *adapter, u8 ch); u8 rtw_get_oper_bw(_adapter *adapter); @@ -765,7 +771,7 @@ void rtw_absorb_ssid_ifneed(_adapter *padapter, WLAN_BSSID_EX *bssid, u8 *pframe int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, struct beacon_keys *recv_beacon); int validate_beacon_len(u8 *pframe, uint len); -void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon); +void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon); int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len); void update_beacon_info(_adapter *padapter, u8 *pframe, uint len, struct sta_info *psta); #ifdef CONFIG_DFS @@ -1115,6 +1121,8 @@ u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf); u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf); u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf); +int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx); + #define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, #define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, diff --git a/include/rtw_security.h b/include/rtw_security.h index ac8432e..36756e1 100644 --- a/include/rtw_security.h +++ b/include/rtw_security.h @@ -176,6 +176,9 @@ struct security_priv { u8 bcheck_grpkey; u8 bgrpkey_handshake; + u8 auth_alg; + u8 auth_type; + u8 extauth_status; /* u8 packet_cnt; */ /* unused, removed */ s32 sw_encrypt;/* from registry_priv */ @@ -494,4 +497,10 @@ u8 rtw_handle_tkip_countermeasure(_adapter *adapter, const char *caller); u16 rtw_calc_crc(u8 *pdata, int length); #endif /*CONFIG_WOWLAN*/ +#define rtw_sec_chk_auth_alg(a, s) \ + ((a)->securitypriv.auth_alg == (s)) + +#define rtw_sec_chk_auth_type(a, s) \ + ((a)->securitypriv.auth_type == (s)) + #endif /* __RTL871X_SECURITY_H_ */ diff --git a/include/rtw_version.h b/include/rtw_version.h index d540441..44aeb0e 100644 --- a/include/rtw_version.h +++ b/include/rtw_version.h @@ -1 +1 @@ -#define DRIVERVERSION "v5.6.4_33522.20190509" +#define DRIVERVERSION "v5.6.4.1_33916.20190619" diff --git a/include/sta_info.h b/include/sta_info.h index 9e100cb..762933a 100644 --- a/include/sta_info.h +++ b/include/sta_info.h @@ -401,6 +401,8 @@ struct sta_info { int wpa_pairwise_cipher; int wpa2_pairwise_cipher; + u32 akm_suite_type; + u8 bpairwise_key_installed; #ifdef CONFIG_RTW_80211R u8 ft_pairwise_key_installed; @@ -478,6 +480,8 @@ struct sta_info { #endif #ifdef CONFIG_IOCTL_CFG80211 + u8 *pauth_frame; + u32 auth_len; u8 *passoc_req; u32 assoc_req_len; #endif diff --git a/include/wlan_bssdef.h b/include/wlan_bssdef.h index b3296d5..167ae7f 100644 --- a/include/wlan_bssdef.h +++ b/include/wlan_bssdef.h @@ -627,7 +627,6 @@ struct wlan_network { int aid; /* will only be valid when a BSS is joinned. */ int join_res; WLAN_BSSID_EX network; /* must be the last item */ - WLAN_BCN_INFO BcnInfo; #ifdef PLATFORM_WINDOWS unsigned char iebuf[MAX_IE_SZ]; #endif diff --git a/os_dep/linux/ioctl_cfg80211.c b/os_dep/linux/ioctl_cfg80211.c index 9a7ba15..cead11b 100755 --- a/os_dep/linux/ioctl_cfg80211.c +++ b/os_dep/linux/ioctl_cfg80211.c @@ -407,6 +407,23 @@ static void rtw_get_chbw_from_cfg80211_chan_def(struct cfg80211_chan_def *chdef, #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) +bool rtw_cfg80211_allow_ch_switch_notify(_adapter *adapter) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) + if ((!MLME_IS_AP(adapter)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) + && (!MLME_IS_ADHOC(adapter)) + && (!MLME_IS_ADHOC_MASTER(adapter)) + && (!MLME_IS_MESH(adapter)) +#elif defined(CONFIG_RTW_MESH) + && (!MLME_IS_MESH(adapter)) +#endif + ) + return 0; +#endif + return 1; +} + u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht) { struct wiphy *wiphy = adapter_to_wiphy(adapter); @@ -415,6 +432,9 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) struct cfg80211_chan_def chdef; + if (!rtw_cfg80211_allow_ch_switch_notify(adapter)) + goto exit; + ret = rtw_chbw_to_cfg80211_chan_def(wiphy, &chdef, ch, bw, offset, ht); if (ret != _SUCCESS) goto exit; @@ -425,6 +445,9 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 int freq = rtw_ch2freq(ch); enum nl80211_channel_type ctype; + if (!rtw_cfg80211_allow_ch_switch_notify(adapter)) + goto exit; + if (!freq) { ret = _FAIL; goto exit; @@ -537,6 +560,7 @@ static const struct ieee80211_txrx_stypes [NL80211_IFTYPE_STATION] = { .tx = 0xffff, .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) }, [NL80211_IFTYPE_AP] = { @@ -3263,6 +3287,7 @@ static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, { RTW_INFO("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type); + psecuritypriv->auth_type = sme_auth_type; switch (sme_auth_type) { case NL80211_AUTHTYPE_AUTOMATIC: @@ -3290,6 +3315,9 @@ static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case NL80211_AUTHTYPE_SAE: + psecuritypriv->auth_alg = WLAN_AUTH_SAE; break; default: psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; @@ -3758,6 +3786,38 @@ static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev) return 0; } +#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) +static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme) +{ + struct rtw_ieee802_11_elems elems; + struct rsne_info info; + u8 AKM_SUITE_SAE[] = { 0x00, 0x0f, 0xac, 8 }; + int i; + + if (sme->auth_type != 1) + return false; + + if (rtw_ieee802_11_parse_elems((u8 *)sme->ie, sme->ie_len, &elems, 0) + == ParseFailed) + return false; + + if (!elems.rsn_ie) + return false; + + if (rtw_rsne_info_parse(elems.rsn_ie - 2, elems.rsn_ie_len + 2, &info) == _FAIL) + return false; + + for (i = 0; i < info.akm_cnt; i++) + if (memcmp(info.akm_list + i * RSN_SELECTOR_LEN, + AKM_SUITE_SAE, RSN_SELECTOR_LEN) == 0) + return true; + + return false; +} +#else +#define rtw_check_connect_sae_compat(sme) false +#endif + static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) { @@ -3780,6 +3840,11 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, RTW_INFO("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n", sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type); + if (rtw_check_connect_sae_compat(sme)) { + sme->auth_type = NL80211_AUTHTYPE_SAE; + RTW_INFO("%s set sme->auth_type=4 for SAE compat\n", __FUNCTION__); + } + if (pwdev_priv->block == _TRUE) { ret = -EBUSY; RTW_INFO("%s wdev_priv.block is set\n", __FUNCTION__); @@ -3850,6 +3915,8 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + psecuritypriv->auth_alg = WLAN_AUTH_OPEN; + psecuritypriv->extauth_status = WLAN_STATUS_UNSPECIFIED_FAILURE; #ifdef CONFIG_WAPI_SUPPORT padapter->wapiInfo.bWapiEnable = false; @@ -4116,36 +4183,20 @@ static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, return 0; } -static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_pmksa *pmksa) +static void _rtw_set_pmksa(struct net_device *ndev, + u8 *bssid, u8 *pmkid) { - u8 index, blInserted = _FALSE; _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); - struct mlme_priv *mlme = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - u8 strZeroMacAddress[ETH_ALEN] = { 0x00 }; - - RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev) - , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid)); - - if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE) - return -EINVAL; - - if (check_fwstate(mlme, _FW_LINKED) == _FALSE) { - RTW_INFO(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev)); - return -EINVAL; - } - - blInserted = _FALSE; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 index, blInserted = _FALSE; /* overwrite PMKID */ for (index = 0 ; index < NUM_PMKID_CACHE; index++) { - if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) == _TRUE) { + if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, bssid, ETH_ALEN) == _TRUE) { /* BSSID is matched, the same AP => rewrite with new PMKID. */ - RTW_INFO(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev)); + RTW_INFO("BSSID("MAC_FMT") exists in the PMKList.\n", MAC_ARG(bssid)); - _rtw_memcpy(psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN); + _rtw_memcpy(psecuritypriv->PMKIDList[index].PMKID, pmkid, WLAN_PMKID_LEN); psecuritypriv->PMKIDList[index].bUsed = _TRUE; psecuritypriv->PMKIDIndex = index + 1; blInserted = _TRUE; @@ -4155,17 +4206,48 @@ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, if (!blInserted) { /* Find a new entry */ - RTW_INFO(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n", - FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex); + RTW_INFO("Use the new entry index = %d for this PMKID.\n", + psecuritypriv->PMKIDIndex); - _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN); - _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN); + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, bssid, ETH_ALEN); + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmkid, WLAN_PMKID_LEN); psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE; psecuritypriv->PMKIDIndex++ ; if (psecuritypriv->PMKIDIndex == 16) psecuritypriv->PMKIDIndex = 0; } +} + +static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa) +{ + u8 index, blInserted = _FALSE; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *mlme = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 strZeroMacAddress[ETH_ALEN] = { 0x00 }; + bool sae_auth = rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE); + + RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev) + , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid)); + + if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE) + return -EINVAL; + + if (check_fwstate(mlme, _FW_LINKED) == _FALSE && !sae_auth) { + RTW_INFO(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev)); + return -EINVAL; + } + + _rtw_set_pmksa(ndev, (u8 *)pmksa->bssid, (u8 *)pmksa->pmkid); + + if (sae_auth && + (psecuritypriv->extauth_status == WLAN_STATUS_SUCCESS)) { + RTW_PRINT("SAE: auth success, start assoc\n"); + start_clnt_assoc(padapter); + } return 0; } @@ -4919,6 +5001,14 @@ static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, ret = -ENOTSUPP; goto exit; } + + /* + Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC. + if the AKM SAE in the RSN IE, we have to update the auth_type for SAE + in rtw_check_beacon_data(). + */ + rtw_cfg80211_set_auth_type(&adapter->securitypriv, settings->auth_type); + rtw_mi_scan_abort(adapter, _TRUE); rtw_mi_buddy_set_scan_deny(adapter, 300); ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len, @@ -6166,10 +6256,7 @@ void rtw_cfg80211_rx_mframe(_adapter *adapter, union recv_frame *rframe, const c #endif RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n", ch, sch, MAC_ARG(get_addr2_ptr(frame))); - #ifdef CONFIG_RTW_MESH - if (!rtw_sae_check_frames(adapter, frame, frame_len, _FALSE)) - #endif - { + if (!rtw_sae_preprocess(adapter, frame, frame_len, _FALSE)) { if (msg) RTW_INFO("RTW_Rx:%s\n", msg); else @@ -6441,6 +6528,54 @@ static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy, } #endif +void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rframe) +{ + struct rtw_external_auth_params params; + struct wireless_dev *wdev = padapter->rtw_wdev; + struct net_device *netdev = wdev_to_ndev(wdev); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + u8 frame[256] = { 0 }; + uint frame_len = 24; + s32 freq = 0; + + /* rframe, in this case is null point */ + + freq = rtw_ch2freq(pmlmeext->cur_channel); + +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO(FUNC_ADPT_FMT": freq(%d, %d)\n", FUNC_ADPT_ARG(padapter), freq); +#endif + +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) + params.action = EXTERNAL_AUTH_START; + _rtw_memcpy(params.bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + params.ssid.ssid_len = pmlmeinfo->network.Ssid.SsidLength; + _rtw_memcpy(params.ssid.ssid, pmlmeinfo->network.Ssid.Ssid, + pmlmeinfo->network.Ssid.SsidLength); + params.key_mgmt_suite = 0x8ac0f00; + + cfg80211_external_auth_request(netdev, + (struct cfg80211_external_auth_params *)¶ms, GFP_ATOMIC); +#elif (KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE) + set_frame_sub_type(frame, WIFI_AUTH); + + _rtw_memcpy(frame + 4, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + _rtw_memcpy(frame + 10, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(frame + 16, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + RTW_PUT_LE32((frame + 18), 0x8ac0f00); + + if (pmlmeinfo->network.Ssid.SsidLength) { + *(frame + 23) = pmlmeinfo->network.Ssid.SsidLength; + _rtw_memcpy(frame + 24, pmlmeinfo->network.Ssid.Ssid, + pmlmeinfo->network.Ssid.SsidLength); + frame_len = 24 + pmlmeinfo->network.Ssid.SsidLength; + } + rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC); +#endif +} + inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val) { adapter->cfg80211_wdinfo.is_ro_ch = val; @@ -7187,15 +7322,19 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, wait_ack = 0; goto dump; } -#ifdef CONFIG_RTW_MESH else if (frame_styp == RTW_IEEE80211_STYPE_AUTH) { + int retval = 0; + RTW_INFO("RTW_Tx:tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf))); - if (!rtw_sae_check_frames(padapter, buf, len, _TRUE)) + + retval = rtw_sae_preprocess(padapter, buf, len, _TRUE); + if (retval == 2) + goto exit; + if (retval == 0) RTW_INFO("RTW_Tx:AUTH\n"); dump_limit = 1; goto dump; } -#endif if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) { RTW_INFO(FUNC_ADPT_FMT" frame_control:0x%02x\n", FUNC_ADPT_ARG(padapter), @@ -7341,16 +7480,27 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, frame_type, reg); #endif - /* Wait QC Verify */ - return; - switch (frame_type) { + case IEEE80211_STYPE_AUTH: /* 0x00B0 */ + if (reg > 0) + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH, reg); + else + CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH, reg); + break; +#ifdef not_yet case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */ - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); + if (reg > 0) + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); + else + CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); break; case IEEE80211_STYPE_ACTION: /* 0x00D0 */ - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); + if (reg > 0) + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); + else + CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); break; +#endif default: break; } @@ -9077,13 +9227,7 @@ static void rtw_cfg80211_init_ht_capab(_adapter *padapter ht_cap->ht_supported = 1; - /* According to the comment in rtw_ap.c: - * "Note: currently we switch to the MIXED op mode if HT non-greenfield - * station is associated. Probably it's a theoretical case, since - * it looks like all known HT STAs support greenfield." - * Therefore Greenfield is added to ht_cap - */ - ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD | + ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type); @@ -9161,75 +9305,6 @@ void rtw_cfg80211_init_wdev_data(_adapter *padapter) #endif } -static void rtw_cfg80211_init_vht_capab_ex(_adapter *padapter, struct ieee80211_sta_vht_cap *vht_cap, u8 rf_type) -{ -//todo: Support for other bandwidths -/* NSS = Number of Spatial Streams */ -#define MAX_BIT_RATE_80MHZ_NSS3 1300 /* Mbps */ -#define MAX_BIT_RATE_80MHZ_NSS2 867 /* Mbps */ -#define MAX_BIT_RATE_80MHZ_NSS1 434 /* Mbps */ - struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; - rtw_vht_use_default_setting(padapter); - /* RX LDPC */ - if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX)) - vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; - /* TX STBC */ - if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX)) - vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; - /* RX STBC */ - if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX)) { - switch (rf_type) { - case RF_1T1R: - vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_1;/*RX STBC One spatial stream*/ - break; - case RF_2T2R: - case RF_1T2R: - vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_2;/*RX STBC Two spatial streams*/ - break; - case RF_3T3R: - case RF_3T4R: - case RF_4T4R: - vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_3;/*RX STBC Three spatial streams*/ - break; - default: - /* DBG_871X("[warning] rf_type %d is not expected\n", rf_type); */ - break; - } - } - /* switch (rf_type) { - case RF_1T1R: - vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS1; - vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS1; - break; - case RF_2T2R: - case RF_1T2R: - vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS2; - vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS2; - break; - case RF_3T3R: - case RF_3T4R: - case RF_4T4R: - vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS3; - vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS3; - break; - default: - DBG_871X("[warning] rf_type %d is not expected\n", rf_type); - break; - } */ - /* MCS map */ - vht_cap->vht_mcs.tx_mcs_map = pvhtpriv->vht_mcs_map[0] | (pvhtpriv->vht_mcs_map[1] << 8); - vht_cap->vht_mcs.rx_mcs_map = vht_cap->vht_mcs.tx_mcs_map; - if (rf_type == RF_1T1R) { - vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS1; - vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS1; - } - if (pvhtpriv->sgi_80m) - vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_80; - vht_cap->cap |= (pvhtpriv->ampdu_len << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); -} - void rtw_cfg80211_init_wiphy(_adapter *padapter) { u8 rf_type; @@ -9453,6 +9528,10 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) ; #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ #endif /* CONFIG_RTW_MESH */ + +#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE) + wiphy->features |= NL80211_FEATURE_SAE; +#endif } #ifdef CONFIG_RFKILL_POLL @@ -9626,6 +9705,94 @@ int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, } #endif /* defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */ +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_external_auth_params *params) +{ + PADAPTER padapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(dev)); + + rtw_cfg80211_external_auth_status(wiphy, dev, + (struct rtw_external_auth_params *)params); + + return 0; +} +#endif + +void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *dev, + struct rtw_external_auth_params *params) +{ + PADAPTER padapter = (_adapter *)rtw_netdev_priv(dev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta = NULL; + u8 *buf = NULL; + u32 len = 0; + _irqL irqL; + + RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(dev)); + + RTW_INFO("SAE: action: %u, status: %u\n", params->action, params->status); + if (params->status == WLAN_STATUS_SUCCESS) { + RTW_INFO("bssid: "MAC_FMT"\n", MAC_ARG(params->bssid)); + RTW_INFO("SSID: [%s]\n", + ((params->ssid.ssid_len == 0) ? "" : (char *)params->ssid.ssid)); + RTW_INFO("suite: 0x%08x\n", params->key_mgmt_suite); + } + + psta = rtw_get_stainfo(pstapriv, params->bssid); + if (psta && (params->status == WLAN_STATUS_SUCCESS)) { + /* AP mode */ + RTW_INFO("station match\n"); + + psta->state &= ~WIFI_FW_AUTH_NULL; + psta->state |= WIFI_FW_AUTH_SUCCESS; + psta->expire_to = padapter->stapriv.assoc_to; + + if (params->pmkid != NULL) { + /* RTW_INFO_DUMP("PMKID:", params->pmkid, PMKID_LEN); */ + _rtw_set_pmksa(dev, params->bssid, params->pmkid); + } + + _enter_critical_bh(&psta->lock, &irqL); + if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) { + buf = rtw_zmalloc(psta->auth_len); + if (buf) { + _rtw_memcpy(buf, psta->pauth_frame, psta->auth_len); + len = psta->auth_len; + } + + rtw_mfree(psta->pauth_frame, psta->auth_len); + psta->pauth_frame = NULL; + psta->auth_len = 0; + } + _exit_critical_bh(&psta->lock, &irqL); + + if (buf) { + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + /* send the SAE auth Confirm */ + + rtw_ps_deny(padapter, PS_DENY_MGNT_TX); + if (_SUCCESS == rtw_pwr_wakeup(padapter)) { + rtw_mi_set_scan_deny(padapter, 1000); + rtw_mi_scan_abort(padapter, _TRUE); + + RTW_INFO("SAE: Tx auth Confirm\n"); + rtw_mgnt_tx_cmd(padapter, pmlmeext->cur_channel, 1, buf, len, 0, RTW_CMDF_DIRECTLY); + + rtw_mfree(buf, len); + buf = NULL; + len = 0; + } + rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX); + } + } else { + /* STA mode */ + psecuritypriv->extauth_status = params->status; + } +} + static struct cfg80211_ops rtw_cfg80211_ops = { .change_virtual_intf = cfg80211_rtw_change_iface, .add_key = cfg80211_rtw_add_key, @@ -9742,6 +9909,9 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) .dump_survey = rtw_hostapd_acs_dump_survey, #endif +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) + .external_auth = cfg80211_rtw_external_auth, +#endif }; struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev) diff --git a/os_dep/linux/ioctl_cfg80211.h b/os_dep/linux/ioctl_cfg80211.h index d16cfdd..b12ce56 100644 --- a/os_dep/linux/ioctl_cfg80211.h +++ b/os_dep/linux/ioctl_cfg80211.h @@ -193,6 +193,20 @@ struct rtw_wdev_priv { }; +enum external_auth_action { + EXTERNAL_AUTH_START, + EXTERNAL_AUTH_ABORT, +}; + +struct rtw_external_auth_params { + enum external_auth_action action; + u8 bssid[ETH_ALEN]__aligned(2); + struct cfg80211_ssid ssid; + unsigned int key_mgmt_suite; + u16 status; + u8 pmkid[PMKID_LEN]; +}; + bool rtw_cfg80211_is_connect_requested(_adapter *adapter); #if RTW_CFG80211_BLOCK_STA_DISCON_EVENT @@ -246,7 +260,8 @@ struct rtw_wiphy_data { #define FUNC_WIPHY_FMT "%s("WIPHY_FMT")" #define FUNC_WIPHY_ARG(wiphy) __func__, WIPHY_ARG(wiphy) -#define SET_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt |= (v ? BIT(t >> 4) : 0)) +#define SET_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt |= BIT(t >> 4)) +#define CLR_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt &= (~BIT(t >> 4))) #define GET_CFG80211_REPORT_MGMT(w, t) ((w->report_mgmt & BIT(t >> 4)) > 0) struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev); @@ -320,6 +335,10 @@ void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const c void rtw_cfg80211_rx_mframe(_adapter *adapter, union recv_frame *rframe, const char *msg); void rtw_cfg80211_rx_probe_request(_adapter *padapter, union recv_frame *rframe); +void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rframe); +void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *dev, + struct rtw_external_auth_params *params); + int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type); bool rtw_cfg80211_pwr_mgmt(_adapter *adapter); diff --git a/os_dep/linux/ioctl_mp.c b/os_dep/linux/ioctl_mp.c index 65b91bf..06233dc 100644 --- a/os_dep/linux/ioctl_mp.c +++ b/os_dep/linux/ioctl_mp.c @@ -19,10 +19,6 @@ #include #include "../../hal/phydm/phydm_precomp.h" -#ifdef MARK_KERNEL_PFU - #include - #include -#endif #if defined(CONFIG_RTL8723B) #include @@ -1722,10 +1718,6 @@ int rtw_mp_tx(struct net_device *dev, PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); - #ifdef MARK_KERNEL_PFU - kernel_fpu_begin(); - #endif - if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE)) CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); @@ -1734,11 +1726,6 @@ int rtw_mp_tx(struct net_device *dev, /* 24 BIT*/ L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); } - - #ifdef MARK_KERNEL_PFU - kernel_fpu_end(); - #endif - /* 48BIT*/ if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); diff --git a/os_dep/linux/mlme_linux.c b/os_dep/linux/mlme_linux.c index 39c0ac1..247e45e 100644 --- a/os_dep/linux/mlme_linux.c +++ b/os_dep/linux/mlme_linux.c @@ -130,6 +130,8 @@ void rtw_reset_securitypriv(_adapter *adapter) adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + adapter->securitypriv.extauth_status = WLAN_STATUS_UNSPECIFIED_FAILURE; + } else { /* reset values in securitypriv */ /* if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE) */ /* { */ @@ -145,6 +147,8 @@ void rtw_reset_securitypriv(_adapter *adapter) psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; /* } */ + + psec_priv->extauth_status = WLAN_STATUS_UNSPECIFIED_FAILURE; } /* add for CONFIG_IEEE80211W, none 11w also can use */ _exit_critical_bh(&adapter->security_key_mutex, &irqL); diff --git a/os_dep/linux/os_intfs.c b/os_dep/linux/os_intfs.c index 1acd713..45146e3 100644 --- a/os_dep/linux/os_intfs.c +++ b/os_dep/linux/os_intfs.c @@ -1364,7 +1364,7 @@ static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb #else , void *accel_priv #endif - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) , select_queue_fallback_t fallback #endif #endif diff --git a/os_dep/linux/rtw_android.c b/os_dep/linux/rtw_android.c index 51b5a65..e468574 100644 --- a/os_dep/linux/rtw_android.c +++ b/os_dep/linux/rtw_android.c @@ -95,6 +95,7 @@ const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = { /* Private command for P2P disable*/ "P2P_DISABLE", "SET_AEK", + "EXT_AUTH_STATUS", "DRIVER_VERSION" }; @@ -935,6 +936,12 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) break; #endif + case ANDROID_WIFI_CMD_EXT_AUTH_STATUS: { + rtw_set_external_auth_status(padapter, + command + strlen("EXT_AUTH_STATUS "), + priv_cmd.total_len - strlen("EXT_AUTH_STATUS ")); + break; + } case ANDROID_WIFI_CMD_DRIVERVERSION: { bytes_written = strlen(DRIVERVERSION); snprintf(command, bytes_written + 1, DRIVERVERSION); diff --git a/os_dep/linux/rtw_proc.c b/os_dep/linux/rtw_proc.c index 8b0d8e1..63be985 100644 --- a/os_dep/linux/rtw_proc.c +++ b/os_dep/linux/rtw_proc.c @@ -3742,6 +3742,17 @@ exit: } #endif /* CONFIG_RTW_TPT_MODE */ +int proc_get_cur_beacon_keys(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + struct mlme_priv *mlme = &adapter->mlmepriv; + + rtw_dump_bcn_keys(m, &mlme->cur_beacon_keys); + + return 0; +} + /* * rtw_adapter_proc: * init/deinit when register/unregister net_device @@ -4108,6 +4119,7 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #endif #endif + RTW_PROC_HDL_SSEQ("cur_beacon_keys", proc_get_cur_beacon_keys, NULL), }; const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl); diff --git a/os_dep/linux/usb_intf.c b/os_dep/linux/usb_intf.c index 3b92dc4..041e4dd 100644 --- a/os_dep/linux/usb_intf.c +++ b/os_dep/linux/usb_intf.c @@ -161,6 +161,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = { {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x881C), .driver_info = RTL8812}, /* Default ID */ /*=== Customer ID ===*/ {USB_DEVICE(0x050D, 0x1106), .driver_info = RTL8812}, /* Belkin - sercomm */ + {USB_DEVICE(0x2001, 0x330E), .driver_info = RTL8812}, /* D-Link - ALPHA */ {USB_DEVICE(0x7392, 0xA822), .driver_info = RTL8812}, /* Edimax - Edimax */ {USB_DEVICE(0x0DF6, 0x0074), .driver_info = RTL8812}, /* Sitecom - Edimax */ {USB_DEVICE(0x04BB, 0x0952), .driver_info = RTL8812}, /* I-O DATA - Edimax */ @@ -170,30 +171,12 @@ static struct usb_device_id rtw_usb_id_tbl[] = { {USB_DEVICE(0x0E66, 0x0022), .driver_info = RTL8812}, /* HAWKING - Edimax */ {USB_DEVICE(0x0586, 0x3426), .driver_info = RTL8812}, /* ZyXEL - */ {USB_DEVICE(0x2001, 0x3313), .driver_info = RTL8812}, /* D-Link - ALPHA */ - {USB_DEVICE(0x1058, 0x0632), .driver_info = RTL8812}, /* WD - Cybertan */ + {USB_DEVICE(0x1058, 0x0632), .driver_info = RTL8812}, /* WD - Cybertan*/ {USB_DEVICE(0x1740, 0x0100), .driver_info = RTL8812}, /* EnGenius - EnGenius */ {USB_DEVICE(0x2019, 0xAB30), .driver_info = RTL8812}, /* Planex - Abocom */ {USB_DEVICE(0x07B8, 0x8812), .driver_info = RTL8812}, /* Abocom - Abocom */ - {USB_DEVICE(0x0846, 0x9051), .driver_info = RTL8812}, /* Netgear A6200 v2 */ - {USB_DEVICE(0x2001, 0x330E), .driver_info = RTL8812}, /* D-Link - ALPHA */ - {USB_DEVICE(0x2001, 0x3313), .driver_info = RTL8812}, /* D-Link - ALPHA */ {USB_DEVICE(0x2001, 0x3315), .driver_info = RTL8812}, /* D-Link - Cameo */ {USB_DEVICE(0x2001, 0x3316), .driver_info = RTL8812}, /* D-Link - Cameo */ - {USB_DEVICE(0x13B1, 0x003F), .driver_info = RTL8812}, /* Linksys - WUSB6300 */ - {USB_DEVICE(0x2357, 0x0101), .driver_info = RTL8812}, /* TP-Link - Archer T4U AC1200 */ - {USB_DEVICE(0x2357, 0x0103), .driver_info = RTL8812}, /* TP-Link - T4UH */ - {USB_DEVICE(0x2357, 0x010D), .driver_info = RTL8812}, /* TP-Link - Archer T4U AC1300 */ - {USB_DEVICE(0x2357, 0x0115), .driver_info = RTL8812}, /* TP-Link - Archer T4U AC1300 */ - {USB_DEVICE(0x2357, 0x010E), .driver_info = RTL8812}, /* TP-Link - Archer T4UH AC1300 */ - {USB_DEVICE(0x2357, 0x010F), .driver_info = RTL8812}, /* TP-Link - T4UHP */ - {USB_DEVICE(0x2357, 0x0122), .driver_info = RTL8812}, /* TP-Link - T4UHP (other) */ - {USB_DEVICE(0x20F4, 0x805B), .driver_info = RTL8812}, /* TRENDnet - */ - {USB_DEVICE(0x0411, 0x025D), .driver_info = RTL8812}, /* Buffalo - WI-U3-866D */ - {USB_DEVICE(0x050D, 0x1109), .driver_info = RTL8812}, /* Belkin F9L1109 - SerComm */ - {USB_DEVICE(0x148F, 0x9097), .driver_info = RTL8812}, /* Amped Wireless ACA1 */ - {USB_DEVICE(0x0BDA, 0x8812), .driver_info = RTL8812}, /* Alfa - AWUS036AC, AWUS036ACH & AWUS036EAC */ - {USB_DEVICE(0x2604, 0x0012), .driver_info = RTL8812}, /* Tenda U12 */ - {USB_DEVICE(0x0BDA, 0x881A), .driver_info = RTL8812}, /* Unex DAUK-W8812 */ #endif #ifdef CONFIG_RTL8821A @@ -206,24 +189,13 @@ static struct usb_device_id rtw_usb_id_tbl[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0823, 0xff, 0xff, 0xff), .driver_info = RTL8821}, /* 8821AU */ /*=== Customer ID ===*/ {USB_DEVICE(0x7392, 0xA811), .driver_info = RTL8821}, /* Edimax - Edimax */ - {USB_DEVICE(0x7392, 0xA812), .driver_info = RTL8821}, /* Edimax - EW-7811UTC */ - {USB_DEVICE(0x7392, 0xA813), .driver_info = RTL8821}, /* Edimax - EW-7811UAC */ {USB_DEVICE(0x04BB, 0x0953), .driver_info = RTL8821}, /* I-O DATA - Edimax */ {USB_DEVICE(0x2001, 0x3314), .driver_info = RTL8821}, /* D-Link - Cameo */ {USB_DEVICE(0x2001, 0x3318), .driver_info = RTL8821}, /* D-Link - Cameo */ {USB_DEVICE(0x0E66, 0x0023), .driver_info = RTL8821}, /* HAWKING - Edimax */ - {USB_DEVICE(0x056E, 0x400E), .driver_info = RTL8821}, /* ELECOM - ELECOM */ - {USB_DEVICE(0x056E, 0x400F), .driver_info = RTL8821}, /* ELECOM - ELECOM */ - {USB_DEVICE(0x0411, 0x0242), .driver_info = RTL8821}, /* ELECOM - WDC-433DU2H */ - {USB_DEVICE(0x2019, 0xAB32), .driver_info = RTL8821}, /* Planex - GW-450S */ - {USB_DEVICE(0x0846, 0x9052), .driver_info = RTL8821}, /* Netgear - A6100 */ - {USB_DEVICE(0x0411, 0x029B), .driver_info = RTL8821}, /* Buffalo - WI-U2-433DHP */ - {USB_DEVICE(0x056E, 0x4007), .driver_info = RTL8821}, /* Elecom - WDC-433DU2HBK */ - {USB_DEVICE(0x0BDA, 0xA811), .driver_info = RTL8821}, /* GMYLE - AC450 */ - {USB_DEVICE(0x3823, 0x6249), .driver_info = RTL8821}, /* Obihai - OBiWiFi */ - {USB_DEVICE(0x2357, 0x011E), .driver_info = RTL8821}, /* TP Link - T2U Nano */ - {USB_DEVICE(0x2357, 0x0122), .driver_info = RTL8821}, /* TP Link - T2U Nano */ - {USB_DEVICE(0x2357, 0x0120), .driver_info = RTL8821}, /* TP Link - T2U Plus */ + {USB_DEVICE(0x056E, 0x400E) , .driver_info = RTL8821}, /* ELECOM - ELECOM */ + {USB_DEVICE(0x056E, 0x400F) , .driver_info = RTL8821}, /* ELECOM - ELECOM */ + {USB_DEVICE(0x20f4, 0x804b), .driver_info = RTL8821}, /* TRENDnet */ #endif #ifdef CONFIG_RTL8192E @@ -245,20 +217,13 @@ static struct usb_device_id rtw_usb_id_tbl[] = { #endif /* CONFIG_RTL8703B */ #ifdef CONFIG_RTL8814A + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8813), .driver_info = RTL8814A}, - {USB_DEVICE(0x2001, 0x331A), .driver_info = RTL8814A}, /* D-Link - D-Link */ - {USB_DEVICE(0x0B05, 0x1817), .driver_info = RTL8814A}, /* ASUS - ASUSTeK */ - {USB_DEVICE(0x0B05, 0x1852), .driver_info = RTL8814A}, /* ASUS - ASUSTeK */ - {USB_DEVICE(0x0B05, 0x1853), .driver_info = RTL8814A}, /* ASUS - ASUSTeK */ + {USB_DEVICE(0x2001, 0x331a), .driver_info = RTL8814A}, /* D-Link - D-Link */ + {USB_DEVICE(0x0b05, 0x1817), .driver_info = RTL8814A}, /* ASUS - ASUSTeK */ {USB_DEVICE(0x056E, 0x400B), .driver_info = RTL8814A}, /* ELECOM - ELECOM */ {USB_DEVICE(0x056E, 0x400D), .driver_info = RTL8814A}, /* ELECOM - ELECOM */ {USB_DEVICE(0x7392, 0xA834), .driver_info = RTL8814A}, /* Edimax - Edimax */ - {USB_DEVICE(0x7392, 0xA833), .driver_info = RTL8814A}, /* Edimax - AC1750 */ - {USB_DEVICE(0x0BDA, 0x8813), .driver_info = RTL8814A}, /* Edimax - EDUP Adapters */ - {USB_DEVICE(0x2357, 0x0106), .driver_info = RTL8814A}, /* TP-LINK Archer T9UH */ - {USB_DEVICE(0x20F4, 0x809A), .driver_info = RTL8814A}, /* TRENDnet - TRENDnet */ - {USB_DEVICE(0x20F4, 0x809B), .driver_info = RTL8814A}, /* TRENDnet TEW-809UB */ - {USB_DEVICE(0x0846, 0x9054), .driver_info = RTL8814A}, /* Netgear A7000 */ #endif /* CONFIG_RTL8814A */ #ifdef CONFIG_RTL8188F diff --git a/os_dep/linux/wifi_regd.c b/os_dep/linux/wifi_regd.c index a7216c6..4c10f84 100644 --- a/os_dep/linux/wifi_regd.c +++ b/os_dep/linux/wifi_regd.c @@ -44,7 +44,7 @@ static struct country_code_to_enum_rd allCountries[] = { /* 2G chan 12 - chan 13, PASSIV SCAN */ #define RTW_2GHZ_CH12_13 \ REG_RULE(2467-10, 2472+10, 40, 0, 20, \ - 0) + NL80211_RRF_PASSIVE_SCAN) /* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */ #define RTW_2GHZ_CH14 \ @@ -69,7 +69,7 @@ static struct country_code_to_enum_rd allCountries[] = { /* 5G chan 36 - chan 165 */ #define RTW_5GHZ_5150_5850 \ REG_RULE(5150-10, 5850+10, 40, 0, 30, \ - 0) + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) static const struct ieee80211_regdomain rtw_regdom_rd = { .n_reg_rules = 3, @@ -81,6 +81,176 @@ static const struct ieee80211_regdomain rtw_regdom_rd = { } }; +static const struct ieee80211_regdomain rtw_regdom_11 = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_12_13 = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_no_midband = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_5GHZ_5150_5350, + RTW_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_60_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_14_60_64 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_2GHZ_CH14, + RTW_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_14 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_2GHZ_CH14, + } +}; + +#if 0 +static struct rtw_regulatory *rtw_regd; +#endif + +#if 0 /* not_yet */ +static void _rtw_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum nl80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + u32 bandwidth = 0; + int r; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (rtw_is_dfs_ch(ch->hw_value) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + r = freq_reg_info(wiphy, ch->center_freq, + bandwidth, ®_rule); + if (r) + continue; + + /* + *If 11d had a rule for this channel ensure + *we enable adhoc/beaconing if it allows us to + *use it. Note that we would have disabled it + *by applying our static world regdomain by + *default during init, prior to calling our + *regulatory_hint(). + */ + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (! + (reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan scan on Ch 12 and 13 */ +static void _rtw_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator + initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + u32 bandwidth = 0; + int r; + + if (!wiphy->bands[NL80211_BAND_2GHZ]) + return; + sband = wiphy->bands[NL80211_BAND_2GHZ]; + + /* + * If no country IE has been received always enable active scan + * on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /* + * If a country IE has been received check its rule for this + * channel first before enabling active scan. The passive scan + * would have been enforced by the initial processing of our + * custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ + r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ + r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} +#endif void rtw_regd_apply_flags(struct wiphy *wiphy) { @@ -104,15 +274,11 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) ch = &sband->channels[j]; if (ch) -#ifndef CONFIG_DISABLE_REGD_C ch->flags = IEEE80211_CHAN_DISABLED; -#else - ch->flags = 0; -#endif } } } -#ifndef CONFIG_DISABLE_REGD_C + /* channels apply by channel plans. */ for (i = 0; i < max_chan_nums; i++) { channel = channel_set[i].ChannelNum; @@ -150,14 +316,21 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) } #endif /* CONFIG_DFS */ } -#endif } static const struct ieee80211_regdomain *_rtw_regdomain_select(struct rtw_regulatory *reg) { +#if 0 + switch (reg->country_code) { + case COUNTRY_CODE_USER: + default: + return &rtw_regdom_rd; + } +#else return &rtw_regdom_rd; +#endif } static void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) @@ -229,6 +402,21 @@ static struct country_code_to_enum_rd *_rtw_regd_find_country(u16 countrycode) int rtw_regd_init(struct wiphy *wiphy) { +#if 0 + if (rtw_regd == NULL) { + rtw_regd = (struct rtw_regulatory *) + rtw_malloc(sizeof(struct rtw_regulatory)); + + rtw_regd->alpha2[0] = '9'; + rtw_regd->alpha2[1] = '9'; + + rtw_regd->country_code = COUNTRY_CODE_USER; + } + + RTW_INFO("%s: Country alpha2 being used: %c%c\n", + __func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]); +#endif + _rtw_regd_init_wiphy(NULL, wiphy); return 0; diff --git a/os_dep/osdep_service.c b/os_dep/osdep_service.c index c4a2519..83c7640 100644 --- a/os_dep/osdep_service.c +++ b/os_dep/osdep_service.c @@ -2201,7 +2201,7 @@ static int isFileReadable(const char *path, u32 *sz) ret = PTR_ERR(fp); else { oldfs = get_fs(); - set_fs(KERNEL_DS); + set_fs(get_ds()); if (1 != readFile(fp, &buf, 1)) ret = PTR_ERR(fp); @@ -2239,7 +2239,7 @@ static int retriveFromFile(const char *path, u8 *buf, u32 sz) RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp); oldfs = get_fs(); - set_fs(KERNEL_DS); + set_fs(get_ds()); ret = readFile(fp, buf, sz); set_fs(oldfs); closeFile(fp); @@ -2274,7 +2274,7 @@ static int storeToFile(const char *path, u8 *buf, u32 sz) RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp); oldfs = get_fs(); - set_fs(KERNEL_DS); + set_fs(get_ds()); ret = writeFile(fp, buf, sz); set_fs(oldfs); closeFile(fp);