]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
{net/RDMA}/mlx5: Add LAG demux table API and vport demux rules
authorShay Drory <shayd@nvidia.com>
Mon, 9 Mar 2026 09:34:34 +0000 (11:34 +0200)
committerLeon Romanovsky <leon@kernel.org>
Mon, 16 Mar 2026 20:23:00 +0000 (16:23 -0400)
Downstream patches will introduce SW-only LAG (e.g. shared_fdb without
HW LAG). In this mode the firmware cannot create the LAG demux table,
but vport demuxing is still required.

Move LAG demux flow-table ownership to the LAG layer and introduce APIs
to init/cleanup the demux table and add/delete per-vport rules. Adjust
the RDMA driver to use the new APIs.

In this mode, the LAG layer will create a flow group that matches vport
metadata. Vports that are not native to the LAG master eswitch add the
demux rule during IB representor load and remove it on unload.
The demux rule forward traffic from said vports to their native eswitch
manager via a new dest type - MLX5_FLOW_DESTINATION_TYPE_VHCA_RX.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260309093435.1850724-9-tariqt@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mlx5/ib_rep.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
include/linux/mlx5/fs.h
include/linux/mlx5/lag.h

index df8f049c58065ad1b3b75466e0d4dde8cf317625..1709b628702ee5ebde62c788c06a33d5ab5d1ba5 100644 (file)
 
 static int
 mlx5_ib_set_vport_rep(struct mlx5_core_dev *dev,
+                     struct mlx5_core_dev *rep_dev,
                      struct mlx5_eswitch_rep *rep,
                      int vport_index)
 {
        struct mlx5_ib_dev *ibdev;
        struct net_device *ndev;
+       int ret;
 
        ibdev = mlx5_eswitch_uplink_get_proto_dev(dev->priv.eswitch, REP_IB);
        if (!ibdev)
@@ -24,7 +26,17 @@ mlx5_ib_set_vport_rep(struct mlx5_core_dev *dev,
        rep->rep_data[REP_IB].priv = ibdev;
        ndev = mlx5_ib_get_rep_netdev(rep->esw, rep->vport);
 
-       return ib_device_set_netdev(&ibdev->ib_dev, ndev, vport_index + 1);
+       ret = ib_device_set_netdev(&ibdev->ib_dev, ndev, vport_index + 1);
+       if (ret)
+               return ret;
+
+       /* Only Vports that are not native to the LAG master eswitch need to add
+        * demux rule.
+        */
+       if (mlx5_eswitch_get_total_vports(dev) > vport_index)
+               return 0;
+
+       return mlx5_lag_demux_rule_add(rep_dev, rep->vport, vport_index);
 }
 
 static void mlx5_ib_register_peer_vport_reps(struct mlx5_core_dev *mdev);
@@ -131,7 +143,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
 
                                if (mlx5_lag_is_master(peer_dev))
                                        lag_master = peer_dev;
-                               else if (!mlx5_lag_is_mpesw(dev))
+                               else if (!mlx5_lag_is_mpesw(peer_dev))
                                /* Only 1 ib port is the representor for all uplinks */
                                        peer_n_ports--;
 
@@ -145,7 +157,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
        if (rep->vport == MLX5_VPORT_UPLINK && !new_uplink)
                profile = &raw_eth_profile;
        else
-               return mlx5_ib_set_vport_rep(lag_master, rep, vport_index);
+               return mlx5_ib_set_vport_rep(lag_master, dev, rep, vport_index);
 
        if (mlx5_lag_is_shared_fdb(dev)) {
                ret = mlx5_ib_take_transport(lag_master);
@@ -233,6 +245,8 @@ mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep)
                vport_index = i;
        }
 
+       mlx5_lag_demux_rule_del(mdev, vport_index);
+
        port = &dev->port[vport_index];
 
        ib_device_set_netdev(&dev->ib_dev, NULL, vport_index + 1);
