]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/net/ethernet/mellanox/mlx5/core/en_main.c
net/mlx5e: Move RSS params to a dedicated struct
[linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_main.c
index 1243edbedc9e96c90196f7b7f311129f2eb0cb04..be782c508f3ac483261625e6bc2c74ac06a8bb32 100644 (file)
@@ -502,6 +502,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
        rq->channel = c;
        rq->ix      = c->ix;
        rq->mdev    = mdev;
+       rq->hw_mtu  = MLX5E_SW2HW_MTU(params, params->sw_mtu);
        rq->stats   = &c->priv->channel_stats[c->ix].rq;
 
        rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL;
@@ -1623,13 +1624,15 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
        int err;
        u32 i;
 
+       err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn);
+       if (err)
+               return err;
+
        err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
                               &cq->wq_ctrl);
        if (err)
                return err;
 
-       mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn);
-
        mcq->cqe_sz     = 64;
        mcq->set_ci_db  = cq->wq_ctrl.db.db;
        mcq->arm_db     = cq->wq_ctrl.db.db + 1;
@@ -1687,6 +1690,10 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
        int eqn;
        int err;
 
+       err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used);
+       if (err)
+               return err;
+
        inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
                sizeof(u64) * cq->wq_ctrl.buf.npages;
        in = kvzalloc(inlen, GFP_KERNEL);
@@ -1700,8 +1707,6 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
        mlx5_fill_page_frag_array(&cq->wq_ctrl.buf,
                                  (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas));
 
-       mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used);
-
        MLX5_SET(cqc,   cqc, cq_period_mode, param->cq_period_mode);
        MLX5_SET(cqc,   cqc, c_eqn,         eqn);
        MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
@@ -1921,6 +1926,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
        int err;
        int eqn;
 
+       err = mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq);
+       if (err)
+               return err;
+
        c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
        if (!c)
                return -ENOMEM;
@@ -1937,7 +1946,6 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
        c->xdp      = !!params->xdp_prog;
        c->stats    = &priv->channel_stats[ix].ch;
 
-       mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq);
        c->irq_desc = irq_to_desc(irq);
 
        netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);
@@ -2496,7 +2504,7 @@ static void mlx5e_fill_rqt_rqns(struct mlx5e_priv *priv, int sz,
                        if (rrp.rss.hfunc == ETH_RSS_HASH_XOR)
                                ix = mlx5e_bits_invert(i, ilog2(sz));
 
-                       ix = priv->channels.params.indirection_rqt[ix];
+                       ix = priv->rss_params.indirection_rqt[ix];
                        rqn = rrp.rss.channels->c[ix]->rq.rqn;
                } else {
                        rqn = rrp.rqn;
@@ -2579,7 +2587,7 @@ static void mlx5e_redirect_rqts_to_channels(struct mlx5e_priv *priv,
                {
                        .rss = {
                                .channels  = chs,
-                               .hfunc     = chs->params.rss_hfunc,
+                               .hfunc     = priv->rss_params.hfunc,
                        }
                },
        };
@@ -2599,6 +2607,54 @@ static void mlx5e_redirect_rqts_to_drop(struct mlx5e_priv *priv)
        mlx5e_redirect_rqts(priv, drop_rrp);
 }
 
