瀏覽代碼

qcacmn: Add check to find IPA iface_ctx based on vdev_id

IPA APIs currently depend on the net_dev value to distinguish
between the IPA iface_contexts, during setup and cleanup calls.
Due to single net_dev multi vdev change, this check is not
valid anymore and causes overwrite of the IPA iface contexts.
This change adds a check to also compare the vdev_id along with
net_dev to properly distinguish between the iface contexts.

Change-Id: Ifa9bad267d26957f61f9c82644753278d2be1cd0
CRs-Fixed: 3576347
Namita Nair 1 年之前
父節點
當前提交
aa4f14ce5a

+ 21 - 3
ipa/core/inc/wlan_ipa_core.h

@@ -156,17 +156,33 @@ QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx);
 struct wlan_ipa_iface_context
 *wlan_ipa_get_iface(struct wlan_ipa_priv *ipa_ctx, uint8_t mode);
 
+/**
+ * wlan_ipa_check_iface_netdev_sessid() - Check IPA interface using netdev
+ * and session id
+ *
+ * @ipa_iface: IPA iface
+ * @net_dev: net dev
+ * @session_id: vdev id
+ *
+ * Return: Result if iface is matching or not
+ */
+int wlan_ipa_check_iface_netdev_sessid(struct wlan_ipa_iface_context *ipa_iface,
+				       qdf_netdev_t net_dev,
+				       uint8_t session_id);
+
 /**
  * wlan_ipa_get_iface_by_mode_netdev() - Get IPA interface
  * @ipa_ctx: IPA context
  * @ndev: Interface netdev pointer
  * @mode: Interface device mode
+ * @session_id: vdev id
  *
  * Return: IPA interface address
  */
 struct wlan_ipa_iface_context *
 wlan_ipa_get_iface_by_mode_netdev(struct wlan_ipa_priv *ipa_ctx,
-				  qdf_netdev_t ndev, uint8_t mode);
+				  qdf_netdev_t ndev, uint8_t mode,
+				  uint8_t session_id);
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \
 	!defined(CONFIG_IPA_WDI_UNIFIED_API)
@@ -788,6 +804,7 @@ bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx);
  * wlan_ipa_uc_cleanup_sta - disconnect and cleanup sta iface
  * @ipa_ctx: IPA context
  * @net_dev: Interface net device
+ * @session_id: vdev id
  *
  * Send disconnect sta event to IPA driver and cleanup IPA iface
  * if not yet done
@@ -795,7 +812,7 @@ bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx);
  * Return: void
  */
 void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
-			     qdf_netdev_t net_dev);
+			     qdf_netdev_t net_dev, uint8_t session_id);
 
 /**
  * wlan_ipa_uc_disconnect_ap() - send ap disconnect event
@@ -813,11 +830,12 @@ QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
  * wlan_ipa_cleanup_dev_iface() - Clean up net dev IPA interface
  * @ipa_ctx: IPA context
  * @net_dev: Interface net device
+ * @session_id: vdev id
  *
  * Return: None
  */
 void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx,
-				qdf_netdev_t net_dev);
+				qdf_netdev_t net_dev, uint8_t session_id);
 
 /**
  * wlan_ipa_uc_ssr_cleanup() - handle IPA UC clean up during SSR

+ 4 - 2
ipa/core/inc/wlan_ipa_main.h

@@ -484,6 +484,7 @@ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
  * ipa_uc_cleanup_sta() - disconnect and cleanup sta iface
  * @pdev: pdev obj
  * @net_dev: Interface net device
+ * @session_id: vdev id
  *
  * Send disconnect sta event to IPA driver and cleanup IPA iface,
  * if not yet done
@@ -491,7 +492,7 @@ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
  * Return: void
  */
 void ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
-			qdf_netdev_t net_dev);
+			qdf_netdev_t net_dev, uint8_t session_id);
 
 /**
  * ipa_uc_disconnect_ap() - send ap disconnect event
@@ -509,11 +510,12 @@ QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
  * ipa_cleanup_dev_iface() - Clean up net dev IPA interface
  * @pdev: pdev obj
  * @net_dev: Interface net device
+ * @session_id: vdev_id
  *
  * Return: None
  */
 void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
