qcacld-3.0: Fix to pre CAC interface clean up

If is_pre_cac_on is set, in __wlan_hdd_del_virtual_intf firstly
frees the sap context by calling hdd_clean_up_interface and then
frees the pre cac by calling hdd_clean_up_pre_cac_interface this
will fails to access the sap context which is already freed.

So, replace order of calling, firstly hdd_clean_up_pre_cac_interface
and then hdd_clean_up_interface.

cds flush work will cancel the work which will not delete the pre cac
vdev. Replace with qdf_flush_work will wait for a work to finish,
executing the last queueing instance.

Assign NULL to fn and arg of pre cac work to ensure proper cleanup
of work.

Change-Id: I093bf627ce7a73e7c4f7c4cf30e2ec56814a80ed
CRs-Fixed: 3286477
This commit is contained in:
Vinod Kumar Myadam 2022-09-22 15:19:00 +05:30
commit be0dd23640
3 changed files with 16 additions and 6 deletions

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -7242,12 +7242,13 @@ static void hdd_close_pre_cac_adapter(struct hdd_context *hdd_ctx)
SAP_PRE_CAC_IFNAME);
if (!pre_cac_adapter)
return;
hdd_ctx->sap_pre_cac_work.fn = NULL;
hdd_ctx->sap_pre_cac_work.arg = NULL;
errno = osif_vdev_sync_trans_start_wait(pre_cac_adapter->dev,
&vdev_sync);
if (errno)
return;
osif_vdev_sync_unregister(pre_cac_adapter->dev);
osif_vdev_sync_wait_for_ops(vdev_sync);
@ -7475,7 +7476,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
if (!wlan_sap_is_pre_cac_context(sap_ctx) &&
(hdd_ctx->sap_pre_cac_work.fn))
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
qdf_flush_work(&hdd_ctx->sap_pre_cac_work);
hdd_close_pre_cac_adapter(hdd_ctx);
@ -7652,7 +7653,7 @@ QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
hdd_enter();
if (hdd_ctx->sap_pre_cac_work.fn)
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
qdf_flush_work(&hdd_ctx->sap_pre_cac_work);
hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
NET_DEV_HOLD_STOP_ALL_ADAPTERS) {
@ -18156,6 +18157,7 @@ void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
uint8_t vdev_id;
QDF_STATUS status;
struct hdd_adapter *precac_adapter;
struct sap_context *sap_ctx;
status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &vdev_id);
if (QDF_IS_STATUS_ERROR(status)) {
@ -18169,6 +18171,13 @@ void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
return;
}
sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(precac_adapter);
if (wlan_sap_is_pre_cac_context(sap_ctx) &&
hdd_ctx->sap_pre_cac_work.fn) {
hdd_debug("pre_cac_work already scheduled");
return;
}
qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
wlan_hdd_sap_pre_cac_failure,
(void *)precac_adapter);

View file

@ -960,8 +960,8 @@ int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
if (adapter->device_mode == QDF_SAP_MODE &&
wlan_sap_is_pre_cac_active(hdd_ctx->mac_handle)) {
hdd_clean_up_interface(hdd_ctx, adapter);
hdd_clean_up_pre_cac_interface(hdd_ctx);
hdd_clean_up_interface(hdd_ctx, adapter);
} else if (wlan_hdd_is_session_type_monitor(
adapter->device_mode) &&
ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -255,7 +256,7 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx,
if (pre_cac_adapter) {
/* Flush existing pre_cac work */
if (hdd_ctx->sap_pre_cac_work.fn)
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
qdf_flush_work(&hdd_ctx->sap_pre_cac_work);
} else {
if (policy_mgr_get_connection_count(hdd_ctx->psoc) > 1) {
hdd_err("pre cac not allowed in concurrency");