index 635002e684a55fcc2f6c42127f67abba38809b08..9fb0629978bd26af7da02a095b4897f47ba7df53 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/mlx5/fs.h>
 #include <linux/mlx5/eswitch.h>
 #include <linux/mlx5/driver.h>
+#include <linux/mlx5/lag.h>
 #include <linux/list.h>
 #include <rdma/ib_smi.h>
 #include <rdma/ib_umem_odp.h>
@@ -3678,12 +3679,12 @@ static void mlx5e_lag_event_unregister(struct mlx5_ib_dev *dev)
 
 static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
 {
+       struct mlx5_flow_table_attr ft_attr = {};
        struct mlx5_core_dev *mdev = dev->mdev;
-       struct mlx5_flow_namespace *ns = mlx5_get_flow_namespace(mdev,
-                                                                MLX5_FLOW_NAMESPACE_LAG);
-       struct mlx5_flow_table *ft;
+       struct mlx5_flow_namespace *ns;
        int err;
 
+       ns = mlx5_get_flow_namespace(mdev, MLX5_FLOW_NAMESPACE_LAG);
        if (!ns || !mlx5_lag_is_active(mdev))
                return 0;
 
@@ -3691,14 +3692,15 @@ static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
        if (err)
                return err;
 
-       ft = mlx5_create_lag_demux_flow_table(ns, 0, 0);
-       if (IS_ERR(ft)) {
-               err = PTR_ERR(ft);
+       ft_attr.level = 0;
+       ft_attr.prio = 0;
+       ft_attr.max_fte = dev->num_ports;
+
+       err = mlx5_lag_demux_init(mdev, &ft_attr);
+       if (err)
                goto err_destroy_vport_lag;
-       }
 
        mlx5e_lag_event_register(dev);
-       dev->flow_db->lag_demux_ft = ft;
        dev->lag_ports = mlx5_lag_get_num_ports(mdev);
        dev->lag_active = true;
        return 0;
@@ -3716,8 +3718,7 @@ static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)
                dev->lag_active = false;
 
                mlx5e_lag_event_unregister(dev);
-               mlx5_destroy_flow_table(dev->flow_db->lag_demux_ft);
-               dev->flow_db->lag_demux_ft = NULL;
+               mlx5_lag_demux_cleanup(mdev);
 
                mlx5_cmd_destroy_vport_lag(mdev);
        }
index 4f4114d9513000e63b83554cf5903d57cc0d401d..3fc31415e1079df926b5d5551bdb95b06dcb3e25 100644 (file)
@@ -306,7 +306,6 @@ struct mlx5_ib_flow_db {
        struct mlx5_ib_flow_prio        rdma_rx[MLX5_IB_NUM_FLOW_FT];
        struct mlx5_ib_flow_prio        rdma_tx[MLX5_IB_NUM_FLOW_FT];
        struct mlx5_ib_flow_prio        opfcs[MLX5_IB_OPCOUNTER_MAX];
-       struct mlx5_flow_table          *lag_demux_ft;
        struct mlx5_ib_flow_prio        *rdma_transport_rx[MLX5_RDMA_TRANSPORT_BYPASS_PRIO];
        struct mlx5_ib_flow_prio        *rdma_transport_tx[MLX5_RDMA_TRANSPORT_BYPASS_PRIO];
        /* Protect flow steering bypass flow tables
index 96309a732d5050b76651965db86b29635d1891f8..9b729789537f1ea9f445d4c92a933dba99332f30 100644 (file)
@@ -940,6 +940,12 @@ int mlx5_esw_ipsec_vf_packet_offload_supported(struct mlx5_core_dev *dev,
                                               u16 vport_num);
 bool mlx5_esw_host_functions_enabled(const struct mlx5_core_dev *dev);
 void mlx5_eswitch_safe_aux_devs_remove(struct mlx5_core_dev *dev);
+struct mlx5_flow_group *
+mlx5_esw_lag_demux_fg_create(struct mlx5_eswitch *esw,
+                            struct mlx5_flow_table *ft);
+struct mlx5_flow_handle *
+mlx5_esw_lag_demux_rule_create(struct mlx5_eswitch *esw, u16 vport_num,
+                              struct mlx5_flow_table *lag_ft);
 #else  /* CONFIG_MLX5_ESWITCH */
 /* eswitch API stubs */
 static inline int  mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
@@ -1025,6 +1031,12 @@ mlx5_esw_vport_vhca_id(struct mlx5_eswitch *esw, u16 vportn, u16 *vhca_id)
 
 static inline void
 mlx5_eswitch_safe_aux_devs_remove(struct mlx5_core_dev *dev) {}
+static inline struct mlx5_flow_handle *
+mlx5_esw_lag_demux_rule_create(struct mlx5_eswitch *esw, u16 vport_num,
+                              struct mlx5_flow_table *lag_ft)
+{
+       return ERR_PTR(-EOPNOTSUPP);
+}
 
 #endif /* CONFIG_MLX5_ESWITCH */
 
index 90e6f97bdf4a0166f748c03ee1551b92f9e4c3dd..f98837470f390634e00f999923e97bcfe4383191 100644 (file)
@@ -1459,6 +1459,83 @@ esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag)
        return flow_rule;
 }
 
