From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT:
 drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c

Change-Id: If7deb93c015f9c4b4a7979681f6d389b89a1b877
---
 .../ethernet/mellanox/mlx5/core/sf/devlink.c  | 71 +++++++++++++++++--
 1 file changed, 66 insertions(+), 5 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
@@ -34,9 +34,26 @@ struct mlx5_sf_table {
 	struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */
 	struct notifier_block esw_nb;
 	struct notifier_block vhca_nb;
+#ifdef HAVE_DEVLINK_INSTANCES_RELATIONSHIPS_EXPOSURE
 	struct notifier_block mdev_nb;
+#endif
 };
 
+#ifndef HAVE_DEVLINK_PORT_OPS
+static struct mlx5_sf *
+mlx5_sf_lookup_by_index(struct mlx5_sf_table *table, unsigned int port_index)
+{
+	unsigned long index;
+	struct mlx5_sf *sf;
+
+	xa_for_each(&table->function_ids, index, sf) {
+		if (sf->port_index == port_index)
+			return sf;
+	}
+	return NULL;
+}
+#endif
+
 static struct mlx5_sf *
 mlx5_sf_lookup_by_function_id(struct mlx5_sf_table *table, unsigned int fn_id)
 {
@@ -142,8 +159,12 @@ static bool mlx5_sf_is_active(const stru
 {
 	return sf->hw_state == MLX5_VHCA_STATE_ACTIVE || sf->hw_state == MLX5_VHCA_STATE_IN_USE;
 }
-
-int mlx5_devlink_sf_port_fn_state_get(struct devlink_port *dl_port,
+#if defined(HAVE_PORT_FUNCTION_HW_ADDR_GET_GET_4_PARAM) || defined(HAVE_DEVLINK_PORT_OPS)
+int mlx5_devlink_sf_port_fn_state_get(
+#else
+int mlx5_devlink_sf_port_fn_state_get(struct devlink *devlink,
+#endif
+				      struct devlink_port *dl_port,
 				      enum devlink_port_fn_state *state,
 				      enum devlink_port_fn_opstate *opstate,
 				      struct netlink_ext_ack *extack)
@@ -152,6 +173,9 @@ int mlx5_devlink_sf_port_fn_state_get(st
 	struct mlx5_sf_table *table = dev->priv.sf_table;
 	struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
 
+	if (!table || !sf)
+		return -EOPNOTSUPP;
+
 	mutex_lock(&table->sf_state_lock);
 	*state = mlx5_sf_to_devlink_state(sf->hw_state);
 	*opstate = mlx5_sf_to_devlink_opstate(sf->hw_state);
@@ -225,7 +249,12 @@ out:
 	return err;
 }
 
-int mlx5_devlink_sf_port_fn_state_set(struct devlink_port *dl_port,
+#if defined(HAVE_PORT_FUNCTION_HW_ADDR_GET_GET_4_PARAM) || defined(HAVE_DEVLINK_PORT_OPS)
+int mlx5_devlink_sf_port_fn_state_set(
+#else
+int mlx5_devlink_sf_port_fn_state_set(struct devlink *devlink,
+#endif
+				      struct devlink_port *dl_port,
 				      enum devlink_port_fn_state state,
 				      struct netlink_ext_ack *extack)
 {
@@ -239,7 +268,11 @@ int mlx5_devlink_sf_port_fn_state_set(st
 static int mlx5_sf_add(struct mlx5_core_dev *dev, struct mlx5_sf_table *table,
 		       const struct devlink_port_new_attrs *new_attr,
 		       struct netlink_ext_ack *extack,
+#ifdef HAVE_DEVLINK_PORT_OPS
 		       struct devlink_port **dl_port)
+#else
+		       unsigned int *new_port_index)
+#endif
 {
 	struct mlx5_eswitch *esw = dev->priv.eswitch;
 	struct mlx5_sf *sf;
@@ -253,7 +286,11 @@ static int mlx5_sf_add(struct mlx5_core_
 					 &sf->dl_port, new_attr->controller, new_attr->sfnum);
 	if (err)
 		goto esw_err;
+#ifdef HAVE_DEVLINK_PORT_OPS
 	*dl_port = &sf->dl_port.dl_port;
+#else
+	*new_port_index = sf->port_index;
+#endif
 	trace_mlx5_sf_add(dev, sf->port_index, sf->controller, sf->hw_fn_id, new_attr->sfnum);
 	return 0;
 
@@ -301,7 +338,11 @@ static bool mlx5_sf_table_supported(cons
 int mlx5_devlink_sf_port_new(struct devlink *devlink,
 			     const struct devlink_port_new_attrs *new_attr,
 			     struct netlink_ext_ack *extack,
+#ifdef HAVE_DEVLINK_PORT_OPS
 			     struct devlink_port **dl_port)
+#else
+			     unsigned int *new_port_index)
+#endif
 {
 	struct mlx5_core_dev *dev = devlink_priv(devlink);
 	struct mlx5_sf_table *table = dev->priv.sf_table;
@@ -322,7 +363,11 @@ int mlx5_devlink_sf_port_new(struct devl
 		return -EOPNOTSUPP;
 	}
 
+#ifdef HAVE_DEVLINK_PORT_OPS
 	return mlx5_sf_add(dev, table, new_attr, extack, dl_port);
+#else
+	return mlx5_sf_add(dev, table, new_attr, extack, new_port_index);
+#endif
 }
 
 static void mlx5_sf_dealloc(struct mlx5_sf_table *table, struct mlx5_sf *sf)
@@ -362,13 +407,24 @@ static void mlx5_sf_del(struct mlx5_sf_t
 	mlx5_sf_dealloc(table, sf);
 }
 
+#ifdef HAVE_DEVLINK_PORT_OPS
 int mlx5_devlink_sf_port_del(struct devlink *devlink,
 			     struct devlink_port *dl_port,
 			     struct netlink_ext_ack *extack)
+#else
+int mlx5_devlink_sf_port_del(struct devlink *devlink, unsigned int port_index,
+			     struct netlink_ext_ack *extack)
+#endif
 {
 	struct mlx5_core_dev *dev = devlink_priv(devlink);
 	struct mlx5_sf_table *table = dev->priv.sf_table;
-	struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+	struct mlx5_sf *sf;
+
+#ifdef HAVE_DEVLINK_PORT_OPS
+	sf = mlx5_sf_by_dl_port(dl_port);
+#else
+	sf = mlx5_sf_lookup_by_index(table, port_index);
+#endif
 
 	mlx5_sf_del(table, sf);
 	return 0;
@@ -448,6 +504,7 @@ static int mlx5_sf_esw_event(struct noti
 	return 0;
 }
 
+#ifdef HAVE_DEVLINK_INSTANCES_RELATIONSHIPS_EXPOSURE
 static int mlx5_sf_mdev_event(struct notifier_block *nb, unsigned long event, void *data)
 {
 	struct mlx5_sf_table *table = container_of(nb, struct mlx5_sf_table, mdev_nb);
@@ -472,6 +529,7 @@ out:
 	mutex_unlock(&table->sf_state_lock);
 	return ret;
 }
+#endif
 
 int mlx5_sf_table_init(struct mlx5_core_dev *dev)
 {
@@ -499,9 +557,10 @@ int mlx5_sf_table_init(struct mlx5_core_
 	if (err)
 		goto vhca_err;
 
+#ifdef HAVE_DEVLINK_INSTANCES_RELATIONSHIPS_EXPOSURE
 	table->mdev_nb.notifier_call = mlx5_sf_mdev_event;
 	mlx5_blocking_notifier_register(dev, &table->mdev_nb);
-
+#endif
 	return 0;
 
 vhca_err:
@@ -520,7 +579,9 @@ void mlx5_sf_table_cleanup(struct mlx5_c
 	if (!table)
 		return;
 
+#ifdef HAVE_DEVLINK_INSTANCES_RELATIONSHIPS_EXPOSURE
 	mlx5_blocking_notifier_unregister(dev, &table->mdev_nb);
+#endif
 	mlx5_vhca_event_notifier_unregister(table->dev, &table->vhca_nb);
 	mlx5_esw_event_notifier_unregister(dev->priv.eswitch, &table->esw_nb);
 	mutex_destroy(&table->sf_state_lock);
