Browse Source

qcacld-3.0: Fix assert for sta ipa interface leaked

Once 1 roaming happened, ipa_ctx->sta_connected increased 1, and its
type was uint8_t, once increased to 256, overflow happened.
ipa_ctx->sta_connected became 0. then wlan_ipa_cleanup_iface couldn’t be
called to free old iface, but wlan_ipa_setup_iface was called to add new
iface, then there were 2 sta ipa interfaces with same session id 2.

When sta disconnected, only 1 ipa interface was freed, the other ipa
interface with session id 2 was left, but vdev 2 was deleted.

If 1st client connected DUT SAP, sta vdev 2 was found by mistake,
WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID was sent to F/W to enable IPA path
for vdev 2, but vdev 2 wasn't existed, assert happened.

To fix it, when LFR3 roaming happens, when wlan_ipa_cleanup_iface is
called to free old iface, ipa_ctx->sta_connected is decreased by 1
first, when wlan_ipa_setup_iface is called to add new iface,
ipa_ctx->sta_connected is increased by 1, then
ipa_ctx->sta_connected reflects real STA number on DUT.

Change-Id: I5c91b3402dcfe8b1828d8d1f0701f66ca3c15d50
CRs-Fixed: 2859438
Jianmin Zhu 4 years ago
parent
commit
cd6a5aa828
1 changed files with 7 additions and 3 deletions
  1. 7 3
      components/ipa/core/src/wlan_ipa_core.c

+ 7 - 3
components/ipa/core/src/wlan_ipa_core.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021 The Linux Foundation. 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
@@ -2240,13 +2240,17 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
 		qdf_mutex_acquire(&ipa_ctx->event_lock);
 
 		/* STA already connected and without disconnect, connect again
-		 * This is Roaming scenario
+		 * This is Roaming scenario, clean up ipa iface first, then add
+		 * ipa iface later, sta_connected-- first, sta_connected++
+		 * later to reflect real sta number on DUT.
 		 */
 		if (ipa_ctx->sta_connected) {
 			iface_ctx = wlan_ipa_get_iface_by_mode_netdev(
 					ipa_ctx, net_dev, QDF_STA_MODE);
-			if (iface_ctx)
+			if (iface_ctx) {
+				ipa_ctx->sta_connected--;
 				wlan_ipa_cleanup_iface(iface_ctx);
+			}
 			status = wlan_ipa_send_msg(net_dev,
 						   QDF_IPA_STA_DISCONNECT,
 						   mac_addr);