Ver Fonte

qcacld-3.0: Abort any ongoing p2p scans while enabling NAN

Framework disables p2p before enabling NAN as P2P+NAN concurrency
is not supported. NAN operations happens through wifihal and p2p
operations happen through wpa_supplicant which are two different
userspace components. Wifihal call to enable NAN may come to host
driver before disabling p2p through wpa_supplicant. There are high
chances for p2p scan to be in running state while NAN enable is
received. Firmware NAN state machine goes to inconsistent state
and disables NAN as p2p scan is running in such cases.
So, stop the ongoing p2p scan before enabling NAN as P2P+NAN
concurrency is not supported currently.
Also, forward the pdev to NAN component inorder to iterate through
all P2P vdevs.

Change-Id: Ibe30a5ebe90514aee4f6721cdc5476570524cad8
CRs-Fixed: 3054576
Srinivas Dasari há 3 anos atrás
pai
commit
3d0e41cad1

+ 2 - 0
components/nan/core/inc/nan_public_structs.h

@@ -611,6 +611,7 @@ struct nan_disable_req {
  * @social_chan_2g_freq: Social channel in 2G band for the NAN Discovery
  * @social_chan_5g_freq: Social channel in 5G band for the NAN Discovery
  * @params: NAN request structure containing message for the target
+ * @pdev: Pointer to the pdev object
  */
 struct nan_enable_req {
 	struct wlan_objmgr_psoc *psoc;
@@ -618,6 +619,7 @@ struct nan_enable_req {
 	uint32_t social_chan_5g_freq;
 	/* Variable length, do not add anything after this */
 	struct nan_msg_params params;
+	struct wlan_objmgr_pdev *pdev;
 };
 
 /**

+ 5 - 1
components/nan/core/src/nan_main.c

@@ -36,6 +36,7 @@
 #include "wlan_objmgr_vdev_obj.h"
 #include "qdf_platform.h"
 #include "wlan_osif_request_manager.h"
+#include "wlan_p2p_api.h"
 
 QDF_STATUS nan_set_discovery_state(struct wlan_objmgr_psoc *psoc,
 				   enum nan_disc_state new_state)
@@ -1166,10 +1167,11 @@ pre_enable_failure:
 	return status;
 }
 
-QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc,
+QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_pdev *pdev,
 				    uint32_t nan_ch_freq)
 {
 	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 
 	status = nan_set_discovery_state(psoc, NAN_DISC_ENABLE_IN_PROGRESS);
 
@@ -1187,6 +1189,8 @@ QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc,
 		goto pre_enable_failure;
 	}
 
+	wlan_p2p_abort_scan(pdev);
+
 	if (policy_mgr_is_hw_dbs_capable(psoc)) {
 		status = nan_set_hw_mode(psoc, nan_ch_freq);
 		if (QDF_IS_STATUS_ERROR(status))

+ 2 - 2
components/nan/core/src/nan_main_i.h

@@ -239,12 +239,12 @@ QDF_STATUS nan_set_discovery_state(struct wlan_objmgr_psoc *psoc,
 
 /*
  * nan_discovery_pre_enable: Takes steps before sending NAN Enable to Firmware
- * @psoc: PSOC object
+ * @pdev: pdev object
  * @nan_ch_freq: Primary social channel for NAN Discovery
  *
  * Return: status of operation
  */
-QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_psoc *psoc,
+QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_pdev *pdev,
 				    uint32_t nan_ch_freq);
 
 /*

+ 2 - 1
components/nan/dispatcher/src/nan_ucfg_api.c

@@ -677,7 +677,7 @@ QDF_STATUS ucfg_nan_discovery_req(void *in_req, uint32_t req_type)
 				return status;
 			}
 
-			status = nan_discovery_pre_enable(psoc,
+			status = nan_discovery_pre_enable(req->pdev,
 						  req->social_chan_2g_freq);
 			if (QDF_IS_STATUS_SUCCESS(status)) {
 				len = sizeof(struct nan_enable_req) +
@@ -1190,6 +1190,7 @@ QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc,
 	nan_req = qdf_mem_malloc(sizeof(*nan_req) + data_len);
 	if (!nan_req)
 		return -ENOMEM;
+	qdf_mem_zero(nan_req, sizeof(*nan_req) + data_len);
 
 	nan_req->psoc = psoc;
 	nan_req->disable_2g_discovery = true;

+ 5 - 4
components/p2p/core/src/wlan_p2p_roc.c

@@ -196,14 +196,15 @@ fail:
 }
 
 /**
- * p2p_scan_abort() - Abort scan
+ * p2p_roc_abort() - Abort roc
  * @roc_ctx: remain on channel request
  *
- * This function trigger an abort scan request to scan component.
+ * This function triggers an abort scan request to scan component to abort the
+ * ROC request which is running through roc_ctx.
  *
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
-static QDF_STATUS p2p_scan_abort(struct p2p_roc_context *roc_ctx)
+static QDF_STATUS p2p_roc_abort(struct p2p_roc_context *roc_ctx)
 {
 	QDF_STATUS status;
 	struct scan_cancel_request *req;
@@ -350,7 +351,7 @@ static QDF_STATUS p2p_execute_cancel_roc_req(
 	if (status != QDF_STATUS_SUCCESS)
 		p2p_err("Failed to stop roc timer, roc %pK", roc_ctx);
 
-	status = p2p_scan_abort(roc_ctx);
+	status = p2p_roc_abort(roc_ctx);
 	if (status != QDF_STATUS_SUCCESS) {
 		p2p_err("Failed to abort scan, status:%d, destroy roc %pK",
 			status, roc_ctx);

+ 11 - 1
components/p2p/dispatcher/inc/wlan_p2p_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. 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
@@ -60,4 +60,14 @@ QDF_STATUS wlan_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev *vdev);
  */
 QDF_STATUS wlan_p2p_status_connect(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * wlan_p2p_abort_scan() - Abort on going scan on p2p interfaces
+ * @pdev: pdev object
+ *
+ * This function triggers an abort scan request to scan component to abort the
+ * ongoing scan request on p2p vdevs.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS wlan_p2p_abort_scan(struct wlan_objmgr_pdev *pdev);
 #endif

+ 51 - 1
components/p2p/dispatcher/src/wlan_p2p_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. 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
@@ -25,6 +25,8 @@
 #include "wlan_p2p_public_struct.h"
 #include "../../core/src/wlan_p2p_main.h"
 #include "../../core/src/wlan_p2p_roc.h"
+#include <cds_utils.h>
+#include "wlan_scan_api.h"
 
 bool wlan_p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len)
 {
@@ -71,3 +73,51 @@ QDF_STATUS wlan_p2p_status_connect(struct wlan_objmgr_vdev *vdev)
 
 	return p2p_status_connect(vdev);
 }
+
+static void wlan_p2p_abort_vdev_scan(struct wlan_objmgr_pdev *pdev,
+				     void *object, void *arg)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
+	struct scan_cancel_request *req;
+	struct p2p_soc_priv_obj *p2p_soc_obj;
+	QDF_STATUS status;
+
+	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_DEVICE_MODE)
+		return;
+
+	p2p_soc_obj =
+		wlan_objmgr_psoc_get_comp_private_obj(wlan_vdev_get_psoc(vdev),
+						      WLAN_UMAC_COMP_P2P);
+	if (!p2p_soc_obj) {
+		p2p_err("P2P soc object is NULL");
+		return;
+	}
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return;
+
+	req->vdev = vdev;
+	req->cancel_req.requester = p2p_soc_obj->scan_req_id;
+	req->cancel_req.scan_id = INVALID_SCAN_ID;
+	req->cancel_req.vdev_id = wlan_vdev_get_id(vdev);
+	req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
+
+	qdf_mtrace(QDF_MODULE_ID_P2P, QDF_MODULE_ID_SCAN,
+		   req->cancel_req.req_type,
+		   req->cancel_req.vdev_id,
+		   req->cancel_req.scan_id);
+	status = wlan_scan_cancel(req);
+
+	p2p_debug("abort scan, scan req id:%d, scan id:%d, status:%d",
+		  req->cancel_req.requester,
+		  req->cancel_req.scan_id, status);
+}
+
+QDF_STATUS wlan_p2p_abort_scan(struct wlan_objmgr_pdev *pdev)
+{
+	return wlan_objmgr_pdev_iterate_obj_list(pdev,
+						 WLAN_VDEV_OP,
+						 wlan_p2p_abort_vdev_scan,
+						 NULL, 0, WLAN_P2P_ID);
+}

