Update to 5.6.1.5

This commit is contained in:
Rin Cat
2019-11-14 18:16:30 -05:00
parent 20fba52b05
commit c8ee6e0746
63 changed files with 41239 additions and 40294 deletions

View File

@@ -1179,33 +1179,12 @@ void rtw_mesh_adjust_chbw(u8 req_ch, u8 *req_bw, u8 *req_offset)
}
}
int rtw_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx)
void rtw_mesh_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx, u16 alg, u16 seq, u16 status)
{
const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr);
u16 alg;
u16 seq;
u16 status;
int ret = 0;
alg = RTW_GET_LE16(frame_body);
if (alg != 3)
goto exit;
seq = RTW_GET_LE16(frame_body + 2);
status = RTW_GET_LE16(frame_body + 4);
RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x\n"
, (tx == _TRUE) ? "Tx" : "Rx", alg, seq, status);
ret = 1;
#if CONFIG_RTW_MESH_PEER_BLACKLIST
if (tx && seq == 1)
rtw_mesh_plink_set_peer_conf_timeout(adapter, GetAddr1Ptr(buf));
#endif
exit:
return ret;
}
#if CONFIG_RTW_MPM_TX_IES_SYNC_BSS

View File

@@ -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);

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1897,6 +1897,7 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
u16 cap, ht_cap = _FALSE;
uint ie_len = 0;
int group_cipher, pairwise_cipher;
u32 akm;
u8 mfp_opt = MFP_NO;
u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
int supportRateNum = 0;
@@ -2057,13 +2058,14 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
psecuritypriv->wpa_psk = 0;
/* wpa2 */
akm = 0;
group_cipher = 0;
pairwise_cipher = 0;
psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) {
if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) {
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
@@ -2071,6 +2073,15 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
psecuritypriv->wpa2_group_cipher = group_cipher;
psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
/*
Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC
in cfg80211_rtw_start_ap().
if the AKM SAE in the RSN IE, we have to update the auth_type for SAE
in rtw_check_beacon_data().
*/
if (CHECK_BIT(WLAN_AKM_TYPE_SAE, akm))
psecuritypriv->auth_type = NL80211_AUTHTYPE_SAE;
#if 0
switch (group_cipher) {
case WPA_CIPHER_NONE:
@@ -3858,6 +3869,12 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso
_enter_critical_bh(&psta->lock, &irqL);
psta->state &= ~(_FW_LINKED | WIFI_UNDER_KEY_HANDSHAKE);
if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) {
rtw_mfree(psta->pauth_frame, psta->auth_len);
psta->pauth_frame = NULL;
psta->auth_len = 0;
}
_exit_critical_bh(&psta->lock, &irqL);
if (!MLME_IS_MESH(padapter)) {
@@ -5172,6 +5189,7 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct
u8 *wpa_ie;
int wpa_ie_len;
int group_cipher = 0, pairwise_cipher = 0;
u32 akm = 0;
u8 mfp_opt = MFP_NO;
u16 status = _STATS_SUCCESSFUL_;
@@ -5187,13 +5205,17 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct
wpa_ie = elems->rsn_ie;
wpa_ie_len = elems->rsn_ie_len;
if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) {
if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, &akm, &mfp_opt) == _SUCCESS) {
sta->dot8021xalg = 1;/* psk, todo:802.1x */
sta->wpa_psk |= BIT(1);
sta->wpa2_group_cipher = group_cipher & sec->wpa2_group_cipher;
sta->wpa2_pairwise_cipher = pairwise_cipher & sec->wpa2_pairwise_cipher;
sta->akm_suite_type = akm;
if ((CHECK_BIT(WLAN_AKM_TYPE_SAE, akm)) && (MFP_NO == mfp_opt))
status = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
if (!sta->wpa2_group_cipher)
status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
@@ -5239,6 +5261,18 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct
else if (sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL)
sta->flags |= WLAN_STA_MFP;
if ((sec->auth_type == NL80211_AUTHTYPE_SAE) &&
(CHECK_BIT(WLAN_AKM_TYPE_SAE, sta->akm_suite_type)) &&
(WLAN_AUTH_OPEN == sta->authalg)) {
/* WPA3-SAE, PMK caching */
if (rtw_cached_pmkid(adapter, sta->cmn.mac_addr) == -1) {
RTW_INFO("SAE: No PMKSA cache entry found\n");
status = WLAN_STATUS_INVALID_PMKID;
} else {
RTW_INFO("SAE: PMKSA cache entry found\n");
}
}
if (status != _STATS_SUCCESSFUL_)
goto exit;

View File

@@ -33,14 +33,28 @@ u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };
u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
u16 RSN_VERSION_BSD = 1;
u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };
u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };
u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };
u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };
u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };
u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 };
u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };
u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };
u8 WLAN_AKM_8021X[] = {0x00, 0x0f, 0xac, 1};
u8 WLAN_AKM_PSK[] = {0x00, 0x0f, 0xac, 2};
u8 WLAN_AKM_FT_8021X[] = {0x00, 0x0f, 0xac, 3};
u8 WLAN_AKM_FT_PSK[] = {0x00, 0x0f, 0xac, 4};
u8 WLAN_AKM_8021X_SHA256[] = {0x00, 0x0f, 0xac, 5};
u8 WLAN_AKM_PSK_SHA256[] = {0x00, 0x0f, 0xac, 6};
u8 WLAN_AKM_TDLS[] = {0x00, 0x0f, 0xac, 7};
u8 WLAN_AKM_SAE[] = {0x00, 0x0f, 0xac, 8};
u8 WLAN_AKM_FT_OVER_SAE[] = {0x00, 0x0f, 0xac, 9};
u8 WLAN_AKM_8021X_SUITE_B[] = {0x00, 0x0f, 0xac, 11};
u8 WLAN_AKM_8021X_SUITE_B_192[] = {0x00, 0x0f, 0xac, 12};
u8 WLAN_AKM_FILS_SHA256[] = {0x00, 0x0f, 0xac, 14};
u8 WLAN_AKM_FILS_SHA384[] = {0x00, 0x0f, 0xac, 15};
u8 WLAN_AKM_FT_FILS_SHA256[] = {0x00, 0x0f, 0xac, 16};
u8 WLAN_AKM_FT_FILS_SHA384[] = {0x00, 0x0f, 0xac, 17};
/* -----------------------------------------------------------
* for adhoc-master to generate ie and provide supported-rate to fw
* ----------------------------------------------------------- */
@@ -661,8 +675,44 @@ int rtw_get_wpa2_cipher_suite(u8 *s)
return 0;
}
u32 rtw_get_akm_suite_bitmap(u8 *s)
{
if (_rtw_memcmp(s, WLAN_AKM_8021X, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_8021X;
if (_rtw_memcmp(s, WLAN_AKM_PSK, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_PSK;
if (_rtw_memcmp(s, WLAN_AKM_FT_8021X, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FT_8021X;
if (_rtw_memcmp(s, WLAN_AKM_FT_PSK, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FT_PSK;
if (_rtw_memcmp(s, WLAN_AKM_8021X_SHA256, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_8021X_SHA256;
if (_rtw_memcmp(s, WLAN_AKM_PSK_SHA256, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_PSK_SHA256;
if (_rtw_memcmp(s, WLAN_AKM_TDLS, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_TDLS;
if (_rtw_memcmp(s, WLAN_AKM_SAE, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_SAE;
if (_rtw_memcmp(s, WLAN_AKM_FT_OVER_SAE, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FT_OVER_SAE;
if (_rtw_memcmp(s, WLAN_AKM_8021X_SUITE_B, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_8021X_SUITE_B;
if (_rtw_memcmp(s, WLAN_AKM_8021X_SUITE_B_192, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_8021X_SUITE_B_192;
if (_rtw_memcmp(s, WLAN_AKM_FILS_SHA256, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FILS_SHA256;
if (_rtw_memcmp(s, WLAN_AKM_FILS_SHA384, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FILS_SHA384;
if (_rtw_memcmp(s, WLAN_AKM_FT_FILS_SHA256, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FT_FILS_SHA256;
if (_rtw_memcmp(s, WLAN_AKM_FT_FILS_SHA384, RSN_SELECTOR_LEN) == _TRUE)
return WLAN_AKM_TYPE_FT_FILS_SHA384;
int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
return 0;
}
int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
int *pairwise_cipher, u32 *akm)
{
int i, ret = _SUCCESS;
int left, count;
@@ -721,11 +771,11 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwis
return _FAIL;
}
if (is_8021x) {
if (akm) {
if (left >= 6) {
pos += 2;
if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) {
*is_8021x = 1;
*akm = WLAN_AKM_TYPE_8021X;
}
}
}
@@ -833,11 +883,11 @@ err:
return _FAIL;
}
int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x, u8 *mfp_opt)
int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher,
int *pairwise_cipher, u32 *akm, u8 *mfp_opt)
{
struct rsne_info info;
int i, ret = _SUCCESS;
u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01};
ret = rtw_rsne_info_parse(rsn_ie, rsn_ie_len, &info);
if (ret != _SUCCESS)
@@ -856,11 +906,10 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi
*pairwise_cipher |= rtw_get_wpa2_cipher_suite(info.pcs_list + 4 * i);
}
if (is_8021x) {
*is_8021x = 0;
/* here only check the first AKM suite */
if (info.akm_cnt && _rtw_memcmp(SUITE_1X, info.akm_list, 4) == _TRUE)
*is_8021x = 1;
if (akm) {
*akm = 0;
for (i = 0; i < info.akm_cnt; i++)
*akm |= rtw_get_akm_suite_bitmap(info.akm_list + 4 * i);
}
if (mfp_opt) {
@@ -2660,86 +2709,6 @@ int ieee80211_get_hdrlen(u16 fc)
return hdrlen;
}
int rtw_get_cipher_info(struct wlan_network *pnetwork)
{
u32 wpa_ielen;
unsigned char *pbuf;
int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
int ret = _FAIL;
pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
if (pbuf && (wpa_ielen > 0)) {
if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) {
pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
pnetwork->BcnInfo.group_cipher = group_cipher;
pnetwork->BcnInfo.is_8021x = is8021x;
ret = _SUCCESS;
}
} else {
pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
if (pbuf && (wpa_ielen > 0)) {
if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x, NULL)) {
pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
pnetwork->BcnInfo.group_cipher = group_cipher;
pnetwork->BcnInfo.is_8021x = is8021x;
ret = _SUCCESS;
}
}
}
return ret;
}
void rtw_get_bcn_info(struct wlan_network *pnetwork)
{
unsigned short cap = 0;
u8 bencrypt = 0;
/* u8 wpa_ie[255],rsn_ie[255]; */
u16 wpa_len = 0, rsn_len = 0;
struct HT_info_element *pht_info = NULL;
struct rtw_ieee80211_ht_cap *pht_cap = NULL;
unsigned int len;
unsigned char *p;
_rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
cap = le16_to_cpu(cap);
if (cap & WLAN_CAPABILITY_PRIVACY) {
bencrypt = 1;
pnetwork->network.Privacy = 1;
} else
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, NULL, &rsn_len, NULL, &wpa_len);
if (rsn_len > 0)
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2;
else if (wpa_len > 0)
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA;
else {
if (bencrypt)
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP;
}
rtw_get_cipher_info(pnetwork);
/* get bwmode and ch_offset */
/* parsing HT_CAP_IE */
p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_);
if (p && len > 0) {
pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
pnetwork->BcnInfo.ht_cap_info = pht_cap->cap_info;
} else
pnetwork->BcnInfo.ht_cap_info = 0;
/* parsing HT_INFO_IE */
p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_);
if (p && len > 0) {
pht_info = (struct HT_info_element *)(p + 2);
pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0];
} else
pnetwork->BcnInfo.ht_info_infos_0 = 0;
}
u8 rtw_ht_mcsset_to_nss(u8 *supp_mcs_set)
{
u8 nss = 1;

View File

@@ -4272,7 +4272,12 @@ static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
}
static int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent)
int rtw_cached_pmkid(_adapter *Adapter, u8 *bssid)
{
return SecIsInPMKIDList(Adapter, bssid);
}
int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent)
{
struct security_priv *sec = &adapter->securitypriv;
struct rsne_info info;

View File

@@ -1848,7 +1848,6 @@ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
struct beacon_keys recv_beacon;
update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
rtw_get_bcn_info(&(pmlmepriv->cur_network));
/* update bcn keys */
if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
@@ -2087,9 +2086,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 */
@@ -2163,6 +2162,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",
@@ -2284,6 +2294,21 @@ unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
RTW_INFO("%s\n", __FUNCTION__);
#ifdef CONFIG_IOCTL_CFG80211
if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) {
if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
RTW_INFO("SAE: PMKSA cache entry found\n");
goto normal;
}
rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
return _SUCCESS;
}
}
normal:
#endif /* CONFIG_IOCTL_CFG80211 */
/* check A1 matches or not */
if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
return _SUCCESS;
@@ -2421,6 +2446,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)) {
@@ -9142,7 +9178,18 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc)
rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe);
} else
#endif
{
#ifdef CONFIG_IOCTL_CFG80211
if (rtw_sec_chk_auth_alg(padapter, WLAN_AUTH_OPEN) &&
rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) {
s32 entry = rtw_cached_pmkid(padapter, pmlmepriv->assoc_bssid);
rtw_rsn_sync_pmkid(padapter, (u8 *)pIE, (pIE->Length + 2), entry);
}
#endif /* CONFIG_IOCTL_CFG80211 */
pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
}
break;
#ifdef CONFIG_80211N_HT
case EID_HTCapability:
@@ -10323,7 +10370,7 @@ void issue_action_BSSCoexistPacket(_adapter *padapter)
u8 InfoContent[16] = {0};
u8 ICS[8][15];
#ifdef CONFIG_80211N_HT
if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
if ((pmlmepriv->num_FortyMHzIntolerant == 0) && (pmlmepriv->num_sta_no_ht == 0))
return;
if (_TRUE == pmlmeinfo->bwmode_updated)
@@ -10368,18 +10415,15 @@ void issue_action_BSSCoexistPacket(_adapter *padapter)
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
/* */
if (pmlmepriv->num_FortyMHzIntolerant > 0) {
/* TODO calculate 40Mhz intolerant via ch and ch offset */
/* if (pmlmepriv->num_FortyMHzIntolerant > 0) */
{
u8 iedata = 0;
iedata |= BIT(2);/* 20 MHz BSS Width Request */
pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
}
/* */
_rtw_memset(ICS, 0, sizeof(ICS));
if (pmlmepriv->num_sta_no_ht > 0) {
@@ -11305,6 +11349,7 @@ void start_clnt_auth(_adapter *padapter)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
_cancel_timer_ex(&pmlmeext->link_timer);
@@ -11324,6 +11369,22 @@ void start_clnt_auth(_adapter *padapter)
} else
#endif
RTW_PRINT("start auth\n");
#ifdef CONFIG_IOCTL_CFG80211
if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) {
if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
RTW_INFO("SAE: PMKSA cache entry found\n");
padapter->securitypriv.auth_alg = WLAN_AUTH_OPEN;
goto no_external_auth;
}
RTW_PRINT("SAE: start external auth\n");
rtw_cfg80211_external_auth_request(padapter, NULL);
return;
}
no_external_auth:
#endif /* CONFIG_IOCTL_CFG80211 */
issue_auth(padapter, NULL, 0);
set_link_timer(pmlmeext, REAUTH_TO);
@@ -13005,6 +13066,12 @@ void link_timer_hdl(void *ctx)
pmlmeinfo->state = WIFI_FW_NULL_STATE;
report_join_res(padapter, -3, WLAN_STATUS_UNSPECIFIED_FAILURE);
} else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
#ifdef CONFIG_IOCTL_CFG80211
if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE))
return;
#endif /* CONFIG_IOCTL_CFG80211 */
/* re-auth timer */
if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
/* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
@@ -13183,7 +13250,6 @@ void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame)
struct beacon_keys recv_beacon;
update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
rtw_get_bcn_info(&(pmlmepriv->cur_network));
/* update bcn keys */
if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
@@ -16204,11 +16270,48 @@ exit:
*ch = u_ch;
*bw = u_bw;
*offset = u_offset;
#if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
{
u8 ht_option = 0;
#ifdef CONFIG_80211N_HT
ht_option = adapter->mlmepriv.htpriv.ht_option;
#endif /* CONFIG_80211N_HT */
/*
when supplicant send the mlme frame,
the bss freq is updated by channel switch event.
*/
rtw_cfg80211_ch_switch_notify(adapter,
cur_ch, cur_bw, cur_ch_offset, ht_option);
}
#endif
}
return connect_allow == _TRUE ? _SUCCESS : _FAIL;
}
void rtw_set_external_auth_status(_adapter *padapter,
const void *data, int len)
{
#ifdef CONFIG_IOCTL_CFG80211
struct net_device *dev = padapter->pnetdev;
struct wiphy *wiphy = adapter_to_wiphy(padapter);
struct rtw_external_auth_params params;
/* convert data to external_auth_params */
params.action = RTW_GET_BE32((u8 *)data);
_rtw_memcpy(&params.bssid, (u8 *)data + 4, ETH_ALEN);
_rtw_memcpy(&params.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(&params.pmkid, (u8 *)data + 64, PMKID_LEN);
rtw_cfg80211_external_auth_status(wiphy, dev, &params);
#endif /* CONFIG_IOCTL_CFG80211 */
}
u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf)
{
@@ -16591,3 +16694,65 @@ u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
return H2C_SUCCESS;
}
int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx)
{
#ifdef CONFIG_IOCTL_CFG80211
const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr);
u16 alg;
u16 seq;
u16 status;
int ret = _FAIL;
alg = RTW_GET_LE16(frame_body);
if (alg != WLAN_AUTH_SAE)
goto exit;
seq = RTW_GET_LE16(frame_body + 2);
status = RTW_GET_LE16(frame_body + 4);
RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x, mesg:%s\n",
(tx == _TRUE) ? "Tx" : "Rx", alg, seq, status,
(seq == 1) ? "Commit" : "Confirm");
ret = _SUCCESS;
#ifdef CONFIG_RTW_MESH
if (MLME_IS_MESH(adapter)) {
rtw_mesh_sae_check_frames(adapter, buf, len, tx, alg, seq, status);
goto exit;
}
#endif
if (tx && (seq == 2) && (status == 0)) {
/* quere commit frame until external auth statue update */
struct sta_priv *pstapriv = &adapter->stapriv;
struct sta_info *psta = NULL;
_irqL irqL;
psta = rtw_get_stainfo(pstapriv, GetAddr1Ptr(buf));
if (psta) {
_enter_critical_bh(&psta->lock, &irqL);
if (psta->pauth_frame) {
rtw_mfree(psta->pauth_frame, psta->auth_len);
psta->pauth_frame = NULL;
psta->auth_len = 0;
}
psta->pauth_frame = rtw_zmalloc(len);
if (psta->pauth_frame) {
_rtw_memcpy(psta->pauth_frame, buf, len);
psta->auth_len = len;
}
_exit_critical_bh(&psta->lock, &irqL);
ret = 2;
}
}
exit:
return ret;
#else
return _SUCCESS;
#endif /* CONFIG_IOCTL_CFG80211 */
}

