mirror of
https://github.com/RinCat/RTL88x2BU-Linux-Driver.git
synced 2026-01-29 07:16:35 +00:00
Update to 5.13.1 from upstream
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user