Update to 5.13.1 from upstream

This commit is contained in:
Rin Cat (鈴猫)
2021-12-04 07:42:09 -05:00
parent aab1daf818
commit c0e109d401
352 changed files with 50307 additions and 18938 deletions

View File

@@ -143,7 +143,7 @@ exit:
return ret;
}
int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
int _rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b, u8 **a_mconf_ie_r, u8 **b_mconf_ie_r)
{
int ret = 0;
u8 *a_mconf_ie, *b_mconf_ie;
@@ -154,11 +154,16 @@ int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
a_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(a), WLAN_EID_MESH_CONFIG, &a_mconf_ie_len, BSS_EX_TLV_IES_LEN(a));
if (!a_mconf_ie || a_mconf_ie_len != 7)
goto exit;
if (a_mconf_ie_r)
*a_mconf_ie_r = a_mconf_ie;
if (b->InfrastructureMode != Ndis802_11_mesh)
goto exit;
b_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(b), WLAN_EID_MESH_CONFIG, &b_mconf_ie_len, BSS_EX_TLV_IES_LEN(b));
if (!b_mconf_ie || b_mconf_ie_len != 7)
goto exit;
if (b_mconf_ie_r)
*b_mconf_ie_r = b_mconf_ie;
if (a->mesh_id.SsidLength != b->mesh_id.SsidLength
|| _rtw_memcmp(a->mesh_id.Ssid, b->mesh_id.Ssid, a->mesh_id.SsidLength) == _FALSE)
@@ -173,25 +178,28 @@ exit:
return ret;
}
int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer)
int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
{
return _rtw_bss_is_same_mbss(a, b, NULL, NULL);
}
int rtw_bss_is_candidate_mesh_peer(_adapter *adapter, WLAN_BSSID_EX *target, u8 ch, u8 add_peer)
{
int ret = 0;
u8 *mconf_ie;
sint mconf_ie_len;
WLAN_BSSID_EX *self = &adapter->mlmepriv.cur_network.network;
u8 *s_mconf_ie, *t_mconf_ie;
u8 auth_pid;
int i, j;
if (!rtw_bss_is_same_mbss(self, target))
goto exit;
if (ch && self->Configuration.DSConfig != target->Configuration.DSConfig)
goto exit;
if (!_rtw_bss_is_same_mbss(self, target, &s_mconf_ie, &t_mconf_ie))
goto exit;
if (add_peer) {
/* Accept additional mesh peerings */
mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(target), WLAN_EID_MESH_CONFIG, &mconf_ie_len, BSS_EX_TLV_IES_LEN(target));
if (!mconf_ie || mconf_ie_len != 7)
goto exit;
if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mconf_ie + 2) == 0)
if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(t_mconf_ie + 2) == 0)
goto exit;
}
@@ -223,10 +231,38 @@ int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u
}
}
/* BSSBasicMCSSet */
/* 802.1X connected to AS ? */
auth_pid = GET_MESH_CONF_ELE_AUTH_PROTO_ID(s_mconf_ie + 2);
if (auth_pid && auth_pid <= 2) {
struct security_priv *sec = &adapter->securitypriv;
u8 *rsn_ie;
int rsn_ie_len;
int group_cipher = 0, pairwise_cipher = 0, gmcs = 0;
u8 mfp_opt = MFP_NO;
/* 802.1X connected to AS ? */
/* RSN */
rsn_ie = rtw_get_wpa2_ie(BSS_EX_TLV_IES(target), &rsn_ie_len, BSS_EX_TLV_IES_LEN(target));
if (!rsn_ie || rsn_ie_len == 0)
goto exit;
if (rtw_parse_wpa2_ie(rsn_ie, rsn_ie_len + 2, &group_cipher, &pairwise_cipher, &gmcs, NULL, &mfp_opt, NULL) != _SUCCESS)
goto exit;
if ((sec->mfp_opt == MFP_REQUIRED && mfp_opt < MFP_OPTIONAL)
|| (mfp_opt == MFP_REQUIRED && sec->mfp_opt < MFP_OPTIONAL))
goto exit;
if (!(sec->wpa2_group_cipher & group_cipher))
goto exit;
if (!(sec->wpa2_pairwise_cipher & pairwise_cipher))
goto exit;
#ifdef CONFIG_IEEE80211W
if ((sec->mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL)
&& security_type_bip_to_gmcs(sec->dot11wCipher) != gmcs)
goto exit;
#endif
}
ret = 1;
@@ -339,7 +375,7 @@ static bool rtw_mesh_acnode_candidate_exist(_adapter *adapter)
#if CONFIG_RTW_MACADDR_ACL
&& rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
#endif
&& rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
&& rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 1, 1)
#if CONFIG_RTW_MESH_PEER_BLACKLIST
&& !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
#endif
@@ -679,7 +715,7 @@ void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scann
if (rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms
|| (mcfg->rssi_threshold && mcfg->rssi_threshold > scanned->network.Rssi)
|| !rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
|| !rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 1, 1)
#if CONFIG_RTW_MACADDR_ACL
|| rtw_access_ctrl(adapter, scanned->network.MacAddress) == _FALSE
#endif
@@ -760,7 +796,7 @@ void rtw_mesh_peer_status_chk(_adapter *adapter)
flush = 0;
/* remove unsuitable peer */
if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 0)
if (!rtw_bss_is_candidate_mesh_peer(adapter, &plink->scanned->network, 1, 0)
#if CONFIG_RTW_MACADDR_ACL
|| rtw_access_ctrl(adapter, plink->addr) == _FALSE
#endif
@@ -809,6 +845,10 @@ flush_add:
if (flush) {
rtw_list_delete(&sta->asoc_list);
stapriv->asoc_list_cnt--;
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
if (sta->tbtx_enable)
stapriv->tbtx_asoc_list_cnt--;
#endif
STA_SET_MESH_PLINK(sta, NULL);
stainfo_offset = rtw_stainfo_offset(stapriv, sta);
@@ -828,7 +868,7 @@ flush_add:
continue;
/* remove unsuitable peer */
if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 1)
if (!rtw_bss_is_candidate_mesh_peer(adapter, &plink->scanned->network, 1, 1)
#if CONFIG_RTW_MACADDR_ACL
|| rtw_access_ctrl(adapter, plink->addr) == _FALSE
#endif
@@ -901,7 +941,7 @@ static u8 rtw_mesh_offch_cto_mgate_required(_adapter *adapter)
#if CONFIG_RTW_MACADDR_ACL
&& rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
#endif
&& rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
&& rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 1, 1)
&& rtw_bss_is_cto_mgate(&scanned->network)
#if CONFIG_RTW_MESH_PEER_BLACKLIST
&& !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
@@ -988,7 +1028,7 @@ u8 rtw_mesh_select_operating_ch(_adapter *adapter)
#if CONFIG_RTW_MACADDR_ACL
&& rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
#endif
&& rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 0, 0)
&& rtw_bss_is_candidate_mesh_peer(adapter, &scanned->network, 0, 0)
#if CONFIG_RTW_MESH_PEER_BLACKLIST
&& !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
#endif
@@ -999,7 +1039,7 @@ u8 rtw_mesh_select_operating_ch(_adapter *adapter)
int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scanned->network.Configuration.DSConfig);
if (ch_set_idx >= 0
&& rfctl->channel_set[ch_set_idx].ScanType != SCAN_PASSIVE
&& !(rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR)
&& !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx])
) {
u8 nop, accept;
@@ -1074,6 +1114,11 @@ void dump_mesh_networks(void *sel, _adapter *adapter)
#endif
u8 *mesh_conf_ie;
sint mesh_conf_ie_len;
u8 auth_pid;
u8 *rsn_ie;
int rsn_ie_len;
int gcs, pcs, gmcs;
u8 mfp_opt;
struct wlan_network **mesh_networks;
u8 mesh_network_cnt = 0;
int i;
@@ -1103,13 +1148,54 @@ void dump_mesh_networks(void *sel, _adapter *adapter)
exit_critical_bh(&queue->lock);
RTW_PRINT_SEL(sel, " %-17s %-3s %-4s %-5s %-32s %-3s %-3s %-3s"
RTW_PRINT_SEL(sel, " %-17s %-3s %-4s %-5s %-32s %-10s"
" %-3s %-3s %-4s"
" %-3s %-3s %-3s"
NSTATE_TITLE_FMT_ACN
"\n"
, "bssid", "ch", "rssi", "age", "mesh_id", "nop", "fwd", "cto"
, "bssid", "ch", "rssi", "age", "mesh_id", "P M C S A "
, "pcs", "gcs", "gmcs"
, "nop", "fwd", "cto"
NSTATE_TITLE_ARG_ACN
);
if (MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)) {
network = &mlme->cur_network;
mesh_conf_ie = rtw_get_ie(BSS_EX_TLV_IES(&network->network), WLAN_EID_MESH_CONFIG
, &mesh_conf_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
if (mesh_conf_ie && mesh_conf_ie_len == 7) {
gcs = pcs = gmcs = 0;
mfp_opt = MFP_NO;
auth_pid = GET_MESH_CONF_ELE_AUTH_PROTO_ID(mesh_conf_ie + 2);
if (auth_pid && auth_pid <= 2) {
rsn_ie = rtw_get_wpa2_ie(BSS_EX_TLV_IES(&network->network)
, &rsn_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
if (rsn_ie && rsn_ie_len)
rtw_parse_wpa2_ie(rsn_ie, rsn_ie_len + 2, &gcs, &pcs, &gmcs, NULL, &mfp_opt, NULL);
}
RTW_PRINT_SEL(sel, "* "MAC_FMT" %3d %-32s %2x%2x%2x%2x%2x"
" %03x %03x %c%03x"
" %c%2u %3u %c%c "
"\n"
, MAC_ARG(network->network.MacAddress)
, network->network.Configuration.DSConfig
, network->network.mesh_id.Ssid
, GET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_SYNC_METHOD_ID(mesh_conf_ie + 2)
, auth_pid
, pcs, gcs, mfp_opt == MFP_REQUIRED ? 'R' : (mfp_opt == MFP_OPTIONAL ? 'C' : ' ')
, mfp_opt >= MFP_OPTIONAL ? gmcs : 0
, GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mesh_conf_ie + 2) ? '+' : ' '
, GET_MESH_CONF_ELE_NUM_OF_PEERINGS(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_FORWARDING(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_CTO_MGATE(mesh_conf_ie + 2) ? 'G' : ' '
, GET_MESH_CONF_ELE_CTO_AS(mesh_conf_ie + 2) ? 'A' : ' '
);
}
}
for (i = 0; i < mesh_network_cnt; i++) {
network = mesh_networks[i];
@@ -1121,6 +1207,14 @@ void dump_mesh_networks(void *sel, _adapter *adapter)
if (!mesh_conf_ie || mesh_conf_ie_len != 7)
continue;
gcs = pcs = gmcs = 0;
mfp_opt = MFP_NO;
auth_pid = GET_MESH_CONF_ELE_AUTH_PROTO_ID(mesh_conf_ie + 2);
if (auth_pid && auth_pid <= 2) {
rsn_ie = rtw_get_wpa2_ie(BSS_EX_TLV_IES(&network->network), &rsn_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
if (rsn_ie && rsn_ie_len)
rtw_parse_wpa2_ie(rsn_ie, rsn_ie_len + 2, &gcs, &pcs, &gmcs, NULL, &mfp_opt, NULL);
}
age_ms = rtw_get_passing_time_ms(network->last_scanned);
#if CONFIG_RTW_MESH_ACNODE_PREVENT
if (network->acnode_stime == 0)
@@ -1142,13 +1236,15 @@ void dump_mesh_networks(void *sel, _adapter *adapter)
blocked = 1;
else if (plink)
;
else if (rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &network->network, 0, 1))
else if (rtw_bss_is_candidate_mesh_peer(adapter, &network->network, 0, 1))
candidate = 1;
else if (rtw_bss_is_same_mbss(&mlme->cur_network.network, &network->network))
same_mbss = 1;
}
RTW_PRINT_SEL(sel, "%c "MAC_FMT" %3d %4ld %5d %-32s %c%2u %3u %c%c "
RTW_PRINT_SEL(sel, "%c "MAC_FMT" %3d %4ld %5d %-32s %2x%2x%2x%2x%2x"
" %03x %03x %c%03x"
" %c%2u %3u %c%c "
NSTATE_VALUE_FMT_ACN
"\n"
, established ? 'E' : (blocked ? 'B' : (plink ? 'N' : (candidate ? 'C' : (same_mbss ? 'S' : ' '))))
@@ -1157,6 +1253,13 @@ void dump_mesh_networks(void *sel, _adapter *adapter)
, network->network.Rssi
, age_ms < 99999 ? age_ms : 99999
, network->network.mesh_id.Ssid
, GET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_SYNC_METHOD_ID(mesh_conf_ie + 2)
, auth_pid
, pcs, gcs, mfp_opt == MFP_REQUIRED ? 'R' : (mfp_opt == MFP_OPTIONAL ? 'C' : ' ')
, mfp_opt >= MFP_OPTIONAL ? gmcs : 0
, GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mesh_conf_ie + 2) ? '+' : ' '
, GET_MESH_CONF_ELE_NUM_OF_PEERINGS(mesh_conf_ie + 2)
, GET_MESH_CONF_ELE_FORWARDING(mesh_conf_ie + 2)
@@ -1205,7 +1308,7 @@ static int rtw_mpm_ampe_dec(_adapter *adapter, struct mesh_plink_ent *plink
_rtw_memcpy(iv_crypt, mic_ie + 2, iv_crypt_len);
verify_ret = aes_siv_decrypt(plink->aek, iv_crypt, iv_crypt_len
verify_ret = rtw_aes_siv_decrypt(plink->aek, 32, iv_crypt, iv_crypt_len
, 3, aad, aad_len, ampe_buf);
rtw_mfree(iv_crypt, iv_crypt_len);
@@ -1216,7 +1319,7 @@ static int rtw_mpm_ampe_dec(_adapter *adapter, struct mesh_plink_ent *plink
} else if (*ampe_buf != WLAN_EID_AMPE) {
RTW_WARN("plaintext is not AMPE IE\n");
goto exit;
} else if (AES_BLOCK_SIZE + 2 + *(ampe_buf + 1) > iv_crypt_len) {
} else if ( 16 /* AES_BLOCK_SIZE*/ + 2 + *(ampe_buf + 1) > iv_crypt_len) {
RTW_WARN("plaintext AMPE IE length is not valid\n");
goto exit;
}
@@ -1251,7 +1354,7 @@ static int rtw_mpm_ampe_enc(_adapter *adapter, struct mesh_plink_ent *plink
_rtw_memcpy(ampe_ie, ampe_buf, ampe_ie_len);
protect_ret = aes_siv_encrypt(plink->aek, ampe_ie, ampe_ie_len
protect_ret = rtw_aes_siv_encrypt(plink->aek, 32, ampe_ie, ampe_ie_len
, 3, aad, aad_len, mic_ie + 2);
rtw_mfree(ampe_ie, ampe_ie_len);
@@ -1296,7 +1399,7 @@ static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *pli
/* decode */
if (mic_ie) {
ampe_buf_len = flen - (mic_ie + 2 + AES_BLOCK_SIZE - fhead);
ampe_buf_len = flen - (mic_ie + 2 + 16 /* AES_BLOCK_SIZE */ - fhead);
ampe_buf = rtw_malloc(ampe_buf_len);
if (!ampe_buf)
goto exit;
@@ -1340,7 +1443,7 @@ static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *pli
}
new_len += mpm_ielen + 2;
if (mic_ie)
new_len += AES_BLOCK_SIZE + 2 + ampe_buf_len;
new_len += 16 /* AES_BLOCK_SIZE*/ + 2 + ampe_buf_len;
/* alloc new frame */
new_buf = rtw_malloc(new_len);
@@ -1385,7 +1488,7 @@ static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *pli
if (mic_ie) {
new_mic_ie = fpos;
*fpos++ = WLAN_EID_MIC;
*fpos++ = AES_BLOCK_SIZE;
*fpos++ = 16 /* AES_BLOCK_SIZE */;
}
#ifdef CONFIG_RTW_MESH_AEK
@@ -1585,7 +1688,7 @@ static int rtw_mpm_check_frames(_adapter *adapter, u8 action, const u8 **buf, si
mic_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
, WLAN_EID_MIC, &mic_ielen
, flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
if (!mic_ie || mic_ielen != AES_BLOCK_SIZE)
if (!mic_ie || mic_ielen != 16 /* AES_BLOCK_SIZE */)
goto exit;
}
@@ -1661,6 +1764,10 @@ bypass_sync_bss:
if (!rtw_is_list_empty(&sac->asoc_list)) {
rtw_list_delete(&sac->asoc_list);
stapriv->asoc_list_cnt--;
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
if (sac->tbtx_enable)
stapriv->tbtx_asoc_list_cnt--;
#endif
STA_SET_MESH_PLINK(sac, NULL);
}
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
@@ -2357,7 +2464,7 @@ void dump_mesh_plink_ctl(void *sel, _adapter *adapter)
}
/* this function is called with plink_ctl being locked */
int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta)
static int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta)
{
#ifndef DBG_RTW_MESH_PEER_ESTABLISH
#define DBG_RTW_MESH_PEER_ESTABLISH 0
@@ -2372,7 +2479,11 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str
struct rtw_ieee802_11_elems elems;
_irqL irqL;
int i;
u16 status = 0;
int ret = _FAIL;
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
u8 sta_tbtx_enable = _FALSE;
#endif
if (!plink->rx_conf_ies || !plink->rx_conf_ies_len) {
RTW_INFO(FUNC_ADPT_FMT" no rx confirm from sta "MAC_FMT"\n"
@@ -2424,11 +2535,15 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str
rtw_ap_parse_sta_capability(adapter, sta, plink->rx_conf_ies);
if (rtw_ap_parse_sta_supported_rates(adapter, sta, tlv_ies, tlv_ieslen) != _STATS_SUCCESSFUL_)
status = rtw_ap_parse_sta_supported_rates(adapter, sta, tlv_ies, tlv_ieslen);
if (status != _STATS_SUCCESSFUL_)
goto exit;
if (rtw_ap_parse_sta_security_ie(adapter, sta, &elems) != _STATS_SUCCESSFUL_)
status = rtw_ap_parse_sta_security_ie(adapter, sta, &elems);
if (status != _STATS_SUCCESSFUL_) {
RTW_INFO(FUNC_ADPT_FMT" security check fail, status=%u\n", FUNC_ADPT_ARG(adapter), status);
goto exit;
}
rtw_ap_parse_sta_wmm_ie(adapter, sta, tlv_ies, tlv_ieslen);
#ifdef CONFIG_RTS_FULL_BW
@@ -2436,6 +2551,14 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str
rtw_parse_sta_vendor_ie_8812(adapter, sta, tlv_ies, tlv_ieslen);
#endif/*CONFIG_RTS_FULL_BW*/
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
if (elems.tbtx_cap && elems.tbtx_cap_len != 0) {
if(rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len)) {
sta_tbtx_enable = _TRUE;
}
}
#endif
rtw_ap_parse_sta_ht_ie(adapter, sta, &elems);
rtw_ap_parse_sta_vht_ie(adapter, sta, &elems);
@@ -2467,6 +2590,12 @@ int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, str
/* sta->expire_to = mcfg->plink_timeout / 2; */
rtw_list_insert_tail(&sta->asoc_list, &stapriv->asoc_list);
stapriv->asoc_list_cnt++;
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
if (sta_tbtx_enable) {
sta->tbtx_enable = _TRUE;
stapriv->tbtx_asoc_list_cnt++;
}
#endif
}
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
@@ -2480,6 +2609,167 @@ exit:
return ret;
}
int rtw_mesh_set_plink_state(_adapter *adapter, const u8 *mac, u8 plink_state)
{
struct rtw_mesh_info *minfo = &adapter->mesh_info;
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
struct mesh_plink_ent *plink = NULL;
_irqL irqL2;
struct sta_priv *stapriv = &adapter->stapriv;
struct sta_info *sta = NULL;
_irqL irqL;
struct sta_info *del_sta = NULL;
int ret = _SUCCESS;
_enter_critical_bh(&(plink_ctl->lock), &irqL2);
plink = _rtw_mesh_plink_get(adapter, mac);
if (!plink) {
ret = _FAIL;
goto release_plink_ctl;
}
plink->plink_state = plink_state;
#if CONFIG_RTW_MESH_ACNODE_PREVENT
if (plink_state == RTW_MESH_PLINK_OPN_SNT) {
if (rtw_mesh_scanned_is_acnode_confirmed(adapter, plink->scanned)
&& rtw_mesh_acnode_prevent_allow_sacrifice(adapter)
) {
struct sta_info *sac = rtw_mesh_acnode_prevent_pick_sacrifice(adapter);
if (sac) {
del_sta = sac;
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
if (!rtw_is_list_empty(&del_sta->asoc_list)) {
rtw_list_delete(&del_sta->asoc_list);
stapriv->asoc_list_cnt--;
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
if (del_sta->tbtx_enable)
stapriv->tbtx_asoc_list_cnt--;
#endif
STA_SET_MESH_PLINK(del_sta, NULL);
}
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
RTW_INFO(FUNC_ADPT_FMT" sacrifice "MAC_FMT" for acnode\n"
, FUNC_ADPT_ARG(adapter), MAC_ARG(del_sta->cmn.mac_addr));
}
}
} else
#endif
if (plink_state == RTW_MESH_PLINK_OPN_RCVD
|| plink_state == RTW_MESH_PLINK_CNF_RCVD
|| plink_state == RTW_MESH_PLINK_ESTAB
) {
sta = rtw_get_stainfo(stapriv, mac);
if (!sta) {
sta = rtw_alloc_stainfo(stapriv, mac);
if (!sta)
goto release_plink_ctl;
}
if (plink_state == RTW_MESH_PLINK_ESTAB) {
if (rtw_mesh_peer_establish(adapter, plink, sta) != _SUCCESS) {
del_sta = sta;
ret = _FAIL;
goto release_plink_ctl;
}
}
}
else if (plink_state == RTW_MESH_PLINK_HOLDING) {
del_sta = rtw_get_stainfo(stapriv, mac);
if (!del_sta)
goto release_plink_ctl;
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
if (!rtw_is_list_empty(&del_sta->asoc_list)) {
rtw_list_delete(&del_sta->asoc_list);
stapriv->asoc_list_cnt--;
#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
if (del_sta->tbtx_enable)
stapriv->tbtx_asoc_list_cnt--;
#endif
STA_SET_MESH_PLINK(del_sta, NULL);
}
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
}
release_plink_ctl:
_exit_critical_bh(&(plink_ctl->lock), &irqL2);
if (del_sta) {
u8 sta_addr[ETH_ALEN];
u8 updated = _FALSE;
_rtw_memcpy(sta_addr, del_sta->cmn.mac_addr, ETH_ALEN);
updated = ap_free_sta(adapter, del_sta, 0, 0, 1);
rtw_mesh_expire_peer(stapriv->padapter, sta_addr);
associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
}
return ret;
}
struct mesh_set_plink_cmd_parm {
const u8 *mac;
u8 plink_state;
};
u8 rtw_mesh_set_plink_state_cmd_hdl(_adapter *adapter, u8 *parmbuf)
{
struct mesh_set_plink_cmd_parm *parm = (struct mesh_set_plink_cmd_parm *)parmbuf;
if (rtw_mesh_set_plink_state(adapter, parm->mac, parm->plink_state) == _SUCCESS)
return H2C_SUCCESS;
return H2C_CMD_FAIL;
}
u8 rtw_mesh_set_plink_state_cmd(_adapter *adapter, const u8 *mac, u8 plink_state)
{
struct cmd_obj *cmdobj;
struct mesh_set_plink_cmd_parm *parm;
struct cmd_priv *cmdpriv = &adapter->cmdpriv;
struct submit_ctx sctx;
u8 res = _SUCCESS;
/* prepare cmd parameter */
parm = rtw_zmalloc(sizeof(*parm));
if (parm == NULL) {
res = _FAIL;
goto exit;
}
parm->mac = mac;
parm->plink_state = plink_state;
/* need enqueue, prepare cmd_obj and enqueue */
cmdobj = rtw_zmalloc(sizeof(*cmdobj));
if (cmdobj == NULL) {
res = _FAIL;
rtw_mfree(parm, sizeof(*parm));
goto exit;
}
init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_MESH_PLINK_STATE);
cmdobj->sctx = &sctx;
rtw_sctx_init(&sctx, 2000);
res = rtw_enqueue_cmd(cmdpriv, cmdobj);
if (res == _SUCCESS) {
rtw_sctx_wait(&sctx, __func__);
_enter_critical_mutex(&cmdpriv->sctx_mutex, NULL);
if (sctx.status == RTW_SCTX_SUBMITTED)
cmdobj->sctx = NULL;
_exit_critical_mutex(&cmdpriv->sctx_mutex, NULL);
if (sctx.status != RTW_SCTX_DONE_SUCCESS)
res = _FAIL;
}
exit:
return res;
}
void rtw_mesh_expire_peer_notify(_adapter *adapter, const u8 *peer_addr)
{
u8 null_ssid[2] = {0, 0};
@@ -2511,7 +2801,7 @@ static u8 *rtw_mesh_construct_peer_mesh_close(_adapter *adapter, struct mesh_pli
+ 2 /* category, action */
+ 2 + minfo->mesh_id_len /* mesh id */
+ 2 + 8 + (minfo->mesh_auth_id ? 16 : 0) /* mpm */
+ (minfo->mesh_auth_id ? 2 + AES_BLOCK_SIZE : 0) /* mic */
+ (minfo->mesh_auth_id ? 2 + 16 /* AES_BLOCK_SIZE */ : 0) /* mic */
+ (minfo->mesh_auth_id ? 70 : 0) /* ampe */
;
@@ -2545,7 +2835,7 @@ static u8 *rtw_mesh_construct_peer_mesh_close(_adapter *adapter, struct mesh_pli
int enc_ret;
*pos = WLAN_EID_MIC;
*(pos + 1) = AES_BLOCK_SIZE;
*(pos + 1) = 16 /* AES_BLOCK_SIZE */;
ampe_buf[0] = WLAN_EID_AMPE;
ampe_buf[1] = 68;
@@ -3017,6 +3307,7 @@ void rtw_mesh_cfg_init_peer_sel_policy(struct rtw_mesh_cfg *mcfg)
void rtw_mesh_cfg_init(_adapter *adapter)
{
struct registry_priv *regsty = adapter_to_regsty(adapter);
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS;
@@ -3047,8 +3338,8 @@ void rtw_mesh_cfg_init(_adapter *adapter)
#endif
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
mcfg->b2u_flags_msrc = 0;
mcfg->b2u_flags_mfwd = RTW_MESH_B2U_GA_UCAST;
mcfg->b2u_flags_msrc = regsty->msrc_b2u_flags;
mcfg->b2u_flags_mfwd = regsty->mfwd_b2u_flags;
#endif
}
@@ -3256,7 +3547,7 @@ endlookup:
static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter
, const u8 *da, const u8 *sa, const u8 *mda, const u8 *msa
, u8 ae_need, const u8 *ori_ta, u8 mfwd_ttl
, _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq)
, u16 os_qid, _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq)
{
struct sta_priv *stapriv = &adapter->stapriv;
struct xmit_priv *xmitpriv = &adapter->xmitpriv;
@@ -3292,14 +3583,14 @@ static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter
struct pkt_attrib *attrib;
sta = rtw_get_stainfo_by_offset(stapriv, b2u_sta_id[i]);
if (!(sta->state & _FW_LINKED)
if (!(sta->state & WIFI_ASOC_STATE)
|| _rtw_memcmp(sta->cmn.mac_addr, msa, ETH_ALEN) == _TRUE
|| (ori_ta && _rtw_memcmp(sta->cmn.mac_addr, ori_ta, ETH_ALEN) == _TRUE)
|| is_broadcast_mac_addr(sta->cmn.mac_addr)
|| is_zero_mac_addr(sta->cmn.mac_addr))
continue;
b2uframe = rtw_alloc_xmitframe(xmitpriv);
b2uframe = rtw_alloc_xmitframe(xmitpriv, os_qid);
if (!b2uframe) {
bmc_need = _TRUE;
break;
@@ -3339,7 +3630,7 @@ void dump_mesh_b2u_flags(void *sel, _adapter *adapter)
}
#endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */
int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list)
int rtw_mesh_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list)
{
struct pkt_file pktfile;
struct ethhdr etherhdr;
@@ -3401,7 +3692,7 @@ int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pk
bmc_need = rtw_mesh_data_bmc_to_uc(adapter
, etherhdr.h_dest, etherhdr.h_source
, etherhdr.h_dest, adapter_mac_addr(adapter), ae_need, NULL, 0
, b2u_list, &b2u_num, &b2u_mseq);
, os_qid, b2u_list, &b2u_num, &b2u_mseq);
if (bmc_need == _FALSE) {
res = RTW_BMC_NO_NEED;
goto exit;
@@ -3578,7 +3869,7 @@ int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, s
goto exit;
switch (rattrib->to_fr_ds) {
case 1:
case 2:
if (!IS_MCAST(GetAddr1Ptr(whdr)))
goto exit;
*sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr));
@@ -3666,7 +3957,7 @@ int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe
ae = mctrl->flags & MESH_FLAGS_AE;
mlen = ae_to_mesh_ctrl_len[ae];
switch (rattrib->to_fr_ds) {
case 1:
case 2:
*da = mda;
if (ae == MESH_FLAGS_AE_A4)
*sa = mctrl->eaddr1;
@@ -3776,6 +4067,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
, const u8 *mda, const u8 *msa
, const u8 *da, const u8 *sa
, struct rtw_ieee80211s_hdr *mctrl
, u8 *msdu, enum rtw_rx_llc_hdl llc_hdl
, struct xmit_frame **fwd_frame, _list *b2u_list)
{
_adapter *adapter = rframe->u.hdr.adapter;
@@ -3785,6 +4077,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
struct rtw_mesh_path *mppath;
u8 is_mda_bmc = IS_MCAST(mda);
u8 is_mda_self = !is_mda_bmc && _rtw_memcmp(mda, adapter_mac_addr(adapter), ETH_ALEN);
u16 os_qid;
struct xmit_frame *xframe;
struct pkt_attrib *xattrib;
u8 fwd_ra[ETH_ALEN] = {0};
@@ -4012,6 +4305,8 @@ fwd_chk:
goto exit;
}
os_qid = rtw_os_recv_select_queue(msdu, llc_hdl);
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
_rtw_init_listhead(b2u_list);
#endif
@@ -4025,13 +4320,13 @@ fwd_chk:
) {
bmc_need = rtw_mesh_data_bmc_to_uc(adapter
, da, sa, mda, msa, ae_need, rframe->u.hdr.psta->cmn.mac_addr, mctrl->ttl - 1
, b2u_list, &b2u_num, &fwd_mseq);
, os_qid, b2u_list, &b2u_num, &fwd_mseq);
}
if (bmc_need == _TRUE)
#endif
{
xframe = rtw_alloc_xmitframe(&adapter->xmitpriv);
xframe = rtw_alloc_xmitframe(&adapter->xmitpriv, os_qid);
if (!xframe) {
#ifdef DBG_TX_DROP_FRAME
RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n"

View File

@@ -412,7 +412,7 @@ u8 *rtw_set_ie_mesh_config(u8 *buf, u32 *buf_len
, bool mbca_en, bool tbtt_adj, bool ps_level);
int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer);
int rtw_bss_is_candidate_mesh_peer(_adapter *adapter, WLAN_BSSID_EX *target, u8 ch, u8 add_peer);
void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scanned);
@@ -484,7 +484,8 @@ void rtw_mesh_plink_ctl_init(_adapter *adapter);
void rtw_mesh_plink_ctl_deinit(_adapter *adapter);
void dump_mesh_plink_ctl(void *sel, _adapter *adapter);
int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta);
u8 rtw_mesh_set_plink_state_cmd(_adapter *adapter, const u8 *mac, u8 plink_state);
void _rtw_mesh_expire_peer_ent(_adapter *adapter, struct mesh_plink_ent *plink);
void rtw_mesh_expire_peer(_adapter *adapter, const u8 *peer_addr);
u8 rtw_mesh_ps_annc(_adapter *adapter, u8 ps);
@@ -501,7 +502,7 @@ void rtw_mesh_deinit_mesh_info(_adapter *adapter);
void dump_mesh_b2u_flags(void *sel, _adapter *adapter);
#endif
int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list);
int rtw_mesh_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list);
s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib);
void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf);
@@ -518,6 +519,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
, const u8 *mda, const u8 *msa
, const u8 *da, const u8 *sa
, struct rtw_ieee80211s_hdr *mctrl
, u8 *msdu, enum rtw_rx_llc_hdl llc_hdl
, struct xmit_frame **fwd_frame, _list *b2u_list);
void dump_mesh_stats(void *sel, _adapter *adapter);

