diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/Makefile b/drivers/net/wireless/rockchip_wlan/rtl8723cs/Makefile index f42f734461f5..b07017734d91 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/Makefile +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/Makefile @@ -66,7 +66,7 @@ CONFIG_RTW_CHPLAN = 0xFF CONFIG_RTW_ADAPTIVITY_EN = disable CONFIG_RTW_ADAPTIVITY_MODE = normal CONFIG_SIGNAL_SCALE_MAPPING = n -CONFIG_80211W = n +CONFIG_80211W = y CONFIG_REDUCE_TX_CPU_LOADING = n CONFIG_BR_EXT = y CONFIG_TDLS = n @@ -79,8 +79,7 @@ CONFIG_RTW_NETIF_SG = y CONFIG_TX_CSUM_OFFLOAD = n CONFIG_RTW_IPCAM_APPLICATION = n CONFIG_RTW_REPEATER_SON = n -CONFIG_PLATFORM_ANDROID = n -CONFIG_RTW_WIFI_HAL = n +CONFIG_RTW_WIFI_HAL = y CONFIG_ICMP_VOQ = n CONFIG_IP_R_MONITOR = n #arp VOQ and high rate ########################## Debug ########################### diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.c index 4565f762a487..35c72bbdf5c0 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.c @@ -1178,33 +1178,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.h index e40cbc294b35..7c098b810eb8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/mesh/rtw_mesh.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/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/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ap.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ap.c index c82aec09f04b..edbdde452dcb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ap.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ap.c @@ -1775,10 +1775,7 @@ chbw_decision: if (!(ifbmp_ch_changed & BIT(i)) || !pdvobj->padapters[i]) continue; - /* pure AP is not needed*/ - if (MLME_IS_GO(pdvobj->padapters[i]) - || MLME_IS_MESH(pdvobj->padapters[i]) - ) { + { u8 ht_option = 0; #ifdef CONFIG_80211N_HT @@ -1789,7 +1786,7 @@ chbw_decision: , pdvobj->padapters[i]->mlmeextpriv.cur_channel , pdvobj->padapters[i]->mlmeextpriv.cur_bwmode , pdvobj->padapters[i]->mlmeextpriv.cur_ch_offset - , ht_option); + , ht_option, 0); } } #endif /* defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */ @@ -1899,6 +1896,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; u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01}; @@ -2025,13 +2023,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 */ @@ -2039,6 +2038,21 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) psecuritypriv->wpa2_group_cipher = group_cipher; psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; + +#ifdef CONFIG_IOCTL_CFG80211 + /** + * Kernel < v5.x, 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)) { + RTW_INFO("%s: Auth type as SAE\n", __func__); + psecuritypriv->auth_type = MLME_AUTHTYPE_SAE; + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + } +#endif #if 0 switch (group_cipher) { case WPA_CIPHER_NONE: @@ -3807,6 +3821,11 @@ 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) { + 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)) { @@ -5122,6 +5141,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_; @@ -5137,12 +5157,15 @@ 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 (MLME_IS_AP(adapter) && (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; @@ -5189,6 +5212,21 @@ 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; +#ifdef CONFIG_IOCTL_CFG80211 + if (MLME_IS_AP(adapter) && + (sec->auth_type == MLME_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"); + } + } +#endif /* CONFIG_IOCTL_CFG80211 */ + if (status != _STATS_SUCCESSFUL_) goto exit; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ieee80211.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ieee80211.c index be8aeebe8583..1e704051a465 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_ieee80211.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/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 * ----------------------------------------------------------- */ @@ -681,8 +695,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; @@ -741,11 +791,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; } } } @@ -853,11 +903,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) @@ -876,11 +926,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) { @@ -1162,6 +1211,60 @@ u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id , u8 return NULL; } +/* OWE */ +/** + * rtw_get_OWE_ie - Search OWE IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @wps_ie: If not NULL and OWE IE is found, OWE IE will be copied to the buf starting from owe_ie + * @wps_ielen: If not NULL and OWE IE is found, will set to the length of the entire OWE IE + * + * Returns: The address of the OWE IE found, or NULL + */ +u8 *rtw_get_owe_ie(const u8 *in_ie, uint in_len, u8 *owe_ie, uint *owe_ielen) +{ + uint cnt; + const u8 *oweie_ptr = NULL; + u8 eid; + + if (owe_ielen) + *owe_ielen = 0; + + if (!in_ie) { + rtw_warn_on(1); + return (u8 *)oweie_ptr; + } + + if (in_len <= 0) + return (u8 *)oweie_ptr; + + cnt = 0; + + while (cnt + 1 + 4 < in_len) { + eid = in_ie[cnt]; + + if (cnt + 1 + 4 >= MAX_IE_SZ) { + rtw_warn_on(1); + return NULL; + } + + if ((eid == WLAN_EID_EXTENSION) && (in_ie[cnt + 2] == WLAN_EID_EXT_OWE_DH_PARAM)) { + oweie_ptr = in_ie + cnt; + + if (owe_ie) + _rtw_memcpy(owe_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); + + if (owe_ielen) + *owe_ielen = in_ie[cnt + 1] + 2; + + break; + } else + cnt += in_ie[cnt + 1] + 2; + } + return (u8 *)oweie_ptr; +} + + static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, struct rtw_ieee802_11_elems *elems, int show_errors) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme.c index ca59aa694207..b427e72732ff 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme.c @@ -4197,7 +4197,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme_ext.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme_ext.c index 9fcc69bfe1f5..97aa4fc4da01 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme_ext.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_mlme_ext.c @@ -105,6 +105,7 @@ unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; +unsigned char DPP_OUI[] = {0x50, 0x6F, 0x9A, 0x1A}; unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; @@ -2097,9 +2098,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 +2174,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 +2306,20 @@ 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, MLME_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 +2457,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)) { @@ -6455,6 +6492,9 @@ unsigned int on_action_public_vendor(union recv_frame *precv_frame) unsigned int ret = _FAIL; u8 *pframe = precv_frame->u.hdr.rx_data; u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + _adapter *adapter = precv_frame->u.hdr.adapter; + int cnt = 0; + char msg[64]; if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) { if (rtw_action_public_decache(precv_frame, 7) == _FAIL) @@ -6464,6 +6504,13 @@ unsigned int on_action_public_vendor(union recv_frame *precv_frame) rtw_rframe_del_wfd_ie(precv_frame, 8); ret = on_action_public_p2p(precv_frame); + } else if (_rtw_memcmp(frame_body + 2, DPP_OUI, 4) == _TRUE) { + u8 dpp_type = frame_body[7]; + +#ifdef CONFIG_IOCTL_CFG80211 + cnt += sprintf((msg + cnt), "DPP(type:%u)", dpp_type); + rtw_cfg80211_rx_action(adapter, precv_frame, msg); +#endif } exit: @@ -8849,6 +8896,24 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p #endif } +static u32 rtw_append_assoc_req_owe_ie(_adapter *adapter, u8 *pbuf) +{ + struct security_priv *sec = &adapter->securitypriv; + u32 len = 0; + + if (sec == NULL) + goto exit; + + if (sec->owe_ie && sec->owe_ie_len > 0) { + len = sec->owe_ie_len; + _rtw_memcpy(pbuf, sec->owe_ie, len); + } + +exit: + return len; +} + + void _issue_assocreq(_adapter *padapter, u8 is_reassoc) { int ret = _FAIL; @@ -9090,7 +9155,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, MLME_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: @@ -9283,7 +9359,14 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) pattrib->pktlen += wfdielen; #endif #endif /* CONFIG_P2P */ + /* OWE */ + { + u32 owe_ie_len; + owe_ie_len = rtw_append_assoc_req_owe_ie(padapter, pframe); + pframe += owe_ie_len; + pattrib->pktlen += owe_ie_len; + } #ifdef CONFIG_RTW_REPEATER_SON rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen); #endif @@ -11237,6 +11320,8 @@ 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); @@ -11256,6 +11341,20 @@ void start_clnt_auth(_adapter *padapter) } else #endif RTW_PRINT("start auth\n"); +#ifdef CONFIG_IOCTL_CFG80211 + if (rtw_sec_chk_auth_type(padapter, MLME_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); @@ -12942,6 +13041,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, MLME_AUTHTYPE_SAE)) + return; +#endif /* CONFIG_IOCTL_CFG80211 */ + /* re-auth timer */ if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) { /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */ @@ -15934,7 +16039,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) rtw_start_bss_hdl_after_chbw_decided(iface); - if (MLME_IS_GO(iface) || MLME_IS_MESH(iface)) { /* pure AP is not needed*/ + { #if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) u8 ht_option = 0; @@ -15944,7 +16049,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) rtw_cfg80211_ch_switch_notify(iface , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset - , ht_option); + , ht_option, 0); #endif } } @@ -16142,17 +16247,52 @@ connect_allow_hdl: #endif /* CONFIG_CONCURRENT_MODE */ exit: - if (connect_allow == _TRUE) { RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); *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, 1); + } +#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) { @@ -16535,3 +16675,63 @@ 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/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_p2p.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_p2p.c index 441e5c1b0f0f..26539dd7d505 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_p2p.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_p2p.c @@ -4397,7 +4397,7 @@ void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength) u32 ies_len; u8 *p2p_ie; u32 p2p_ielen = 0; - u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */ + u8 *noa_attr; /* NoA length should be n*(13) + 2 */ u32 attr_contentlen = 0; struct wifidirect_info *pwdinfo = &(padapter->wdinfo); @@ -4424,7 +4424,8 @@ void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength) while (p2p_ie) { find_p2p = _TRUE; /* Get Notice of Absence IE. */ - if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) { + noa_attr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, NULL, &attr_contentlen); + if (noa_attr) { find_p2p_ps = _TRUE; noa_index = noa_attr[0]; @@ -4437,8 +4438,8 @@ void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength) noa_offset = 2; noa_num = 0; /* NoA length should be n*(13) + 2 */ - if (attr_contentlen > 2) { - while (noa_offset < attr_contentlen) { + if (attr_contentlen > 2 && (attr_contentlen - 2) % 13 == 0) { + while (noa_offset < attr_contentlen && noa_num < P2P_MAX_NOA_NUM) { /* _rtw_memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */ pwdinfo->noa_count[noa_num] = noa_attr[noa_offset]; noa_offset += 1; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_wlan_util.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_wlan_util.c index 18ebefcf62b2..388af71e62c2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_wlan_util.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/core/rtw_wlan_util.c @@ -2290,41 +2290,35 @@ int validate_beacon_len(u8 *pframe, u32 len) return _TRUE; } - -u8 support_rate_ranges[] = { - IEEE80211_CCK_RATE_1MB, - IEEE80211_CCK_RATE_2MB, - IEEE80211_CCK_RATE_5MB, - IEEE80211_CCK_RATE_11MB, - IEEE80211_OFDM_RATE_6MB, - IEEE80211_OFDM_RATE_9MB, - IEEE80211_OFDM_RATE_12MB, - IEEE80211_OFDM_RATE_18MB, - IEEE80211_OFDM_RATE_24MB, - IEEE80211_OFDM_RATE_36MB, - IEEE80211_OFDM_RATE_48MB, - IEEE80211_OFDM_RATE_54MB, -}; - -inline bool match_ranges(u16 EID, u32 value) +inline bool is_valid_rate(u8 rate) { int i; int nr_range; - - switch (EID) { - case _EXT_SUPPORTEDRATES_IE_: - case _SUPPORTEDRATES_IE_: - nr_range = sizeof(support_rate_ranges)/sizeof(u8); - for (i = 0; i < nr_range; i++) { - /* clear bit7 before searching. */ - value &= ~BIT(7); - if (value == support_rate_ranges[i]) - return _TRUE; - } - break; - default: - break; + u8 valid_rates[] = { + IEEE80211_CCK_RATE_1MB, + IEEE80211_CCK_RATE_2MB, + IEEE80211_CCK_RATE_5MB, + IEEE80211_CCK_RATE_11MB, + IEEE80211_OFDM_RATE_6MB, + IEEE80211_OFDM_RATE_9MB, + IEEE80211_OFDM_RATE_12MB, + IEEE80211_OFDM_RATE_18MB, + IEEE80211_PBCC_RATE_22MB, + IEEE80211_FREAK_RATE_22_5MB, + IEEE80211_OFDM_RATE_24MB, + IEEE80211_OFDM_RATE_36MB, + IEEE80211_OFDM_RATE_48MB, + IEEE80211_OFDM_RATE_54MB, }; + + nr_range = sizeof(valid_rates) / sizeof(u8); + for (i = 0; i < nr_range; i++) { + /* clear bit7 before searching. */ + rate &= ~BIT(7); + if (rate == valid_rates[i]) + return _TRUE; + } + return _FALSE; } @@ -2341,16 +2335,14 @@ inline bool match_ranges(u16 EID, u32 value) */ bool rtw_validate_value(u16 EID, u8 *p, u16 len) { - u8 rate; u32 i, nr_val; switch (EID) { case _EXT_SUPPORTEDRATES_IE_: case _SUPPORTEDRATES_IE_: nr_val = len; - for (i=0; iencryp_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; @@ -2568,9 +2560,9 @@ void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon) 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_INFO("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) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/hal_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/hal_mp.c index 79bc77f05117..4ba9aa5bca7c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/hal_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/hal_mp.c @@ -1104,7 +1104,7 @@ void mpt_SetRFPath_8723B(PADAPTER pAdapter) } switch (pAdapter->mppriv.antenna_tx) { - u8 i; + u8 p = 0, i = 0; case ANTENNA_A: { /*/ Actually path S1 (Wi-Fi)*/ pMptCtx->mpt_rf_path = RF_PATH_A; phy_set_bb_reg(pAdapter, rS0S1_PathSwitch, BIT9 | BIT8 | BIT7, 0x0); @@ -1169,6 +1169,7 @@ void mpt_SetRFPath_8723B(PADAPTER pAdapter) void mpt_SetRFPath_8703B(PADAPTER pAdapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 i = 0; u32 ulAntennaTx, ulAntennaRx; PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx); struct dm_struct *pDM_Odm = &pHalData->odmpriv; @@ -1183,8 +1184,6 @@ void mpt_SetRFPath_8703B(PADAPTER pAdapter) } switch (pAdapter->mppriv.antenna_tx) { - u8 i; - case ANTENNA_A: { /* Actually path S1 (Wi-Fi) */ pMptCtx->mpt_rf_path = RF_PATH_A; phy_set_bb_reg(pAdapter, rS0S1_PathSwitch, BIT9 | BIT8 | BIT7, 0x0); @@ -1248,7 +1247,6 @@ void mpt_SetRFPath_8703B(PADAPTER pAdapter) void mpt_SetRFPath_8723D(PADAPTER pAdapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); - u8 p = 0, i = 0; u32 ulAntennaTx, ulAntennaRx, offset = 0, data = 0, val32 = 0; PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx); struct dm_struct *pDM_Odm = &pHalData->odmpriv; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.c index 7713ab6edc25..fecf85ab9c64 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.c @@ -1454,10 +1454,8 @@ void halrf_segment_iqk_trigger(void *dm_void, boolean clear, *rf->is_carrier_suppresion))) return; -#if (DM_ODM_SUPPORT_TYPE == ODM_CE) if (!(rf->rf_supportability & HAL_RF_IQK)) return; -#endif #if DISABLE_BB_RF return; @@ -2557,6 +2555,26 @@ void halrf_dpk_reload(void *dm_void) } } +void halrf_dpk_switch(void *dm_void, u8 enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct dm_dpk_info *dpk_info = &dm->dpk_info; + struct _hal_rf_ *rf = &dm->rf_table; + + if (enable) { + rf->rf_supportability = rf->rf_supportability | HAL_RF_DPK; + dpk_info->is_dpk_enable = true; + halrf_dpk_enable_disable(dm); + halrf_dpk_trigger(dm); + halrf_set_dpk_track(dm, 1); + } else { + halrf_set_dpk_track(dm, 0); + dpk_info->is_dpk_enable = false; + halrf_dpk_enable_disable(dm); + rf->rf_supportability = rf->rf_supportability & ~HAL_RF_DPK; + } +} + void halrf_dpk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2804,6 +2822,86 @@ u32 halrf_tssi_get_de(void *dm_void, u8 path) return 0; } +void _halrf_dump_subpage(void *dm_void, u32 *_used, char *output, u32 *_out_len, u8 page) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + u32 used = *_used; + u32 out_len = *_out_len; + u32 addr; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "\n===============[ Subpage_%d start]===============\n", page); + + odm_set_bb_reg(dm, R_0x1b00, BIT(2) | BIT(1), page); + + for (addr = 0x1b00; addr < 0x1c00; addr += 0x10) { + PDM_SNPF(out_len, used, output + used, out_len - used, + " 0x%x : 0x%08x 0x%08x 0x%08x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x4, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x8, MASKDWORD), + odm_get_bb_reg(dm, addr + 0xc, MASKDWORD)); + } + + *_used = used; + *_out_len = out_len; +} + +void halrf_dump_rfk_reg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct _hal_rf_ *rf = &dm->rf_table; + + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u32 reg_1b00, supportability; + u8 page; + + if (!(dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES))) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "CMD is Unsupported due to IC type!!!\n"); + return; + } else if (rf->is_dpk_in_progress || dm->rf_calibrate_info.is_iqk_in_progress || + dm->is_psd_in_process || rf->is_tssi_in_progress) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Bypass CMD due to RFK is doing!!!\n"); + return; + } + + supportability = rf->rf_supportability; + + /*to avoid DPK track interruption*/ + rf->rf_supportability = rf->rf_supportability & ~HAL_RF_DPK_TRACK; + + reg_1b00 = odm_get_bb_reg(dm, R_0x1b00, MASKDWORD); + + if (input[2]) + PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[0]); + + if ((strcmp(input[2], help) == 0)) + PDM_SNPF(out_len, used, output + used, out_len - used, + "dump subpage {0:Page0, 1:Page1, 2:Page2, 3:Page3, 4:all}\n"); + else if (var1[0] > 4) + PDM_SNPF(out_len, used, output + used, out_len - used, + "Wrong subpage number!!\n"); + else if (var1[0] == 4) { + for (page = 0; page < 4; page++) + _halrf_dump_subpage(dm, &used, output, &out_len, page); + } else + _halrf_dump_subpage(dm, &used, output, &out_len, (u8)var1[0]); + + odm_set_bb_reg(dm, R_0x1b00, MASKDWORD, reg_1b00); + + rf->rf_supportability = supportability; + + *_used = used; + *_out_len = out_len; +} + /*Golbal function*/ void halrf_reload_bp(void *dm_void, u32 *bp_reg, u32 *bp, u32 num) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.h index 0c4449692267..7c9193649cee 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf.h @@ -66,12 +66,12 @@ #define IQK_VER_8192F "0x01" #define IQK_VER_8723B "0x1e" #define IQK_VER_8812A "0x02" -#define IQK_VER_8821A "0x01" +#define IQK_VER_8821A "0x02" #elif (DM_ODM_SUPPORT_TYPE & (ODM_CE)) #define IQK_VER_8188E "0x01" #define IQK_VER_8192E "0x01" #define IQK_VER_8192F "0x01" -#define IQK_VER_8723B "0x1e" +#define IQK_VER_8723B "0x1f" #define IQK_VER_8812A "0x01" #define IQK_VER_8821A "0x01" #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) @@ -96,17 +96,17 @@ #define IQK_VER_8710B "0x01" #define IQK_VER_8723D "0x02" #define IQK_VER_8822B "0x30" -#define IQK_VER_8822C "0x0d" +#define IQK_VER_8822C "0x12" #define IQK_VER_8821C "0x23" #define IQK_VER_8198F "0x09" #define IQK_VER_8814B "0x0b" #define IQK_VER_8812F "0x07" /*LCK version*/ -#define LCK_VER_8188E "0x01" -#define LCK_VER_8192E "0x01" +#define LCK_VER_8188E "0x02" +#define LCK_VER_8192E "0x02" #define LCK_VER_8192F "0x01" -#define LCK_VER_8723B "0x01" +#define LCK_VER_8723B "0x02" #define LCK_VER_8812A "0x01" #define LCK_VER_8821A "0x01" #define LCK_VER_8814A "0x01" @@ -170,7 +170,7 @@ /*DACK version*/ -#define DACK_VER_8822C "0x8" +#define DACK_VER_8822C "0xa" #define DACK_VER_8814B "0x3" /*Kfree tracking version*/ @@ -599,6 +599,8 @@ void halrf_dpk_track(void *dm_void); void halrf_dpk_reload(void *dm_void); +void halrf_dpk_switch(void *dm_void, u8 enable); + void halrf_dpk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size); /*Global function*/ @@ -683,4 +685,8 @@ void halrf_dack_dbg(void *dm_void); void halrf_iqk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size); void halrf_set_rfsupportability(void *dm_void); + +void halrf_dump_rfk_reg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); + #endif /*__HALRF_H__*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_debug.c index 882cf0700a78..684384785f6f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_debug.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_debug.c @@ -149,6 +149,8 @@ enum halrf_CMD_ID { HALRF_IQK_INFO, HALRF_IQK, HALRF_IQK_DEBUG, + HALRF_DPK, + HALRF_DUMP_RFK_REG, }; struct halrf_command halrf_cmd_ary[] = { @@ -159,6 +161,8 @@ struct halrf_command halrf_cmd_ary[] = { {"iqk_info", HALRF_IQK_INFO}, {"iqk", HALRF_IQK}, {"iqk_dbg", HALRF_IQK_DEBUG}, + {"dpk", HALRF_DPK}, + {"dump_rfk_reg", HALRF_DUMP_RFK_REG}, }; void halrf_cmd_parser(void *dm_void, char input[][16], u32 *_used, char *output, @@ -239,6 +243,14 @@ void halrf_cmd_parser(void *dm_void, char input[][16], u32 *_used, char *output, #endif } break; + case HALRF_DPK: + PDM_SNPF(out_len, used, output + used, out_len - used, + "DPK Trigger\n"); + halrf_dpk_trigger(dm); + break; + case HALRF_DUMP_RFK_REG: + halrf_dump_rfk_reg(dm, input, &used, output, &out_len); + break; default: break; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_iqk.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_iqk.h index a48d1f46bcad..a8e65f0974aa 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_iqk.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/halrf_iqk.h @@ -50,6 +50,7 @@ struct dm_dack_info { boolean dack_en; u16 msbk_d[2][2][15]; u8 dck_d[2][2][2]; + u16 biask_d[2][2]; }; struct dm_iqk_info { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/rtl8703b/halrf_8703b.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/rtl8703b/halrf_8703b.c index dcbe58c326e5..4ab63ff6cc27 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/rtl8703b/halrf_8703b.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/halrf/rtl8703b/halrf_8703b.c @@ -1197,7 +1197,8 @@ void _phy_mac_setting_calibration8703b(struct dm_struct *dm, u32 *mac_reg, odm_write_1byte(dm, mac_reg[i], 0x3F); for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) odm_write_1byte(dm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(3)))); - odm_write_1byte(dm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(5)))); + /*remove 0x40[5]setting for coex reason*/ + /*odm_write_1byte(dm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(5))));*/ } boolean diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.c index 86e1709a019d..6174541ca531 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.c @@ -318,6 +318,24 @@ void phydm_common_info_self_init(struct dm_struct *dm) } } +void phydm_iot_patch_id_update(void *dm_void, u32 iot_idx, boolean en) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_iot_center *iot_table = &dm->iot_table; + + PHYDM_DBG(dm, DBG_CMN, "[IOT] 0x%x = %d\n", iot_idx, en); + switch (iot_idx) { + case 0x021f0800: + iot_table->patch_id_021f0800 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_021f0800 = %d\n", + iot_table->patch_id_021f0800); + break; + default: + pr_debug("[%s] warning!\n", __func__); + break; + } +} + void phydm_cmn_sta_info_update(void *dm_void, u8 macid) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -534,6 +552,11 @@ void phydm_hw_setting(struct dm_struct *dm) if (dm->support_ic_type & ODM_RTL8192F) phydm_hwsetting_8192f(dm); #endif + +#if (RTL8822C_SUPPORT) + if (dm->support_ic_type & ODM_RTL8822C) + phydm_hwsetting_8822c(dm); +#endif } #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.h index d3eac4260fea..0c0e1ff0f975 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.h @@ -669,8 +669,9 @@ struct phydm_bt_info { struct phydm_iot_center { boolean is_linked_cmw500; - u8 win_patch_id; /*@Customer ID*/ - u32 phydm_patch_id; + u8 win_patch_id; /*Customer ID*/ + boolean patch_id_021f0800; + u32 phydm_patch_id; /*temp for CCX IOT */ }; @@ -803,6 +804,11 @@ struct dm_struct { #if (RTL8822C_SUPPORT) u8 txagc_buff[2][NUM_RATE_AC_2SS]; u32 bp_0x9b0; + u16 agc_rf_gain_ori[16][64];/*[table][mp_gain_idx]*/ + u16 agc_rf_gain[16][64];/*[table][mp_gain_idx]*/ + u8 agc_table_cnt; + boolean is_agc_tab_pos_shift; + u8 agc_table_shift; #endif /*@-----------HOOK BEFORE REG INIT-----------*/ /*@===========================================================*/ @@ -1039,6 +1045,9 @@ struct dm_struct { /*@-----------------------------------------------------------*/ boolean bsomlenabled; /* @D-SoML control */ + u8 no_ndp_cnts; + u8 ndp_cnt_pre; + boolean is_beamformed; boolean bhtstfdisabled; /* @dynamic HTSTF gain control*/ u32 n_iqk_cnt; u32 n_iqk_ok_cnt; @@ -1401,6 +1410,9 @@ phydm_dc_cancellation(struct dm_struct *dm); void phydm_receiver_blocking(void *dm_void); +void +phydm_iot_patch_id_update(void *dm_void, u32 iot_idx, boolean en); + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) void odm_init_all_work_items( diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.mk b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.mk index 550f768e8ec7..c2558cef26dd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.mk +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm.mk @@ -208,6 +208,7 @@ RTL871X = rtl8822c _PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8822c_bb.o\ hal/phydm/$(RTL871X)/phydm_hal_api8822c.o\ hal/phydm/$(RTL871X)/phydm_regconfig8822c.o\ + hal/phydm/$(RTL871X)/phydm_rtl8822c.o\ hal/phydm/halrf/$(RTL871X)/halrf_8822c.o\ hal/phydm/halrf/$(RTL871X)/halrf_iqk_8822c.o\ hal/phydm/halrf/$(RTL871X)/halrf_tssi_8822c.o\ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.c index 03503e1f85c4..579310f57919 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.c @@ -126,6 +126,31 @@ phydm_ap_num_check(void *dm_void) } return dis_adapt; } + +void phydm_set_l2h_th_ini_win(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + /*@ [New Format: JGR3]IGI-idx:45 = RSSI:35 = -65dBm*/ + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & ODM_RTL8822C) + dm->th_l2h_ini = 45; + else if (dm->support_ic_type & ODM_RTL8814B) + dm->th_l2h_ini = 49; + } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + /*@ [Old Format] -11+base(50) = IGI_idx:39 = RSSI:29 = -71dBm*/ + if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8812)) { + dm->th_l2h_ini = -17; + } else { + if (*dm->band_type == ODM_BAND_5G) + dm->th_l2h_ini = -14; + else if (*dm->band_type == ODM_BAND_2_4G) + dm->th_l2h_ini = -9; + } + } else { /*ODM_IC_11N_SERIES*/ + dm->th_l2h_ini = -9; + } +} #endif void phydm_dig_up_bound_lmt_en(void *dm_void) @@ -543,6 +568,8 @@ void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info, case PHYDM_ADAPINFO_AP_NUM_TH: adaptivity->ap_num_th = (u8)value; break; + case PHYDM_ADAPINFO_SWITCH_TH_L2H_INI_IN_BAND: + adaptivity->switch_th_l2h_ini_in_band = (u8)value; default: break; } @@ -576,7 +603,8 @@ void phydm_adaptivity_init(void *dm_void) #if (DM_ODM_SUPPORT_TYPE & (ODM_CE | ODM_WIN)) if (!dm->carrier_sense_enable) { - if (dm->th_l2h_ini == 0) + if (dm->th_l2h_ini == 0 && + !adaptivity->switch_th_l2h_ini_in_band) phydm_set_l2h_th_ini(dm); } else { phydm_set_l2h_th_ini_carrier_sense(dm); @@ -696,7 +724,12 @@ void phydm_adaptivity(void *dm_void) odm_set_bb_reg(dm, R_0x800, BIT(10), 1); /*@ADC_mask disable*/ odm_set_bb_reg(dm, R_0x800, BIT(10), 0); /*@ADC_mask enable*/ } - +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (!dm->carrier_sense_enable && + !adapt->debug_mode && + adapt->switch_th_l2h_ini_in_band) + phydm_set_l2h_th_ini_win(dm); +#endif if (!adapt->debug_mode) phydm_check_adaptivity(dm); /*@Check adaptivity enable*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.h index 4a754ea6e260..bb326014b945 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_adaptivity.h @@ -63,7 +63,8 @@ enum phydm_adapinfo { PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, PHYDM_ADAPINFO_AP_NUM_TH, PHYDM_ADAPINFO_DOMAIN_CODE_2G, - PHYDM_ADAPINFO_DOMAIN_CODE_5G + PHYDM_ADAPINFO_DOMAIN_CODE_5G, + PHYDM_ADAPINFO_SWITCH_TH_L2H_INI_IN_BAND }; enum phydm_mac_edcca_type { @@ -100,6 +101,7 @@ struct phydm_adaptivity_struct { u8 regulation_5g; boolean is_adapt_en; boolean edcca_en; + u8 switch_th_l2h_ini_in_band; }; #ifdef PHYDM_SUPPORT_ADAPTIVITY diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.c index eefa82a31c2f..072932a2f695 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.c @@ -2307,6 +2307,48 @@ u8 phydm_api_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate) return ret; } +#if (RTL8822C_SUPPORT) +void phydm_shift_rxagc_table(void *dm_void, boolean is_pos_shift, u8 sft) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 i = 0; + u8 j = 0; + u32 reg = 0; + u16 max_rf_gain = 0; + u16 min_rf_gain = 0; + + dm->is_agc_tab_pos_shift = is_pos_shift; + dm->agc_table_shift = sft; + + for (i = 0; i <= dm->agc_table_cnt; i++) { + max_rf_gain = dm->agc_rf_gain_ori[i][0]; + min_rf_gain = dm->agc_rf_gain_ori[i][63]; + + for (j = 0; j < 64; j++) { + if (is_pos_shift) { + if (j < sft) + reg = (max_rf_gain & 0x3ff); + else + reg = (dm->agc_rf_gain_ori[i][j - sft] & + 0x3ff); + } else { + if (j > 63 - sft) + reg = (min_rf_gain & 0x3ff); + else + reg = (dm->agc_rf_gain_ori[i][j + sft] & + 0x3ff); + } + dm->agc_rf_gain[i][j] = (u16)(reg & 0x3ff); + + reg |= (j & 0x3f) << 16;/*mp_gain_idx*/ + reg |= (i & 0xf) << 22;/*table*/ + reg |= BIT(29) | BIT(28);/*write en*/ + odm_set_bb_reg(dm, R_0x1d90, MASKDWORD, reg); + } + } +} +#endif + boolean phydm_api_switch_bw_channel(void *dm_void, u8 ch, u8 pri_ch, enum channel_width bw) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.h index bceb0c4e346c..a7dd9d237d54 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_api.h @@ -168,6 +168,10 @@ phydm_api_set_txagc(void *dm_void, u32 power_index, enum rf_path path, u8 phydm_api_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate); +#if (RTL8822C_SUPPORT) +void phydm_shift_rxagc_table(void *dm_void, boolean shift_up, u8 shift); +#endif + boolean phydm_api_switch_bw_channel(void *dm_void, u8 central_ch, u8 primary_ch_idx, enum channel_width bandwidth); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_cck_pd.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_cck_pd.c index 8f5229abf957..ecf51aa178e1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_cck_pd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_cck_pd.c @@ -1039,6 +1039,9 @@ void phydm_cck_pd_init(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + if (*dm->mp_mode) + return; + if (dm->support_ic_type & CCK_PD_IC_TYPE1) cckpd_t->cckpd_hw_type = 1; else if (dm->support_ic_type & CCK_PD_IC_TYPE2) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_debug.c index bc8cc8dcd5d1..1bff39cb2531 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_debug.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_debug.c @@ -2304,6 +2304,13 @@ void phydm_basic_dbg_msg_linked(void *dm_void) (dbg_t->is_ldpc_pkt) ? "Y" : "N", (dbg_t->is_stbc_pkt) ? "Y" : "N"); #endif + +#if (RTL8822C_SUPPORT) + /*Beamformed pkt*/ + if (dm->support_ic_type == ODM_RTL8822C) + PHYDM_DBG(dm, DBG_CMN, "Beamformed=((%s))\n", + (dm->is_beamformed) ? "Y" : "N"); +#endif } void phydm_dm_summary(void *dm_void, u8 macid) @@ -4540,6 +4547,122 @@ void phydm_mp_dbg(void *dm_void, char input[][16], u32 *_used, char *output, *_out_len = out_len; } +#if (RTL8822C_SUPPORT) +u16 phydm_get_agc_rf_gain(void *dm_void, boolean is_mod, u8 tab, u8 mp_gain_i) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u16 rf_gain = 0x0; + + if (is_mod) + rf_gain = dm->agc_rf_gain[tab][mp_gain_i]; + else + rf_gain = dm->agc_rf_gain_ori[tab][mp_gain_i]; + + return rf_gain; +} +#endif + +void phydm_get_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 tab = 0; + boolean is_modified = false; + u8 mp_gain = 0; + u16 rf_gain = 0; + u8 i = 0; + +#if (RTL8822C_SUPPORT) + if (!(dm->support_ic_type & ODM_RTL8822C)) + return; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "get rxagc table : {0:ori, 1:modified} {table:0~15} {mp_gain_idx:0~63, all:0xff}\n"); + } else { + for (i = 0; i < 3; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + } + + is_modified = (boolean)var1[0]; + tab = (u8)var1[1]; + mp_gain = (u8)var1[2]; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "agc_table_cnt:%d, is_agc_tab_pos_shift:%d, agc_table_shift:%d\n", + dm->agc_table_cnt, dm->is_agc_tab_pos_shift, + dm->agc_table_shift); + + if (mp_gain == 0xff) { + for (i = 0; i < 64; i++) { + rf_gain = phydm_get_agc_rf_gain(dm, is_modified, + tab, i); + + PDM_SNPF(out_len, used, output + used, + out_len - used, + "agc_table:%d, mp_gain_idx:0x%x, rf_gain_idx:0x%x\n", + tab, i, rf_gain); + } + } else { + rf_gain = phydm_get_agc_rf_gain(dm, is_modified, tab, + mp_gain); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "agc_table:%d, mp_gain_idx:0x%x, rf_gain_idx:0x%x\n", + tab, mp_gain, rf_gain); + } + } +#endif + *_used = used; + *_out_len = out_len; +} + +void phydm_shift_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + u16 value_db = 0; + +#if (RTL8822C_SUPPORT) + if (!(dm->support_ic_type & ODM_RTL8822C)) + return; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "shift rxagc table : {0:-, 1:+} {value(0~63, unit:2dB)}\n"); + } else { + for (i = 0; i < 3; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + if ((u8)var1[1] > 63) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Do not enter the value larger than 63!\n"); + } else { + phydm_shift_rxagc_table(dm, (boolean)var1[0], + (u8)var1[1]); + + value_db = (u8)var1[1] << 1; + PDM_SNPF(out_len, used, output + used, out_len - used, + "shift %s%d dB gain\n", + (((boolean)var1[0]) ? "+" : "-"), value_db); + } + } +#endif +} + #if RTL8814B_SUPPORT void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) @@ -4662,8 +4785,11 @@ enum PHYDM_CMD_ID { PHYDM_ANAPAR, PHYDM_BEAM_FORMING, #if RTL8814B_SUPPORT - PHYDM_SPUR_DETECT + PHYDM_SPUR_DETECT, #endif + PHYDM_GET_RXAGC, + PHYDM_SHIFT_RXAGC + }; struct phydm_command phy_dm_ary[] = { @@ -4718,8 +4844,11 @@ struct phydm_command phy_dm_ary[] = { {"anapar", PHYDM_ANAPAR}, {"bf", PHYDM_BEAM_FORMING}, #if RTL8814B_SUPPORT - {"spur_detect", PHYDM_SPUR_DETECT} + {"spur_detect", PHYDM_SPUR_DETECT}, #endif + {"get_rxagc", PHYDM_GET_RXAGC}, + {"shift_rxagc", PHYDM_SHIFT_RXAGC} + }; #endif /*@#ifdef CONFIG_PHYDM_DEBUG_FUNCTION*/ @@ -5070,6 +5199,12 @@ void phydm_cmd_parser(struct dm_struct *dm, char input[][MAX_ARGV], phydm_spur_detect_dbg(dm, input, &used, output, &out_len); break; #endif + case PHYDM_GET_RXAGC: + phydm_get_rxagc_table_dbg(dm, input, &used, output, &out_len); + break; + case PHYDM_SHIFT_RXAGC: + phydm_shift_rxagc_table_dbg(dm, input, &used, output, &out_len); + break; default: PDM_SNPF(out_len, used, output + used, out_len - used, "Do not support this command\n"); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_dig.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_dig.c index 367c939edfc9..2e45a1d0de08 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_dig.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_dig.c @@ -2852,13 +2852,26 @@ void phydm_mcc_igi_cal(void *dm_void) phydm_mcc_igi_chk(dm); igi_val0 = mcc_dm->mcc_rssi[0] - shift; igi_val1 = mcc_dm->mcc_rssi[1] - shift; + + if (igi_val0 < DIG_MIN_PERFORMANCE) + igi_val0 = DIG_MIN_PERFORMANCE; + + if (igi_val1 < DIG_MIN_PERFORMANCE) + igi_val1 = DIG_MIN_PERFORMANCE; + + switch (dm->ic_ip_series) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT - phydm_fill_mcccmd(dm, 0, R_0x1d70, igi_val0, igi_val1); - phydm_fill_mcccmd(dm, 1, R_0x1d70 + 1, igi_val0, igi_val1); - #else - phydm_fill_mcccmd(dm, 0, 0xc50, igi_val0, igi_val1); - phydm_fill_mcccmd(dm, 1, 0xe50, igi_val0, igi_val1); + case PHYDM_IC_JGR3: + phydm_fill_mcccmd(dm, 0, R_0x1d70, igi_val0, igi_val1); + phydm_fill_mcccmd(dm, 1, R_0x1d70 + 1, igi_val0, igi_val1); + break; #endif + default: + phydm_fill_mcccmd(dm, 0, R_0xc50, igi_val0, igi_val1); + phydm_fill_mcccmd(dm, 1, R_0xe50, igi_val0, igi_val1); + break; + } + PHYDM_DBG(dm, DBG_COMP_MCC, "RSSI_min: %d %d, MCC_igi: %d %d\n", mcc_dm->mcc_rssi[0], mcc_dm->mcc_rssi[1], mcc_dm->mcc_dm_val[0][0], mcc_dm->mcc_dm_val[0][1]); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_precomp.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_precomp.h index 5b434c7be147..483ceeaf0269 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_precomp.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_precomp.h @@ -474,11 +474,12 @@ rtw_phydm_cfg_phy_para( #if (RTL8822C_SUPPORT) #include "rtl8822c/halhwimg8822c_bb.h" #include "rtl8822c/phydm_regconfig8822c.h" + #include "rtl8822c/phydm_hal_api8822c.h" + #include "rtl8822c/version_rtl8822c.h" + #include "rtl8822c/phydm_rtl8822c.h" #include "halrf/rtl8822c/halrf_8822c.h" #include "halrf/rtl8822c/halhwimg8822c_rf.h" #include "halrf/rtl8822c/version_rtl8822c_rf.h" - #include "rtl8822c/phydm_hal_api8822c.h" - #include "rtl8822c/version_rtl8822c.h" #if (DM_ODM_SUPPORT_TYPE == ODM_CE) /* @struct HAL_DATA_TYPE */ #include diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_regtable.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_regtable.h index f8bcda9c993a..f560c0c97a0a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_regtable.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/phydm/phydm_regtable.h @@ -1,3 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * + *****************************************************************************/ + #define R_0x0 0x0 #define R_0x00 0x00 #define R_0x0106 0x0106 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c index 2c0e96657e19..7ce356907bc6 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/hal/rtl8703b/sdio/sdio_ops.c @@ -1658,7 +1658,6 @@ u8 RecvOnePkt(PADAPTER padapter) if (len) { sdio_claim_host(func); res = sd_recv_rxfifo(padapter, len, &precvbuf); - if (precvbuf) { /* printk("Completed Recv One Pkt.\n"); */ sd_rxhandler(padapter, precvbuf); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/autoconf.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/autoconf.h index b07bcb0b8481..eb91e5b0c77c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/autoconf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/autoconf.h @@ -132,7 +132,7 @@ #define CONFIG_SDIO_RX_COPY #define CONFIG_XMIT_THREAD_MODE /* #define CONFIG_SDIO_TX_ENABLE_AVAL_INT */ - +/* #define CONFIG_RECV_THREAD_MODE */ /* * Others diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/ieee80211.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/ieee80211.h index 60b192332d36..1d6286660a8b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/ieee80211.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/ieee80211.h @@ -132,8 +132,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[]; @@ -141,6 +139,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 @@ -591,7 +622,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 #define WLAN_CAPABILITY_BSS (1<<0) @@ -707,6 +738,8 @@ struct ieee80211_snap_hdr { #define WLAN_EID_VHT_CAPABILITY 191 #define WLAN_EID_VHT_OPERATION 192 #define WLAN_EID_VHT_OP_MODE_NOTIFY 199 +#define WLAN_EID_EXTENSION 255 +#define WLAN_EID_EXT_OWE_DH_PARAM 32 #define IEEE80211_MGMT_HDR_LEN 24 #define IEEE80211_DATA_HDR3_LEN 24 @@ -740,6 +773,8 @@ struct ieee80211_snap_hdr { #define IEEE80211_OFDM_RATE_12MB 0x18 #define IEEE80211_OFDM_RATE_18MB 0x24 #define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_PBCC_RATE_22MB 0x2C +#define IEEE80211_FREAK_RATE_22_5MB 0x2D #define IEEE80211_OFDM_RATE_36MB 0x48 #define IEEE80211_OFDM_RATE_48MB 0x60 #define IEEE80211_OFDM_RATE_54MB 0x6C @@ -1292,6 +1327,7 @@ struct ieee80211_txb { #define MAX_WPA_IE_LEN (256) #define MAX_WPS_IE_LEN (512) +#define MAX_OWE_IE_LEN (128) #define MAX_P2P_IE_LEN (256) #define MAX_WFD_IE_LEN (128) @@ -1907,8 +1943,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); @@ -1917,6 +1953,7 @@ u8 *rtw_get_wps_ie_from_scan_queue(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps u8 *rtw_get_wps_ie(const u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id , u8 *buf_attr, u32 *len_attr); u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id , u8 *buf_content, uint *len_content); +u8 *rtw_get_owe_ie(const u8 *in_ie, uint in_len, u8 *owe_ie, uint *owe_ielen); /** * for_each_ie - iterate over continuous IEs diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/osdep_service.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/osdep_service.h index 81c4973c7ff7..85d94e2caf07 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/osdep_service.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/osdep_service.h @@ -67,6 +67,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_android.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_android.h index efc981aa1e95..f9d6b4972505 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_android.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/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/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme.h index a86cc97f69e2..647ac1418c39 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme.h @@ -175,6 +175,39 @@ enum dot11AuthAlgrthmNum { dot11AuthAlgrthm_MaxNum }; +/** + * enum mlme_auth_type - AuthenticationType + * + * @MLME_AUTHTYPE_OPEN_SYSTEM: Open System authentication + * @MLME_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) + * @MLME_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) + * @MLME_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) + * @MLME_AUTHTYPE_SAE: Simultaneous authentication of equals + * @MLME_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key + * @MLME_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS + * @MLME_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key + * @__MLME_AUTHTYPE_NUM: internal + * @MLME_AUTHTYPE_MAX: maximum valid auth algorithm + * @MLME_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by trying + * multiple times); this is invalid in netlink -- leave out the attribute + * for this on CONNECT commands. + */ +enum mlme_auth_type { + MLME_AUTHTYPE_OPEN_SYSTEM, + MLME_AUTHTYPE_SHARED_KEY, + MLME_AUTHTYPE_FT, + MLME_AUTHTYPE_NETWORK_EAP, + MLME_AUTHTYPE_SAE, + MLME_AUTHTYPE_FILS_SK, + MLME_AUTHTYPE_FILS_SK_PFS, + MLME_AUTHTYPE_FILS_PK, + + /* keep last */ + __MLME_AUTHTYPE_NUM, + MLME_AUTHTYPE_MAX = __MLME_AUTHTYPE_NUM - 1, + MLME_AUTHTYPE_AUTOMATIC +}; + /* Scan type including active and passive scan. */ typedef enum _RT_SCAN_TYPE { SCAN_PASSIVE, @@ -535,7 +568,7 @@ struct beacon_keys { 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 @@ -1167,7 +1200,8 @@ u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms); 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/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme_ext.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme_ext.h index a7386d1fb24c..a581ac745546 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme_ext.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_mlme_ext.h @@ -163,20 +163,16 @@ enum SCAN_STATE { SCAN_PS_ANNC_WAIT = 2, SCAN_ENTER = 3, SCAN_PROCESS = 4, - /* backop */ SCAN_BACKING_OP = 5, SCAN_BACK_OP = 6, SCAN_LEAVING_OP = 7, SCAN_LEAVE_OP = 8, - /* SW antenna diversity (before linked) */ SCAN_SW_ANTDIV_BL = 9, - /* legacy p2p */ SCAN_TO_P2P_LISTEN = 10, SCAN_P2P_LISTEN = 11, - SCAN_COMPLETE = 12, SCAN_STATE_MAX, }; @@ -679,6 +675,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); @@ -1113,6 +1111,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_security.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_security.h index be37f2956021..2d7499ff4018 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_security.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_security.h @@ -164,6 +164,8 @@ struct security_priv { u8 wps_ie[MAX_WPS_IE_LEN];/* added in assoc req */ int wps_ie_len; + u8 owe_ie[MAX_OWE_IE_LEN];/* added in assoc req */ + int owe_ie_len; u8 binstallGrpkey; #ifdef CONFIG_GTK_OL @@ -175,7 +177,9 @@ struct security_priv { u8 busetkipkey; 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 */ @@ -491,4 +495,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_version.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_version.h index f4de32c36521..11a7ca4de391 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_version.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/rtw_version.h @@ -1,2 +1,3 @@ -#define DRIVERVERSION "v5.7.1_34242.20190822_beta" +/* SPDX-License-Identifier: GPL-2.0 */ +#define DRIVERVERSION "v5.7.1.3_35649.20191114_beta" #define BTCOEXVERSION "COEX20180330-1e00" diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/sta_info.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/sta_info.h index 9deab7c2d18e..77491da790a3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/sta_info.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/sta_info.h @@ -400,6 +400,7 @@ struct sta_info { int wpa2_group_cipher; int wpa_pairwise_cipher; int wpa2_pairwise_cipher; + u32 akm_suite_type; u8 bpairwise_key_installed; #ifdef CONFIG_RTW_80211R @@ -478,6 +479,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/wifi.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/wifi.h index cc67bb5bc253..83075ba34400 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/wifi.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/include/wifi.h @@ -966,8 +966,8 @@ typedef enum _HT_CAP_AMPDU_DENSITY { * A-PMDU buffer sizes * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */ -#define IEEE80211_MIN_AMPDU_BUF 0x8 -#define IEEE80211_MAX_AMPDU_BUF_HT 0x40 +/* #define IEEE80211_MIN_AMPDU_BUF 0x8 */ +/* #define IEEE80211_MAX_AMPDU_BUF 0x40 */ /* Spatial Multiplexing Power Save Modes */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.c index 78282272d0db..ed18accf652c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.c @@ -407,7 +407,24 @@ static void rtw_get_chbw_from_nl80211_channel_type(struct ieee80211_channel *cha #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) -u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht) +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, bool started) { struct wiphy *wiphy = adapter_to_wiphy(adapter); u8 ret = _SUCCESS; @@ -419,12 +436,25 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 if (ret != _SUCCESS) goto exit; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + if (started) { + cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0); + goto exit; + } +#endif + + if (!rtw_cfg80211_allow_ch_switch_notify(adapter)) + goto exit; + cfg80211_ch_switch_notify(adapter->pnetdev, &chdef); #else 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 +567,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] = { @@ -3262,6 +3293,21 @@ static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, { RTW_INFO("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type); + if (NL80211_AUTHTYPE_MAX <= (int)MLME_AUTHTYPE_SAE) { + if (MLME_AUTHTYPE_SAE == psecuritypriv->auth_type) { + /* This case pre handle in + * rtw_check_connect_sae_compat() + */ + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + return 0; + } + } else if (sme_auth_type == (int)MLME_AUTHTYPE_SAE) { + psecuritypriv->auth_type = MLME_AUTHTYPE_SAE; + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + return 0; + } + + psecuritypriv->auth_type = sme_auth_type; switch (sme_auth_type) { case NL80211_AUTHTYPE_AUTOMATIC: @@ -3290,6 +3336,7 @@ static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, break; + default: psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* return -ENOTSUPP; */ @@ -3388,7 +3435,9 @@ static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key psecuritypriv->rsn_akm_suite_type = 4; } #endif - else { + else if (key_mgt == WLAN_AKM_SUITE_SAE) { + psecuritypriv->rsn_akm_suite_type = 8; + } else { RTW_INFO("Invalid key mgt: 0x%x\n", key_mgt); /* return -EINVAL; */ } @@ -3529,6 +3578,18 @@ static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); } + {/* handle owe_ie */ + uint owe_ielen; + u8 *owe_ie; + + owe_ie = rtw_get_owe_ie(buf, ielen, NULL, &owe_ielen); + if (owe_ie && owe_ielen > 0) { + RTW_INFO("got owe_ie, owe_ielen:%u\n", owe_ielen); + padapter->securitypriv.owe_ie_len = owe_ielen < MAX_OWE_IE_LEN ? owe_ielen : MAX_OWE_IE_LEN; + _rtw_memcpy(padapter->securitypriv.owe_ie, owe_ie, padapter->securitypriv.owe_ie_len); + } + } + #ifdef CONFIG_P2P {/* check p2p_ie for assoc req; */ uint p2p_ielen = 0; @@ -3757,6 +3818,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 != (int)MLME_AUTHTYPE_SHARED_KEY) + 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) { @@ -3779,6 +3872,13 @@ 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 = MLME_AUTHTYPE_SAE; + psecuritypriv->auth_type = MLME_AUTHTYPE_SAE; + psecuritypriv->auth_alg = WLAN_AUTH_SAE; + RTW_INFO("%s set sme->auth_type for SAE compat\n", __FUNCTION__); + } + if (pwdev_priv->block == _TRUE) { ret = -EBUSY; RTW_INFO("%s wdev_priv.block is set\n", __FUNCTION__); @@ -3849,6 +3949,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; @@ -4115,36 +4217,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; @@ -4154,17 +4240,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, MLME_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; } @@ -4921,6 +5038,14 @@ static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, ret = -ENOTSUPP; goto exit; } + + /* Kernel < v5.x, 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(). + * + * we only update auth_type when 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, @@ -5963,6 +6088,50 @@ static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, */ #endif /* CONFIG_AP_MODE */ +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); + +#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 +} + void rtw_cfg80211_rx_probe_request(_adapter *adapter, union recv_frame *rframe) { struct wireless_dev *wdev = adapter->rtw_wdev; @@ -6176,10 +6345,9 @@ 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 (!MLME_IS_MESH(adapter) + || !rtw_sae_preprocess(adapter, frame, frame_len, _FALSE) + ) { if (msg) RTW_INFO("RTW_Rx:%s\n", msg); else @@ -6451,6 +6619,7 @@ static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy, } #endif + inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val) { adapter->cfg80211_wdinfo.is_ro_ch = val; @@ -7200,8 +7369,14 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, } #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 (!MLME_IS_MESH(padapter) || (retval == 0)) RTW_INFO("RTW_Tx:AUTH\n"); dump_limit = 1; goto dump; @@ -7356,12 +7531,27 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, 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; } @@ -9389,6 +9579,9 @@ 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 @@ -9562,6 +9755,95 @@ 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_ps_deny_cancel(padapter, PS_DENY_MGNT_TX); + + rtw_mfree(buf, len); + buf = NULL; + len = 0; + } + } 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, @@ -9678,6 +9960,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/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.h b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.h index d16cfdde316d..787a454364bb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/ioctl_cfg80211.h @@ -192,6 +192,19 @@ struct rtw_wdev_priv { #endif }; +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); @@ -247,6 +260,7 @@ struct rtw_wiphy_data { #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 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); @@ -319,6 +333,9 @@ void rtw_cfg80211_rx_action_p2p(_adapter *padapter, union recv_frame *rframe); void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const char *msg); 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); @@ -388,7 +405,7 @@ void rtw_cfg80211_deinit_rfkill(struct wiphy *wiphy); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) -u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht); +u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht, bool started); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/mlme_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/mlme_linux.c index 39c0ac157f6e..70ca949bc230 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/mlme_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/mlme_linux.c @@ -129,6 +129,7 @@ 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 +146,7 @@ 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/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/os_intfs.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/os_intfs.c index de2c21d0977a..fced6657ea97 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/os_intfs.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/os_intfs.c @@ -1657,13 +1657,10 @@ int rtw_os_ndev_alloc(_adapter *adapter) #if defined(CONFIG_IOCTL_CFG80211) if (rtw_cfg80211_ndev_res_alloc(adapter) != _SUCCESS) { rtw_warn_on(1); - goto free_ndev; - } + } else #endif - ret = _SUCCESS; -free_ndev: if (ret != _SUCCESS && ndev) rtw_free_netdev(ndev); exit: @@ -1735,7 +1732,9 @@ int rtw_os_ndev_register(_adapter *adapter, const char *name) } #endif +#if defined(CONFIG_IOCTL_CFG80211) exit: +#endif #ifdef CONFIG_RTW_NAPI if (ret != _SUCCESS) netif_napi_del(&adapter->napi); @@ -1833,8 +1832,7 @@ int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) #if defined(CONFIG_IOCTL_CFG80211) if (rtw_cfg80211_dev_res_alloc(dvobj) != _SUCCESS) { rtw_warn_on(1); - status = _FAIL; - goto exit; + return _FAIL; } #endif @@ -1874,7 +1872,7 @@ int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) if (status != _SUCCESS) rtw_cfg80211_dev_res_free(dvobj); #endif -exit: + return status; } @@ -3128,8 +3126,7 @@ int rtw_os_ndevs_register(struct dvobj_priv *dvobj) #if defined(CONFIG_IOCTL_CFG80211) if (rtw_cfg80211_dev_res_register(dvobj) != _SUCCESS) { rtw_warn_on(1); - status = _FAIL; - goto exit; + return _FAIL; } #endif @@ -3178,7 +3175,6 @@ int rtw_os_ndevs_register(struct dvobj_priv *dvobj) if (status != _SUCCESS) rtw_cfg80211_dev_res_unregister(dvobj); #endif -exit: return status; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/rtw_android.c b/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/rtw_android.c index 2a9932bf2c38..bd5cb26b15ee 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8723cs/os_dep/linux/rtw_android.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8723cs/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" }; @@ -936,6 +937,13 @@ 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);