Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be0dd236 authored by Vinod Kumar Myadam's avatar Vinod Kumar Myadam
Browse files

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
parent 682543e6
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
/*
 * 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);
+1 −1
Original line number Diff line number Diff line
@@ -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) !=
+2 −1
Original line number Diff line number Diff line
/*
 * 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");