-			   qdf_netdev_t net_dev);
+			   qdf_netdev_t net_dev, uint8_t session_id);
 
 /**
  * ipa_uc_ssr_cleanup() - handle IPA UC cleanup during SSR

+ 33 - 12
ipa/core/src/wlan_ipa_core.c

@@ -2258,7 +2258,8 @@ static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx,
 
 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 		iface_context = &(ipa_ctx->iface_context[i]);
-		if (iface_context->dev == net_dev) {
+		if (wlan_ipa_check_iface_netdev_sessid(iface_context, net_dev,
+						       session_id)) {
 			if (iface_context->device_mode == device_mode) {
 				/**
 				 * Lower layer may send multiple START_BSS_EVENT
@@ -3140,7 +3141,9 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 			    type == QDF_IPA_AP_DISCONNECT) {
 				for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 					iface_ctx = &ipa_ctx->iface_context[i];
-					if (iface_ctx->dev == net_dev) {
+					if (wlan_ipa_check_iface_netdev_sessid(
+							     iface_ctx, net_dev,
+							     session_id)) {
 						wlan_ipa_cleanup_iface(
 								iface_ctx,
 								mac_addr);
@@ -3176,7 +3179,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 		 */
 		if (ipa_ctx->sta_connected) {
 			iface_ctx = wlan_ipa_get_iface_by_mode_netdev(
-					ipa_ctx, net_dev, QDF_STA_MODE);
+					ipa_ctx, net_dev, QDF_STA_MODE,
+					session_id);
 			if (iface_ctx) {
 				ipa_ctx->sta_connected--;
 				wlan_ipa_cleanup_iface(iface_ctx, NULL);
@@ -3314,7 +3318,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 
 			iface = wlan_ipa_get_iface_by_mode_netdev(ipa_ctx,
 								  net_dev,
-								  QDF_STA_MODE);
+								  QDF_STA_MODE,
+								  session_id);
 			if (iface)
 				wlan_ipa_cleanup_iface(iface, mac_addr);
 
@@ -3371,7 +3376,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 
 		iface_ctx = wlan_ipa_get_iface_by_mode_netdev(ipa_ctx,
 							      net_dev,
-							      QDF_STA_MODE);
+							      QDF_STA_MODE,
+							      session_id);
 		if (iface_ctx)
 			wlan_ipa_cleanup_iface(iface_ctx, mac_addr);
 
@@ -3423,7 +3429,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 
 		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 			iface_ctx = &ipa_ctx->iface_context[i];
-			if (iface_ctx->dev == net_dev) {
+			if (wlan_ipa_check_iface_netdev_sessid(iface_ctx,
+							net_dev, session_id)) {
 				wlan_ipa_cleanup_iface(iface_ctx, mac_addr);
 				break;
 			}
@@ -4530,9 +4537,19 @@ struct wlan_ipa_iface_context
 	return NULL;
 }
 
+int wlan_ipa_check_iface_netdev_sessid(struct wlan_ipa_iface_context *iface_ctx,
+				       qdf_netdev_t net_dev, uint8_t session_id)
+{
+	if (iface_ctx->dev == net_dev && iface_ctx->session_id == session_id)
+		return 1;
+
+	return 0;
+}
+
 struct wlan_ipa_iface_context *
 wlan_ipa_get_iface_by_mode_netdev(struct wlan_ipa_priv *ipa_ctx,
-				  qdf_netdev_t ndev, uint8_t mode)
+				  qdf_netdev_t ndev, uint8_t mode,
+				  uint8_t session_id)
 {
 	struct wlan_ipa_iface_context *iface_ctx = NULL;
 	int i;
@@ -4540,7 +4557,9 @@ wlan_ipa_get_iface_by_mode_netdev(struct wlan_ipa_priv *ipa_ctx,
 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 		iface_ctx = &ipa_ctx->iface_context[i];
 
-		if (iface_ctx->device_mode == mode && iface_ctx->dev == ndev)
+		if (iface_ctx->device_mode == mode &&
+		    wlan_ipa_check_iface_netdev_sessid(iface_ctx, ndev,
+						       session_id))
 			return iface_ctx;
 	}
 
@@ -5051,7 +5070,7 @@ static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev,
 }
 
 void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
-			     qdf_netdev_t net_dev)
+			     qdf_netdev_t net_dev, uint8_t session_id)
 {
 	struct wlan_ipa_iface_context *iface_ctx;
 	int i;
@@ -5061,7 +5080,8 @@ void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 		iface_ctx = &ipa_ctx->iface_context[i];
 		if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE &&
-		    iface_ctx->dev && iface_ctx->dev == net_dev) {
+		    wlan_ipa_check_iface_netdev_sessid(iface_ctx, net_dev,
+						       session_id)) {
 			wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT,
 					     (uint8_t *)net_dev->dev_addr,
 					     ipa_ctx);
