Browse Source

qcacld-3.0: Notify OSIF on assoc vdev connect active

Post link switch the order of VDEV to link info in OSIF
changes and for the next connection, need to restore the
order. This restore currently happens when there is set
MAC address update before every connect, but however if
set MAC address is not received then the unrestored order
of VDEV will be used during connect which can be undesirable
in certain cases.

To avoid going ahead with connection with unrestored VDEV
mapping, make sure this is reset to proper order via
notifying HDD once assoc VDEV connect request becomes active.

Change-Id: Id3ba542820f7c2bc9c721a49735738df00b6e5d5
CRs-Fixed: 3827913
Vinod Kumar Pirla 1 year ago
parent
commit
befb72ff0c

+ 5 - 2
core/hdd/inc/wlan_hdd_main.h

@@ -2841,15 +2841,18 @@ wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev);
 /**
  * hdd_adapter_disable_all_links() - Reset the links on stop adapter.
  * @adapter: HDD adapter
+ * @clear_macaddr: Clears mac address if set to true
  *
  * Resets the MAC address in each link info and resets the link info
  * mapping in adapter array.
  *
  * Return: void
  */
-void hdd_adapter_disable_all_links(struct hdd_adapter *adapter);
+void
+hdd_adapter_disable_all_links(struct hdd_adapter *adapter, bool clear_macaddr);
 #else
-static inline void hdd_adapter_disable_all_links(struct hdd_adapter *adapter)
+static inline void
+hdd_adapter_disable_all_links(struct hdd_adapter *adapter, bool clear_macaddr)
 {
 }
 #endif

+ 23 - 0
core/hdd/inc/wlan_hdd_mlo.h

@@ -355,6 +355,22 @@ QDF_STATUS hdd_derive_link_address_from_mld(struct wlan_objmgr_psoc *psoc,
 					    uint8_t max_idx);
 
 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
+/**
+ * hdd_adapter_restore_link_vdev_map() - Change the VDEV to link info mapping
+ * in adapter.
+ * @adapter: HDD adapter pointer
+ * @same_vdev_mac_map: Maintain VDEV to MAC address mapping during the restore.
+ *
+ * This API restores the VDEV to HDD link info mapping to its initial order
+ * which could have got remapped in the process of link switch. If
+ * @same_vdev_mac_map is set to %true then the MAC address to VDEV mapping is
+ * preserved.
+ *
+ * Returns: %true if any mapping changes or %false otherwise.
+ */
+bool hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter,
+				       bool same_vdev_mac_map);
+
 /**
  * hdd_mlo_mgr_register_osif_ops() - Register OSIF ops with global MLO manager
  * for callback to notify.
@@ -376,6 +392,13 @@ QDF_STATUS hdd_mlo_mgr_register_osif_ops(void);
  */
 QDF_STATUS hdd_mlo_mgr_unregister_osif_ops(void);
 #else
+static inline bool
+hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter,
+				  bool same_vdev_mac_map)
+{
+	return false;
+}
+
 static inline QDF_STATUS hdd_mlo_mgr_register_osif_ops(void)
 {
 	return QDF_STATUS_SUCCESS;

+ 1 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -2912,6 +2912,7 @@ void hdd_roam_profile_init(struct wlan_hdd_link_info *link_info)
 }
 
 struct osif_cm_ops osif_ops = {
+	.connect_active_notify_cb = hdd_cm_connect_active_notify,
 	.connect_complete_cb = hdd_cm_connect_complete,
 	.disconnect_complete_cb = hdd_cm_disconnect_complete,
 	.netif_queue_control_cb = hdd_cm_netif_queue_control,

+ 18 - 1
core/hdd/src/wlan_hdd_cm_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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
@@ -81,6 +81,23 @@ QDF_STATUS hdd_cm_netif_queue_control(struct wlan_objmgr_vdev *vdev,
 				      enum netif_action_type action,
 				      enum netif_reason_type reason);
 
+#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
+/**
+ * hdd_cm_connect_active_notify() - Callback to HDD on  connection request
+ * becomes active.
+ * @vdev_id: VDEV ID on which connection became active.
+ *
+ * The callback to make sure connection related fields are properly set
+ * from HDD.
+ *
+ * Returns: void
+ */
+void hdd_cm_connect_active_notify(uint8_t vdev_id);
+#else
+static inline void hdd_cm_connect_active_notify(uint8_t vdev_id)
+{
+}
+#endif
 QDF_STATUS hdd_cm_connect_complete(struct wlan_objmgr_vdev *vdev,
 				   struct wlan_cm_connect_resp *rsp,
 				   enum osif_cb_type type);

+ 23 - 0
core/hdd/src/wlan_hdd_cm_connect.c

@@ -23,6 +23,7 @@
  */
 
 #include "wlan_hdd_main.h"
+#include <wlan_hdd_mlo.h>
 #include "wlan_hdd_cm_api.h"
 #include "wlan_hdd_trace.h"
 #include "wlan_hdd_object_manager.h"
@@ -1868,6 +1869,28 @@ static void hdd_cm_connect_success(struct wlan_objmgr_vdev *vdev,
 	}
 }
 