+struct mlx5_flow_group *
+mlx5_esw_lag_demux_fg_create(struct mlx5_eswitch *esw,
+                            struct mlx5_flow_table *ft)
+{
+       int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+       struct mlx5_flow_group *fg;
+       void *match_criteria;
+       void *flow_group_in;
+
+       if (!mlx5_eswitch_vport_match_metadata_enabled(esw))
+               return ERR_PTR(-EOPNOTSUPP);
+
+       if (IS_ERR(ft))
+               return ERR_CAST(ft);
+
+       flow_group_in = kvzalloc(inlen, GFP_KERNEL);
+       if (!flow_group_in)
+               return ERR_PTR(-ENOMEM);
+
+       match_criteria = MLX5_ADDR_OF(create_flow_group_in, flow_group_in,
+                                     match_criteria);
+       MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
+                MLX5_MATCH_MISC_PARAMETERS_2);
+       MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
+       MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index,
+                ft->max_fte - 1);
+
+       MLX5_SET(fte_match_param, match_criteria,
+                misc_parameters_2.metadata_reg_c_0,
+                mlx5_eswitch_get_vport_metadata_mask());
+
+       fg = mlx5_create_flow_group(ft, flow_group_in);
+       kvfree(flow_group_in);
+       if (IS_ERR(fg))
+               esw_warn(esw->dev, "Can't create LAG demux flow group\n");
+
+       return fg;
+}
+
+struct mlx5_flow_handle *
+mlx5_esw_lag_demux_rule_create(struct mlx5_eswitch *esw, u16 vport_num,
+                              struct mlx5_flow_table *lag_ft)
+{
+       struct mlx5_flow_spec *spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
+       struct mlx5_flow_destination dest = {};
+       struct mlx5_flow_act flow_act = {};
+       struct mlx5_flow_handle *ret;
+       void *misc;
+
+       if (!spec)
+               return ERR_PTR(-ENOMEM);
+
+       if (!mlx5_eswitch_vport_match_metadata_enabled(esw)) {
+               kvfree(spec);
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+
+       misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+                           misc_parameters_2);
+       MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
+                mlx5_eswitch_get_vport_metadata_mask());
+       spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2;
+
+       misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
+                           misc_parameters_2);
+       MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
+                mlx5_eswitch_get_vport_metadata_for_match(esw, vport_num));
+
+       flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+       dest.type = MLX5_FLOW_DESTINATION_TYPE_VHCA_RX;
+       dest.vhca.id = MLX5_CAP_GEN(esw->dev, vhca_id);
+
+       ret = mlx5_add_flow_rules(lag_ft, spec, &flow_act, &dest, 1);
+       kvfree(spec);
+       return ret;
+}
+
 #define MAX_PF_SQ 256
 #define MAX_SQ_NVPORTS 32
 
