Procházet zdrojové kódy

qcacld-3.0: Remove policy mgr entry after NDI delete

In the host driver, after receiving NDP END INDICATIONs for all NDP
connections then policy manager deletes NDI mode from
pm_conc_connection_list.

From user-space application, if NDP END REQUEST and NDI DELETE request
are issued back to back without waiting for NDP END indication, then
firmware could process NDI DELETE command firstly and avoid NDP END
indication due to peer delete as a part of NDI delete.

If vendor command NDI delete request is issued without receiving
NDP_END_INDICATIONs for all active NDP peers then pm_conc_connection_list
contains stale entry of PM_NDI_MODE associated with deleted NDI.

Stale NDI entry in pm_conc_connection_list is the cause for failure of
get_second_connection_pcl_table_index() for PM_NAN_DISC_MODE, therefore
further NAN enable requests are rejected.

To address this issue, cleanup PM_NDI_MODE from pm_conc_connection_list
as a part of NDI delete.

Change-Id: Ic1535420b60224cc426b24e22fe7486781fd2fa6
CRs-Fixed: 2519625
Rajeev Kumar Sirasanagandla před 5 roky
rodič
revize
c64548c8a8

+ 9 - 0
components/nan/dispatcher/inc/nan_ucfg_api.h

@@ -320,6 +320,15 @@ int ucfg_nan_register_wma_callbacks(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS
 ucfg_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * ucfg_ndi_remove_entry_from_policy_mgr() - API to remove NDI entry from
+ *	policy manager.
+ * @vdev: vdev pointer for NDI interface
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_ndi_remove_entry_from_policy_mgr(struct wlan_objmgr_vdev *vdev);
+
 #else /* WLAN_FEATURE_NAN */
 
 static inline

+ 42 - 0
components/nan/dispatcher/src/nan_ucfg_api.c

@@ -833,3 +833,45 @@ cleanup:
 
 	return status;
 }
+
+QDF_STATUS ucfg_ndi_remove_entry_from_policy_mgr(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct nan_psoc_priv_obj *psoc_priv_obj;
+	struct nan_vdev_priv_obj *vdev_priv_obj = nan_get_vdev_priv_obj(vdev);
+	enum nan_datapath_state state;
+	uint32_t active_ndp_peers;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		nan_err("can't get psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	psoc_priv_obj = nan_get_psoc_priv_obj(psoc);
+	if (!psoc_priv_obj) {
+		nan_err("psoc_priv_obj is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!vdev_priv_obj) {
+		nan_err("priv_obj is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	qdf_spin_lock_bh(&vdev_priv_obj->lock);
+	state = vdev_priv_obj->state;
+	active_ndp_peers = vdev_priv_obj->active_ndp_peers;
+	qdf_spin_unlock_bh(&vdev_priv_obj->lock);
+
+	if (state == NAN_DATA_NDI_DELETED_STATE &&
+	    psoc_priv_obj->nan_caps.ndi_dbs_supported &&
+	    active_ndp_peers) {
+		nan_info("Delete NDP peers: %u and remove NDI from policy mgr",
+			 active_ndp_peers);
+		policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE,
+						wlan_vdev_get_id(vdev));
+	}
+
+	return QDF_STATUS_SUCCESS;
+}

+ 1 - 0
os_if/nan/src/os_if_nan.c

@@ -2451,6 +2451,7 @@ void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev)
 
 	ucfg_nan_set_ndp_delete_transaction_id(vdev, 0);
 	ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE);
+	ucfg_ndi_remove_entry_from_policy_mgr(vdev);
 	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
 
 	return;