+static const struct mlx5e_tirc_config tirc_default_config[MLX5E_NUM_INDIR_TIRS] = {
+       [MLX5E_TT_IPV4_TCP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
+                               .l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
+                               .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
+       },
+       [MLX5E_TT_IPV6_TCP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
+                               .l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
+                               .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
+       },
+       [MLX5E_TT_IPV4_UDP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
+                               .l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
+                               .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
+       },
+       [MLX5E_TT_IPV6_UDP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
+                               .l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
+                               .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
+       },
+       [MLX5E_TT_IPV4_IPSEC_AH] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
+                                    .l4_prot_type = 0,
+                                    .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
+       },
+       [MLX5E_TT_IPV6_IPSEC_AH] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
+                                    .l4_prot_type = 0,
+                                    .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
+       },
+       [MLX5E_TT_IPV4_IPSEC_ESP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
+                                     .l4_prot_type = 0,
+                                     .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
+       },
+       [MLX5E_TT_IPV6_IPSEC_ESP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
+                                     .l4_prot_type = 0,
+                                     .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
+       },
+       [MLX5E_TT_IPV4] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
+                           .l4_prot_type = 0,
+                           .rx_hash_fields = MLX5_HASH_IP,
+       },
+       [MLX5E_TT_IPV6] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
+                           .l4_prot_type = 0,
+                           .rx_hash_fields = MLX5_HASH_IP,
+       },
+};
+
+struct mlx5e_tirc_config mlx5e_tirc_get_default_config(enum mlx5e_traffic_types tt)
+{
+       return tirc_default_config[tt];
+}
+
 static void mlx5e_build_tir_ctx_lro(struct mlx5e_params *params, void *tirc)
 {
        if (!params->lro_en)
@@ -2614,116 +2670,58 @@ static void mlx5e_build_tir_ctx_lro(struct mlx5e_params *params, void *tirc)
        MLX5_SET(tirc, tirc, lro_timeout_period_usecs, params->lro_timeout);
 }
 
-void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params,
-                                   enum mlx5e_traffic_types tt,
+void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_rss_params *rss_params,
+                                   const struct mlx5e_tirc_config *ttconfig,
                                    void *tirc, bool inner)
 {
        void *hfso = inner ? MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_inner) :
                             MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
 
-#define MLX5_HASH_IP            (MLX5_HASH_FIELD_SEL_SRC_IP   |\
-                                MLX5_HASH_FIELD_SEL_DST_IP)
-
-#define MLX5_HASH_IP_L4PORTS    (MLX5_HASH_FIELD_SEL_SRC_IP   |\
-                                MLX5_HASH_FIELD_SEL_DST_IP   |\
-                                MLX5_HASH_FIELD_SEL_L4_SPORT |\
-                                MLX5_HASH_FIELD_SEL_L4_DPORT)
-
-#define MLX5_HASH_IP_IPSEC_SPI  (MLX5_HASH_FIELD_SEL_SRC_IP   |\
-                                MLX5_HASH_FIELD_SEL_DST_IP   |\
-                                MLX5_HASH_FIELD_SEL_IPSEC_SPI)
-
-       MLX5_SET(tirc, tirc, rx_hash_fn, mlx5e_rx_hash_fn(params->rss_hfunc));
-       if (params->rss_hfunc == ETH_RSS_HASH_TOP) {
+       MLX5_SET(tirc, tirc, rx_hash_fn, mlx5e_rx_hash_fn(rss_params->hfunc));
+       if (rss_params->hfunc == ETH_RSS_HASH_TOP) {
                void *rss_key = MLX5_ADDR_OF(tirc, tirc,
                                             rx_hash_toeplitz_key);
                size_t len = MLX5_FLD_SZ_BYTES(tirc,
                                               rx_hash_toeplitz_key);
 
                MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
-               memcpy(rss_key, params->toeplitz_hash_key, len);
+               memcpy(rss_key, rss_params->toeplitz_hash_key, len);
        }
+       MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
+                ttconfig->l3_prot_type);
+       MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
+                ttconfig->l4_prot_type);
+       MLX5_SET(rx_hash_field_select, hfso, selected_fields,
+                ttconfig->rx_hash_fields);
+}
 
