|
@@ -760,6 +760,37 @@ static int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static int mlx5e_modify_rq_scatter_fcs(struct mlx5e_rq *rq, bool enable)
|
|
|
+{
|
|
|
+ struct mlx5e_channel *c = rq->channel;
|
|
|
+ struct mlx5e_priv *priv = c->priv;
|
|
|
+ struct mlx5_core_dev *mdev = priv->mdev;
|
|
|
+
|
|
|
+ void *in;
|
|
|
+ void *rqc;
|
|
|
+ int inlen;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
|
|
|
+ in = mlx5_vzalloc(inlen);
|
|
|
+ if (!in)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
|
|
|
+
|
|
|
+ MLX5_SET(modify_rq_in, in, rq_state, MLX5_RQC_STATE_RDY);
|
|
|
+ MLX5_SET64(modify_rq_in, in, modify_bitmask,
|
|
|
+ MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS);
|
|
|
+ MLX5_SET(rqc, rqc, scatter_fcs, enable);
|
|
|
+ MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY);
|
|
|
+
|
|
|
+ err = mlx5_core_modify_rq(mdev, rq->rqn, in, inlen);
|
|
|
+
|
|
|
+ kvfree(in);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd)
|
|
|
{
|
|
|
struct mlx5e_channel *c = rq->channel;
|
|
@@ -1388,21 +1419,16 @@ static void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)
|
|
|
mlx5e_free_xdpsq(sq);
|
|
|
}
|
|
|
|
|
|
-static int mlx5e_alloc_cq(struct mlx5e_channel *c,
|
|
|
- struct mlx5e_cq_param *param,
|
|
|
- struct mlx5e_cq *cq)
|
|
|
+static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
|
|
|
+ struct mlx5e_cq_param *param,
|
|
|
+ struct mlx5e_cq *cq)
|
|
|
{
|
|
|
- struct mlx5_core_dev *mdev = c->mdev;
|
|
|
struct mlx5_core_cq *mcq = &cq->mcq;
|
|
|
int eqn_not_used;
|
|
|
unsigned int irqn;
|
|
|
int err;
|
|
|
u32 i;
|
|
|
|
|
|
- param->wq.buf_numa_node = cpu_to_node(c->cpu);
|
|
|
- param->wq.db_numa_node = cpu_to_node(c->cpu);
|
|
|
- param->eq_ix = c->ix;
|
|
|
-
|
|
|
err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq,
|
|
|
&cq->wq_ctrl);
|
|
|
if (err)
|
|
@@ -1410,8 +1436,6 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c,
|
|
|
|
|
|
mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn);
|
|
|
|
|
|
- cq->napi = &c->napi;
|
|
|
-
|
|
|
mcq->cqe_sz = 64;
|
|
|
mcq->set_ci_db = cq->wq_ctrl.db.db;
|
|
|
mcq->arm_db = cq->wq_ctrl.db.db + 1;
|
|
@@ -1428,12 +1452,30 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c,
|
|
|
cqe->op_own = 0xf1;
|
|
|
}
|
|
|
|
|
|
- cq->channel = c;
|
|
|
cq->mdev = mdev;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int mlx5e_alloc_cq(struct mlx5e_channel *c,
|
|
|
+ struct mlx5e_cq_param *param,
|
|
|
+ struct mlx5e_cq *cq)
|
|
|
+{
|
|
|
+ struct mlx5_core_dev *mdev = c->priv->mdev;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ param->wq.buf_numa_node = cpu_to_node(c->cpu);
|
|
|
+ param->wq.db_numa_node = cpu_to_node(c->cpu);
|
|
|
+ param->eq_ix = c->ix;
|
|
|
+
|
|
|
+ err = mlx5e_alloc_cq_common(mdev, param, cq);
|
|
|
+
|
|
|
+ cq->napi = &c->napi;
|
|
|
+ cq->channel = c;
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
static void mlx5e_free_cq(struct mlx5e_cq *cq)
|
|
|
{
|
|
|
mlx5_cqwq_destroy(&cq->wq_ctrl);
|
|
@@ -1834,6 +1876,7 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
|
|
|
MLX5_SET(wq, wq, pd, priv->mdev->mlx5e_res.pdn);
|
|
|
MLX5_SET(rqc, rqc, counter_set_id, priv->q_counter);
|
|
|
MLX5_SET(rqc, rqc, vsd, params->vlan_strip_disable);
|
|
|
+ MLX5_SET(rqc, rqc, scatter_fcs, params->scatter_fcs_en);
|
|
|
|
|
|
param->wq.buf_numa_node = dev_to_node(&priv->mdev->pdev->dev);
|
|
|
param->wq.linear = 1;
|
|
@@ -1901,10 +1944,6 @@ static void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
|
|
|
}
|
|
|
|
|
|
mlx5e_build_common_cq_param(priv, param);
|
|
|
-
|
|
|
- if (params->rx_am_enabled)
|
|
|
- params->rx_cq_moderation =
|
|
|
- mlx5e_am_get_def_profile(params->rx_cq_period_mode);
|
|
|
}
|
|
|
|
|
|
static void mlx5e_build_tx_cq_param(struct mlx5e_priv *priv,
|
|
@@ -2665,31 +2704,7 @@ static int mlx5e_alloc_drop_cq(struct mlx5_core_dev *mdev,
|
|
|
struct mlx5e_cq *cq,
|
|
|
struct mlx5e_cq_param *param)
|
|
|
{
|
|
|
- struct mlx5_core_cq *mcq = &cq->mcq;
|
|
|
- int eqn_not_used;
|
|
|
- unsigned int irqn;
|
|
|
- int err;
|
|
|
-
|
|
|
- err = mlx5_cqwq_create(mdev, ¶m->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;
|
|
|
- *mcq->set_ci_db = 0;
|
|
|
- *mcq->arm_db = 0;
|
|
|
- mcq->vector = param->eq_ix;
|
|
|
- mcq->comp = mlx5e_completion_event;
|
|
|
- mcq->event = mlx5e_cq_error_event;
|
|
|
- mcq->irqn = irqn;
|
|
|
-
|
|
|
- cq->mdev = mdev;
|
|
|
-
|
|
|
- return 0;
|
|
|
+ return mlx5e_alloc_cq_common(mdev, param, cq);
|
|
|
}
|
|
|
|
|
|
static int mlx5e_open_drop_rq(struct mlx5_core_dev *mdev,
|
|
@@ -2904,7 +2919,21 @@ void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv)
|
|
|
mlx5e_destroy_tir(priv->mdev, &priv->direct_tir[i]);
|
|
|
}
|
|
|
|
|
|
-int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
|
|
|
+static int mlx5e_modify_channels_scatter_fcs(struct mlx5e_channels *chs, bool enable)
|
|
|
+{
|
|
|
+ int err = 0;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < chs->num; i++) {
|
|
|
+ err = mlx5e_modify_rq_scatter_fcs(&chs->c[i]->rq, enable);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
|
|
|
{
|
|
|
int err = 0;
|
|
|
int i;
|
|
@@ -3121,6 +3150,23 @@ static int set_feature_rx_all(struct net_device *netdev, bool enable)
|
|
|
return mlx5_set_port_fcs(mdev, !enable);
|
|
|
}
|
|
|
|
|
|
+static int set_feature_rx_fcs(struct net_device *netdev, bool enable)
|
|
|
+{
|
|
|
+ struct mlx5e_priv *priv = netdev_priv(netdev);
|
|
|
+ int err;
|
|
|
+
|
|
|
+ mutex_lock(&priv->state_lock);
|
|
|
+
|
|
|
+ priv->channels.params.scatter_fcs_en = enable;
|
|
|
+ err = mlx5e_modify_channels_scatter_fcs(&priv->channels, enable);
|
|
|
+ if (err)
|
|
|
+ priv->channels.params.scatter_fcs_en = !enable;
|
|
|
+
|
|
|
+ mutex_unlock(&priv->state_lock);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
static int set_feature_rx_vlan(struct net_device *netdev, bool enable)
|
|
|
{
|
|
|
struct mlx5e_priv *priv = netdev_priv(netdev);
|
|
@@ -3194,6 +3240,8 @@ static int mlx5e_set_features(struct net_device *netdev,
|
|
|
set_feature_tc_num_filters);
|
|
|
err |= mlx5e_handle_feature(netdev, features, NETIF_F_RXALL,
|
|
|
set_feature_rx_all);
|
|
|
+ err |= mlx5e_handle_feature(netdev, features, NETIF_F_RXFCS,
|
|
|
+ set_feature_rx_fcs);
|
|
|
err |= mlx5e_handle_feature(netdev, features, NETIF_F_HW_VLAN_CTAG_RX,
|
|
|
set_feature_rx_vlan);
|
|
|
#ifdef CONFIG_RFS_ACCEL
|
|
@@ -3735,6 +3783,10 @@ void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
|
|
|
params->rx_cq_moderation.usec =
|
|
|
MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE;
|
|
|
|
|
|
+ if (params->rx_am_enabled)
|
|
|
+ params->rx_cq_moderation =
|
|
|
+ mlx5e_am_get_def_profile(params->rx_cq_period_mode);
|
|
|
+
|
|
|
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_BASED_MODER,
|
|
|
params->rx_cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
|
|
|
}
|
|
@@ -3908,6 +3960,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
|
|
|
if (fcs_supported)
|
|
|
netdev->hw_features |= NETIF_F_RXALL;
|
|
|
|
|
|
+ if (MLX5_CAP_ETH(mdev, scatter_fcs))
|
|
|
+ netdev->hw_features |= NETIF_F_RXFCS;
|
|
|
+
|
|
|
netdev->features = netdev->hw_features;
|
|
|
if (!priv->channels.params.lro_en)
|
|
|
netdev->features &= ~NETIF_F_LRO;
|
|
@@ -3915,6 +3970,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
|
|
|
if (fcs_enabled)
|
|
|
netdev->features &= ~NETIF_F_RXALL;
|
|
|
|
|
|
+ if (!priv->channels.params.scatter_fcs_en)
|
|
|
+ netdev->features &= ~NETIF_F_RXFCS;
|
|
|
+
|
|
|
#define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f)
|
|
|
if (FT_CAP(flow_modify_en) &&
|
|
|
FT_CAP(modify_root) &&
|