Explorar o código

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

This reverts commit 54c2fe240ad44abfd990d556117d6510c7e74c8f.

Change-Id: Ic0028674e4728b951215bf7b4d9a7535b8b49efe
CRs-Fixed: 3523826
Rahul Gusain hai 1 ano
pai
achega
bb7e163983

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

@@ -83,6 +83,7 @@ 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,
@@ -102,6 +103,7 @@ enum nan_datapath_msg_type {
 	NDP_PEER_DEPARTED            = 14,
 	NDP_SCHEDULE_UPDATE          = 15,
 	NDP_END_ALL                  = 16,
+	NDP_HOST_UPDATE              = 17,
 };
 
 /**
@@ -765,6 +767,17 @@ 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

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

@@ -999,6 +999,38 @@ 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;
@@ -1087,6 +1119,11 @@ 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;

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

@@ -473,7 +473,8 @@ 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.
+ * 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.
  *
  * Return: status of operation
  */

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

@@ -956,6 +956,7 @@ 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;
@@ -963,7 +964,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 = 0,
+		.priv_size = sizeof(struct nan_datapath_host_event),
 		.timeout_ms = 1000,
 	};
 
@@ -1009,6 +1010,7 @@ 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;
 	}
 
@@ -1021,7 +1023,18 @@ ucfg_nan_disable_ndi(struct wlan_objmgr_psoc *psoc, uint32_t ndi_vdev_id)
 		goto cleanup;
 	}
 
-	policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE, ndi_vdev_id);
+	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);
+	}
 
 cleanup:
 	/* Restore original NDI state in case of failure */
@@ -1030,8 +1043,6 @@ 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);
 

+ 70 - 0
components/target_if/nan/src/target_if_nan.c

@@ -96,6 +96,9 @@ 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;
 	}
@@ -138,6 +141,9 @@ 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;
@@ -724,6 +730,61 @@ 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 */
@@ -1001,6 +1062,15 @@ 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;
 }
 

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

@@ -1980,42 +1980,6 @@ 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
@@ -2049,10 +2013,6 @@ 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)
@@ -2391,6 +2351,39 @@ 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)
@@ -2429,6 +2422,9 @@ 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;
 	}