From be0dd236406c80b84bd1585931e4848d1595f540 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Myadam Date: Thu, 22 Sep 2022 15:19:00 +0530 Subject: [PATCH] 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 --- core/hdd/src/wlan_hdd_main.c | 17 +++++++++++++---- core/hdd/src/wlan_hdd_p2p.c | 2 +- core/hdd/src/wlan_hdd_sap_cond_chan_switch.c | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 1c010f73e6df..69500ce5819f 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -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); diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index d947d31a71d0..4743ce81ba2a 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -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) != diff --git a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c index 7eb6d637e1e1..4230c92baaaa 100644 --- a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c +++ b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c @@ -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");