svn commit: r331568 - stable/11/sys/dev/mlx5/mlx5_en
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Mar 26 20:04:05 UTC 2018
Author: hselasky
Date: Mon Mar 26 19:59:00 2018
New Revision: 331568
URL: https://svnweb.freebsd.org/changeset/base/331568
Log:
MFC r325659:
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
Modified:
stable/11/sys/dev/mlx5/mlx5_en/en.h
stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/mlx5/mlx5_en/en.h
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_en/en.h Mon Mar 26 19:53:36 2018 (r331567)
+++ stable/11/sys/dev/mlx5/mlx5_en/en.h Mon Mar 26 19:59:00 2018 (r331568)
@@ -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")
@@ -838,5 +840,8 @@ int mlx5e_enable_sq(struct mlx5e_sq *, struct mlx5e_sq
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_ */
Modified: stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c Mon Mar 26 19:53:36 2018 (r331567)
+++ stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c Mon Mar 26 19:59:00 2018 (r331568)
@@ -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;
Modified: stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
==============================================================================
--- stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Mon Mar 26 19:53:36 2018 (r331567)
+++ stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Mon Mar 26 19:59:00 2018 (r331568)
@@ -2928,6 +2928,164 @@ sysctl_firmware(SYSCTL_HANDLER_ARGS)
}
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)
{
SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw),
More information about the svn-src-all
mailing list