summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2017-08-03 13:55:39 +0000
committerhselasky <hselasky@FreeBSD.org>2017-08-03 13:55:39 +0000
commit93bf9844dbdbabe5deeeb7efda1eed8f270b4d11 (patch)
treed84b95577e22e34d00066bf9ac6b48a244ed1796
parenta0055f85ba1455ed54505439ad259b07227f4682 (diff)
downloadFreeBSD-src-93bf9844dbdbabe5deeeb7efda1eed8f270b4d11.zip
FreeBSD-src-93bf9844dbdbabe5deeeb7efda1eed8f270b4d11.tar.gz
MFC r312527:
Add runtime support for modifying the SQ and RQ completion event moderation mode. The presence of this feature is indicated through the firmware capabilities. Sponsored by: Mellanox Technologies
-rw-r--r--sys/dev/mlx5/cq.h6
-rw-r--r--sys/dev/mlx5/mlx5_core/mlx5_cq.c22
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c22
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c41
4 files changed, 85 insertions, 6 deletions
diff --git a/sys/dev/mlx5/cq.h b/sys/dev/mlx5/cq.h
index 85e4846..60819f7 100644
--- a/sys/dev/mlx5/cq.h
+++ b/sys/dev/mlx5/cq.h
@@ -88,6 +88,7 @@ enum {
MLX5_CQ_MODIFY_PERIOD = 1 << 0,
MLX5_CQ_MODIFY_COUNT = 1 << 1,
MLX5_CQ_MODIFY_OVERRUN = 1 << 2,
+ MLX5_CQ_MODIFY_PERIOD_MODE = 1 << 4,
};
enum {
@@ -165,6 +166,11 @@ int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,
struct mlx5_core_cq *cq, u16 cq_period,
u16 cq_max_count);
+int mlx5_core_modify_cq_moderation_mode(struct mlx5_core_dev *dev,
+ struct mlx5_core_cq *cq,
+ u16 cq_period,
+ u16 cq_max_count,
+ u8 cq_mode);
int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_cq.c b/sys/dev/mlx5/mlx5_core/mlx5_cq.c
index bab3f29..5a7b39d 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_cq.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_cq.c
@@ -266,6 +266,28 @@ int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,
return mlx5_core_modify_cq(dev, cq, &in, sizeof(in));
}
+int mlx5_core_modify_cq_moderation_mode(struct mlx5_core_dev *dev,
+ struct mlx5_core_cq *cq,
+ u16 cq_period,
+ u16 cq_max_count,
+ u8 cq_mode)
+{
+ struct mlx5_modify_cq_mbox_in in;
+
+ memset(&in, 0, sizeof(in));
+
+ in.cqn = cpu_to_be32(cq->cqn);
+ in.ctx.cq_period = cpu_to_be16(cq_period);
+ in.ctx.cq_max_count = cpu_to_be16(cq_max_count);
+ in.ctx.cqe_sz_flags = (cq_mode & 2) >> 1;
+ in.ctx.st = (cq_mode & 1) << 7;
+ in.field_select = cpu_to_be32(MLX5_CQ_MODIFY_PERIOD |
+ MLX5_CQ_MODIFY_COUNT |
+ MLX5_CQ_MODIFY_PERIOD_MODE);
+
+ return mlx5_core_modify_cq(dev, cq, &in, sizeof(in));
+}
+
int mlx5_init_cq_table(struct mlx5_core_dev *dev)
{
struct mlx5_cq_table *table = &dev->priv.cq_table;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
index 45500d7..092fdcb 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
@@ -92,6 +92,7 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
{
struct mlx5e_priv *priv = arg1;
uint64_t value;
+ int mode_modify;
int was_opened;
int error;
@@ -114,6 +115,7 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
goto done;
}
was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
+ mode_modify = MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify);
switch (MLX5_PARAM_OFFSET(arg[arg2])) {
case MLX5_PARAM_OFFSET(rx_coalesce_usecs):
@@ -266,7 +268,7 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
case MLX5_PARAM_OFFSET(rx_coalesce_mode):
/* network interface must be down */
- if (was_opened)
+ if (was_opened != 0 && mode_modify == 0)
mlx5e_close_locked(priv->ifp);
/* import RX coalesce mode */
@@ -276,13 +278,17 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
priv->params_ethtool.rx_coalesce_mode;
/* restart network interface, if any */
- if (was_opened)
- mlx5e_open_locked(priv->ifp);
+ if (was_opened != 0) {
+ if (mode_modify == 0)
+ mlx5e_open_locked(priv->ifp);
+ else
+ error = mlx5e_refresh_channel_params(priv);
+ }
break;
case MLX5_PARAM_OFFSET(tx_coalesce_mode):
/* network interface must be down */
- if (was_opened)
+ if (was_opened != 0 && mode_modify == 0)
mlx5e_close_locked(priv->ifp);
/* import TX coalesce mode */
@@ -292,8 +298,12 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
priv->params_ethtool.tx_coalesce_mode;
/* restart network interface, if any */
- if (was_opened)
- mlx5e_open_locked(priv->ifp);
+ if (was_opened != 0) {
+ if (mode_modify == 0)
+ mlx5e_open_locked(priv->ifp);
+ else
+ error = mlx5e_refresh_channel_params(priv);
+ }
break;
case MLX5_PARAM_OFFSET(hw_lro):
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index 090085e..727268b 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -1780,6 +1780,25 @@ mlx5e_close_channels(struct mlx5e_priv *priv)
static int
mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq)
{
+
+ if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) {
+ uint8_t cq_mode;
+
+ switch (priv->params.tx_cq_moderation_mode) {
+ case 0:
+ cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
+ break;
+ default:
+ cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
+ break;
+ }
+
+ return (mlx5_core_modify_cq_moderation_mode(priv->mdev, &sq->cq.mcq,
+ priv->params.tx_cq_moderation_usec,
+ priv->params.tx_cq_moderation_pkts,
+ cq_mode));
+ }
+
return (mlx5_core_modify_cq_moderation(priv->mdev, &sq->cq.mcq,
priv->params.tx_cq_moderation_usec,
priv->params.tx_cq_moderation_pkts));
@@ -1788,6 +1807,28 @@ mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq)
static int
mlx5e_refresh_rq_params(struct mlx5e_priv *priv, struct mlx5e_rq *rq)
{
+
+ if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) {
+ uint8_t cq_mode;
+ int retval;
+
+ switch (priv->params.rx_cq_moderation_mode) {
+ case 0:
+ cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
+ break;
+ default:
+ cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
+ break;
+ }
+
+ retval = mlx5_core_modify_cq_moderation_mode(priv->mdev, &rq->cq.mcq,
+ priv->params.rx_cq_moderation_usec,
+ priv->params.rx_cq_moderation_pkts,
+ cq_mode);
+
+ return (retval);
+ }
+
return (mlx5_core_modify_cq_moderation(priv->mdev, &rq->cq.mcq,
priv->params.rx_cq_moderation_usec,
priv->params.rx_cq_moderation_pkts));
OpenPOWER on IntegriCloud