+ 1 - 1
core/hdd/src/wlan_hdd_nan.c

@@ -93,7 +93,7 @@ static int __wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy,
 		return -EAGAIN;
 	}
 
-	return os_if_process_nan_req(hdd_ctx->psoc, adapter->vdev_id,
+	return os_if_process_nan_req(hdd_ctx->pdev, adapter->vdev_id,
 				     data, data_len);
 }
 

+ 2 - 2
os_if/nan/inc/os_if_nan.h

@@ -158,14 +158,14 @@ static inline QDF_STATUS os_if_nan_set_ndp_delete_transaction_id(
 /**
  * os_if_process_nan_req: os_if api to handle NAN requests attached to the
  * vendor command QCA_NL80211_VENDOR_SUBCMD_NAN_EXT
- * @psoc: pointer to psoc object
+ * @pdev: pointer to pdev object
  * @vdev_id: NAN vdev id
  * @data: request data. contains vendor cmd tlvs
  * @data_len: length of data
  *
  * Return: status of operation
  */
-int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+int os_if_process_nan_req(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 			  const void *data, int data_len);
 #else
 

+ 7 - 3
os_if/nan/src/os_if_nan.c

@@ -2501,6 +2501,7 @@ static int os_if_nan_generic_req(struct wlan_objmgr_psoc *psoc,
 	nan_req = qdf_mem_malloc(sizeof(*nan_req) +  buf_len);
 	if (!nan_req)
 		return -ENOMEM;
+	qdf_mem_zero(nan_req, sizeof(*nan_req) + buf_len);
 
 	nan_req->psoc = psoc;
 	nan_req->params.request_data_len = buf_len;
@@ -2533,7 +2534,7 @@ static int os_if_process_nan_disable_req(struct wlan_objmgr_psoc *psoc,
 	return qdf_status_to_os_return(status);
 }
 
-static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc,
+static int os_if_process_nan_enable_req(struct wlan_objmgr_pdev *pdev,
 					struct nlattr **tb)
 {
 	uint32_t chan_freq_2g, chan_freq_5g = 0;
@@ -2541,6 +2542,7 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc,
 	QDF_STATUS status;
 	uint32_t fine_time_meas_cap;
 	struct nan_enable_req *nan_req;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ]) {
 		osif_err("NAN Social channel for 2.4Gz is unavailable!");
@@ -2570,6 +2572,7 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc,
 	if (chan_freq_5g)
 		nan_req->social_chan_5g_freq = chan_freq_5g;
 	nan_req->psoc = psoc;
+	nan_req->pdev = pdev;
 	nan_req->params.request_data_len = buf_len;
 
 	ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap);
@@ -2592,11 +2595,12 @@ static int os_if_process_nan_enable_req(struct wlan_objmgr_psoc *psoc,
 	return qdf_status_to_os_return(status);
 }
 
-int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+int os_if_process_nan_req(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 			  const void *data, int data_len)
 {
 	uint32_t nan_subcmd;
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX + 1];
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 
 	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX,
 				    data, data_len, nan_attr_policy)) {
@@ -2631,7 +2635,7 @@ int os_if_process_nan_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 
 	switch (nan_subcmd) {
 	case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ:
-		return os_if_process_nan_enable_req(psoc, tb);
+		return os_if_process_nan_enable_req(pdev, tb);
 	case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ:
 		return os_if_process_nan_disable_req(psoc, tb);
 	default: