فهرست منبع

qcacld-3.0: release the NDP end all command

Currently, driver post NDP end all command on the scheduler but
never release it. This casues timeout in the scheduler and driver
releases the vdev which is never referenced. This causes crash in
driver.

To resolve this issue, release the NDP end all command when NDP
Host Update event received from the firmware.

Change-Id: Iffe4f79b7c131c48cbf2b085d8bbc6e1fb0b5f0a
CRs-Fixed: 3521989
Rahul Gusain 1 سال پیش
والد
کامیت
bcb01fb787
3فایلهای تغییر یافته به همراه40 افزوده شده و 72 حذف شده
  1. 3 22
      components/nan/core/src/nan_main.c
  2. 6 14
      components/nan/dispatcher/src/nan_ucfg_api.c
  3. 31 36
      os_if/nan/src/os_if_nan.c

+ 3 - 22
components/nan/core/src/nan_main.c

@@ -1000,35 +1000,16 @@ static QDF_STATUS nan_handle_schedule_update(
 }
 
 /**
- * nan_handle_host_update() - Updates Host about NAN Datapath status
+ * nan_handle_host_update() - extract the vdev from host event
  * @evt: Event data received from firmware
  * @vdev: pointer to vdev
  *
- * Return: status of operation
+ * Return: none
  */
-static QDF_STATUS nan_handle_host_update(struct nan_datapath_host_event *evt,
+static void 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)

+ 6 - 14
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,
 	};
 
@@ -1023,18 +1022,11 @@ 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);
-	}
+	/*
+	 * 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 */

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

@@ -1980,6 +1980,33 @@ 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
+ * @vdev: pointer to vdev object
+ *
+ * Return: None
+ */
+static void os_if_ndp_end_all_handler(struct wlan_objmgr_vdev *vdev)
+{
+	struct nan_vdev_priv_obj *vdev_nan_obj;
+	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;
+	}
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
 /**
  * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication
  * @vdev: vdev object
@@ -2013,6 +2040,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(vdev);
 }
 
 static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void)
@@ -2351,39 +2382,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 +2420,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;
 	}