-       switch (tt) {
-       case MLX5E_TT_IPV4_TCP:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV4);
-               MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
-                        MLX5_L4_PROT_TYPE_TCP);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_L4PORTS);
-               break;
-
-       case MLX5E_TT_IPV6_TCP:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV6);
-               MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
-                        MLX5_L4_PROT_TYPE_TCP);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_L4PORTS);
-               break;
-
-       case MLX5E_TT_IPV4_UDP:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV4);
-               MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
-                        MLX5_L4_PROT_TYPE_UDP);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_L4PORTS);
-               break;
-
-       case MLX5E_TT_IPV6_UDP:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV6);
-               MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
-                        MLX5_L4_PROT_TYPE_UDP);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_L4PORTS);
-               break;
-
-       case MLX5E_TT_IPV4_IPSEC_AH:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV4);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_IPSEC_SPI);
-               break;
-
-       case MLX5E_TT_IPV6_IPSEC_AH:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV6);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_IPSEC_SPI);
-               break;
+void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
+{
+       void *tirc = MLX5_ADDR_OF(modify_tir_in, in, ctx);
+       struct mlx5_core_dev *mdev = priv->mdev;
+       int ctxlen = MLX5_ST_SZ_BYTES(tirc);
+       int tt;
 
-       case MLX5E_TT_IPV4_IPSEC_ESP:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV4);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_IPSEC_SPI);
-               break;
+       MLX5_SET(modify_tir_in, in, bitmask.hash, 1);
 
-       case MLX5E_TT_IPV6_IPSEC_ESP:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV6);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP_IPSEC_SPI);
-               break;
+       for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
+               memset(tirc, 0, ctxlen);
+               mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
+                                              &tirc_default_config[tt],
+                                              tirc, false);
+               mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen);
+       }
 
-       case MLX5E_TT_IPV4:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV4);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP);
-               break;
+       if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
+               return;
 
-       case MLX5E_TT_IPV6:
-               MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
-                        MLX5_L3_PROT_TYPE_IPV6);
-               MLX5_SET(rx_hash_field_select, hfso, selected_fields,
-                        MLX5_HASH_IP);
-               break;
-       default:
-               WARN_ONCE(true, "%s: bad traffic type!\n", __func__);
+       for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
+               memset(tirc, 0, ctxlen);
+               mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
+                                              &tirc_default_config[tt],
+                                              tirc, true);
+               mlx5_core_modify_tir(mdev, priv->inner_indir_tir[tt].tirn, in,
+                                    inlen);
        }
 }
 
@@ -2780,7 +2778,8 @@ static void mlx5e_build_inner_indir_tir_ctx(struct mlx5e_priv *priv,
        MLX5_SET(tirc, tirc, indirect_table, priv->indir_rqt.rqtn);
        MLX5_SET(tirc, tirc, tunneled_offload_en, 0x1);
 
-       mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, true);
+       mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
+                                      &tirc_default_config[tt], tirc, true);
 }
 
 static int mlx5e_set_mtu(struct mlx5_core_dev *mdev,
@@ -3172,7 +3171,9 @@ static void mlx5e_build_indir_tir_ctx(struct mlx5e_priv *priv,
 
        MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
        MLX5_SET(tirc, tirc, indirect_table, priv->indir_rqt.rqtn);
-       mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, false);
+
+       mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
+                                      &tirc_default_config[tt], tirc, false);
 }
 
 static void mlx5e_build_direct_tir_ctx(struct mlx5e_priv *priv, u32 rqtn, u32 *tirc)
@@ -3574,6 +3575,7 @@ static int set_feature_cvlan_filter(struct net_device *netdev, bool enable)
        return 0;
 }
 
+#ifdef CONFIG_MLX5_ESWITCH
 static int set_feature_tc_num_filters(struct net_device *netdev, bool enable)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -3586,6 +3588,7 @@ static int set_feature_tc_num_filters(struct net_device *netdev, bool enable)
 
        return 0;
 }
+#endif
 
 static int set_feature_rx_all(struct net_device *netdev, bool enable)
 {
@@ -3684,7 +3687,9 @@ static int mlx5e_set_features(struct net_device *netdev,
        err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro);
        err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER,
                                    set_feature_cvlan_filter);
