qcacmn: Retry MLO connection with SLO on connection failure
Currently if MLO connection fails then connection is tried with same link until it reaches to maximum no of trials but connection is not tried with same assoc link by changing partner link or with SLO. So, when vendor roam score algorithm is enabled, add logic to try MLO connection again by reducing number of partner links with each retry till SLO connection is tried. Change-Id: Ic0e3acd2198cfa0ed0ff893da6ae32d669d32a41 CRs-Fixed: 3521159
此提交包含在:

提交者
Rahul Choudhary

父節點
9253c14181
當前提交
fe4e1c1ae3
@@ -1974,6 +1974,7 @@ static int cm_calculate_mlo_bss_score(struct wlan_objmgr_psoc *psoc,
|
||||
|
||||
return best_total_score;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int cm_calculate_emlsr_score(struct weight_cfg *weight_config)
|
||||
{
|
||||
@@ -1998,6 +1999,101 @@ static int cm_calculate_mlo_bss_score(struct wlan_objmgr_psoc *psoc,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(CONN_MGR_ADV_FEATURE)
|
||||
static void
|
||||
cm_sort_vendor_algo_mlo_bss_entry(struct wlan_objmgr_psoc *psoc,
|
||||
struct scan_cache_entry *entry,
|
||||
struct psoc_phy_config *phy_config,
|
||||
qdf_list_t *scan_list,
|
||||
enum MLO_TYPE bss_mlo_type)
|
||||
{
|
||||
struct scan_cache_entry *entry_partner[MLD_MAX_LINKS - 1];
|
||||
uint32_t freq[MLD_MAX_LINKS - 1];
|
||||
uint32_t etp_score[MLD_MAX_LINKS - 1] = {0};
|
||||
uint32_t total_score[MLD_MAX_LINKS - 1] = {0};
|
||||
uint8_t i, j;
|
||||
uint32_t best_total_score = 0;
|
||||
uint8_t best_partner_index = 0;
|
||||
uint32_t freq_entry;
|
||||
struct partner_link_info *link;
|
||||
bool eht_capab;
|
||||
struct partner_link_info tmp_link_info;
|
||||
uint32_t tmp_total_score = 0;
|
||||
|
||||
wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
|
||||
if (!eht_capab)
|
||||
return;
|
||||
|
||||
link = &entry->ml_info.link_info[0];
|
||||
freq_entry = entry->channel.chan_freq;
|
||||
for (i = 0; i < entry->ml_info.num_links; i++) {
|
||||
mlme_debug("freq: %d, link id: %d is valid %d "QDF_MAC_ADDR_FMT,
|
||||
link[i].freq, link[i].link_id,
|
||||
link[i].is_valid_link,
|
||||
QDF_MAC_ADDR_REF(link[i].link_addr.bytes));
|
||||
if (!link[i].is_valid_link)
|
||||
continue;
|
||||
|
||||
entry_partner[i] = cm_get_entry(scan_list, &link[i].link_addr);
|
||||
if (entry_partner[i])
|
||||
freq[i] = entry_partner[i]->channel.chan_freq;
|
||||
else
|
||||
freq[i] = link[i].freq;
|
||||
|
||||
if (policy_mgr_are_2_freq_on_same_mac(psoc, freq[i],
|
||||
freq_entry)) {
|
||||
link[i].is_valid_link = false;
|
||||
total_score[i] = 0;
|
||||
mlme_nofl_debug("freq %d and %d can't be MLMR",
|
||||
freq[i], freq_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry_partner[i])
|
||||
continue;
|
||||
|
||||
etp_score[i] = cm_calculate_etp_score(psoc, entry_partner[i],
|
||||
phy_config, bss_mlo_type);
|
||||
|
||||
total_score[i] = etp_score[i];
|
||||
if (total_score[i] > best_total_score) {
|
||||
best_total_score = total_score[i];
|
||||
best_partner_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* reorder the link idx per score */
|
||||
for (j = 0; j < entry->ml_info.num_links; j++) {
|
||||
tmp_total_score = total_score[j];
|
||||
best_partner_index = j;
|
||||
for (i = j + 1; i < entry->ml_info.num_links; i++) {
|
||||
if (tmp_total_score < total_score[i]) {
|
||||
tmp_total_score = total_score[i];
|
||||
best_partner_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_partner_index != j) {
|
||||
tmp_link_info = entry->ml_info.link_info[j];
|
||||
entry->ml_info.link_info[j] =
|
||||
entry->ml_info.link_info[best_partner_index];
|
||||
entry->ml_info.link_info[best_partner_index] =
|
||||
tmp_link_info;
|
||||
total_score[best_partner_index] = total_score[j];
|
||||
}
|
||||
total_score[j] = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void
|
||||
cm_sort_vendor_algo_mlo_bss_entry(struct wlan_objmgr_psoc *psoc,
|
||||
struct scan_cache_entry *entry,
|
||||
struct psoc_phy_config *phy_config,
|
||||
qdf_list_t *scan_list,
|
||||
enum MLO_TYPE bss_mlo_type)
|
||||
{}
|
||||
#endif
|
||||
|
||||
static int cm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
|
||||
struct scan_cache_entry *entry,
|
||||
int pcl_chan_weight,
|
||||
@@ -2063,6 +2159,15 @@ static int cm_calculate_bss_score(struct wlan_objmgr_psoc *psoc,
|
||||
score = cm_calculate_etp_score(psoc, entry, phy_config,
|
||||
bss_mlo_type);
|
||||
entry->bss_score = score;
|
||||
if (bss_mlo_type == MLMR) {
|
||||
cm_sort_vendor_algo_mlo_bss_entry(psoc, entry,
|
||||
phy_config, scan_list,
|
||||
bss_mlo_type);
|
||||
}
|
||||
mlme_nofl_debug("Candidate("QDF_MAC_ADDR_FMT" freq %d): rssi %d score %d",
|
||||
QDF_MAC_ADDR_REF(entry->bssid.bytes),
|
||||
entry->channel.chan_freq,
|
||||
entry->rssi_raw, entry->bss_score);
|
||||
return score;
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include "wlan_mlo_mgr_op.h"
|
||||
#include <wlan_objmgr_vdev_obj.h>
|
||||
#include "wlan_psoc_mlme_api.h"
|
||||
#include "wlan_scan_public_structs.h"
|
||||
|
||||
void
|
||||
cm_fill_failure_resp_from_cm_id(struct cnx_mgr *cm_ctx,
|
||||
@@ -886,6 +887,54 @@ cm_inform_dlm_connect_complete(struct wlan_objmgr_vdev *vdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
static bool
|
||||
cm_update_mlo_links_for_retry_with_same_candidate(struct wlan_objmgr_psoc *psoc,
|
||||
struct cm_connect_req *cm_req)
|
||||
{
|
||||
uint8_t mlo_link_num;
|
||||
struct scan_cache_entry *entry;
|
||||
|
||||
if (!cm_req->req.ml_parnter_info.num_partner_links)
|
||||
return false;
|
||||
|
||||
entry = cm_req->cur_candidate->entry;
|
||||
|
||||
mlo_link_num = wlan_mlme_get_sta_mlo_conn_max_num(psoc);
|
||||
if (cm_req->req.ml_parnter_info.num_partner_links > mlo_link_num)
|
||||
cm_req->req.ml_parnter_info.num_partner_links = mlo_link_num;
|
||||
|
||||
/*
|
||||
* Try next candidate for non-ML AP
|
||||
*/
|
||||
if (!entry->ie_list.multi_link_bv || !entry->ml_info.num_links) {
|
||||
cm_req->req.ml_parnter_info.num_partner_links = NO_LINK;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cm_req->req.ml_parnter_info.num_partner_links > NO_LINK) {
|
||||
/*
|
||||
* Try to same AP exhaustively till single link ML connection
|
||||
* is tried with the AP
|
||||
*/
|
||||
cm_req->req.ml_parnter_info.num_partner_links--;
|
||||
}
|
||||
|
||||
mlme_debug(CM_PREFIX_FMT "try ML connection with %d partner links",
|
||||
CM_PREFIX_REF(cm_req->req.vdev_id, cm_req->cm_id),
|
||||
cm_req->req.ml_parnter_info.num_partner_links);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static inline bool
|
||||
cm_update_mlo_links_for_retry_with_same_candidate(struct wlan_objmgr_psoc *psoc,
|
||||
struct cm_connect_req *cm_req)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cm_is_retry_with_same_candidate() - This API check if reconnect attempt is
|
||||
* required with the same candidate again
|
||||
@@ -907,14 +956,25 @@ static bool cm_is_retry_with_same_candidate(struct cnx_mgr *cm_ctx,
|
||||
bool sae_connection;
|
||||
QDF_STATUS status;
|
||||
qdf_freq_t freq;
|
||||
struct scoring_cfg *score_config;
|
||||
struct psoc_mlme_obj *mlme_psoc_obj;
|
||||
|
||||
psoc = wlan_pdev_get_psoc(wlan_vdev_get_pdev(cm_ctx->vdev));
|
||||
mlme_psoc_obj = wlan_psoc_mlme_get_cmpt_obj(psoc);
|
||||
if (!mlme_psoc_obj)
|
||||
return false;
|
||||
|
||||
score_config = &mlme_psoc_obj->psoc_cfg.score_config;
|
||||
key_mgmt = req->cur_candidate->entry->neg_sec_info.key_mgmt;
|
||||
freq = req->cur_candidate->entry->channel.chan_freq;
|
||||
|
||||
/* Try once again for the invalid PMKID case without PMKID */
|
||||
if (resp->status_code == STATUS_INVALID_PMKID)
|
||||
if (resp->status_code == STATUS_INVALID_PMKID) {
|
||||
if (score_config->vendor_roam_score_algorithm)
|
||||
cm_update_mlo_links_for_retry_with_same_candidate(psoc,
|
||||
req);
|
||||
goto use_same_candidate;
|
||||
}
|
||||
|
||||
/* Try again for the JOIN timeout if only one candidate */
|
||||
if (resp->reason == CM_JOIN_TIMEOUT &&
|
||||
@@ -929,6 +989,9 @@ static bool cm_is_retry_with_same_candidate(struct cnx_mgr *cm_ctx,
|
||||
return false;
|
||||
|
||||
wlan_mlme_get_sae_assoc_retry_count(psoc, &max_retry_count);
|
||||
if (score_config->vendor_roam_score_algorithm)
|
||||
cm_update_mlo_links_for_retry_with_same_candidate(psoc,
|
||||
req);
|
||||
goto use_same_candidate;
|
||||
}
|
||||
|
||||
@@ -946,9 +1009,29 @@ static bool cm_is_retry_with_same_candidate(struct cnx_mgr *cm_ctx,
|
||||
if (sae_connection)
|
||||
wlan_mlme_get_sae_assoc_retry_count(psoc,
|
||||
&max_retry_count);
|
||||
|
||||
if (score_config->vendor_roam_score_algorithm)
|
||||
cm_update_mlo_links_for_retry_with_same_candidate(psoc,
|
||||
req);
|
||||
goto use_same_candidate;
|
||||
}
|
||||
|
||||
/*
|
||||
* When vendor roam score algorithm is enabled and association failure
|
||||
* happens while trying MLO connection with multiple link, then
|
||||
* retry with same candidate with same primary link and other band as
|
||||
* secondary link. If still failure happens, then try standlone single
|
||||
* link MLO mode with the same candidate AP. Ex:
|
||||
* Priority 1(candidate AP’s 6 GHz case) – 6 GHz (Associating link) +
|
||||
* 5 GHz + 2.4 GHz
|
||||
* Priority 2(candidate AP’s 6 GHz case) – 6 GHz (Associating link) +
|
||||
* 2.4 GHz
|
||||
* Priority 3(AP’s 6 GHz case) – 6 GHz (single Link)
|
||||
*/
|
||||
if (resp->status_code && score_config->vendor_roam_score_algorithm &&
|
||||
cm_update_mlo_links_for_retry_with_same_candidate(psoc, req))
|
||||
goto use_same_candidate;
|
||||
|
||||
return false;
|
||||
|
||||
use_same_candidate:
|
||||
@@ -1707,6 +1790,30 @@ connect_err:
|
||||
return cm_send_connect_start_fail(cm_ctx, cm_req, reason);
|
||||
}
|
||||
|
||||
#if defined(CONN_MGR_ADV_FEATURE) && defined(WLAN_FEATURE_11BE_MLO)
|
||||
static void
|
||||
cm_connect_req_update_ml_partner_info(struct cnx_mgr *cm_ctx,
|
||||
struct cm_req *cm_req,
|
||||
bool same_candidate_used)
|
||||
{
|
||||
bool eht_capable = false;
|
||||
struct cm_connect_req *conn_req = &cm_req->connect_req;
|
||||
|
||||
wlan_psoc_mlme_get_11be_capab(wlan_vdev_get_psoc(cm_ctx->vdev),
|
||||
&eht_capable);
|
||||
if (!same_candidate_used && eht_capable &&
|
||||
cm_bss_peer_is_assoc_peer(conn_req))
|
||||
cm_get_ml_partner_info(conn_req->cur_candidate->entry,
|
||||
&conn_req->req.ml_parnter_info);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
cm_connect_req_update_ml_partner_info(struct cnx_mgr *cm_ctx,
|
||||
struct cm_req *cm_req,
|
||||
bool same_candidate_used)
|
||||
{}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cm_get_valid_candidate() - This API will be called to get the next valid
|
||||
* candidate
|
||||
@@ -1850,6 +1957,9 @@ try_same_candidate:
|
||||
cm_req->connect_req.connect_attempts++;
|
||||
cm_req->connect_req.cur_candidate = new_candidate;
|
||||
|
||||
cm_connect_req_update_ml_partner_info(cm_ctx, cm_req,
|
||||
use_same_candidate);
|
||||
|
||||
flush_single_pmk:
|
||||
akm = wlan_crypto_get_param(cm_ctx->vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
|
||||
/*
|
||||
@@ -2106,17 +2216,21 @@ static inline void cm_set_fils_connection(struct cnx_mgr *cm_ctx,
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
static inline
|
||||
void cm_update_ml_partner_info(struct wlan_cm_connect_req *req,
|
||||
void cm_update_ml_partner_info(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_connect_req *req,
|
||||
struct wlan_cm_vdev_connect_req *connect_req)
|
||||
{
|
||||
if (req->ml_parnter_info.num_partner_links)
|
||||
qdf_mem_copy(&connect_req->ml_parnter_info,
|
||||
&req->ml_parnter_info,
|
||||
sizeof(struct mlo_partner_info));
|
||||
if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
|
||||
return;
|
||||
|
||||
qdf_mem_copy(&connect_req->ml_parnter_info,
|
||||
&req->ml_parnter_info,
|
||||
sizeof(struct mlo_partner_info));
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void cm_update_ml_partner_info(struct wlan_cm_connect_req *req,
|
||||
void cm_update_ml_partner_info(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_connect_req *req,
|
||||
struct wlan_cm_vdev_connect_req *connect_req)
|
||||
{
|
||||
}
|
||||
@@ -2310,7 +2424,7 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
|
||||
req.vht_caps = cm_req->connect_req.req.vht_caps;
|
||||
req.vht_caps_mask = cm_req->connect_req.req.vht_caps_mask;
|
||||
req.is_non_assoc_link = cm_req->connect_req.req.is_non_assoc_link;
|
||||
cm_update_ml_partner_info(&cm_req->connect_req.req, &req);
|
||||
cm_update_ml_partner_info(cm_ctx->vdev, &cm_req->connect_req.req, &req);
|
||||
|
||||
neg_sec_info = &cm_req->connect_req.cur_candidate->entry->neg_sec_info;
|
||||
if (util_scan_entry_is_hidden_ap(req.bss->entry) &&
|
||||
|
@@ -548,6 +548,20 @@ struct ml_info {
|
||||
struct partner_link_info link_info[MLD_MAX_LINKS - 1];
|
||||
uint16_t ml_bss_score;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum number_of_partner_link: Enumeration for number of partner links
|
||||
* @NO_LINK: Default value
|
||||
* @ONE_LINK: Single Link
|
||||
* @TWO_LINK: 2 Links
|
||||
* @THREE_LINK: 3 Links
|
||||
*/
|
||||
enum number_of_partner_link {
|
||||
NO_LINK,
|
||||
ONE_LINK,
|
||||
TWO_LINK,
|
||||
THREE_LINK,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
新增問題並參考
封鎖使用者