@@ -2047,7 +2124,8 @@ static int esw_create_vport_rx_group(struct mlx5_eswitch *esw)
 
        if (IS_ERR(g)) {
                err = PTR_ERR(g);
-               mlx5_core_warn(esw->dev, "Failed to create vport rx group err %d\n", err);
+               esw_warn(esw->dev, "Failed to create vport rx group err %d\n",
+                        err);
                goto out;
        }
 
@@ -2092,7 +2170,8 @@ static int esw_create_vport_rx_drop_group(struct mlx5_eswitch *esw)
 
        if (IS_ERR(g)) {
                err = PTR_ERR(g);
-               mlx5_core_warn(esw->dev, "Failed to create vport rx drop group err %d\n", err);
+               esw_warn(esw->dev,
+                        "Failed to create vport rx drop group err %d\n", err);
                goto out;
        }
 
index 003d211306a7d9f9929af5dd4865b983bfde2549..61a6ba1e49dda5f18e84d15d34e0c393a4e0a993 100644 (file)
@@ -1438,15 +1438,9 @@ mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns,
 
 struct mlx5_flow_table*
 mlx5_create_lag_demux_flow_table(struct mlx5_flow_namespace *ns,
-                                int prio, u32 level)
+                                struct mlx5_flow_table_attr *ft_attr)
 {
-       struct mlx5_flow_table_attr ft_attr = {};
-
-       ft_attr.level = level;
-       ft_attr.prio  = prio;
-       ft_attr.max_fte = 1;
-
-       return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_LAG_DEMUX, 0);
+       return __mlx5_create_flow_table(ns, ft_attr, FS_FT_OP_MOD_LAG_DEMUX, 0);
 }
 EXPORT_SYMBOL(mlx5_create_lag_demux_flow_table);
 
index 51ec8f61ecbb4352277ffdf4c2bb36bd678bf8f0..449e4bd86c0645afd180e6a1b070ed1fbb9edbe4 100644 (file)
@@ -1471,6 +1471,158 @@ struct mlx5_devcom_comp_dev *mlx5_lag_get_devcom_comp(struct mlx5_lag *ldev)
        return devcom;
 }
 
+static int mlx5_lag_demux_ft_fg_init(struct mlx5_core_dev *dev,
+                                    struct mlx5_flow_table_attr *ft_attr,
+                                    struct mlx5_lag *ldev)
+{
+#ifdef CONFIG_MLX5_ESWITCH
+       struct mlx5_flow_namespace *ns;
+       struct mlx5_flow_group *fg;
+       int err;
+
+       ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_LAG);
+       if (!ns)
+               return 0;
+
+       ldev->lag_demux_ft = mlx5_create_flow_table(ns, ft_attr);
+       if (IS_ERR(ldev->lag_demux_ft))
+               return PTR_ERR(ldev->lag_demux_ft);
+
+       fg = mlx5_esw_lag_demux_fg_create(dev->priv.eswitch,
+                                         ldev->lag_demux_ft);
+       if (IS_ERR(fg)) {
+               err = PTR_ERR(fg);
+               mlx5_destroy_flow_table(ldev->lag_demux_ft);
+               ldev->lag_demux_ft = NULL;
+               return err;
+       }
+
+       ldev->lag_demux_fg = fg;
+       return 0;
+#else
+       return -EOPNOTSUPP;
+#endif
+}
+
+static int mlx5_lag_demux_fw_init(struct mlx5_core_dev *dev,
+                                 struct mlx5_flow_table_attr *ft_attr,
+                                 struct mlx5_lag *ldev)
+{
+       struct mlx5_flow_namespace *ns;
+       int err;
+
+       ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_LAG);
+       if (!ns)
+               return 0;
+
+       ldev->lag_demux_fg = NULL;
+       ft_attr->max_fte = 1;
+       ldev->lag_demux_ft = mlx5_create_lag_demux_flow_table(ns, ft_attr);
+       if (IS_ERR(ldev->lag_demux_ft)) {
+               err = PTR_ERR(ldev->lag_demux_ft);
+               ldev->lag_demux_ft = NULL;
+               return err;
+       }
+
+       return 0;
+}
+
+int mlx5_lag_demux_init(struct mlx5_core_dev *dev,
+                       struct mlx5_flow_table_attr *ft_attr)
+{
+       struct mlx5_lag *ldev;
+
+       if (!ft_attr)
+               return -EINVAL;
+
+       ldev = mlx5_lag_dev(dev);
+       if (!ldev)
+               return -ENODEV;
+
+       xa_init(&ldev->lag_demux_rules);
+
+       if (mlx5_get_sd(dev))
+               return mlx5_lag_demux_ft_fg_init(dev, ft_attr, ldev);
+
+       return mlx5_lag_demux_fw_init(dev, ft_attr, ldev);
+}
+EXPORT_SYMBOL(mlx5_lag_demux_init);
+
+void mlx5_lag_demux_cleanup(struct mlx5_core_dev *dev)
+{
+       struct mlx5_flow_handle *rule;
+       struct mlx5_lag *ldev;
+       unsigned long vport_num;
+
+       ldev = mlx5_lag_dev(dev);
+       if (!ldev)
+               return;
+
+       xa_for_each(&ldev->lag_demux_rules, vport_num, rule)
+               mlx5_del_flow_rules(rule);
+       xa_destroy(&ldev->lag_demux_rules);
+
+       if (ldev->lag_demux_fg)
+               mlx5_destroy_flow_group(ldev->lag_demux_fg);
+       if (ldev->lag_demux_ft)
+               mlx5_destroy_flow_table(ldev->lag_demux_ft);
+       ldev->lag_demux_fg = NULL;
+       ldev->lag_demux_ft = NULL;
+}
+EXPORT_SYMBOL(mlx5_lag_demux_cleanup);
+
+int mlx5_lag_demux_rule_add(struct mlx5_core_dev *vport_dev, u16 vport_num,
+                           int index)
+{
+       struct mlx5_flow_handle *rule;
+       struct mlx5_lag *ldev;
+       int err;
+
+       ldev = mlx5_lag_dev(vport_dev);
+       if (!ldev || !ldev->lag_demux_fg)
+               return 0;
+
+       if (xa_load(&ldev->lag_demux_rules, index))
+               return 0;
+
+       rule = mlx5_esw_lag_demux_rule_create(vport_dev->priv.eswitch,
+                                             vport_num, ldev->lag_demux_ft);
+       if (IS_ERR(rule)) {
+               err = PTR_ERR(rule);
+               mlx5_core_warn(vport_dev,
+                              "Failed to create LAG demux rule for vport %u, err %d\n",
+                              vport_num, err);
+               return err;
+       }
+
+       err = xa_err(xa_store(&ldev->lag_demux_rules, index, rule,
+                             GFP_KERNEL));
+       if (err) {
+               mlx5_del_flow_rules(rule);
+               mlx5_core_warn(vport_dev,
+                              "Failed to store LAG demux rule for vport %u, err %d\n",
+                              vport_num, err);
+       }
+
+       return err;
+}
+EXPORT_SYMBOL(mlx5_lag_demux_rule_add);
+
+void mlx5_lag_demux_rule_del(struct mlx5_core_dev *dev, int index)
+{
+       struct mlx5_flow_handle *rule;
+       struct mlx5_lag *ldev;
+
+       ldev = mlx5_lag_dev(dev);
+       if (!ldev || !ldev->lag_demux_fg)
+               return;
+
+       rule = xa_erase(&ldev->lag_demux_rules, index);
+       if (rule)
+               mlx5_del_flow_rules(rule);
+}
+EXPORT_SYMBOL(mlx5_lag_demux_rule_del);
+
 static void mlx5_queue_bond_work(struct mlx5_lag *ldev, unsigned long delay)
 {
        queue_delayed_work(ldev->wq, &ldev->bond_work, delay);
index 30cbd61768f81a64c8cd74bf27c84d1f2f10f5b1..6c911374f409ba7d3ecedb465cdb7b4965d01ba9 100644 (file)
@@ -5,6 +5,9 @@
 #define __MLX5_LAG_H__
 
 #include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/xarray.h>
+#include <linux/mlx5/fs.h>
 
 #define MLX5_LAG_MAX_HASH_BUCKETS 16
 /* XArray mark for the LAG master device
@@ -83,6 +86,9 @@ struct mlx5_lag {
        /* Protect lag fields/state changes */
        struct mutex              lock;
        struct lag_mpesw          lag_mpesw;
+       struct mlx5_flow_table   *lag_demux_ft;
+       struct mlx5_flow_group   *lag_demux_fg;
+       struct xarray             lag_demux_rules;
 };
 
 static inline struct mlx5_lag *
