Commit 472a1e44 authored by Tariq Toukan's avatar Tariq Toukan Committed by Saeed Mahameed

net/mlx5e: Save MTU in channels params

Knowing the MTU is required for RQ creation flow.
By our design, channels creation flow is totally isolated
from priv/netdev, and can be completed with access to
channels params and mdev.
Adding the MTU to the channels params helps preserving that.
In addition, we save it in RQ to make its access faster in
datapath checks.
Signed-off-by: default avatarTariq Toukan <tariqt@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 53378898
...@@ -57,8 +57,8 @@ ...@@ -57,8 +57,8 @@
#define MLX5E_ETH_HARD_MTU (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN) #define MLX5E_ETH_HARD_MTU (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
#define MLX5E_HW2SW_MTU(priv, hwmtu) ((hwmtu) - ((priv)->hard_mtu)) #define MLX5E_HW2SW_MTU(params, hwmtu) ((hwmtu) - ((params)->hard_mtu))
#define MLX5E_SW2HW_MTU(priv, swmtu) ((swmtu) + ((priv)->hard_mtu)) #define MLX5E_SW2HW_MTU(params, swmtu) ((swmtu) + ((params)->hard_mtu))
#define MLX5E_MAX_DSCP 64 #define MLX5E_MAX_DSCP 64
#define MLX5E_MAX_NUM_TC 8 #define MLX5E_MAX_NUM_TC 8
...@@ -251,6 +251,8 @@ struct mlx5e_params { ...@@ -251,6 +251,8 @@ struct mlx5e_params {
u32 lro_timeout; u32 lro_timeout;
u32 pflags; u32 pflags;
struct bpf_prog *xdp_prog; struct bpf_prog *xdp_prog;
unsigned int sw_mtu;
int hard_mtu;
}; };
#ifdef CONFIG_MLX5_CORE_EN_DCB #ifdef CONFIG_MLX5_CORE_EN_DCB
...@@ -534,6 +536,7 @@ struct mlx5e_rq { ...@@ -534,6 +536,7 @@ struct mlx5e_rq {
/* XDP */ /* XDP */
struct bpf_prog *xdp_prog; struct bpf_prog *xdp_prog;
unsigned int hw_mtu;
struct mlx5e_xdpsq xdpsq; struct mlx5e_xdpsq xdpsq;
/* control */ /* control */
...@@ -767,7 +770,6 @@ struct mlx5e_priv { ...@@ -767,7 +770,6 @@ struct mlx5e_priv {
struct mlx5e_tir inner_indir_tir[MLX5E_NUM_INDIR_TIRS]; struct mlx5e_tir inner_indir_tir[MLX5E_NUM_INDIR_TIRS];
struct mlx5e_tir direct_tir[MLX5E_MAX_NUM_CHANNELS]; struct mlx5e_tir direct_tir[MLX5E_MAX_NUM_CHANNELS];
u32 tx_rates[MLX5E_MAX_NUM_SQS]; u32 tx_rates[MLX5E_MAX_NUM_SQS];
int hard_mtu;
struct mlx5e_flow_steering fs; struct mlx5e_flow_steering fs;
struct mlx5e_vxlan_db vxlan; struct mlx5e_vxlan_db vxlan;
...@@ -1111,7 +1113,7 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv); ...@@ -1111,7 +1113,7 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv);
void mlx5e_destroy_netdev(struct mlx5e_priv *priv); void mlx5e_destroy_netdev(struct mlx5e_priv *priv);
void mlx5e_build_nic_params(struct mlx5_core_dev *mdev, void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
struct mlx5e_params *params, struct mlx5e_params *params,
u16 max_channels); u16 max_channels, u16 mtu);
u8 mlx5e_params_calculate_tx_min_inline(struct mlx5_core_dev *mdev); u8 mlx5e_params_calculate_tx_min_inline(struct mlx5_core_dev *mdev);
void mlx5e_rx_dim_work(struct work_struct *work); void mlx5e_rx_dim_work(struct work_struct *work);
#endif /* __MLX5_EN_H__ */ #endif /* __MLX5_EN_H__ */
...@@ -419,6 +419,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, ...@@ -419,6 +419,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
rq->channel = c; rq->channel = c;
rq->ix = c->ix; rq->ix = c->ix;
rq->mdev = mdev; rq->mdev = mdev;
rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu);
rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL; rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL;
if (IS_ERR(rq->xdp_prog)) { if (IS_ERR(rq->xdp_prog)) {
...@@ -494,7 +495,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, ...@@ -494,7 +495,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
byte_count = params->lro_en ? byte_count = params->lro_en ?
params->lro_wqe_sz : params->lro_wqe_sz :
MLX5E_SW2HW_MTU(c->priv, c->netdev->mtu); MLX5E_SW2HW_MTU(params, params->sw_mtu);
#ifdef CONFIG_MLX5_EN_IPSEC #ifdef CONFIG_MLX5_EN_IPSEC
if (MLX5_IPSEC_DEV(mdev)) if (MLX5_IPSEC_DEV(mdev))
byte_count += MLX5E_METADATA_ETHER_LEN; byte_count += MLX5E_METADATA_ETHER_LEN;
...@@ -2498,10 +2499,10 @@ static void mlx5e_build_inner_indir_tir_ctx(struct mlx5e_priv *priv, ...@@ -2498,10 +2499,10 @@ static void mlx5e_build_inner_indir_tir_ctx(struct mlx5e_priv *priv,
mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, true); mlx5e_build_indir_tir_ctx_hash(&priv->channels.params, tt, tirc, true);
} }
static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) static int mlx5e_set_mtu(struct mlx5_core_dev *mdev,
struct mlx5e_params *params, u16 mtu)
{ {
struct mlx5_core_dev *mdev = priv->mdev; u16 hw_mtu = MLX5E_SW2HW_MTU(params, mtu);
u16 hw_mtu = MLX5E_SW2HW_MTU(priv, mtu);
int err; int err;
err = mlx5_set_port_mtu(mdev, hw_mtu, 1); err = mlx5_set_port_mtu(mdev, hw_mtu, 1);
...@@ -2513,9 +2514,9 @@ static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) ...@@ -2513,9 +2514,9 @@ static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu)
return 0; return 0;
} }
static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu) static void mlx5e_query_mtu(struct mlx5_core_dev *mdev,
struct mlx5e_params *params, u16 *mtu)
{ {
struct mlx5_core_dev *mdev = priv->mdev;
u16 hw_mtu = 0; u16 hw_mtu = 0;
int err; int err;
...@@ -2523,25 +2524,27 @@ static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu) ...@@ -2523,25 +2524,27 @@ static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu)
if (err || !hw_mtu) /* fallback to port oper mtu */ if (err || !hw_mtu) /* fallback to port oper mtu */
mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1);
*mtu = MLX5E_HW2SW_MTU(priv, hw_mtu); *mtu = MLX5E_HW2SW_MTU(params, hw_mtu);
} }
static int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) static int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
{ {
struct mlx5e_params *params = &priv->channels.params;
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
struct mlx5_core_dev *mdev = priv->mdev;
u16 mtu; u16 mtu;
int err; int err;
err = mlx5e_set_mtu(priv, netdev->mtu); err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
if (err) if (err)
return err; return err;
mlx5e_query_mtu(priv, &mtu); mlx5e_query_mtu(mdev, params, &mtu);
if (mtu != netdev->mtu) if (mtu != params->sw_mtu)
netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
__func__, mtu, netdev->mtu); __func__, mtu, params->sw_mtu);
netdev->mtu = mtu; params->sw_mtu = mtu;
return 0; return 0;
} }
...@@ -3411,34 +3414,33 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -3411,34 +3414,33 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_channels new_channels = {}; struct mlx5e_channels new_channels = {};
int curr_mtu; struct mlx5e_params *params;
int err = 0; int err = 0;
bool reset; bool reset;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
reset = !priv->channels.params.lro_en && params = &priv->channels.params;
(priv->channels.params.rq_wq_type != reset = !params->lro_en &&
MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ); (params->rq_wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ);
reset = reset && test_bit(MLX5E_STATE_OPENED, &priv->state); reset = reset && test_bit(MLX5E_STATE_OPENED, &priv->state);
curr_mtu = netdev->mtu;
netdev->mtu = new_mtu;
if (!reset) { if (!reset) {
params->sw_mtu = new_mtu;
mlx5e_set_dev_port_mtu(priv); mlx5e_set_dev_port_mtu(priv);
netdev->mtu = params->sw_mtu;
goto out; goto out;
} }
new_channels.params = priv->channels.params; new_channels.params = *params;
new_channels.params.sw_mtu = new_mtu;
err = mlx5e_open_channels(priv, &new_channels); err = mlx5e_open_channels(priv, &new_channels);
if (err) { if (err)
netdev->mtu = curr_mtu;
goto out; goto out;
}
mlx5e_switch_priv_channels(priv, &new_channels, mlx5e_set_dev_port_mtu); mlx5e_switch_priv_channels(priv, &new_channels, mlx5e_set_dev_port_mtu);
netdev->mtu = new_channels.params.sw_mtu;
out: out:
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
...@@ -4111,10 +4113,12 @@ static u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeo ...@@ -4111,10 +4113,12 @@ static u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeo
void mlx5e_build_nic_params(struct mlx5_core_dev *mdev, void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
struct mlx5e_params *params, struct mlx5e_params *params,
u16 max_channels) u16 max_channels, u16 mtu)
{ {
u8 cq_period_mode = 0; u8 cq_period_mode = 0;
params->sw_mtu = mtu;
params->hard_mtu = MLX5E_ETH_HARD_MTU;
params->num_channels = max_channels; params->num_channels = max_channels;
params->num_tc = 1; params->num_tc = 1;
...@@ -4175,9 +4179,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev, ...@@ -4175,9 +4179,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
priv->profile = profile; priv->profile = profile;
priv->ppriv = ppriv; priv->ppriv = ppriv;
priv->msglevel = MLX5E_MSG_LEVEL; priv->msglevel = MLX5E_MSG_LEVEL;
priv->hard_mtu = MLX5E_ETH_HARD_MTU;
mlx5e_build_nic_params(mdev, &priv->channels.params, profile->max_nch(mdev)); mlx5e_build_nic_params(mdev, &priv->channels.params,
profile->max_nch(mdev), netdev->mtu);
mutex_init(&priv->state_lock); mutex_init(&priv->state_lock);
...@@ -4454,7 +4458,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) ...@@ -4454,7 +4458,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
/* MTU range: 68 - hw-specific max */ /* MTU range: 68 - hw-specific max */
netdev->min_mtu = ETH_MIN_MTU; netdev->min_mtu = ETH_MIN_MTU;
mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1); mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
netdev->max_mtu = MLX5E_HW2SW_MTU(priv, max_mtu); netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
mlx5e_set_dev_port_mtu(priv); mlx5e_set_dev_port_mtu(priv);
mlx5_lag_add(mdev, netdev); mlx5_lag_add(mdev, netdev);
......
...@@ -877,6 +877,7 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev, ...@@ -877,6 +877,7 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
MLX5_CQ_PERIOD_MODE_START_FROM_CQE : MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
MLX5_CQ_PERIOD_MODE_START_FROM_EQE; MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
params->hard_mtu = MLX5E_ETH_HARD_MTU;
params->log_sq_size = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE; params->log_sq_size = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
params->rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST; params->rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST;
params->log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE; params->log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
...@@ -926,8 +927,6 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev, ...@@ -926,8 +927,6 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
priv->channels.params.num_channels = profile->max_nch(mdev); priv->channels.params.num_channels = profile->max_nch(mdev);
priv->hard_mtu = MLX5E_ETH_HARD_MTU;
mlx5e_build_rep_params(mdev, &priv->channels.params); mlx5e_build_rep_params(mdev, &priv->channels.params);
mlx5e_build_rep_netdev(netdev); mlx5e_build_rep_netdev(netdev);
......
...@@ -766,8 +766,7 @@ static inline bool mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq, ...@@ -766,8 +766,7 @@ static inline bool mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
prefetchw(wqe); prefetchw(wqe);
if (unlikely(dma_len < MLX5E_XDP_MIN_INLINE || if (unlikely(dma_len < MLX5E_XDP_MIN_INLINE || rq->hw_mtu < dma_len)) {
MLX5E_SW2HW_MTU(rq->channel->priv, rq->netdev->mtu) < dma_len)) {
rq->stats.xdp_drop++; rq->stats.xdp_drop++;
return false; return false;
} }
......
...@@ -66,6 +66,7 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, ...@@ -66,6 +66,7 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
MLX5I_PARAMS_DEFAULT_LOG_RQ_SIZE; MLX5I_PARAMS_DEFAULT_LOG_RQ_SIZE;
params->lro_en = false; params->lro_en = false;
params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
} }
/* Called directly after IPoIB netdevice was created to initialize SW structs */ /* Called directly after IPoIB netdevice was created to initialize SW structs */
...@@ -81,10 +82,10 @@ void mlx5i_init(struct mlx5_core_dev *mdev, ...@@ -81,10 +82,10 @@ void mlx5i_init(struct mlx5_core_dev *mdev,
priv->netdev = netdev; priv->netdev = netdev;
priv->profile = profile; priv->profile = profile;
priv->ppriv = ppriv; priv->ppriv = ppriv;
priv->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
mutex_init(&priv->state_lock); mutex_init(&priv->state_lock);
mlx5e_build_nic_params(mdev, &priv->channels.params, profile->max_nch(mdev)); mlx5e_build_nic_params(mdev, &priv->channels.params,
profile->max_nch(mdev), netdev->mtu);
mlx5i_build_nic_params(mdev, &priv->channels.params); mlx5i_build_nic_params(mdev, &priv->channels.params);
mlx5e_timestamp_init(priv); mlx5e_timestamp_init(priv);
...@@ -368,25 +369,27 @@ static int mlx5i_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -368,25 +369,27 @@ static int mlx5i_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
struct mlx5e_channels new_channels = {}; struct mlx5e_channels new_channels = {};
int curr_mtu; struct mlx5e_params *params;
int err = 0; int err = 0;
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
curr_mtu = netdev->mtu; params = &priv->channels.params;
netdev->mtu = new_mtu;
if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
params->sw_mtu = new_mtu;
netdev->mtu = params->sw_mtu;
goto out; goto out;
}
new_channels.params = priv->channels.params; new_channels.params = *params;
new_channels.params.sw_mtu = new_mtu;
err = mlx5e_open_channels(priv, &new_channels); err = mlx5e_open_channels(priv, &new_channels);
if (err) { if (err)
netdev->mtu = curr_mtu;
goto out; goto out;
}
mlx5e_switch_priv_channels(priv, &new_channels, NULL); mlx5e_switch_priv_channels(priv, &new_channels, NULL);
netdev->mtu = new_channels.params.sw_mtu;
out: out:
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment