Ver código fonte

qcacld-3.0: Handle link switch start notify in HDD

Once VDEV ops using DSC lock are completed, move the deflink
pointer in adapter to non-transitioning link so that all userspace
requests happen on the non-transitioning link while the other
link is in link switch operation.

Change-Id: Idfdd488e47e7d4ba013c9ed1e61def86ede8db90
CRs-Fixed: 3568098
Vinod Kumar Pirla 1 ano atrás
pai
commit
5a000144a7
2 arquivos alterados com 58 adições e 0 exclusões
  1. 11 0
      core/hdd/inc/wlan_hdd_mlo.h
  2. 47 0
      core/hdd/src/wlan_hdd_mlo.c

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

@@ -249,6 +249,17 @@ struct hdd_adapter *hdd_get_ml_adapter(struct hdd_context *hdd_ctx)
  */
 void hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter);
 
+/**
+ * hdd_adapter_link_switch_notification() - Get HDD notification on link switch
+ * start.
+ * @vdev: VDEV on which link switch will happen
+ * @non_trans_vdev_id: VDEV not part of link switch.
+ *
+ * Return: QDF_STATUS.
+ */
+QDF_STATUS hdd_adapter_link_switch_notification(struct wlan_objmgr_vdev *vdev,
+						uint8_t non_trans_vdev_id);
+
 /**
  * hdd_mlo_t2lm_register_callback() - Register T2LM callback
  * @vdev: Pointer to vdev

+ 47 - 0
core/hdd/src/wlan_hdd_mlo.c

@@ -255,6 +255,8 @@ void hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter)
 static struct mlo_osif_ext_ops mlo_osif_ops = {
 	.mlo_mgr_osif_update_bss_info = hdd_cm_save_connected_links_info,
 	.mlo_mgr_osif_update_mac_addr = hdd_link_switch_vdev_mac_addr_update,
+	.mlo_mgr_osif_link_switch_notification =
+					hdd_adapter_link_switch_notification,
 };
 
 QDF_STATUS hdd_mlo_mgr_register_osif_ops(void)
@@ -270,6 +272,51 @@ QDF_STATUS hdd_mlo_mgr_unregister_osif_ops(void)
 
 	return wlan_mlo_mgr_unregister_osif_ext_ops(mlo_mgr_ctx);
 }
+
+QDF_STATUS hdd_adapter_link_switch_notification(struct wlan_objmgr_vdev *vdev,
+						uint8_t non_trans_vdev_id)
+{
+	int errno;
+	bool found = false;
+	struct hdd_adapter *adapter;
+	struct vdev_osif_priv *osif_priv;
+	struct wlan_hdd_link_info *link_info, *iter_link_info;
+	struct osif_vdev_sync *vdev_sync;
+
+	osif_priv = wlan_vdev_get_ospriv(vdev);
+	if (!osif_priv) {
+		hdd_err("Invalid osif priv");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	link_info = osif_priv->legacy_osif_priv;
+	adapter = link_info->adapter;
+
+	if (link_info->vdev_id != adapter->deflink->vdev_id) {
+		hdd_err("Default VDEV %d not equal", adapter->deflink->vdev_id);
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync);
+	if (errno)
+		return QDF_STATUS_E_FAILURE;
+
+	osif_vdev_sync_wait_for_ops(vdev_sync);
+	hdd_adapter_for_each_link_info(adapter, iter_link_info) {
+		if (non_trans_vdev_id == iter_link_info->vdev_id) {
+			adapter->deflink = iter_link_info;
+			found = true;
+			break;
+		}
+	}
+	osif_vdev_sync_trans_stop(vdev_sync);
+
+	if (!found)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 void hdd_mlo_t2lm_register_callback(struct wlan_objmgr_vdev *vdev)