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
此提交包含在:
Pragaspathi Thilagaraj
2023-05-20 23:29:20 +05:30
提交者 Rahul Choudhary
父節點 9253c14181
當前提交 fe4e1c1ae3
共有 3 個檔案被更改,包括 241 行新增8 行删除

查看文件

@@ -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
/**