Explorar el Código

qcacld-3.0: Remove link DP intf on mode change to ML SAP

If ML SAP interface is created on ML STA interface, the MAC
address of the link adapter is changed to MLD address as SL SAP
uses same address for MLD and link. This leaves the DP interface
created with link address during open adapter is not cleared
and also leading to two adapter having same link address which
results in calling DP interface delete with same MAC address twice
and eventually leading to device crash.

Release the DP interface on mode change to ML SAP and create new
DP interface on mode change from SAP to STA. If close adapter is
called while in SAP mode then don't delete DP interface for link
adapter.

Change-Id: I001d4733ba208ccbbd2d65b53497d5120f27a179
CRs-Fixed: 3351414
Vinod Kumar Pirla hace 2 años
padre
commit
d3ede92170
Se han modificado 2 ficheros con 38 adiciones y 19 borrados
  1. 29 13
      core/hdd/src/wlan_hdd_cfg80211.c
  2. 9 6
      core/hdd/src/wlan_hdd_mlo.c

+ 29 - 13
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. 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
@@ -20020,23 +20020,27 @@ static bool hdd_is_ap_mode(enum QDF_OPMODE mode)
  *
  * Return: void
  */
-static void
+static QDF_STATUS
 hdd_adapter_update_mac_on_mode_change(struct hdd_adapter *adapter,
 				      bool get_new_addr)
 {
 	uint8_t *new_mac;
 	bool is_mac_equal;
 	struct hdd_adapter *assoc_adapter;
+	struct qdf_mac_addr *assoc_mac;
+	QDF_STATUS status;
 
 	if (!adapter || !hdd_adapter_is_ml_adapter(adapter))
-		return;
+		return QDF_STATUS_SUCCESS;
 
 	assoc_adapter = hdd_get_assoc_link_adapter(adapter);
 	if (!assoc_adapter || qdf_is_macaddr_zero(&assoc_adapter->mld_addr))
-		return;
+		return QDF_STATUS_E_INVAL;
 
-	is_mac_equal = qdf_is_macaddr_equal(&assoc_adapter->mac_addr,
-					    &assoc_adapter->mld_addr);
+	assoc_mac = &assoc_adapter->mac_addr;
+
+	is_mac_equal = qdf_is_macaddr_equal(&assoc_adapter->mld_addr,
+					    assoc_mac);
 
 	if (get_new_addr) {
 		/* If both address are already different
@@ -20048,8 +20052,13 @@ hdd_adapter_update_mac_on_mode_change(struct hdd_adapter *adapter,
 		new_mac = wlan_hdd_get_intf_addr(adapter->hdd_ctx,
 						 QDF_STA_MODE);
 		if (new_mac) {
-			memcpy(assoc_adapter->mac_addr.bytes,
-			       new_mac, QDF_MAC_ADDR_SIZE);
+			memcpy(assoc_mac->bytes, new_mac, QDF_MAC_ADDR_SIZE);
+			status = ucfg_dp_create_intf(
+					assoc_adapter->hdd_ctx->psoc,
+					assoc_mac,
+					(qdf_netdev_t)assoc_adapter->dev);
+			if (QDF_IS_STATUS_ERROR(status))
+				return status;
 		}
 	} else {
 		/* If both address are already equal
@@ -20058,14 +20067,15 @@ hdd_adapter_update_mac_on_mode_change(struct hdd_adapter *adapter,
 		if (is_mac_equal)
 			goto out;
 
-		wlan_hdd_release_intf_addr(adapter->hdd_ctx,
-					   assoc_adapter->mac_addr.bytes);
-		qdf_copy_macaddr(&assoc_adapter->mac_addr, &adapter->mld_addr);
+		wlan_hdd_release_intf_addr(adapter->hdd_ctx, assoc_mac->bytes);
+		ucfg_dp_destroy_intf(adapter->hdd_ctx->psoc, assoc_mac);
+		qdf_copy_macaddr(assoc_mac, &adapter->mld_addr);
 	}
 out:
 	qdf_net_update_net_device_dev_addr(adapter->dev,
 					   adapter->mld_addr.bytes,
 					   QDF_MAC_ADDR_SIZE);
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -20192,7 +20202,10 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
 					QDF_MAC_ADDR_FMT "\n",
 					QDF_MAC_ADDR_REF(ndev->dev_addr));
 			}
-			hdd_adapter_update_mac_on_mode_change(adapter, false);
+			status = hdd_adapter_update_mac_on_mode_change(adapter,
+								       false);
+			if (QDF_IS_STATUS_ERROR(status))
+				goto err;
 			hdd_set_ap_ops(adapter->dev);
 		} else {
 			hdd_err("Changing to device mode '%s' is not supported",
@@ -20207,7 +20220,10 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
 				hdd_err("change mode fail %d", errno);
 				goto err;
 			}
-			hdd_adapter_update_mac_on_mode_change(adapter, true);
+			status = hdd_adapter_update_mac_on_mode_change(adapter,
+								       true);
+			if (QDF_IS_STATUS_ERROR(status))
+				goto err;
 		} else if (hdd_is_ap_mode(new_mode)) {
 			adapter->device_mode = new_mode;
 

+ 9 - 6
core/hdd/src/wlan_hdd_mlo.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. 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 above
@@ -134,13 +134,14 @@ QDF_STATUS hdd_wlan_unregister_mlo_interfaces(struct hdd_adapter *adapter,
 	int i;
 	struct hdd_mlo_adapter_info *mlo_adapter_info;
 	struct hdd_adapter *link_adapter;
-	struct qdf_mac_addr adapter_mac;
 
 	mlo_adapter_info = &adapter->mlo_adapter_info;
 
 	if (mlo_adapter_info->is_link_adapter) {
-		qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr);
-		ucfg_dp_destroy_intf(adapter->hdd_ctx->psoc, &adapter_mac);
+		if (adapter->device_mode == QDF_STA_MODE) {
+			ucfg_dp_destroy_intf(adapter->hdd_ctx->psoc,
+					     &adapter->mac_addr);
+		}
 		hdd_remove_front_adapter(adapter->hdd_ctx, &adapter);
 		return QDF_STATUS_E_AGAIN;
 	}
@@ -149,8 +150,10 @@ QDF_STATUS hdd_wlan_unregister_mlo_interfaces(struct hdd_adapter *adapter,
 		link_adapter = mlo_adapter_info->link_adapter[i];
 		if (!link_adapter)
 			continue;
-		qdf_copy_macaddr(&adapter_mac, &link_adapter->mac_addr);
-		ucfg_dp_destroy_intf(link_adapter->hdd_ctx->psoc, &adapter_mac);
+		if (adapter->device_mode == QDF_STA_MODE) {
+			ucfg_dp_destroy_intf(link_adapter->hdd_ctx->psoc,
+					     &link_adapter->mac_addr);
+		}
 		hdd_remove_adapter(link_adapter->hdd_ctx, link_adapter);
 		hdd_mlo_close_adapter(link_adapter, rtnl_held);
 	}