net/mlx5e: IPoIB, RSS flow steering tables
authorSaeed Mahameed <saeedm@mellanox.com>
Thu, 13 Apr 2017 03:36:57 +0000 (06:36 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 17 Apr 2017 15:08:30 +0000 (11:08 -0400)
Like the mlx5e ethernet mode, on IPoIB mode we need to create RX steering
tables, but IPoIB do not require MAC and VLAN steering tables so the
only tables we create in here are:
1. TTC Table (Traffic Type Classifier table for RSS steering)
2. ARFS Table (for accelerated RFS support)

Creation of those tables is identical to mlx5e ethernet mode, hence the
use of mlx5e_create_ttc_table and mlx5e_arfs_create_tables.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib.c

index e5518536d56f8b0db6d601075a4f0b7921330542..c813eab5d764f8c23708b36d57b20b73b26e73f3 100644 (file)
@@ -999,6 +999,7 @@ int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr);
 void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
 void mlx5e_update_hw_rep_counters(struct mlx5e_priv *priv);
 
+/* common netdev helpers */
 int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv);
 
 int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv);
@@ -1010,6 +1011,9 @@ int mlx5e_create_direct_tirs(struct mlx5e_priv *priv);
 void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv);
 void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt);
 
+int mlx5e_create_ttc_table(struct mlx5e_priv *priv, u32 underlay_qpn);
+void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv);
+
 int mlx5e_create_tises(struct mlx5e_priv *priv);
 void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv);
 int mlx5e_close(struct net_device *netdev);
index 729904c43801e17a9b8996c779e331d7cd473fb4..576d6787b484b6387c55a172a65fa838b50e198a 100644 (file)
@@ -792,7 +792,7 @@ err:
        return err;
 }
 
-static void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
+void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
 {
        struct mlx5e_ttc_table *ttc = &priv->fs.ttc;
 
@@ -800,7 +800,7 @@ static void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
        mlx5e_destroy_flow_table(&ttc->ft);
 }
 
-static int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
+int mlx5e_create_ttc_table(struct mlx5e_priv *priv, u32 underlay_qpn)
 {
        struct mlx5e_ttc_table *ttc = &priv->fs.ttc;
        struct mlx5_flow_table_attr ft_attr = {};
@@ -810,6 +810,7 @@ static int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
        ft_attr.max_fte = MLX5E_TTC_TABLE_SIZE;
        ft_attr.level = MLX5E_TTC_FT_LEVEL;
        ft_attr.prio = MLX5E_NIC_PRIO;
+       ft_attr.underlay_qpn = underlay_qpn;
 
        ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
        if (IS_ERR(ft->t)) {
@@ -1146,7 +1147,7 @@ int mlx5e_create_flow_steering(struct mlx5e_priv *priv)
                priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
        }
 
-       err = mlx5e_create_ttc_table(priv);
+       err = mlx5e_create_ttc_table(priv, 0);
        if (err) {
                netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
                           err);
index f0318920844ef25d652103f35282b6f46d357276..e16e1c7b246e53bb94fe9d4c40b4099cea9bbd90 100644 (file)
@@ -72,6 +72,45 @@ static void mlx5i_cleanup_tx(struct mlx5e_priv *priv)
 {
 }
 
+static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
+{
+       struct mlx5i_priv *ipriv = priv->ppriv;
+       int err;
+
+       priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
+                                              MLX5_FLOW_NAMESPACE_KERNEL);
+
+       if (!priv->fs.ns)
+               return -EINVAL;
+
+       err = mlx5e_arfs_create_tables(priv);
+       if (err) {
+               netdev_err(priv->netdev, "Failed to create arfs tables, err=%d\n",
+                          err);
+               priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
+       }
+
+       err = mlx5e_create_ttc_table(priv, ipriv->qp.qpn);
+       if (err) {
+               netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
+                          err);
+               goto err_destroy_arfs_tables;
+       }
+
+       return 0;
+
+err_destroy_arfs_tables:
+       mlx5e_arfs_destroy_tables(priv);
+
+       return err;
+}
+
+static void mlx5i_destroy_flow_steering(struct mlx5e_priv *priv)
+{
+       mlx5e_destroy_ttc_table(priv);
+       mlx5e_arfs_destroy_tables(priv);
+}
+
 static int mlx5i_init_rx(struct mlx5e_priv *priv)
 {
        int err;
@@ -92,8 +131,14 @@ static int mlx5i_init_rx(struct mlx5e_priv *priv)
        if (err)
                goto err_destroy_indirect_tirs;
 
+       err = mlx5i_create_flow_steering(priv);
+       if (err)
+               goto err_destroy_direct_tirs;
+
        return 0;
 
+err_destroy_direct_tirs:
+       mlx5e_destroy_direct_tirs(priv);
 err_destroy_indirect_tirs:
        mlx5e_destroy_indirect_tirs(priv);
 err_destroy_direct_rqts:
@@ -105,6 +150,7 @@ err_destroy_indirect_rqts:
 
 static void mlx5i_cleanup_rx(struct mlx5e_priv *priv)
 {
+       mlx5i_destroy_flow_steering(priv);
        mlx5e_destroy_direct_tirs(priv);
        mlx5e_destroy_indirect_tirs(priv);
        mlx5e_destroy_direct_rqts(priv);