From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io1-xd2c.google.com (mail-io1-xd2c.google.com [IPv6:2607:f8b0:4864:20::d2c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.bufferbloat.net (Postfix) with ESMTPS id B526F3B29D for ; Fri, 26 Nov 2021 15:59:43 -0500 (EST) Received: by mail-io1-xd2c.google.com with SMTP id m9so13028887iop.0 for ; Fri, 26 Nov 2021 12:59:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :content-transfer-encoding; bh=gznqG9m8VVg/5gE0bCT+9FXHlRuR/t79hDYvo6xE6Eo=; b=WnAn7XxQ9J3Zng3tZjLwiqMYtA7n+Rn486wG2RRSwfw6Z08ITRFYmpdKfPQAaHa1+U wbbmErNKVwZgoaSBnUSe3A9Rj3isy64/qzEN6ueTflB0EWl/g8Bj4Dnevcmk3I2vkPQi iTgxCUofkMAd0eGC3C50k9ubCC+0EZ82BAs04SYArq0w6orzdJuZDZu1VUo4t2fQoHmX CZvnqONEXtHxm6pnWTCFdgcWjFhmoQW8DPyqlQBNbsb/GfL2hdAy4G+r9FaQfF1EDsW1 6BYu7w0KYM1omXgJ3bq1jAOlOkJc5hY9lOo4HS1RdSSC9kAUqVtqCnUxNobi4g7Bhdqy rYCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:content-transfer-encoding; bh=gznqG9m8VVg/5gE0bCT+9FXHlRuR/t79hDYvo6xE6Eo=; b=bYWWA2wRkQYdgKZVttYTdjmKG1WoaMMz11Nu/fVutEfnuc3b+vGgVR7UrNwC6M7cCg 1mzXieYybDQh4XLvmUP9ZRfEZFtL15z16QIMiKcYrWmofphj3cQ2cQrWqSnRoP2AMaiO mDHXTVKfew5Hhr9GO763gzdn8YShUbQXlKqCF96EWZajTK+a5dmhUmdRjMaB4w5aEHPw nD6Q45NiW2lMeBE2puK8OG+Lp51E5PUyu3DU9tyB/Gclu7CyFT5Z5QBw4o/UHkOSJPwv FkA52YvkQOCoQI9aFyQcBXVE8fV6OqmAhkc4/4bPW2ZmDtgebBRcK0Yq68gEZthfEBMo ACjg== X-Gm-Message-State: AOAM531P49oMgLhUIZX0ABEGRped3IxYNt+MAv1rl2f8fHQDEWsF3q6P 9cD8CBd3jjI4MOsx8q+Lcers9MmFc66upw+DqsbzogVL X-Google-Smtp-Source: ABdhPJxytnCnD4SpPhrZofKMFIzFP7JIaikjCKj41m5H5GonCu3FfNRh0UCibPxt4JD86QCkhqiuhOH1HCf1VWL4ykc= X-Received: by 2002:a02:a314:: with SMTP id q20mr44906659jai.104.1637960382781; Fri, 26 Nov 2021 12:59:42 -0800 (PST) MIME-Version: 1.0 References: <20211125154813.579169-1-maxime.chevallier@bootlin.com> <20211125154813.579169-5-maxime.chevallier@bootlin.com> In-Reply-To: <20211125154813.579169-5-maxime.chevallier@bootlin.com> From: Dave Taht Date: Fri, 26 Nov 2021 12:59:30 -0800 Message-ID: To: cerowrt-devel Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: [Cerowrt-devel] Fwd: [PATCH net-next 4/4] net: mvneta: Add TC traffic shaping offload X-BeenThere: cerowrt-devel@lists.bufferbloat.net X-Mailman-Version: 2.1.20 Precedence: list List-Id: Development issues regarding the cerowrt test router project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Nov 2021 20:59:43 -0000 ---------- Forwarded message --------- From: Maxime Chevallier Date: Fri, Nov 26, 2021 at 12:42 PM Subject: [PATCH net-next 4/4] net: mvneta: Add TC traffic shaping offload To: Cc: Maxime Chevallier , , , , , Andrew Lunn , Pali Roh=C3=A1r The mvneta controller is able to do some tocken-bucket per-queue traffic shaping. This commit adds support for setting these using the TC mqprio interface. The token-bucket parameters are customisable, but the current implementation configures them to have a 10kbps resolution for the rate limitation, since it allows to cover the whole range of max_rate values from 10kbps to 5Gbps with 10kbps increments. Signed-off-by: Maxime Chevallier --- drivers/net/ethernet/marvell/mvneta.c | 121 +++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index aba452e8abfe..ca7b3c5cfe0a 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -248,12 +248,39 @@ #define MVNETA_TXQ_SENT_DESC_MASK 0x3fff0000 #define MVNETA_PORT_TX_RESET 0x3cf0 #define MVNETA_PORT_TX_DMA_RESET BIT(0) +#define MVNETA_TXQ_CMD1_REG 0x3e00 +#define MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 BIT(3) +#define MVNETA_TXQ_CMD1_BW_LIM_EN BIT(0) +#define MVNETA_REFILL_NUM_CLK_REG 0x3e08 +#define MVNETA_REFILL_MAX_NUM_CLK 0x0000ffff #define MVNETA_TX_MTU 0x3e0c #define MVNETA_TX_TOKEN_SIZE 0x3e14 #define MVNETA_TX_TOKEN_SIZE_MAX 0xffffffff +#define MVNETA_TXQ_BUCKET_REFILL_REG(q) (0x3e20 + ((q) << = 2)) +#define MVNETA_TXQ_BUCKET_REFILL_PERIOD_MASK 0x3ff00000 +#define MVNETA_TXQ_BUCKET_REFILL_PERIOD_SHIFT 20 +#define MVNETA_TXQ_BUCKET_REFILL_VALUE_MAX 0x0007ffff #define MVNETA_TXQ_TOKEN_SIZE_REG(q) (0x3e40 + ((q) << 2)) #define MVNETA_TXQ_TOKEN_SIZE_MAX 0x7fffffff +/* The values of the bucket refill base period and refill period are taken= from + * the reference manual, and adds up to a base resolution of 10Kbps. This allows + * to cover all rate-limit values from 10Kbps up to 5Gbps + */ + +/* Base period for the rate limit algorithm */ +#define MVNETA_TXQ_BUCKET_REFILL_BASE_PERIOD_NS 100 + +/* Number of Base Period to wait between each bucket refill */ +#define MVNETA_TXQ_BUCKET_REFILL_PERIOD 1000 + +/* The base resolution for rate limiting, in bps. Any max_rate value shoul= d be + * a multiple of that value. + */ +#define MVNETA_TXQ_RATE_LIMIT_RESOLUTION (NSEC_PER_SEC / \ + (MVNETA_TXQ_BUCKET_REFILL_BASE_PERIOD_NS * \ + MVNETA_TXQ_BUCKET_REFILL_PERIOD)) + #define MVNETA_LPI_CTRL_0 0x2cc0 #define MVNETA_LPI_CTRL_1 0x2cc4 #define MVNETA_LPI_REQUEST_ENABLE BIT(0) @@ -4906,11 +4933,75 @@ static void mvneta_map_vlan_prio_to_rxq(struct mvneta_port *pp, u8 pri, u8 rxq) mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val); } +static int mvneta_enable_per_queue_rate_limit(struct mvneta_port *pp) +{ + unsigned long core_clk_rate; + u32 refill_cycles; + u32 val; + + core_clk_rate =3D clk_get_rate(pp->clk); + if (!core_clk_rate) + return -EINVAL; + + refill_cycles =3D MVNETA_TXQ_BUCKET_REFILL_BASE_PERIOD_NS / + (NSEC_PER_SEC / core_clk_rate); + + if (refill_cycles > MVNETA_REFILL_MAX_NUM_CLK) + return -EINVAL; + + /* Enable bw limit algorithm version 3 */ + val =3D mvreg_read(pp, MVNETA_TXQ_CMD1_REG); + val &=3D ~(MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 | MVNETA_TXQ_CMD1_BW_LIM_E= N); + mvreg_write(pp, MVNETA_TXQ_CMD1_REG, val); + + /* Set the base refill rate */ + mvreg_write(pp, MVNETA_REFILL_NUM_CLK_REG, refill_cycles); + + return 0; +} + +static void mvneta_disable_per_queue_rate_limit(struct mvneta_port *pp) +{ + u32 val =3D mvreg_read(pp, MVNETA_TXQ_CMD1_REG); + + val |=3D (MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 | MVNETA_TXQ_CMD1_BW_LIM_EN= ); + mvreg_write(pp, MVNETA_TXQ_CMD1_REG, val); +} + +static int mvneta_setup_queue_rates(struct mvneta_port *pp, int queue, + u64 min_rate, u64 max_rate) +{ + u32 refill_val; + u32 val =3D 0; + + /* Convert to from Bps to bps */ + max_rate *=3D 8; + + if (min_rate) + return -EINVAL; + + if (max_rate % MVNETA_TXQ_RATE_LIMIT_RESOLUTION) + return -EINVAL; + + refill_val =3D max_rate / MVNETA_TXQ_RATE_LIMIT_RESOLUTION; + + if (refill_val =3D=3D 0 || refill_val > MVNETA_TXQ_BUCKET_REFILL_VA= LUE_MAX) + return -EINVAL; + + val =3D refill_val; + val |=3D (MVNETA_TXQ_BUCKET_REFILL_PERIOD << + MVNETA_TXQ_BUCKET_REFILL_PERIOD_SHIFT); + + mvreg_write(pp, MVNETA_TXQ_BUCKET_REFILL_REG(queue), val); + + return 0; +} + static int mvneta_setup_mqprio(struct net_device *dev, struct tc_mqprio_qopt_offload *mqprio) { struct mvneta_port *pp =3D netdev_priv(dev); - int rxq, tc; + int rxq, txq, tc, ret; u8 num_tc; if (mqprio->qopt.hw !=3D TC_MQPRIO_HW_OFFLOAD_TCS) @@ -4924,6 +5015,7 @@ static int mvneta_setup_mqprio(struct net_device *dev= , mvneta_clear_rx_prio_map(pp); if (!num_tc) { + mvneta_disable_per_queue_rate_limit(pp); netdev_reset_tc(dev); return 0; } @@ -4944,6 +5036,33 @@ static int mvneta_setup_mqprio(struct net_device *de= v, } } + if (mqprio->shaper !=3D TC_MQPRIO_SHAPER_BW_RATE) { + mvneta_disable_per_queue_rate_limit(pp); + return 0; + } + + if (mqprio->qopt.num_tc > txq_number) + return -EINVAL; + + ret =3D mvneta_enable_per_queue_rate_limit(pp); + if (ret) + return ret; + + for (tc =3D 0; tc < mqprio->qopt.num_tc; tc++) { + for (txq =3D mqprio->qopt.offset[tc]; + txq < mqprio->qopt.count[tc] + mqprio->qopt.offset[tc]= ; + txq++) { + if (txq >=3D txq_number) + return -EINVAL; + + ret =3D mvneta_setup_queue_rates(pp, txq, + mqprio->min_rate[tc]= , + mqprio->max_rate[tc]= ); + if (ret) + return ret; + } + } + return 0; } -- 2.25.4 --=20 I tried to build a better future, a few times: https://wayforward.archive.org/?site=3Dhttps%3A%2F%2Fwww.icei.org Dave T=C3=A4ht CEO, TekLibre, LLC