1 /*- 2 * Copyright (c) 2018 Mellanox Technologies. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "opt_rss.h" 27 #include "opt_ratelimit.h" 28 29 #include <dev/mlx5/mlx5_en/en.h> 30 31 void 32 mlx5e_dim_build_cq_param(struct mlx5e_priv *priv, 33 struct mlx5e_cq_param *param) 34 { 35 struct net_dim_cq_moder prof; 36 void *cqc = param->cqc; 37 38 if (priv->params.rx_cq_moderation_mode < 2) 39 return; 40 41 switch (MLX5_GET(cqc, cqc, cq_period_mode)) { 42 case MLX5_CQ_PERIOD_MODE_START_FROM_CQE: 43 prof = net_dim_profile[NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE] 44 [NET_DIM_DEF_PROFILE_CQE]; 45 MLX5_SET(cqc, cqc, cq_period, prof.usec); 46 MLX5_SET(cqc, cqc, cq_max_count, prof.pkts); 47 break; 48 49 case MLX5_CQ_PERIOD_MODE_START_FROM_EQE: 50 prof = net_dim_profile[NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE] 51 [NET_DIM_DEF_PROFILE_EQE]; 52 MLX5_SET(cqc, cqc, cq_period, prof.usec); 53 MLX5_SET(cqc, cqc, cq_max_count, prof.pkts); 54 break; 55 default: 56 break; 57 } 58 } 59 60 void 61 mlx5e_dim_work(struct work_struct *work) 62 { 63 struct net_dim *dim = container_of(work, struct net_dim, work); 64 struct mlx5e_rq *rq = container_of(dim, struct mlx5e_rq, dim); 65 struct mlx5e_channel *c = container_of(rq, struct mlx5e_channel, rq); 66 struct net_dim_cq_moder cur_profile; 67 u8 profile_ix; 68 u8 mode; 69 70 /* copy current auto moderation settings and set new state */ 71 mtx_lock(&rq->mtx); 72 profile_ix = dim->profile_ix; 73 mode = dim->mode; 74 dim->state = NET_DIM_START_MEASURE; 75 mtx_unlock(&rq->mtx); 76 77 /* check for invalid mode */ 78 if (mode == 255) 79 return; 80 81 /* get current profile */ 82 cur_profile = net_dim_profile[mode][profile_ix]; 83 84 /* apply LRO restrictions */ 85 if (c->priv->params.hw_lro_en && 86 cur_profile.pkts > MLX5E_DIM_MAX_RX_CQ_MODERATION_PKTS_WITH_LRO) { 87 cur_profile.pkts = MLX5E_DIM_MAX_RX_CQ_MODERATION_PKTS_WITH_LRO; 88 } 89 90 /* modify CQ */ 91 mlx5_core_modify_cq_moderation(c->priv->mdev, &rq->cq.mcq, 92 cur_profile.usec, cur_profile.pkts); 93 } 94