@@ -133,6 +139,12 @@ mlx5_lag_is_ready(struct mlx5_lag *ldev)
 
 bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev);
 bool mlx5_lag_check_prereq(struct mlx5_lag *ldev);
+int mlx5_lag_demux_init(struct mlx5_core_dev *dev,
+                       struct mlx5_flow_table_attr *ft_attr);
+void mlx5_lag_demux_cleanup(struct mlx5_core_dev *dev);
+int mlx5_lag_demux_rule_add(struct mlx5_core_dev *dev, u16 vport_num,
+                           int vport_index);
+void mlx5_lag_demux_rule_del(struct mlx5_core_dev *dev, int vport_index);
 void mlx5_modify_lag(struct mlx5_lag *ldev,
                     struct lag_tracker *tracker);
 int mlx5_activate_lag(struct mlx5_lag *ldev,
index 02064424e868a15993bb4ba9659c96851a40f403..d8f3b7ef319e192cc9fa895be8d0735c2df4463a 100644 (file)
@@ -252,9 +252,9 @@ mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns,
 struct mlx5_flow_table *
 mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns,
                             struct mlx5_flow_table_attr *ft_attr, u16 vport);
-struct mlx5_flow_table *mlx5_create_lag_demux_flow_table(
-                                              struct mlx5_flow_namespace *ns,
-                                              int prio, u32 level);
+struct mlx5_flow_table *
+mlx5_create_lag_demux_flow_table(struct mlx5_flow_namespace *ns,
+                                struct mlx5_flow_table_attr *ft_attr);
 int mlx5_destroy_flow_table(struct mlx5_flow_table *ft);
 
 /* inbox should be set with the following values:
index d370dfd1905537e16226071b9c5913206250fed1..ab9f754664e53a3de96a1e164f5fe55cfdddcefe 100644 (file)
@@ -4,8 +4,18 @@
 #ifndef __MLX5_LAG_API_H__
 #define __MLX5_LAG_API_H__
 
+#include <linux/types.h>
+
 struct mlx5_core_dev;
+struct mlx5_flow_table;
+struct mlx5_flow_table_attr;
 
+int mlx5_lag_demux_init(struct mlx5_core_dev *dev,
+                       struct mlx5_flow_table_attr *ft_attr);
+void mlx5_lag_demux_cleanup(struct mlx5_core_dev *dev);
+int mlx5_lag_demux_rule_add(struct mlx5_core_dev *dev, u16 vport_num,
+                           int vport_index);
+void mlx5_lag_demux_rule_del(struct mlx5_core_dev *dev, int vport_index);
 int mlx5_lag_get_dev_seq(struct mlx5_core_dev *dev);
 
 #endif /* __MLX5_LAG_API_H__ */