qcacmn: Handle bridge peer creation in WDS station

Handle case where device topology needs bridge peer.
So if the device have connection on two opposite links
create bridge peer on the central vap.
Sample topology:
AP
2 GHz<-->6 GHz MLO Links
STA topology
       (5 GHz Low VAP)
         chip0
      /         \
 (2 GHz VAP)chip1    chip2 (6 GHz VAP)
      \         /
         chip3
       (5 GHz High VAP)
In the above case we will have Bridge peer on either
5 GHz Low or 5 GHz High VAP

CRs-Fixed: 3575939
Change-Id: I923cc01b3c6e23099436a25565cbabab5a08d93c
This commit is contained in:
Uraj Sasan
2023-08-08 11:45:33 +05:30
committed by Rahul Choudhary
parent 674627f868
commit 85dafccb66
4 changed files with 214 additions and 13 deletions

View File

@@ -570,6 +570,7 @@ cm_candidate_mlo_update(struct scan_cache_entry *scan_entry,
validate_bss_info->is_mlo = !!scan_entry->ie_list.multi_link_bv;
validate_bss_info->scan_entry = scan_entry;
}
#else
static inline
void cm_set_vdev_link_id(struct cnx_mgr *cm_ctx,
@@ -612,6 +613,20 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
mlme_err("invalid cm_ctx");
return;
}
if (mlo_is_sta_bridge_vdev(cm_ctx->vdev) && req) {
/* Acquire lock as required by wlan_vdev_mlme_get_mldaddr() */
wlan_vdev_obj_lock(cm_ctx->vdev);
bssid = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(cm_ctx->vdev);
wlan_vdev_obj_unlock(cm_ctx->vdev);
mld_mac = mlo_get_sta_ctx_bss_mld_addr(cm_ctx->vdev);
status = mlme_cm_bss_peer_create_req(cm_ctx->vdev,
bssid,
mld_mac,
is_assoc_link);
goto peer_create_fail;
}
if (!req || !req->cur_candidate || !req->cur_candidate->entry) {
mlme_err("invalid req");
return;
@@ -624,12 +639,14 @@ static void cm_create_bss_peer(struct cnx_mgr *cm_ctx,
cm_set_vdev_link_id(cm_ctx, req);
wlan_mlo_init_cu_bpcc(cm_ctx->vdev);
mld_mac = cm_get_bss_peer_mld_addr(req);
mlo_set_sta_ctx_bss_mld_addr(cm_ctx->vdev, mld_mac);
is_assoc_link = cm_bss_peer_is_assoc_peer(req);
}
bssid = &req->cur_candidate->entry->bssid;
status = mlme_cm_bss_peer_create_req(cm_ctx->vdev, bssid,
mld_mac, is_assoc_link);
peer_create_fail:
if (QDF_IS_STATUS_ERROR(status)) {
struct wlan_cm_connect_resp *resp;
uint8_t vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
@@ -1782,6 +1799,15 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx,
}
}
if (mlo_is_sta_bridge_vdev(cm_ctx->vdev)) {
status = cm_ser_connect_req(pdev, cm_ctx, cm_req);
if (QDF_IS_STATUS_ERROR(status)) {
reason = CM_SER_FAILURE;
goto connect_err;
}
return QDF_STATUS_SUCCESS;
}
status = cm_connect_get_candidates(pdev, cm_ctx, cm_req);
/* In case of status pending connect will continue after scan */
@@ -2265,7 +2291,11 @@ QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
cm_fill_vdev_crypto_params(cm_ctx, req);
cm_store_wep_key(cm_ctx, &req->crypto, *cm_id);
status = cm_get_valid_candidate(cm_ctx, cm_req, NULL, NULL);
if (mlo_is_sta_bridge_vdev(cm_ctx->vdev))
status = QDF_STATUS_SUCCESS;
else
status = cm_get_valid_candidate(cm_ctx, cm_req, NULL, NULL);
if (QDF_IS_STATUS_ERROR(status))
goto connect_err;
@@ -2517,6 +2547,7 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
struct security_info *neg_sec_info;
uint8_t country_code[REG_ALPHA2_LEN + 1] = {0};
struct wlan_objmgr_psoc *psoc;
struct cm_connect_req *conn_req = NULL;
psoc = wlan_pdev_get_psoc(wlan_vdev_get_pdev(cm_ctx->vdev));
@@ -2524,6 +2555,27 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
if (!cm_req)
return QDF_STATUS_E_FAILURE;
conn_req = &cm_req->connect_req;
/* Handle WDS bridge vdev */
if (mlo_is_sta_bridge_vdev(cm_ctx->vdev) && conn_req) {
req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
req.cm_id = *cm_id;
req.force_rsne_override = conn_req->req.force_rsne_override;
req.is_wps_connection = conn_req->req.is_wps_connection;
req.is_osen_connection = conn_req->req.is_osen_connection;
req.assoc_ie = conn_req->req.assoc_ie;
req.scan_ie = conn_req->req.scan_ie;
cm_copy_fils_info(&req, cm_req);
req.ht_caps = conn_req->req.ht_caps;
req.ht_caps_mask = conn_req->req.ht_caps_mask;
req.vht_caps = conn_req->req.vht_caps;
req.vht_caps_mask = conn_req->req.vht_caps_mask;
req.is_non_assoc_link = conn_req->req.is_non_assoc_link;
cm_update_ml_partner_info(cm_ctx->vdev, &conn_req->req, &req);
wlan_reg_get_cc_and_src(psoc, country_code);
goto connect_req;
}
/*
* As keymgmt and ucast cipher can be multiple.
* Choose one keymgmt and one ucastcipherset based on higher security.
@@ -2567,7 +2619,7 @@ cm_resume_connect_after_peer_create(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
req.is_osen_connection, req.force_rsne_override,
country_code[0],
country_code[1]);
connect_req:
status = mlme_cm_connect_req(cm_ctx->vdev, &req);
if (QDF_IS_STATUS_ERROR(status)) {
mlme_err(CM_PREFIX_FMT "connect request failed",

View File

@@ -1038,6 +1038,7 @@ struct mlo_tgt_partner_info {
* @is_force_central_primary: Flag to tell if bridge should be primary umac
* @bridge_vap_exists: If there is bridge vap
* @bridge_node_auth: Is bridge node auth done
* @bss_mld_addr: MLD address of the BSS
*/
struct wlan_mlo_bridge_sta {
struct mlo_partner_info bridge_partners;
@@ -1047,6 +1048,7 @@ struct wlan_mlo_bridge_sta {
bool is_force_central_primary;
bool bridge_vap_exists;
bool bridge_node_auth;
struct qdf_mac_addr bss_mld_addr;
};
/**

View File

@@ -196,6 +196,14 @@ QDF_STATUS mlo_check_topology(struct wlan_objmgr_pdev *pdev,
void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev,
struct mlo_partner_info *partner_info);
/**
* mlo_get_total_links() - get total links supported by device
* @pdev: pdev pointer
*
* Return: Number of total links supported
*/
uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev);
/**
* mlo_is_sta_bridge_vdev() - Check if the vdev is sta bridge vdev
@@ -215,15 +223,97 @@ bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev);
bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev);
/**
* mlo_get_total_links() - get total links supported by device
* @pdev: pdev pointer
* mlo_is_force_central_primary() - Check if central vdev is forced
* as primary
* @vdev: vdev pointer
*
* Return: Number of total links supported
* Return: True if Central Vdev is force as primary else false
*/
uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev);
#endif
bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev);
/**
* mlo_set_sta_ctx_bss_mld_addr() - Save BSS MLD in sta ctx
* @vdev: vdev pointer
* @bss_mld_addr: MLD Address of BSS
*
* Return: none
*/
static inline
void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *bss_mld_addr)
{
struct wlan_mlo_dev_context *ml_dev = NULL;
if (!vdev || !vdev->mlo_dev_ctx || !bss_mld_addr)
return;
ml_dev = vdev->mlo_dev_ctx;
if (mlo_sta_bridge_exists(vdev) &&
qdf_is_macaddr_zero(&ml_dev->bridge_sta_ctx->bss_mld_addr)) {
if (qdf_is_macaddr_zero(bss_mld_addr))
return;
qdf_copy_macaddr(&ml_dev->bridge_sta_ctx->bss_mld_addr,
bss_mld_addr);
}
}
/**
* mlo_get_sta_ctx_bss_mld_addr() - Get BSS MLD from sta ctx
* @vdev: vdev pointer
*
* Return: pointer to qdf_mac_addr
*/
static inline
struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev)
{
struct wlan_mlo_dev_context *ml_dev = NULL;
struct qdf_mac_addr *mld_addr;
if (!vdev || !vdev->mlo_dev_ctx)
return NULL;
ml_dev = vdev->mlo_dev_ctx;
if (mlo_sta_bridge_exists(vdev) &&
!qdf_is_macaddr_zero(&ml_dev->bridge_sta_ctx->bss_mld_addr)) {
mld_addr = &ml_dev->bridge_sta_ctx->bss_mld_addr;
return mld_addr;
}
return NULL;
}
#else
static inline
void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *bss_mld_addr)
{ }
static inline
struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev)
{
return NULL;
}
static inline
bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline
bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline
bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev)
{
return false;
}
#endif
/**
* wlan_mlo_get_tdls_link_vdev() - API to get tdls link vdev
* @vdev: vdev object
@@ -781,6 +871,35 @@ mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc,
get_ml_link_state_cb *resp_cb,
void **context, uint8_t vdev_id);
#else
static inline
void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *bss_mld_addr)
{ }
static inline
struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev)
{
return NULL;
}
static inline
bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline
bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline
bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline
QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_req *req)

View File

@@ -728,8 +728,12 @@ void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev,
bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
{
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
struct wlan_mlo_dev_context *ml_dev = vdev->mlo_dev_ctx;
struct wlan_mlo_dev_context *ml_dev = NULL;
if (!vdev)
return false;
ml_dev = vdev->mlo_dev_ctx;
if (!ml_dev || !ml_dev->bridge_sta_ctx)
return false;
@@ -737,7 +741,7 @@ bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev)
if (vdev->vdev_objmgr.mlo_central_vdev &&
ml_dev->bridge_sta_ctx->bridge_vap_exists)
return true;
#endif
return false;
}
@@ -745,20 +749,44 @@ qdf_export_symbol(mlo_is_sta_bridge_vdev);
bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev)
{
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
struct wlan_mlo_dev_context *ml_dev = vdev->mlo_dev_ctx;
struct wlan_mlo_dev_context *ml_dev = NULL;
if (!vdev)
return false;
ml_dev = vdev->mlo_dev_ctx;
if (!ml_dev || !ml_dev->bridge_sta_ctx)
return false;
if (ml_dev->bridge_sta_ctx->bridge_vap_exists)
return true;
#endif
return false;
}
qdf_export_symbol(mlo_sta_bridge_exists);
bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev)
{
struct wlan_mlo_dev_context *ml_dev = NULL;
if (!vdev)
return false;
ml_dev = vdev->mlo_dev_ctx;
if (!ml_dev || !ml_dev->bridge_sta_ctx)
return false;
if (ml_dev->bridge_sta_ctx->is_force_central_primary)
return true;
return false;
}
qdf_export_symbol(mlo_is_force_central_primary);
uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev)
{
uint8_t ml_grp_id;