|
@@ -146,7 +146,7 @@ bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev)
|
|
|
/**
|
|
|
* mlo_send_link_disconnect- Issue the disconnect request on MLD links
|
|
|
*
|
|
|
- * @mlo_dev_ctx: pointer to mlo dev context
|
|
|
+ * @vdev: pointer to vdev
|
|
|
* @source: disconnect source
|
|
|
* @reason_code: disconnect reason
|
|
|
* @bssid: bssid of AP to disconnect, can be null if not known
|
|
@@ -154,7 +154,7 @@ bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev)
|
|
|
* Return: QDF_STATUS
|
|
|
*/
|
|
|
static QDF_STATUS
|
|
|
-mlo_send_link_disconnect(struct wlan_mlo_dev_context *mlo_dev_ctx,
|
|
|
+mlo_send_link_disconnect(struct wlan_objmgr_vdev *vdev,
|
|
|
enum wlan_cm_source source,
|
|
|
enum wlan_reason_code reason_code,
|
|
|
struct qdf_mac_addr *bssid)
|
|
@@ -162,7 +162,16 @@ mlo_send_link_disconnect(struct wlan_mlo_dev_context *mlo_dev_ctx,
|
|
|
uint8_t i = 0;
|
|
|
enum wlan_cm_source link_source = source;
|
|
|
struct wlan_objmgr_vdev *assoc_vdev =
|
|
|
- mlo_get_assoc_link_vdev(mlo_dev_ctx);
|
|
|
+ mlo_get_assoc_link_vdev(vdev->mlo_dev_ctx);
|
|
|
+ struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
|
|
|
+ uint16_t vdev_count = 0;
|
|
|
+ struct wlan_mlo_sta *sta_ctx = NULL;
|
|
|
+
|
|
|
+ sta_ctx = vdev->mlo_dev_ctx->sta_ctx;
|
|
|
+ if (!sta_ctx) {
|
|
|
+ mlo_err("Invalid sta_ctx");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
|
|
|
if (!assoc_vdev)
|
|
|
return QDF_STATUS_E_FAILURE;
|
|
@@ -174,19 +183,20 @@ mlo_send_link_disconnect(struct wlan_mlo_dev_context *mlo_dev_ctx,
|
|
|
if (source != CM_OSIF_DISCONNECT)
|
|
|
link_source = CM_MLO_LINK_VDEV_DISCONNECT;
|
|
|
|
|
|
- for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
|
|
- if (!mlo_dev_ctx->wlan_vdev_list[i])
|
|
|
- continue;
|
|
|
-
|
|
|
- if (qdf_test_bit(i, mlo_dev_ctx->sta_ctx->wlan_connected_links) &&
|
|
|
- mlo_dev_ctx->wlan_vdev_list[i] != mlo_get_assoc_link_vdev(mlo_dev_ctx))
|
|
|
- wlan_cm_disconnect(mlo_dev_ctx->wlan_vdev_list[i],
|
|
|
+ mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
|
|
|
+ for (i = 0; i < vdev_count; i++) {
|
|
|
+ if (qdf_test_bit(i, sta_ctx->wlan_connected_links) &&
|
|
|
+ wlan_vdev_list[i] !=
|
|
|
+ mlo_get_assoc_link_vdev(vdev->mlo_dev_ctx))
|
|
|
+ wlan_cm_disconnect(wlan_vdev_list[i],
|
|
|
link_source, reason_code,
|
|
|
NULL);
|
|
|
+ mlo_release_vdev_ref(wlan_vdev_list[i]);
|
|
|
}
|
|
|
|
|
|
wlan_cm_disconnect(assoc_vdev,
|
|
|
source, reason_code, NULL);
|
|
|
+
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
@@ -407,7 +417,7 @@ static QDF_STATUS mlo_disconnect_no_lock(struct wlan_objmgr_vdev *vdev,
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
- status = mlo_send_link_disconnect(mlo_dev_ctx, source,
|
|
|
+ status = mlo_send_link_disconnect(vdev, source,
|
|
|
reason_code, bssid);
|
|
|
}
|
|
|
|
|
@@ -502,15 +512,19 @@ QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
|
|
|
mlo_err("Failed to allocate orig connect req");
|
|
|
copied_conn_req_lock_release(sta_ctx);
|
|
|
mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
+
|
|
|
return QDF_STATUS_E_NOMEM;
|
|
|
}
|
|
|
|
|
|
if (QDF_IS_STATUS_SUCCESS(status)) {
|
|
|
mlo_clear_connected_links_bmap(vdev);
|
|
|
- status = wlan_cm_start_connect(vdev, req);
|
|
|
+ mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
+
|
|
|
+ return wlan_cm_start_connect(vdev, req);
|
|
|
}
|
|
|
|
|
|
mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
+
|
|
|
return status;
|
|
|
}
|
|
|
|
|
@@ -610,6 +624,8 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
|
|
|
/* Create the secondary interface, Send keys if the last link */
|
|
|
uint8_t i, partner_idx = 0;
|
|
|
struct wlan_ssid ssid = {0};
|
|
|
+ struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
|
|
|
+ uint16_t vdev_count = 0;
|
|
|
|
|
|
mlo_debug("Sending link connect on partner interface");
|
|
|
wlan_vdev_mlme_get_ssid(
|
|
@@ -624,24 +640,27 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
|
|
|
if(wlan_vdev_mlme_is_mlo_link_vdev(vdev))
|
|
|
return;
|
|
|
|
|
|
- for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
|
|
- if (!mlo_dev_ctx->wlan_vdev_list[i] ||
|
|
|
- (mlo_dev_ctx->wlan_vdev_list[i] == vdev))
|
|
|
+ mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
|
|
|
+ for (i = 0; i < vdev_count; i++) {
|
|
|
+ if (wlan_vdev_list[i] == vdev) {
|
|
|
+ mlo_release_vdev_ref(wlan_vdev_list[i]);
|
|
|
continue;
|
|
|
+ }
|
|
|
wlan_vdev_mlme_set_mlo_vdev(mlo_dev_ctx->wlan_vdev_list[i]);
|
|
|
wlan_vdev_mlme_set_mlo_link_vdev(mlo_dev_ctx->wlan_vdev_list[i]);
|
|
|
wlan_vdev_set_link_id(
|
|
|
- mlo_dev_ctx->wlan_vdev_list[i],
|
|
|
+ wlan_vdev_list[i],
|
|
|
ml_parnter_info->partner_link_info[partner_idx].link_id);
|
|
|
ml_parnter_info->partner_link_info[partner_idx].vdev_id =
|
|
|
wlan_vdev_get_id(mlo_dev_ctx->wlan_vdev_list[i]);
|
|
|
mlo_prepare_and_send_connect(
|
|
|
- mlo_dev_ctx->wlan_vdev_list[i],
|
|
|
+ wlan_vdev_list[i],
|
|
|
*ml_parnter_info,
|
|
|
ml_parnter_info->partner_link_info[partner_idx],
|
|
|
ssid);
|
|
|
- mlo_update_connected_links(mlo_dev_ctx->wlan_vdev_list[i], 1);
|
|
|
+ mlo_update_connected_links(wlan_vdev_list[i], 1);
|
|
|
partner_idx++;
|
|
|
+ mlo_release_vdev_ref(wlan_vdev_list[i]);
|
|
|
}
|
|
|
}
|
|
|
#else
|
|
@@ -1063,10 +1082,10 @@ QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev,
|
|
|
mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
return status;
|
|
|
}
|
|
|
+ mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
|
|
|
- status = mlo_send_link_disconnect(mlo_dev_ctx, source,
|
|
|
+ status = mlo_send_link_disconnect(vdev, source,
|
|
|
reason_code, bssid);
|
|
|
- mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
if (QDF_IS_STATUS_SUCCESS(status))
|
|
|
mlo_free_copied_conn_req(sta_ctx);
|
|
|
|
|
@@ -1120,44 +1139,41 @@ QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev,
|
|
|
/**
|
|
|
* mlo_handle_disconnect_resp- Issue desired actions on partner link vdev
|
|
|
*
|
|
|
- * @mlo_dev_ctx: pointer to mlo dev context
|
|
|
+ * @vdev: pointer to vdev
|
|
|
* @resp: disconnect resp
|
|
|
*
|
|
|
* Return: none
|
|
|
*/
|
|
|
#ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
|
|
|
static
|
|
|
-void mlo_handle_disconnect_resp(struct wlan_mlo_dev_context *mlo_dev_ctx,
|
|
|
+void mlo_handle_disconnect_resp(struct wlan_objmgr_vdev *vdev,
|
|
|
struct wlan_cm_discon_rsp *resp)
|
|
|
{
|
|
|
/* If it is secondary link then delete vdev object from mlo device. */
|
|
|
enum wlan_cm_source source;
|
|
|
enum wlan_reason_code reason_code;
|
|
|
uint8_t i = 0;
|
|
|
+ struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
|
|
|
+ uint16_t vdev_count = 0;
|
|
|
|
|
|
- mlo_dev_lock_acquire(mlo_dev_ctx);
|
|
|
- for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
|
|
- if (!mlo_dev_ctx->wlan_vdev_list[i])
|
|
|
- continue;
|
|
|
-
|
|
|
- if (wlan_cm_is_vdev_connected(mlo_dev_ctx->wlan_vdev_list[i])) {
|
|
|
+ mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
|
|
|
+ for (i = 0; i < vdev_count; i++) {
|
|
|
+ if (wlan_cm_is_vdev_connected(wlan_vdev_list[i])) {
|
|
|
if (wlan_vdev_mlme_is_mlo_link_vdev(
|
|
|
- mlo_dev_ctx->wlan_vdev_list[i])) {
|
|
|
+ wlan_vdev_list[i])) {
|
|
|
source = resp->req.req.source;
|
|
|
reason_code = resp->req.req.reason_code;
|
|
|
wlan_cm_disconnect(
|
|
|
- mlo_dev_ctx->wlan_vdev_list[i],
|
|
|
+ wlan_vdev_list[i],
|
|
|
source, reason_code, NULL);
|
|
|
- mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
- return;
|
|
|
}
|
|
|
}
|
|
|
+ mlo_release_vdev_ref(wlan_vdev_list[i]);
|
|
|
}
|
|
|
- mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
}
|
|
|
#else
|
|
|
static
|
|
|
-void mlo_handle_disconnect_resp(struct wlan_mlo_dev_context *mlo_dev_ctx,
|
|
|
+void mlo_handle_disconnect_resp(struct wlan_objmgr_vdev *vdev,
|
|
|
struct wlan_cm_discon_rsp *resp)
|
|
|
{ }
|
|
|
|
|
@@ -1305,7 +1321,7 @@ void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- mlo_handle_disconnect_resp(mlo_dev_ctx, resp);
|
|
|
+ mlo_handle_disconnect_resp(vdev, resp);
|
|
|
}
|
|
|
|
|
|
bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev)
|
|
@@ -1760,6 +1776,8 @@ void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev)
|
|
|
struct wlan_mlo_dev_context *mlo_dev_ctx = NULL;
|
|
|
struct wlan_mlo_sta *sta_ctx = NULL;
|
|
|
uint8_t i;
|
|
|
+ struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
|
|
|
+ uint16_t vdev_count = 0;
|
|
|
|
|
|
if (!vdev)
|
|
|
return;
|
|
@@ -1784,28 +1802,23 @@ void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- mlo_dev_lock_acquire(mlo_dev_ctx);
|
|
|
if (sta_ctx->connect_req) {
|
|
|
mlo_free_connect_ies(sta_ctx->connect_req);
|
|
|
qdf_mem_free(sta_ctx->connect_req);
|
|
|
sta_ctx->connect_req = NULL;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
|
|
- if (!mlo_dev_ctx->wlan_vdev_list[i])
|
|
|
- continue;
|
|
|
-
|
|
|
- if (qdf_test_bit(i,
|
|
|
- mlo_dev_ctx->sta_ctx->wlan_connected_links) &&
|
|
|
- mlo_dev_ctx->wlan_vdev_list[i] !=
|
|
|
+ mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
|
|
|
+ for (i = 0; i < vdev_count; i++) {
|
|
|
+ if (qdf_test_bit(i, sta_ctx->wlan_connected_links) &&
|
|
|
+ wlan_vdev_list[i] !=
|
|
|
mlo_get_assoc_link_vdev(mlo_dev_ctx))
|
|
|
- wlan_cm_disconnect(mlo_dev_ctx->wlan_vdev_list[i],
|
|
|
+ wlan_cm_disconnect(wlan_vdev_list[i],
|
|
|
CM_INTERNAL_DISCONNECT,
|
|
|
REASON_UNSPEC_FAILURE,
|
|
|
NULL);
|
|
|
+ mlo_release_vdev_ref(wlan_vdev_list[i]);
|
|
|
}
|
|
|
-
|
|
|
- mlo_dev_lock_release(mlo_dev_ctx);
|
|
|
}
|
|
|
|
|
|
void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, uint16_t *vdev_count,
|