View File

@@ -394,162 +394,6 @@ int rtw_mesh_path_error_tx(_adapter *adapter,
return 0;
}
static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi)
{
static const u32 base[4][10] = {
{ 6500000,
13000000,
19500000,
26000000,
39000000,
52000000,
58500000,
65000000,
78000000,
/* not in the spec, but some devices use this: */
86500000,
},
{ 13500000,
27000000,
40500000,
54000000,
81000000,
108000000,
121500000,
135000000,
162000000,
180000000,
},
{ 29300000,
58500000,
87800000,
117000000,
175500000,
234000000,
263300000,
292500000,
351000000,
390000000,
},
{ 58500000,
117000000,
175500000,
234000000,
351000000,
468000000,
526500000,
585000000,
702000000,
780000000,
},
};
u32 bitrate;
int bw_idx;
if (mcs > 9) {
RTW_HWMP_INFO("Invalid mcs = %d\n", mcs);
return 0;
}
if (nss > 4 || nss < 1) {
RTW_HWMP_INFO("Now only support nss = 1, 2, 3, 4\n");
}
switch (bw) {
case CHANNEL_WIDTH_160:
bw_idx = 3;
break;
case CHANNEL_WIDTH_80:
bw_idx = 2;
break;
case CHANNEL_WIDTH_40:
bw_idx = 1;
break;
case CHANNEL_WIDTH_20:
bw_idx = 0;
break;
default:
RTW_HWMP_INFO("bw = %d currently not supported\n", bw);
return 0;
}
bitrate = base[bw_idx][mcs];
bitrate *= nss;
if (sgi)
bitrate = (bitrate / 9) * 10;
/* do NOT round down here */
return (bitrate + 50000) / 100000;
}
static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi)
{
int modulation, streams, bitrate;
/* the formula below does only work for MCS values smaller than 32 */
if (mcs >= 32) {
RTW_HWMP_INFO("Invalid mcs = %d\n", mcs);
return 0;
}
if (bw > 1) {
RTW_HWMP_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n");
return 0;
}
modulation = mcs & 7;
streams = (mcs >> 3) + 1;
bitrate = (bw == 1) ? 13500000 : 6500000;
if (modulation < 4)
bitrate *= (modulation + 1);
else if (modulation == 4)
bitrate *= (modulation + 2);
else
bitrate *= (modulation + 3);
bitrate *= streams;
if (sgi)
bitrate = (bitrate / 9) * 10;
/* do NOT round down here */
return (bitrate + 50000) / 100000;
}
/**
* @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz)
* @rate_idx: DESC_RATEXXXX & 0x7f
* @sgi: DESC_RATEXXXX >> 7
* Returns: bitrate in 100kbps
*/
static u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi)
{
u32 bitrate;
if (rate_idx <= DESC_RATE54M){
u16 ofdm_rate[12] = {10, 20, 55, 110,
60, 90, 120, 180, 240, 360, 480, 540};
bitrate = ofdm_rate[rate_idx];
} else if ((DESC_RATEMCS0 <= rate_idx) &&
(rate_idx <= DESC_RATEMCS31)) {
u8 mcs = rate_idx - DESC_RATEMCS0;
bitrate = rtw_get_ht_bitrate(mcs, bw, sgi);
} else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) &&
(rate_idx <= DESC_RATEVHTSS4MCS9)) {
u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10;
u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1;
bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi);
} else {
/* 60Ghz ??? */
bitrate = 1;
}
return bitrate;
}
static u32 rtw_airtime_link_metric_get(_adapter *adapter, struct sta_info *sta)
{
struct dm_struct *dm = adapter_to_phydm(adapter);