+#ifdef CONFIG_MLX5_ESWITCH
        err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters);
+#endif
        err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXALL, set_feature_rx_all);
        err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs);
        err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan);
@@ -3755,10 +3760,11 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
        }
 
        if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
+               bool is_linear = mlx5e_rx_mpwqe_is_linear_skb(priv->mdev, &new_channels.params);
                u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params);
                u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params);
 
-               reset = reset && (ppw_old != ppw_new);
+               reset = reset && (is_linear || (ppw_old != ppw_new));
        }
 
        if (!reset) {
@@ -4505,15 +4511,18 @@ void mlx5e_build_rq_params(struct mlx5_core_dev *mdev,
        mlx5e_init_rq_type_params(mdev, params);
 }
 
-void mlx5e_build_rss_params(struct mlx5e_params *params)
+void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
+                           u16 num_channels)
 {
-       params->rss_hfunc = ETH_RSS_HASH_XOR;
-       netdev_rss_key_fill(params->toeplitz_hash_key, sizeof(params->toeplitz_hash_key));
-       mlx5e_build_default_indir_rqt(params->indirection_rqt,
-                                     MLX5E_INDIR_RQT_SIZE, params->num_channels);
+       rss_params->hfunc = ETH_RSS_HASH_XOR;
+       netdev_rss_key_fill(rss_params->toeplitz_hash_key,
+                           sizeof(rss_params->toeplitz_hash_key));
+       mlx5e_build_default_indir_rqt(rss_params->indirection_rqt,
+                                     MLX5E_INDIR_RQT_SIZE, num_channels);
 }
 
 void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
+                           struct mlx5e_rss_params *rss_params,
                            struct mlx5e_params *params,
                            u16 max_channels, u16 mtu)
 {
@@ -4562,7 +4571,7 @@ void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
        params->tx_min_inline_mode = mlx5e_params_calculate_tx_min_inline(mdev);
 
        /* RSS */
-       mlx5e_build_rss_params(params);
+       mlx5e_build_rss_params(rss_params, params->num_channels);
 }
 
 static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
@@ -4678,7 +4687,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
            FT_CAP(modify_root) &&
            FT_CAP(identified_miss_table_mode) &&
            FT_CAP(flow_table_modify)) {
+#ifdef CONFIG_MLX5_ESWITCH
                netdev->hw_features      |= NETIF_F_HW_TC;
+#endif
 #ifdef CONFIG_MLX5_EN_ARFS
                netdev->hw_features      |= NETIF_F_NTUPLE;
 #endif
@@ -4733,14 +4744,16 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
                          void *ppriv)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
+       struct mlx5e_rss_params *rss = &priv->rss_params;
        int err;
 
        err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
        if (err)
                return err;
 
-       mlx5e_build_nic_params(mdev, &priv->channels.params,
-                              mlx5e_get_netdev_max_channels(netdev), netdev->mtu);
+       mlx5e_build_nic_params(mdev, rss, &priv->channels.params,
+                              mlx5e_get_netdev_max_channels(netdev),
+                              netdev->mtu);
 
        mlx5e_timestamp_init(priv);
 
@@ -5004,11 +5017,21 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
 int mlx5e_attach_netdev(struct mlx5e_priv *priv)
 {
        const struct mlx5e_profile *profile;
+       int max_nch;
        int err;
 
        profile = priv->profile;
        clear_bit(MLX5E_STATE_DESTROYING, &priv->state);
 
+       /* max number of channels may have changed */
+       max_nch = mlx5e_get_max_num_channels(priv->mdev);
+       if (priv->channels.params.num_channels > max_nch) {
+               mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch);
+               priv->channels.params.num_channels = max_nch;
+               mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
+                                             MLX5E_INDIR_RQT_SIZE, max_nch);
+       }
+
        err = profile->init_tx(priv);
        if (err)
                goto out;