Przeglądaj źródła

qcacmn: Update VDEV MAC addr after link switch disconnect

After receiving link switch disconnect completion indication
from connection manager, update the VDEV's MAC address to new
link's address to support link specific OTA frames exchange.

Introduce new dispatcher API to call from VDEV MLME, if the
VDEV for which MAC address response received is in link
switch in progress, then deliver the response to MLO mgr,
or else deliver it directly to OSIF.

Handle the FW response for link switch set MAC address in
MLO manager and if the set MAC addr response is successful,
update OSIF about the new MAC address to perform cleanup on
old link and initialize fields in new link.

If the response is successful, transition the link switch to
initiate connection or else abort link switch.

Change-Id: Ic330dca84e602909cc5ddf7e134809c0e0345a17
CRs-Fixed: 3556506
Vinod Kumar Pirla 2 lat temu
rodzic
commit
a61df6019c

+ 22 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_link_switch.h

@@ -281,6 +281,21 @@ void mlo_mgr_osif_update_connect_info(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS mlo_mgr_link_switch_disconnect_done(struct wlan_objmgr_vdev *vdev,
 					       QDF_STATUS status);
 
+/**
+ * mlo_mgr_link_switch_set_mac_addr_resp() - Handle response of set MAC addr
+ * for VDEV under going link switch.
+ * @vdev: VDEV object manager
+ * @resp_status: Status of MAC address set request.
+ *
+ * The function will handle the response for set MAC address request sent to FW
+ * as part of link switch. If the response is error, then abort the link switch
+ * and send the appropirate status to FW
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlo_mgr_link_switch_set_mac_addr_resp(struct wlan_objmgr_vdev *vdev,
+						 uint8_t resp_status);
+
 /**
  * mlo_mgr_link_switch_init_state() - Set the current state of link switch
  * to init state.
@@ -467,6 +482,13 @@ mlo_mgr_link_switch_disconnect_done(struct wlan_objmgr_vdev *vdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+static inline QDF_STATUS
+mlo_mgr_link_switch_set_mac_addr_resp(struct wlan_objmgr_vdev *vdev,
+				      uint8_t resp_status)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
 static inline QDF_STATUS
 mlo_mgr_link_switch_deinit(struct wlan_mlo_dev_context *ml_dev)
 {

+ 16 - 1
umac/mlo_mgr/inc/wlan_mlo_mgr_public_api.h

@@ -21,7 +21,7 @@
 #ifndef _WLAN_MLO_MGR_PUBLIC_API_H_
 #define _WLAN_MLO_MGR_PUBLIC_API_H_
 
-#include <wlan_mlo_mgr_public_structs.h>
+#include <wlan_mlo_mgr_link_switch.h>
 
 /**
  * wlan_mlo_mgr_register_link_switch_notifier() - Components to register
@@ -102,4 +102,19 @@ wlan_mlo_mgr_link_switch_get_assoc_vdev(struct wlan_objmgr_vdev *vdev)
 {
 	return mlo_mgr_link_switch_get_assoc_vdev(vdev);
 }
+
+/**
+ * wlan_mlo_mgr_link_switch_set_mac_addr_resp() - Dispatcher API to call to
+ * notify about status of set mac addr request.
+ * @vdev: VDEV object manager
+ * @resp_status: Status of request
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+wlan_mlo_mgr_link_switch_set_mac_addr_resp(struct wlan_objmgr_vdev *vdev,
+					   uint8_t resp_status)
+{
+	return mlo_mgr_link_switch_set_mac_addr_resp(vdev, resp_status);
+}
 #endif /* _WLAN_MLO_MGR_PUBLIC_API_H_ */

+ 69 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c

@@ -428,7 +428,10 @@ mlo_mgr_osif_update_connect_info(struct wlan_objmgr_vdev *vdev, int32_t link_id)
 QDF_STATUS mlo_mgr_link_switch_disconnect_done(struct wlan_objmgr_vdev *vdev,
 					       QDF_STATUS status)
 {
+	QDF_STATUS qdf_status;
 	enum mlo_link_switch_req_state cur_state;
+	struct mlo_link_info *new_link_info;
+	struct qdf_mac_addr mac_addr, mld_addr;
 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
 	struct wlan_mlo_link_switch_req *req = &mlo_dev_ctx->link_ctx->last_req;
 
@@ -444,8 +447,73 @@ QDF_STATUS mlo_mgr_link_switch_disconnect_done(struct wlan_objmgr_vdev *vdev,
 	mlo_debug("VDEV %d link switch disconnect complete",
 		  wlan_vdev_get_id(vdev));
 
+	new_link_info =
+		mlo_mgr_get_ap_link_by_link_id(vdev, req->new_ieee_link_id);
+	if (!new_link_info) {
+		mlo_err("New link not found in mlo dev ctx");
+		mlo_mgr_remove_link_switch_cmd(vdev);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_copy_macaddr(&mld_addr, &mlo_dev_ctx->mld_addr);
+	qdf_copy_macaddr(&mac_addr, &new_link_info->link_addr);
+
+	mlo_mgr_link_switch_trans_next_state(mlo_dev_ctx);
+
+	qdf_status = wlan_vdev_mlme_send_set_mac_addr(mac_addr, mld_addr, vdev);
+	if (QDF_IS_STATUS_ERROR(qdf_status))
+		mlo_mgr_remove_link_switch_cmd(vdev);
+
+	return qdf_status;
+}
+
+QDF_STATUS mlo_mgr_link_switch_set_mac_addr_resp(struct wlan_objmgr_vdev *vdev,
+						 uint8_t resp_status)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	enum mlo_link_switch_req_state cur_state;
+	struct mlo_mgr_context *g_mlo_ctx = wlan_objmgr_get_mlo_ctx();
+	struct wlan_mlo_link_switch_req *req;
+	struct mlo_link_info *new_link_info;
+
+	if (resp_status) {
+		mlo_err("VDEV %d set MAC address response %d",
+			wlan_vdev_get_id(vdev), resp_status);
+		mlo_mgr_remove_link_switch_cmd(vdev);
+		return status;
+	}
+
+	if (!g_mlo_ctx) {
+		mlo_err("global mlo ctx NULL");
+		mlo_mgr_remove_link_switch_cmd(vdev);
+		return status;
+	}
+
+	req = &vdev->mlo_dev_ctx->link_ctx->last_req;
+	cur_state = mlo_mgr_link_switch_get_curr_state(vdev->mlo_dev_ctx);
+	if (cur_state != MLO_LINK_SWITCH_STATE_SET_MAC_ADDR) {
+		mlo_err("Link switch cmd flushed, there can be MAC addr mismatch with FW");
+		mlo_mgr_remove_link_switch_cmd(vdev);
+		return status;
+	}
+
+	new_link_info =
+		mlo_mgr_get_ap_link_by_link_id(vdev, req->new_ieee_link_id);
+	if (!new_link_info) {
+		mlo_mgr_remove_link_switch_cmd(vdev);
+		return status;
+	}
+
+	wlan_vdev_mlme_set_macaddr(vdev, new_link_info->link_addr.bytes);
+	wlan_vdev_mlme_set_linkaddr(vdev, new_link_info->link_addr.bytes);
+
+	status = g_mlo_ctx->osif_ops->mlo_mgr_osif_update_mac_addr(
+							req->curr_ieee_link_id,
+							req->new_ieee_link_id,
+							req->vdev_id);
+
 	mlo_mgr_remove_link_switch_cmd(vdev);
-	return status;
+	return QDF_STATUS_SUCCESS;
 }
 
 static QDF_STATUS