mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Add support for disabling and enabling RX and TX DMA rings in mlx5en(4).
This is useful for supporting setups similar to Netmap. Sponsored by: Mellanox Technologies MFC after: 1 week
This commit is contained in:
parent
b35a986d25
commit
bb3616ab20
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=325659
@ -408,6 +408,8 @@ struct mlx5e_params {
|
||||
m(+1, u64 tx_completion_fact_max, "tx_completion_fact_max", "Maximum completion event ratio") \
|
||||
m(+1, u64 hw_lro, "hw_lro", "set to enable hw_lro") \
|
||||
m(+1, u64 cqe_zipping, "cqe_zipping", "0 : CQE zipping disabled") \
|
||||
m(+1, u64 modify_tx_dma, "modify_tx_dma", "0: Enable TX 1: Disable TX") \
|
||||
m(+1, u64 modify_rx_dma, "modify_rx_dma", "0: Enable RX 1: Disable RX") \
|
||||
m(+1, u64 diag_pci_enable, "diag_pci_enable", "0: Disabled 1: Enabled") \
|
||||
m(+1, u64 diag_general_enable, "diag_general_enable", "0: Disabled 1: Enabled")
|
||||
|
||||
@ -837,5 +839,8 @@ int mlx5e_enable_sq(struct mlx5e_sq *, struct mlx5e_sq_param *, int tis_num);
|
||||
int mlx5e_modify_sq(struct mlx5e_sq *, int curr_state, int next_state);
|
||||
void mlx5e_disable_sq(struct mlx5e_sq *);
|
||||
void mlx5e_drain_sq(struct mlx5e_sq *);
|
||||
void mlx5e_modify_tx_dma(struct mlx5e_priv *priv, uint8_t value);
|
||||
void mlx5e_modify_rx_dma(struct mlx5e_priv *priv, uint8_t value);
|
||||
void mlx5e_resume_sq(struct mlx5e_sq *sq);
|
||||
|
||||
#endif /* _MLX5_EN_H_ */
|
||||
|
@ -377,6 +377,32 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
|
||||
mlx5e_open_locked(priv->ifp);
|
||||
break;
|
||||
|
||||
case MLX5_PARAM_OFFSET(modify_tx_dma):
|
||||
/* check if network interface is opened */
|
||||
if (was_opened) {
|
||||
priv->params_ethtool.modify_tx_dma =
|
||||
priv->params_ethtool.modify_tx_dma ? 1 : 0;
|
||||
/* modify tx according to value */
|
||||
mlx5e_modify_tx_dma(priv, value != 0);
|
||||
} else {
|
||||
/* if closed force enable tx */
|
||||
priv->params_ethtool.modify_tx_dma = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MLX5_PARAM_OFFSET(modify_rx_dma):
|
||||
/* check if network interface is opened */
|
||||
if (was_opened) {
|
||||
priv->params_ethtool.modify_rx_dma =
|
||||
priv->params_ethtool.modify_rx_dma ? 1 : 0;
|
||||
/* modify rx according to value */
|
||||
mlx5e_modify_rx_dma(priv, value != 0);
|
||||
} else {
|
||||
/* if closed force enable rx */
|
||||
priv->params_ethtool.modify_rx_dma = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MLX5_PARAM_OFFSET(diag_pci_enable):
|
||||
priv->params_ethtool.diag_pci_enable =
|
||||
priv->params_ethtool.diag_pci_enable ? 1 : 0;
|
||||
|
@ -2927,6 +2927,164 @@ sysctl_firmware(SYSCTL_HANDLER_ARGS)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_disable_tx_dma(struct mlx5e_channel *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ch->num_tc; i++)
|
||||
mlx5e_drain_sq(&ch->sq[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_reset_sq_doorbell_record(struct mlx5e_sq *sq)
|
||||
{
|
||||
|
||||
sq->doorbell.d32[0] = cpu_to_be32(MLX5_OPCODE_NOP);
|
||||
sq->doorbell.d32[1] = cpu_to_be32(sq->sqn << 8);
|
||||
mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
|
||||
sq->doorbell.d64 = 0;
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_resume_sq(struct mlx5e_sq *sq)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* check if already enabled */
|
||||
if (sq->stopped == 0)
|
||||
return;
|
||||
|
||||
err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_ERR,
|
||||
MLX5_SQC_STATE_RST);
|
||||
if (err != 0) {
|
||||
if_printf(sq->ifp,
|
||||
"mlx5e_modify_sq() from ERR to RST failed: %d\n", err);
|
||||
}
|
||||
|
||||
sq->cc = 0;
|
||||
sq->pc = 0;
|
||||
|
||||
/* reset doorbell prior to moving from RST to RDY */
|
||||
mlx5e_reset_sq_doorbell_record(sq);
|
||||
|
||||
err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST,
|
||||
MLX5_SQC_STATE_RDY);
|
||||
if (err != 0) {
|
||||
if_printf(sq->ifp,
|
||||
"mlx5e_modify_sq() from RST to RDY failed: %d\n", err);
|
||||
}
|
||||
|
||||
mtx_lock(&sq->lock);
|
||||
sq->cev_next_state = MLX5E_CEV_STATE_INITIAL;
|
||||
sq->stopped = 0;
|
||||
mtx_unlock(&sq->lock);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_enable_tx_dma(struct mlx5e_channel *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ch->num_tc; i++)
|
||||
mlx5e_resume_sq(&ch->sq[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_disable_rx_dma(struct mlx5e_channel *ch)
|
||||
{
|
||||
struct mlx5e_rq *rq = &ch->rq;
|
||||
int err;
|
||||
|
||||
mtx_lock(&rq->mtx);
|
||||
rq->enabled = 0;
|
||||
callout_stop(&rq->watchdog);
|
||||
mtx_unlock(&rq->mtx);
|
||||
|
||||
callout_drain(&rq->watchdog);
|
||||
|
||||
err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR);
|
||||
if (err != 0) {
|
||||
if_printf(rq->ifp,
|
||||
"mlx5e_modify_rq() from RDY to RST failed: %d\n", err);
|
||||
}
|
||||
|
||||
while (!mlx5_wq_ll_is_empty(&rq->wq)) {
|
||||
msleep(1);
|
||||
rq->cq.mcq.comp(&rq->cq.mcq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Transitioning into RST state will allow the FW to track less ERR state queues,
|
||||
* thus reducing the recv queue flushing time
|
||||
*/
|
||||
err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_ERR, MLX5_RQC_STATE_RST);
|
||||
if (err != 0) {
|
||||
if_printf(rq->ifp,
|
||||
"mlx5e_modify_rq() from ERR to RST failed: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_enable_rx_dma(struct mlx5e_channel *ch)
|
||||
{
|
||||
struct mlx5e_rq *rq = &ch->rq;
|
||||
int err;
|
||||
|
||||
rq->wq.wqe_ctr = 0;
|
||||
mlx5_wq_ll_update_db_record(&rq->wq);
|
||||
err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
|
||||
if (err != 0) {
|
||||
if_printf(rq->ifp,
|
||||
"mlx5e_modify_rq() from RST to RDY failed: %d\n", err);
|
||||
}
|
||||
|
||||
rq->enabled = 1;
|
||||
|
||||
rq->cq.mcq.comp(&rq->cq.mcq);
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_modify_tx_dma(struct mlx5e_priv *priv, uint8_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (priv->channel == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < priv->params.num_channels; i++) {
|
||||
|
||||
if (!priv->channel[i])
|
||||
continue;
|
||||
|
||||
if (value)
|
||||
mlx5e_disable_tx_dma(priv->channel[i]);
|
||||
else
|
||||
mlx5e_enable_tx_dma(priv->channel[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_modify_rx_dma(struct mlx5e_priv *priv, uint8_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (priv->channel == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < priv->params.num_channels; i++) {
|
||||
|
||||
if (!priv->channel[i])
|
||||
continue;
|
||||
|
||||
if (value)
|
||||
mlx5e_disable_rx_dma(priv->channel[i]);
|
||||
else
|
||||
mlx5e_enable_rx_dma(priv->channel[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_add_hw_stats(struct mlx5e_priv *priv)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user