Переглянути джерело

qcacld-3.0: Block NDP_END_ALL req till last NDP_END is received

Firmware sends NDP_HOST_UPDATE event as an immediate response to this
request and starts cleaning peers one by one. Once an NDP session is
ended (indicating NDP_END to peer + internal cleanup), firmware sends
NDP_END_IND to host.
Currently, host driver stops the wait timer and change state from NDP
end to disconnected upon receiving the NDP_HOST_UPDATE. But firmware
might still be in the process of NDP cleanup. As the NDP_END_ALL
context is unblocked, driver may send NAN disable request to firmware.
This may cause inconsistency in firmware state machine and firmware may
drop the ongoing NDP_END request. So, peer doesn't get the NDP_END frame
in such cases.

Unblock the NDP_END_ALL-wait call only upon last NDP_END indication to
avoid such issues. This change moves the major functionality of
NDP_HOST_UPDATE processing to last NDP_END indication. Cleanup/remove
the processing of NDP_HOST_UPDATE as it's not needed anymore.

Change-Id: I19d3e40700c1c0501b9c809820262472bf9bdba4
CRs-Fixed: 3512847
Rahul Gusain 1 рік тому
батько
коміт
54c2fe240a

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

@@ -83,7 +83,6 @@ enum nan_discovery_msg_type {
  * @NDP_PEER_DEPARTED: ndp peer departed/deleted
  * @NDP_SCHEDULE_UPDATE: ndp schedule update
  * @NDP_END_ALL: end all NDPs request
- * @NDP_HOST_UPDATE: update host about ndp status
  */
 enum nan_datapath_msg_type {
 	NAN_DATAPATH_INF_CREATE_REQ  = 0,
@@ -103,7 +102,6 @@ enum nan_datapath_msg_type {
 	NDP_PEER_DEPARTED            = 14,
 	NDP_SCHEDULE_UPDATE          = 15,
 	NDP_END_ALL                  = 16,
-	NDP_HOST_UPDATE              = 17,
 };
 
 /**
@@ -767,17 +765,6 @@ struct nan_datapath_sch_update_event {
 	uint32_t ndp_instances[NDP_NUM_INSTANCE_ID];
 };
 
-/**
- * struct nan_datapath_host_event - ndp host event parameters
- * @vdev: vdev obj associated with the ndp
- * @ndp_termination_in_progress: flag that indicates whether NDPs associated
- * with the given vdev are being terminated
- */
-struct nan_datapath_host_event {
-	struct wlan_objmgr_vdev *vdev;
-	bool ndp_termination_in_progress;
-};
-
 /**
  * struct nan_callbacks - struct containing callback to non-converged driver
  * @os_if_nan_event_handler: OS IF Callback for handling NAN Discovery events

+ 0 - 37
components/nan/core/src/nan_main.c

@@ -999,38 +999,6 @@ static QDF_STATUS nan_handle_schedule_update(
 	return QDF_STATUS_SUCCESS;
 }
 
-/**
- * nan_handle_host_update() - Updates Host about NAN Datapath status
- * @evt: Event data received from firmware
- * @vdev: pointer to vdev
- *
- * Return: status of operation
- */
-static QDF_STATUS nan_handle_host_update(struct nan_datapath_host_event *evt,
-					 struct wlan_objmgr_vdev **vdev)
-{
-	struct wlan_objmgr_psoc *psoc;
-	struct nan_psoc_priv_obj *psoc_nan_obj;
-
-	*vdev = evt->vdev;
-	psoc = wlan_vdev_get_psoc(evt->vdev);
-	if (!psoc) {
-		nan_err("psoc is NULL");
-		return QDF_STATUS_E_NULL_VALUE;
-	}
-
-	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
-	if (!psoc_nan_obj) {
-		nan_err("psoc_nan_obj is NULL");
-		return QDF_STATUS_E_NULL_VALUE;
-	}
-
-	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, evt->vdev,
-						     NDP_HOST_UPDATE, evt);
-
-	return QDF_STATUS_SUCCESS;
-}
-
 QDF_STATUS nan_discovery_event_handler(struct scheduler_msg *msg)
 {
 	struct nan_event_params *nan_event;
@@ -1119,11 +1087,6 @@ QDF_STATUS nan_datapath_event_handler(struct scheduler_msg *pe_msg)
 	case NDP_SCHEDULE_UPDATE:
 		nan_handle_schedule_update(pe_msg->bodyptr);
 		break;
-	case NDP_HOST_UPDATE:
-		nan_handle_host_update(pe_msg->bodyptr, &cmd.vdev);
-		cmd.cmd_type = WLAN_SER_CMD_NDP_END_ALL_REQ;
-		wlan_serialization_remove_cmd(&cmd);
-		break;
 	default:
 		nan_alert("Unhandled NDP event: %d", pe_msg->type);
 		status = QDF_STATUS_E_NOSUPPORT;

+ 1 - 2
components/nan/dispatcher/inc/nan_ucfg_api.h

@@ -473,8 +473,7 @@ QDF_STATUS ucfg_disable_nan_discovery(struct wlan_objmgr_psoc *psoc,
  * @ndi_vdev_id: vdev_id of the NDI to be disabled
  *
  * Disable all the NDPs present on the given NDI by sending NDP_END_ALL
- * to firmware. Firmwere sends an immediate response(NDP_HOST_UPDATE) with
- * ndp_disable param as 1 followed by NDP_END indication for all the NDPs.
+ * to firmware.
  *
  * Return: status of operation
  */

+ 4 - 15
components/nan/dispatcher/src/nan_ucfg_api.c

@@ -956,7 +956,6 @@ QDF_STATUS
 ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id)
 {
 	enum nan_datapath_state curr_ndi_state;
-	struct nan_datapath_host_event *event;
 	struct nan_vdev_priv_obj *ndi_vdev_priv;
 	struct nan_datapath_end_all_ndps req = {0};
 	struct wlan_objmgr_vdev *ndi_vdev;
@@ -964,7 +963,7 @@ ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id)
 	QDF_STATUS status;
 	int err;
 	static const struct osif_request_params params = {
-		.priv_size = sizeof(struct nan_datapath_host_event),
+		.priv_size = 0,
 		.timeout_ms = 1000,
 	};
 
@@ -1010,7 +1009,6 @@ ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id)
 
 	if (QDF_IS_STATUS_ERROR(status)) {
 		nan_err("Unable to disable NDP's on NDI");
-		wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
 		goto cleanup;
 	}
 
@@ -1023,18 +1021,7 @@ ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id)
 		goto cleanup;
 	}
 
-	event = osif_request_priv(request);
-	if (!event->ndp_termination_in_progress) {
-		nan_err("Failed to terminate NDP's on NDI");
-		status = QDF_STATUS_E_FAILURE;
-	} else {
-		/*
-		 * Host can assume NDP delete is successful and
-		 * remove policy mgr entry
-		 */
-		policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE,
-						ndi_vdev_id);
-	}
+	policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE, ndi_vdev_id);
 
 cleanup:
 	/* Restore original NDI state in case of failure */
@@ -1043,6 +1030,8 @@ cleanup:
 	else
 		ucfg_nan_set_ndi_state(ndi_vdev, curr_ndi_state);
 
+	wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
+
 	if (request)
 		osif_request_put(request);
 

+ 1 - 71
components/target_if/nan/src/target_if_nan.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-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
@@ -96,9 +96,6 @@ static QDF_STATUS target_if_ndp_event_flush_cb(struct scheduler_msg *msg)
 	case NDP_SCHEDULE_UPDATE:
 		vdev = ((struct nan_datapath_sch_update_event *)ptr)->vdev;
 		break;
-	case NDP_HOST_UPDATE:
-		vdev = ((struct nan_datapath_host_event *)ptr)->vdev;
-		break;
 	default:
 		break;
 	}
@@ -141,9 +138,6 @@ static QDF_STATUS target_if_ndp_event_dispatcher(struct scheduler_msg *msg)
 	case NDP_SCHEDULE_UPDATE:
 		vdev = ((struct nan_datapath_sch_update_event *)ptr)->vdev;
 		break;
-	case NDP_HOST_UPDATE:
-		vdev = ((struct nan_datapath_host_event *)ptr)->vdev;
-		break;
 	default:
 		target_if_err("invalid msg type %d", msg->type);
 		status = QDF_STATUS_E_INVAL;
@@ -730,61 +724,6 @@ static QDF_STATUS target_if_nan_end_all_ndps_req(void *req)
 	return wmi_unified_terminate_all_ndps_req_cmd(wmi_handle, vdev_id);
 }
 
-static int target_if_ndp_host_event_handler(ol_scn_t scn, uint8_t *data,
-					    uint32_t data_len)
-{
-	QDF_STATUS status;
-	struct wlan_objmgr_psoc *psoc;
-	struct wmi_unified *wmi_handle;
-	struct scheduler_msg msg = {0};
-	struct nan_datapath_host_event *host_evt = NULL;
-
-	psoc = target_if_get_psoc_from_scn_hdl(scn);
-	if (!psoc) {
-		target_if_err("psoc is null");
-		return -EINVAL;
-	}
-
-	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
-	if (!wmi_handle) {
-		target_if_err("wmi_handle is null.");
-		return -EINVAL;
-	}
-
-	host_evt = qdf_mem_malloc(sizeof(*host_evt));
-	if (!host_evt)
-		return -ENOMEM;
-
-	status = wmi_extract_ndp_host_event(wmi_handle, data, host_evt);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		target_if_err("parsing of event failed, %d", status);
-		qdf_mem_free(host_evt);
-		return -EINVAL;
-	}
-
-	if (!host_evt->vdev) {
-		target_if_err("vdev is null");
-		qdf_mem_free(host_evt);
-		return -EINVAL;
-	}
-
-	msg.bodyptr = host_evt;
-	msg.type = NDP_HOST_UPDATE;
-	msg.callback = target_if_ndp_event_dispatcher;
-	msg.flush_callback = target_if_ndp_event_flush_cb;
-	target_if_debug("NDP_HOST_UPDATE sent: %d", msg.type);
-	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
-					QDF_MODULE_ID_TARGET_IF,
-					QDF_MODULE_ID_TARGET_IF, &msg);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		target_if_err("failed to post msg, status: %d", status);
-		target_if_ndp_event_flush_cb(&msg);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static QDF_STATUS target_if_nan_datapath_req(void *req, uint32_t req_type)
 {
 	/* send cmd to fw */
@@ -1062,15 +1001,6 @@ QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	ret = wmi_unified_register_event_handler(handle, wmi_ndp_event_id,
-					       target_if_ndp_host_event_handler,
-					       WMI_RX_UMAC_CTX);
-	if (QDF_IS_STATUS_ERROR(ret)) {
-		target_if_err("wmi event registration failed, ret: %d", ret);
-		target_if_nan_deregister_events(psoc);
-		return QDF_STATUS_E_FAILURE;
-	}
-
 	return QDF_STATUS_SUCCESS;
 }
 

+ 40 - 36
os_if/nan/src/os_if_nan.c

@@ -1980,6 +1980,42 @@ static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev,
 	osif_debug("num_peers: %d", active_peers);
 }
 
+/**
+ * os_if_ndp_end_all_handler: Handler for NDP_END_ALL request cmd
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id of ndi
+ *
+ * Return: None
+ */
+static void os_if_ndp_end_all_handler(struct wlan_objmgr_psoc *psoc,
+				      uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct nan_vdev_priv_obj *vdev_nan_obj;
+	struct osif_request *request;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_NAN_ID);
+	if (!vdev) {
+		osif_err("vdev is NULL for vdev_id %d", vdev_id);
+		return;
+	}
+
+	vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
+	if (!vdev_nan_obj) {
+		osif_err("vdev_nan_obj is NULL");
+		return;
+	}
+
+	request = osif_request_get(vdev_nan_obj->disable_context);
+	if (!request) {
+		osif_debug("Obsolete request");
+		return;
+	}
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
 /**
  * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication
  * @vdev: vdev object
@@ -2013,6 +2049,10 @@ static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev,
 	cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id,
 				&peer_ind->peer_mac_addr,
 				(active_peers == 0 ? true : false));
+
+	/* if no peer left, stop wait timer for NDP_END_ALL` */
+	if (!active_peers)
+		os_if_ndp_end_all_handler(psoc, vdev_id);
 }
 
 static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void)
@@ -2351,39 +2391,6 @@ ndp_sch_ind_nla_failed:
 	wlan_cfg80211_vendor_free_skb(vendor_event);
 }
 
-/**
- * os_if_ndp_host_update_handler() - NDP Host update handler
- * @vdev: vdev object pointer
- * @evt: pointer to host update event
- *
- * Return: none
- */
-static void os_if_ndp_host_update_handler(struct wlan_objmgr_vdev *vdev,
-					  void *evt)
-{
-	struct nan_vdev_priv_obj *vdev_nan_obj;
-	struct nan_datapath_host_event *event;
-	struct osif_request *request;
-
-	vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
-	if (!vdev_nan_obj) {
-		osif_err("vdev_nan_obj is NULL");
-		return;
-	}
-
-	request = osif_request_get(vdev_nan_obj->disable_context);
-	if (!request) {
-		osif_debug("Obsolete request");
-		return;
-	}
-
-	event = osif_request_priv(request);
-	qdf_mem_copy(event, evt, sizeof(*event));
-
-	osif_request_complete(request);
-	osif_request_put(request);
-}
-
 static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
 					     struct wlan_objmgr_vdev *vdev,
 					     uint32_t type, void *msg)
@@ -2422,9 +2429,6 @@ static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
 	case NDP_SCHEDULE_UPDATE:
 		os_if_ndp_sch_update_ind_handler(vdev, msg);
 		break;
-	case NDP_HOST_UPDATE:
-		os_if_ndp_host_update_handler(vdev, msg);
-		break;
 	default:
 		break;
 	}