@@ -5094,14 +5114,15 @@ QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
 }
 
 void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx,
-				qdf_netdev_t net_dev)
+				qdf_netdev_t net_dev, uint8_t session_id)
 {
 	struct wlan_ipa_iface_context *iface_ctx;
 	int i;
 
 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
 		iface_ctx = &ipa_ctx->iface_context[i];
-		if (iface_ctx->dev == net_dev) {
+		if (wlan_ipa_check_iface_netdev_sessid(iface_ctx, net_dev,
+						       session_id)) {
 			wlan_ipa_cleanup_iface(iface_ctx, NULL);
 			break;
 		}

+ 4 - 4
ipa/core/src/wlan_ipa_main.c

@@ -737,7 +737,7 @@ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
 }
 
 void ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
-			qdf_netdev_t net_dev)
+			qdf_netdev_t net_dev, uint8_t session_id)
 {
 	struct wlan_ipa_priv *ipa_obj;
 
@@ -752,7 +752,7 @@ void ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
 		return;
 	}
 
-	return wlan_ipa_uc_cleanup_sta(ipa_obj, net_dev);
+	return wlan_ipa_uc_cleanup_sta(ipa_obj, net_dev, session_id);
 }
 
 QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
@@ -773,7 +773,7 @@ QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
 }
 
 void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
-			   qdf_netdev_t net_dev)
+			   qdf_netdev_t net_dev, uint8_t session_id)
 {
 	struct wlan_ipa_priv *ipa_obj;
 
@@ -786,7 +786,7 @@ void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
 		return;
 	}
 
-	return wlan_ipa_cleanup_dev_iface(ipa_obj, net_dev);
+	return wlan_ipa_cleanup_dev_iface(ipa_obj, net_dev, session_id);
 }
 
 void ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev)

+ 6 - 4
ipa/dispatcher/inc/wlan_ipa_ucfg_api.h

@@ -366,6 +366,7 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
  * ucfg_ipa_uc_cleanup_sta() - disconnect and cleanup sta iface
  * @pdev: pdev obj
  * @net_dev: Interface net device
+ * @session_id: vdev id
  *
  * Send disconnect sta event to IPA driver and cleanup IPA iface,
  * if not yet done
@@ -373,7 +374,7 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
  * Return: void
  */
 void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
-			     qdf_netdev_t net_dev);
+			     qdf_netdev_t net_dev, uint8_t session_id);
 
 /**
  * ucfg_ipa_uc_disconnect_ap() - send ap disconnect event
@@ -391,12 +392,13 @@ QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
  * ucfg_ipa_cleanup_dev_iface() - Clean up net dev IPA interface
  * @pdev: pdev obj
  * @net_dev: Interface net device
+ * @session_id: vdev id
  *
  *
  * Return: None
  */
 void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
-				qdf_netdev_t net_dev);
+				qdf_netdev_t net_dev, uint8_t session_id);
 
 /**
  * ucfg_ipa_uc_ssr_cleanup() - Handle IPA cleanup for SSR
@@ -673,7 +675,7 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
 
 static inline
 void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
-			     qdf_netdev_t net_dev)
+			     qdf_netdev_t net_dev, uint8_t session_id)
 {
 }
 
@@ -686,7 +688,7 @@ QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
 
 static inline
 void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
-				qdf_netdev_t net_dev)
+				qdf_netdev_t net_dev, uint8_t session_id)
 {
 }
 

+ 4 - 4
ipa/dispatcher/src/wlan_ipa_ucfg_api.c

@@ -281,9 +281,9 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
 qdf_export_symbol(ucfg_ipa_is_fw_wdi_activated);
 
 void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
-			     qdf_netdev_t net_dev)
+			     qdf_netdev_t net_dev, uint8_t session_id)
 {
-	return ipa_uc_cleanup_sta(pdev, net_dev);
+	return ipa_uc_cleanup_sta(pdev, net_dev, session_id);
 }
 
 qdf_export_symbol(ucfg_ipa_uc_cleanup_sta);
@@ -297,9 +297,9 @@ QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
 qdf_export_symbol(ucfg_ipa_uc_disconnect_ap);
 
 void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev,
-				qdf_netdev_t net_dev)
+				qdf_netdev_t net_dev, uint8_t session_id)
 {
-	return ipa_cleanup_dev_iface(pdev, net_dev);
+	return ipa_cleanup_dev_iface(pdev, net_dev, session_id);
 }
 
 qdf_export_symbol(ucfg_ipa_cleanup_dev_iface);