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 * $FreeBSD$ 26 */ 27 28 #include "en.h" 29 30 void 31 mlx5e_dim_build_cq_param(struct mlx5e_priv *priv, 32 struct mlx5e_cq_param *param) 33 { 34 struct net_dim_cq_moder prof; 35 void *cqc = param->cqc; 36 37 if (priv->params.rx_cq_moderation_mode < 2) 38 return; 39 40 switch (MLX5_GET(cqc, cqc, cq_period_mode)) { 41 case MLX5_CQ_PERIOD_MODE_START_FROM_CQE: 42 prof = net_dim_profile[NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE] 43 [NET_DIM_DEF_PROFILE_CQE]; 44 MLX5_SET(cqc, cqc, cq_period, prof.usec); 45 MLX5_SET(cqc, cqc, cq_max_count, prof.pkts); 46 break; 47 48 case MLX5_CQ_PERIOD_MODE_START_FROM_EQE: 49 prof = net_dim_profile[NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE] 50 [NET_DIM_DEF_PROFILE_EQE]; 51 MLX5_SET(cqc, cqc, cq_period, prof.usec); 52 MLX5_SET(cqc, cqc, cq_max_count, prof.pkts); 53 break; 54 default: 55 break; 56 } 57 } 58 59 void 60 mlx5e_dim_work(struct work_struct *work) 61 { 62 struct net_dim *dim = container_of(work, struct net_dim, work); 63 struct mlx5e_rq *rq = container_of(dim, struct mlx5e_rq, dim); 64 struct mlx5e_channel *c = container_of(rq, struct mlx5e_channel, rq); 65 struct net_dim_cq_moder cur_profile; 66 u8 profile_ix; 67 u8 mode; 68 69 /* copy current auto moderation settings and set new state */ 70 mtx_lock(&rq->mtx); 71 profile_ix = dim->profile_ix; 72 mode = dim->mode; 73 dim->state = NET_DIM_START_MEASURE; 74 mtx_unlock(&rq->mtx); 75 76 /* check for invalid mode */ 77 if (mode == 255) 78 return; 79 80 /* get current profile */ 81 cur_profile = net_dim_profile[mode][profile_ix]; 82 83 /* apply LRO restrictions */ 84 if (c->priv->params.hw_lro_en && 85 cur_profile.pkts > MLX5E_DIM_MAX_RX_CQ_MODERATION_PKTS_WITH_LRO) { 86 cur_profile.pkts = MLX5E_DIM_MAX_RX_CQ_MODERATION_PKTS_WITH_LRO; 87 } 88 89 /* modify CQ */ 90 mlx5_core_modify_cq_moderation(c->priv->mdev, &rq->cq.mcq, 91 cur_profile.usec, cur_profile.pkts); 92 } 93