Author: hselasky
Date: Fri Nov 10 14:10:41 2017
New Revision: 325659
URL: https://svnweb.freebsd.org/changeset/base/325659

Log:
  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

Modified:
  head/sys/dev/mlx5/mlx5_en/en.h
  head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
  head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c

Modified: head/sys/dev/mlx5/mlx5_en/en.h
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/en.h      Fri Nov 10 14:02:12 2017        
(r325658)
+++ head/sys/dev/mlx5/mlx5_en/en.h      Fri Nov 10 14:10:41 2017        
(r325659)
@@ -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
 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: head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c Fri Nov 10 14:02:12 2017        
(r325658)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c Fri Nov 10 14:10:41 2017        
(r325659)
@@ -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: head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c    Fri Nov 10 14:02:12 2017        
(r325658)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c    Fri Nov 10 14:10:41 2017        
(r325659)
@@ -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),
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to