View File

@@ -743,6 +743,73 @@ u8 PS_RDY_CHECK(_adapter *padapter)
return _TRUE;
}
#ifdef CONFIG_LPS_LCLK
void rtw_set_fw_config_32k(PADAPTER padapter, u8 enable)
{
u8 val8 = 0;
u8 cpwm_orig = 0, cpwm_now = 0;
int cnt = 0;
systime start_time;
if (enable){
/* H2C done, enter 32k */
if (val8 == 0) {
/* ser rpwm to enter 32k */
rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &val8);
RTW_INFO("%s: read rpwm=%02x\n", __FUNCTION__, val8);
val8 += 0x80;
val8 |= BIT(0);
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&val8));
RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, val8);
adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
cnt = val8 = 0;
do {
val8 = rtw_read8(padapter, REG_CR);
cnt++;
RTW_INFO("%s polling 0x100=0x%x, cnt=%d\n",
__func__, val8, cnt);
RTW_INFO("%s 0x08:%02x, 0x03:%02x\n",
__func__,
rtw_read8(padapter, 0x08),
rtw_read8(padapter, 0x03));
rtw_mdelay_os(10);
} while (cnt < 20 && (val8 != 0xEA));
}
} else {
/* for polling cpwm */
cpwm_orig = 0;
rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
/* ser rpwm */
rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &val8);
val8 += 0x80;
val8 |= BIT(6);
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&val8));
RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, val8);
adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
/* do polling cpwm */
start_time = rtw_get_current_time();
do {
rtw_mdelay_os(1);
rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
if ((cpwm_orig ^ cpwm_now) & 0x80)
break;
if (rtw_get_passing_time_ms(start_time) > 100) {
RTW_INFO("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __FUNCTION__);
break;
}
} while (1);
}
}
#endif
#if defined(CONFIG_FWLPS_IN_IPS)
void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable)
{
@@ -785,67 +852,15 @@ void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable)
__func__, val8, cnt);
rtw_mdelay_os(10);
} while (cnt < 100 && (val8 != 0));
#ifdef CONFIG_LPS_LCLK
/* H2C done, enter 32k */
if (val8 == 0) {
/* ser rpwm to enter 32k */
rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &val8);
RTW_INFO("%s: read rpwm=%02x\n", __FUNCTION__, val8);
val8 += 0x80;
val8 |= BIT(0);
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&val8));
RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, val8);
adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
cnt = val8 = 0;
if (parm[1] == 0 || parm[2] == 0) {
do {
val8 = rtw_read8(padapter, REG_CR);
cnt++;
RTW_INFO("%s polling 0x100=0x%x, cnt=%d\n",
__func__, val8, cnt);
RTW_INFO("%s 0x08:%02x, 0x03:%02x\n",
__func__,
rtw_read8(padapter, 0x08),
rtw_read8(padapter, 0x03));
rtw_mdelay_os(10);
} while (cnt < 20 && (val8 != 0xEA));
}
}
#if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_PNO_SUPPORT)
rtw_set_fw_config_32k(padapter, enable);
#endif
} else {
/* Leave IPS */
RTW_INFO("%s: Leaving IPS in FWLPS state\n", __func__);
#ifdef CONFIG_LPS_LCLK
/* for polling cpwm */
cpwm_orig = 0;
rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
/* ser rpwm */
rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &val8);
val8 += 0x80;
val8 |= BIT(6);
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&val8));
RTW_INFO("%s: write rpwm=%02x\n", __FUNCTION__, val8);
adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
/* do polling cpwm */
start_time = rtw_get_current_time();
do {
rtw_mdelay_os(1);
rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
if ((cpwm_orig ^ cpwm_now) & 0x80)
break;
if (rtw_get_passing_time_ms(start_time) > 100) {
RTW_INFO("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __FUNCTION__);
break;
}
} while (1);
#if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_PNO_SUPPORT)
rtw_set_fw_config_32k(padapter, enable);
#endif
parm[0] = 0x0;
parm[1] = 0x0;
@@ -859,6 +874,23 @@ void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable)
}
#endif /* CONFIG_PNO_SUPPORT */
void rtw_leave_lps_and_chk(_adapter *padapter, u8 ps_mode)
{
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
#ifdef CONFIG_LPS_ACK
_enter_critical_mutex(&pwrpriv->lps_ack_mutex, NULL);
rtw_sctx_init(&pwrpriv->lps_ack_sctx, 100);
#endif /* CONFIG_LPS_ACK */
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode));
#ifdef CONFIG_LPS_ACK
_exit_critical_mutex(&pwrpriv->lps_ack_mutex, NULL);
#endif /* CONFIG_LPS_ACK */
}
void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg)
{
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
@@ -1002,9 +1034,7 @@ void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode));
#endif /* CONFIG_WOWLAN */
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode));
rtw_leave_lps_and_chk(padapter, ps_mode);
#ifdef CONFIG_LPS_PG
if (pwrpriv->lps_level == LPS_PG) {
@@ -1339,7 +1369,7 @@ void LeaveAllPowerSaveModeDirect(PADAPTER Adapter)
} else
#endif
{
#if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_RTL8188E)
#if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_RTL8188E) || defined(CONFIG_PNO_SUPPORT)
#ifdef CONFIG_IPS
if (_FALSE == ips_leave(pri_padapter))
RTW_INFO("======> ips_leave fail.............\n");
@@ -2255,7 +2285,10 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter)
rtw_hal_set_hwreg(padapter, HW_VAR_LPS_POFF_INIT, 0);
#endif
#ifdef CONFIG_LPS_ACK
_rtw_mutex_init(&pwrctrlpriv->lps_ack_mutex);
pwrctrlpriv->lps_ack_status = -1;
#endif /* CONFIG_LPS_ACK */
}
@@ -2315,6 +2348,9 @@ void rtw_free_pwrctrl_priv(PADAPTER adapter)
_free_pwrlock(&pwrctrlpriv->lock);
_free_pwrlock(&pwrctrlpriv->check_32k_lock);
#ifdef CONFIG_LPS_ACK
_rtw_mutex_free(&pwrctrlpriv->lps_ack_mutex);
#endif /* CONFIG_LPS_ACK */
}
#ifdef CONFIG_RESUME_IN_WORKQUEUE

View File

@@ -2461,8 +2461,6 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
u16 capability;
unsigned char *pos;
struct rtw_ieee802_11_elems elems;
struct rtw_ieee80211_ht_cap *pht_cap = NULL;
struct HT_info_element *pht_info = NULL;
_rtw_memset(recv_beacon, 0, sizeof(*recv_beacon));
@@ -2475,34 +2473,48 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed)
return _FALSE;
/* check bw and channel offset */
if (elems.ht_capabilities) {
if (elems.ht_capabilities_len != sizeof(*pht_cap))
if (elems.ht_capabilities_len != 26)
return _FALSE;
pht_cap = (struct rtw_ieee80211_ht_cap *) elems.ht_capabilities;
recv_beacon->ht_cap_info = pht_cap->cap_info;
}
if (elems.ht_operation) {
if (elems.ht_operation_len != sizeof(*pht_info))
if (elems.ht_operation_len != 22)
return _FALSE;
pht_info = (struct HT_info_element *) elems.ht_operation;
recv_beacon->ht_info_infos_0_sco = pht_info->infos[0] & 0x03;
}
/* Checking for channel */
if (elems.ds_params && elems.ds_params_len == sizeof(recv_beacon->bcn_channel))
_rtw_memcpy(&recv_beacon->bcn_channel, elems.ds_params,
sizeof(recv_beacon->bcn_channel));
else if (pht_info)
/* In 5G, some ap do not have DSSET IE checking HT info for channel */
recv_beacon->bcn_channel = pht_info->primary_channel;
else {
if (elems.vht_capabilities) {
if (elems.vht_capabilities_len != 12)
return _FALSE;
}
if (elems.vht_operation) {
if (elems.vht_operation_len != 5)
return _FALSE;
}
if (rtw_ies_get_supported_rate(pos, left, recv_beacon->rate_set, &recv_beacon->rate_num) == _FAIL)
return _FALSE;
if (cckratesonly_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
recv_beacon->proto_cap |= PROTO_CAP_11B;
else if (cckrates_included(recv_beacon->rate_set, recv_beacon->rate_num) == _TRUE)
recv_beacon->proto_cap |= PROTO_CAP_11B | PROTO_CAP_11G;
else
recv_beacon->proto_cap |= PROTO_CAP_11G;
if (elems.ht_capabilities && elems.ht_operation)
recv_beacon->proto_cap |= PROTO_CAP_11N;
if (elems.vht_capabilities && elems.vht_operation)
recv_beacon->proto_cap |= PROTO_CAP_11AC;
/* check bw and channel offset */
rtw_ies_get_chbw(pos, left, &recv_beacon->ch, &recv_beacon->bw, &recv_beacon->offset, 1, 1);
if (!recv_beacon->ch) {
/* we don't find channel IE, so don't check it */
/* RTW_INFO("Oops: %s we don't find channel IE, so don't check it\n", __func__); */
recv_beacon->bcn_channel = Adapter->mlmeextpriv.cur_channel;
recv_beacon->ch = Adapter->mlmeextpriv.cur_channel;
}
/* checking SSID */
@@ -2512,22 +2524,21 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
_rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len);
recv_beacon->ssid_len = elems.ssid_len;
} else
; /* means hidden ssid */
}
/* checking RSN first */
if (elems.rsn_ie && elems.rsn_ie_len) {
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2;
rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
&recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
&recv_beacon->is_8021x, NULL);
&recv_beacon->akm, NULL);
}
/* checking WPA secon */
else if (elems.wpa_ie && elems.wpa_ie_len) {
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA;
rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2,
&recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
&recv_beacon->is_8021x);
&recv_beacon->akm);
} else if (capability & BIT(4))
recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP;
@@ -2543,61 +2554,48 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
return _TRUE;
}
void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon)
void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon)
{
u8 ssid[IW_ESSID_MAX_SIZE + 1];
_rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len);
ssid[recv_beacon->ssid_len] = '\0';
RTW_INFO("%s: ssid = %s\n", __func__, ssid);
RTW_INFO("%s: channel = %d\n", __func__, recv_beacon->bcn_channel);
RTW_INFO("%s: ht_cap = 0x%04x\n", __func__, recv_beacon->ht_cap_info);
RTW_INFO("%s: ht_info_infos_0_sco = 0x%02x\n", __func__, recv_beacon->ht_info_infos_0_sco);
RTW_INFO("%s: sec=%d, group = %x, pair = %x, 8021X = %x\n", __func__,
recv_beacon->encryp_protocol, recv_beacon->group_cipher,
recv_beacon->pairwise_cipher, recv_beacon->is_8021x);
RTW_PRINT_SEL(sel, "ssid = %s (len = %u)\n", ssid, recv_beacon->ssid_len);
RTW_PRINT_SEL(sel, "ch = %u,%u,%u\n"
, recv_beacon->ch, recv_beacon->bw, recv_beacon->offset);
RTW_PRINT_SEL(sel, "proto_cap = 0x%02x\n", recv_beacon->proto_cap);
RTW_MAP_DUMP_SEL(sel, "rate_set = "
, recv_beacon->rate_set, recv_beacon->rate_num);
RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n"
, recv_beacon->encryp_protocol, recv_beacon->group_cipher
, recv_beacon->pairwise_cipher, recv_beacon->akm);
}
#define DBG_BCN_CNT
int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
{
unsigned int len;
#define BCNKEY_VERIFY_PROTO_CAP 0
#define BCNKEY_VERIFY_WHOLE_RATE_SET 0
u8 *pbssid = GetAddr3Ptr(pframe);
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys;
struct beacon_keys recv_beacon;
int ret = 0;
if (is_client_associated_to_ap(Adapter) == _FALSE)
return _TRUE;
len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
if (len > MAX_IE_SZ) {
RTW_WARN("%s IE too long for survey event\n", __func__);
return _FAIL;
}
if (_rtw_memcmp(cur_network->network.MacAddress, pbssid, 6) == _FALSE) {
RTW_WARN("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT,
MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress));
return _TRUE;
}
goto exit_success;
if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE)
return _TRUE; /* parsing failed => broken IE */
goto exit_success; /* parsing failed => broken IE */
#ifdef DBG_RX_BCN
rtw_debug_bcn(Adapter, pframe, packet_len);
#endif
/* don't care hidden ssid, use current beacon ssid directly */
if (recv_beacon.ssid_len == 0) {
_rtw_memcpy(recv_beacon.ssid, pmlmepriv->cur_beacon_keys.ssid,
pmlmepriv->cur_beacon_keys.ssid_len);
recv_beacon.ssid_len = pmlmepriv->cur_beacon_keys.ssid_len;
}
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _TRUE)
if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE)
pmlmepriv->new_beacon_cnts = 0;
else if ((pmlmepriv->new_beacon_cnts == 0) ||
_rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) {
@@ -2605,11 +2603,11 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
if (pmlmepriv->new_beacon_cnts == 0) {
RTW_ERR("%s: cur beacon key\n", __func__);
RTW_DBG_EXPR(rtw_dump_bcn_keys(&pmlmepriv->cur_beacon_keys));
RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon));
}
RTW_DBG("%s: new beacon key\n", __func__);
RTW_DBG_EXPR(rtw_dump_bcn_keys(&recv_beacon));
RTW_DBG_EXPR(rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon));
_rtw_memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon));
pmlmepriv->new_beacon_cnts = 1;
@@ -2621,45 +2619,47 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
/* if counter >= max, it means beacon is changed really */
if (pmlmepriv->new_beacon_cnts >= new_bcn_max)
#else
if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _FALSE)
if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _FALSE)
#endif
{
/* check bw mode change only? */
pmlmepriv->cur_beacon_keys.ht_cap_info = recv_beacon.ht_cap_info;
pmlmepriv->cur_beacon_keys.ht_info_infos_0_sco = recv_beacon.ht_info_infos_0_sco;
if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys,
sizeof(recv_beacon)) == _FALSE) {
/* beacon is changed, have to do disconnect/connect */
RTW_WARN("%s: new beacon occur!!\n", __func__);
#ifdef DBG_BCN_CNT
rtw_dump_bcn_keys(&recv_beacon);
#endif
return _FAIL;
struct beacon_keys tmp_beacon;
RTW_INFO(FUNC_ADPT_FMT" new beacon occur!!\n", FUNC_ADPT_ARG(Adapter));
RTW_INFO(FUNC_ADPT_FMT" cur beacon key:\n", FUNC_ADPT_ARG(Adapter));
rtw_dump_bcn_keys(RTW_DBGDUMP, cur_beacon);
RTW_INFO(FUNC_ADPT_FMT" new beacon key:\n", FUNC_ADPT_ARG(Adapter));
rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon);
if (!rtw_is_chbw_grouped(cur_beacon->ch, cur_beacon->bw, cur_beacon->offset
, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset))
goto exit;
_rtw_memcpy(&tmp_beacon, cur_beacon, sizeof(tmp_beacon));
/* check fields excluding below */
tmp_beacon.ch = recv_beacon.ch;
tmp_beacon.bw = recv_beacon.bw;
tmp_beacon.offset = recv_beacon.offset;
if (!BCNKEY_VERIFY_PROTO_CAP)
tmp_beacon.proto_cap = recv_beacon.proto_cap;
if (!BCNKEY_VERIFY_WHOLE_RATE_SET) {
tmp_beacon.rate_num = recv_beacon.rate_num;
_rtw_memcpy(tmp_beacon.rate_set, recv_beacon.rate_set, 12);
}
#ifdef DBG_BCN_CNT
RTW_INFO("%s bw mode change\n", __func__);
RTW_INFO("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
cur_network->BcnInfo.ht_cap_info,
cur_network->BcnInfo.ht_info_infos_0);
#endif
if (_rtw_memcmp(&tmp_beacon, &recv_beacon, sizeof(recv_beacon)) == _FALSE)
goto exit;
cur_network->BcnInfo.ht_cap_info = recv_beacon.ht_cap_info;
cur_network->BcnInfo.ht_info_infos_0 =
(cur_network->BcnInfo.ht_info_infos_0 & (~0x03)) |
recv_beacon.ht_info_infos_0_sco;
#ifdef DBG_BCN_CNT
RTW_INFO("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
cur_network->BcnInfo.ht_cap_info,
cur_network->BcnInfo.ht_info_infos_0);
#endif
_rtw_memcpy(&pmlmepriv->cur_beacon_keys, &recv_beacon, sizeof(recv_beacon));
_rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon));
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
pmlmepriv->new_beacon_cnts = 0;
#endif
}
return _SUCCESS;
exit_success:
ret = 1;
exit:
return ret;
}
void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)