+#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
+void hdd_cm_connect_active_notify(uint8_t vdev_id)
+{
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	struct wlan_hdd_link_info *link_info;
+
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
+	if (!link_info) {
+		hdd_err("Link info not found for vdev %d", vdev_id);
+		return;
+	}
+
+	if (hdd_adapter_restore_link_vdev_map(link_info->adapter, true))
+		hdd_adapter_update_mlo_mgr_mac_addr(link_info->adapter);
+}
+#endif
+
 QDF_STATUS hdd_cm_connect_complete(struct wlan_objmgr_vdev *vdev,
 				   struct wlan_cm_connect_resp *rsp,
 				   enum osif_cb_type type)

+ 7 - 7
core/hdd/src/wlan_hdd_main.c

@@ -8855,21 +8855,21 @@ wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
 
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
-void hdd_adapter_disable_all_links(struct hdd_adapter *adapter)
+void
+hdd_adapter_disable_all_links(struct hdd_adapter *adapter, bool clear_macaddr)
 {
 	uint8_t idx_pos;
 	struct wlan_hdd_link_info *link_info;
 
 	hdd_adapter_for_each_link_info(adapter, link_info) {
-		qdf_zero_macaddr(&link_info->link_addr);
+		if (clear_macaddr)
+			qdf_zero_macaddr(&link_info->link_addr);
 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
 		adapter->curr_link_info_map[idx_pos] = idx_pos;
 	}
+
 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
-	if (adapter->device_mode == QDF_STA_MODE)
-		adapter->active_links = (1 << adapter->num_links_on_create) - 1;
-	else
-		adapter->active_links = 0x1;
+	adapter->active_links = (1 << adapter->num_links_on_create) - 1;
 }
 #endif
 
@@ -9919,7 +9919,7 @@ QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
 	/* Disable all links (expect default index) in adapter.
 	 * Set link address to NULL
 	 */
-	hdd_adapter_disable_all_links(adapter);
+	hdd_adapter_disable_all_links(adapter, true);
 
 	/* This function should be invoked at the end of this api*/
 	hdd_dump_func_call_map();

+ 20 - 3
core/hdd/src/wlan_hdd_mlo.c

@@ -377,14 +377,17 @@ QDF_STATUS hdd_derive_link_address_from_mld(struct wlan_objmgr_psoc *psoc,
 
 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
-static void hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter)
+bool hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter,
+				       bool same_vdev_mac_map)
 {
 	int i;
+	bool mapping_changed = false;
 	unsigned long link_flags;
 	uint8_t vdev_id, cur_link_idx, temp_link_idx;
 	struct vdev_osif_priv *osif_priv;
 	struct wlan_objmgr_vdev *vdev;
 	struct wlan_hdd_link_info *temp_link_info, *link_info;
+	struct qdf_mac_addr temp_mac;
 
 	hdd_adapter_for_each_link_info(adapter, link_info) {
 		cur_link_idx = hdd_adapter_get_index_of_link_info(link_info);
@@ -437,6 +440,14 @@ static void hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter)
 				osif_priv->legacy_osif_priv = link_info;
 		}
 
+		/* Preserve the VDEV-MAC mapping if requested */
+		if (same_vdev_mac_map) {
+			qdf_copy_macaddr(&temp_mac, &temp_link_info->link_addr);
+			qdf_copy_macaddr(&temp_link_info->link_addr,
+					 &link_info->link_addr);
+			qdf_copy_macaddr(&link_info->link_addr, &temp_mac);
+		}
+
 		/* Swap link flags */
 		link_flags = temp_link_info->link_flags;
 		temp_link_info->link_flags = link_info->link_flags;
@@ -448,8 +459,14 @@ static void hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter)
 		adapter->curr_link_info_map[temp_link_idx] =
 				adapter->curr_link_info_map[cur_link_idx];
 		adapter->curr_link_info_map[cur_link_idx] = cur_link_idx;
+
+		if (!mapping_changed)
+			mapping_changed = true;
 	}
-	hdd_adapter_disable_all_links(adapter);
+
+	hdd_adapter_disable_all_links(adapter, !same_vdev_mac_map);
+
+	return mapping_changed;
 }
 
 int hdd_update_vdev_mac_address(struct hdd_adapter *adapter,
@@ -483,7 +500,7 @@ int hdd_update_vdev_mac_address(struct hdd_adapter *adapter,
 	if (QDF_IS_STATUS_ERROR(status))
 		return qdf_status_to_os_return(status);
 
-	hdd_adapter_restore_link_vdev_map(adapter);
+	hdd_adapter_restore_link_vdev_map(adapter, false);
 
 	i = 0;
 	hdd_adapter_for_each_active_link_info(adapter, link_info) {