From patchwork Tue Aug 13 11:47:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Furong Xu <0x1207@gmail.com> X-Patchwork-Id: 13761880 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 54560C52D7C for ; Tue, 13 Aug 2024 11:51:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=zV/tRwQ1Ly4raeWVajmk3I2C1fdXD3MeAXbuwqZv6o4=; b=qDZ0ZF5GHFexAL8H/TMfNb6ezK e0F63qx8MXf3ofO9mplYwxqukL2vJ83MCcIIE69XOr0SNBR2UNH5AHufCfTFaTb/Zen9LJIiOwkd8 SQJPnm7CfdTS65fk3Wy9Nn6s8Lbgom1BayUosEY5/asAOdqW/8HdjOQyOWaY09G8WSLu8Hz+bQq2o +4B30kv7yHKeNfNmGBgzO626uglqfkXiJx208sHgN8h/xFjRhWJfHO+A1g1XXzZZjGn7SSw3++0G2 PFdQIn7YqpLwmdB9K6bHNOM2x+GKkZZ+HfJWtoEd7QWNoTwuVfvRaWZxnZdYGd1ljpjx8ehUHORUO 65cbQSqQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdq43-00000003a2f-28Dc; Tue, 13 Aug 2024 11:51:47 +0000 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdq1J-00000003Z9a-2M19 for linux-arm-kernel@lists.infradead.org; Tue, 13 Aug 2024 11:48:58 +0000 Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-70d199fb3dfso4271874b3a.3 for ; Tue, 13 Aug 2024 04:48:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723549737; x=1724154537; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zV/tRwQ1Ly4raeWVajmk3I2C1fdXD3MeAXbuwqZv6o4=; b=BJXXQhDb0xWpotjT8cM1BmzSWVLRlxlY218i8VBlJXE4fUDS5wSc3jLT9A3fFx5Wvq LKNrMdRDean5oaBcf5mT6VmnMCi15ec7F6rSWKr0eJqfe7J9UIixezLaJDe6qxJ7UpqZ TcQ4tzY//ucAuX4l9OWZqmgHSrHuMKT/qb9XvXQfU/UoB1YGGbn+2WiTmkje6zqShy8W JSYklDJfclNWR31xI8E/5vyad/XPa28BepUM1M2ym2UjAHAOZvzeQPUnrQnxz1jjsmS0 ureqvPNXN2BaiW8PZ6q/G2JEXWh1+9hkn5qmYibTBK2/rRqhP+CmWVfzVSjIn4VVRP95 M3tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723549737; x=1724154537; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zV/tRwQ1Ly4raeWVajmk3I2C1fdXD3MeAXbuwqZv6o4=; b=gD4flLdP4W/hZXKuaTcjGL2RcY2hgtYnAjSVJyGuBPVlwQkeiRHasF6VZ6AKXfBfSb 2+qraOv4VmzS/3b0z5P2DRy0HTp8JhE88AKUb+4ixG4/joIHM6ajiOKdzNPWgkSHxlZf vTDJsr3epfv8GsV9GMKHrl90mkXfY1jo/G/snv84QVZcXJjKmGADiRahSoVTTcfZHKJz Wlr9upDfbUv/2k4A5VpG/NWGrjYeuHrBhFuNsdVFDwtHyPRYBh+rlG/FZo9f7dqYUjdG f+O95blTK2ua0EUIR4vrVy9c+oENelvTs4Bj1R+TcQLor2+vAwpMmEOH1Sp5uF0gflc9 XAFA== X-Forwarded-Encrypted: i=1; AJvYcCXrw5C3ZrWGWfx7oVFQRHK/+0b6tcVI08Y/2MXdrzdoq2CfRmedEAGuUxZiMpc+2lv8IyflwXv7FZcQ98CEZmnCdS6WlLgw8Hmnkf3ojfPo5pk4IyI= X-Gm-Message-State: AOJu0Yywn0OpiDl3lioUlVyI2gJoo08wTOaRvGYG0L6iWRtdGg+aaFWM MP9qsdE7vu7FF5R/YyaR5Wc+jFdWS/eKFPwwsfgqJqoKGPd10rt8 X-Google-Smtp-Source: AGHT+IGWrbzEcKcDOaqU2Kyo11bD8F1Q7p4Prha1symKz71nP9OZ7loi3Dv6aqOfc5uRRSedSAyuAg== X-Received: by 2002:aa7:88c7:0:b0:705:be21:f2be with SMTP id d2e1a72fcca58-712551adbfemr3634216b3a.18.1723549736681; Tue, 13 Aug 2024 04:48:56 -0700 (PDT) Received: from localhost.localdomain ([129.146.253.192]) by smtp.googlemail.com with ESMTPSA id d2e1a72fcca58-710e5a562bbsm5548755b3a.111.2024.08.13.04.48.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2024 04:48:56 -0700 (PDT) From: Furong Xu <0x1207@gmail.com> To: Serge Semin , Andrew Lunn , Vladimir Oltean , "David S. Miller" , Alexandre Torgue , Jose Abreu , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Maxime Coquelin , Joao Pinto Cc: netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, xfr@outlook.com, rock.xu@nio.com, Furong Xu <0x1207@gmail.com> Subject: [PATCH net-next v2 5/7] net: stmmac: support fp parameter of tc-mqprio Date: Tue, 13 Aug 2024 19:47:31 +0800 Message-Id: <5ebb80730efe965045cb897e6e8e5d07c13ab816.1723548320.git.0x1207@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240813_044857_636465_B1181E03 X-CRM114-Status: GOOD ( 22.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org tc-mqprio can select whether traffic classes are express or preemptible. After some traffic tests, MAC merge layer statistics are all good. Local device: ethtool --include-statistics --json --show-mm eth1 [ { "ifname": "eth1", "pmac-enabled": true, "tx-enabled": true, "tx-active": true, "tx-min-frag-size": 60, "rx-min-frag-size": 60, "verify-enabled": true, "verify-time": 100, "max-verify-time": 128, "verify-status": "SUCCEEDED", "statistics": { "MACMergeFrameAssErrorCount": 0, "MACMergeFrameSmdErrorCount": 0, "MACMergeFrameAssOkCount": 0, "MACMergeFragCountRx": 0, "MACMergeFragCountTx": 35105, "MACMergeHoldCount": 0 } } ] Remote device: ethtool --include-statistics --json --show-mm end1 [ { "ifname": "end1", "pmac-enabled": true, "tx-enabled": true, "tx-active": true, "tx-min-frag-size": 60, "rx-min-frag-size": 60, "verify-enabled": true, "verify-time": 100, "max-verify-time": 128, "verify-status": "SUCCEEDED", "statistics": { "MACMergeFrameAssErrorCount": 0, "MACMergeFrameSmdErrorCount": 0, "MACMergeFrameAssOkCount": 35105, "MACMergeFragCountRx": 35105, "MACMergeFragCountTx": 0, "MACMergeHoldCount": 0 } } ] Tested on DWMAC CORE 5.10a Signed-off-by: Furong Xu <0x1207@gmail.com> --- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 2 + drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 52 +++++++++++++ drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 4 + drivers/net/ethernet/stmicro/stmmac/hwif.h | 10 +++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 + .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 74 +++++++++++++++++++ 6 files changed, 144 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 679efcc631f1..4722bac7e3d4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -1266,6 +1266,7 @@ const struct stmmac_ops dwmac410_ops = { .fpe_irq_status = dwmac5_fpe_irq_status, .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, + .fpe_set_preemptible_tcs = dwmac5_fpe_set_preemptible_tcs, .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, .restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr, @@ -1320,6 +1321,7 @@ const struct stmmac_ops dwmac510_ops = { .fpe_irq_status = dwmac5_fpe_irq_status, .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, + .fpe_set_preemptible_tcs = dwmac5_fpe_set_preemptible_tcs, .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, .restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c index 4c91fa766b13..b6114de34b31 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c @@ -670,3 +670,55 @@ void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) writel(value, ioaddr + MTL_FPE_CTRL_STS); } + +int dwmac5_fpe_set_preemptible_tcs(struct net_device *ndev, + struct netlink_ext_ack *extack, + unsigned long tcs) +{ + struct stmmac_priv *priv = netdev_priv(ndev); + void __iomem *ioaddr = priv->ioaddr; + unsigned long queue_tcs = 0; + int num_tc = ndev->num_tc; + u32 value, queue_weight; + u16 offset, count; + int tc, i; + + if (!tcs) + goto __update_queue_tcs; + + for (tc = 0; tc < num_tc; tc++) { + count = ndev->tc_to_txq[tc].count; + offset = ndev->tc_to_txq[tc].offset; + + if (tcs & BIT(tc)) + queue_tcs |= GENMASK(offset + count - 1, offset); + + /* This is 1:1 mapping, go to next TC */ + if (count == 1) + continue; + + if (priv->plat->tx_sched_algorithm == MTL_TX_ALGORITHM_SP) { + NL_SET_ERR_MSG_FMT_MOD(extack, "TX algorithm SP is not suitable for one TC to multiple TXQs mapping"); + return -EINVAL; + } + + queue_weight = priv->plat->tx_queues_cfg[offset].weight; + for (i = 1; i < count; i++) { + if (queue_weight != priv->plat->tx_queues_cfg[offset + i].weight) { + NL_SET_ERR_MSG_FMT_MOD(extack, "TXQ weight [%u] differs across other TXQs in TC: [%u]", + queue_weight, tc); + return -EINVAL; + } + } + } + +__update_queue_tcs: + value = readl(ioaddr + MTL_FPE_CTRL_STS); + + value &= ~PEC; + value |= FIELD_PREP(PEC, queue_tcs); + + writel(value, ioaddr + MTL_FPE_CTRL_STS); + + return 0; +} diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h index e369e65920fc..d3191c48354d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h @@ -40,6 +40,7 @@ #define MAC_PPSx_WIDTH(x) (0x00000b8c + ((x) * 0x10)) #define MTL_FPE_CTRL_STS 0x00000c90 +#define PEC GENMASK(15, 8) #define AFSZ GENMASK(1, 0) #define MTL_RXP_CONTROL_STATUS 0x00000ca0 @@ -114,5 +115,8 @@ void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev); int dwmac5_fpe_get_add_frag_size(void __iomem *ioaddr); void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size); +int dwmac5_fpe_set_preemptible_tcs(struct net_device *ndev, + struct netlink_ext_ack *extack, + unsigned long tcs); #endif /* __DWMAC5_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index 31767427386b..a02b0f7ed96b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -7,6 +7,7 @@ #include #include +#include #define stmmac_do_void_callback(__priv, __module, __cname, __arg0, __args...) \ ({ \ @@ -428,6 +429,9 @@ struct stmmac_ops { int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev); int (*fpe_get_add_frag_size)(void __iomem *ioaddr); void (*fpe_set_add_frag_size)(void __iomem *ioaddr, u32 add_frag_size); + int (*fpe_set_preemptible_tcs)(struct net_device *ndev, + struct netlink_ext_ack *extack, + unsigned long tcs); }; #define stmmac_core_init(__priv, __args...) \ @@ -536,6 +540,8 @@ struct stmmac_ops { stmmac_do_callback(__priv, mac, fpe_get_add_frag_size, __args) #define stmmac_fpe_set_add_frag_size(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args) +#define stmmac_fpe_set_preemptible_tcs(__priv, __args...) \ + stmmac_do_callback(__priv, mac, fpe_set_preemptible_tcs, __args) /* PTP and HW Timer helpers */ struct stmmac_hwtimestamp { @@ -623,6 +629,8 @@ struct stmmac_tc_ops { struct tc_etf_qopt_offload *qopt); int (*query_caps)(struct stmmac_priv *priv, struct tc_query_caps_base *base); + int (*setup_mqprio)(struct stmmac_priv *priv, + struct tc_mqprio_qopt_offload *qopt); }; #define stmmac_tc_init(__priv, __args...) \ @@ -639,6 +647,8 @@ struct stmmac_tc_ops { stmmac_do_callback(__priv, tc, setup_etf, __args) #define stmmac_tc_query_caps(__priv, __args...) \ stmmac_do_callback(__priv, tc, query_caps, __args) +#define stmmac_tc_setup_mqprio(__priv, __args...) \ + stmmac_do_callback(__priv, tc, setup_mqprio, __args) struct stmmac_counters; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index cc91811eedf0..15c07ee944b4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -6265,6 +6265,8 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type, switch (type) { case TC_QUERY_CAPS: return stmmac_tc_query_caps(priv, priv, type_data); + case TC_SETUP_QDISC_MQPRIO: + return stmmac_tc_setup_mqprio(priv, priv, type_data); case TC_SETUP_BLOCK: return flow_block_cb_setup_simple(type_data, &stmmac_block_cb_list, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index a58282d6458c..a967c6f01e4e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -1174,6 +1174,13 @@ static int tc_query_caps(struct stmmac_priv *priv, struct tc_query_caps_base *base) { switch (base->type) { + case TC_SETUP_QDISC_MQPRIO: { + struct tc_mqprio_caps *caps = base->caps; + + caps->validate_queue_counts = true; + + return 0; + } case TC_SETUP_QDISC_TAPRIO: { struct tc_taprio_caps *caps = base->caps; @@ -1190,6 +1197,72 @@ static int tc_query_caps(struct stmmac_priv *priv, } } +static void stmmac_reset_tc_mqprio(struct net_device *ndev, + struct netlink_ext_ack *extack) +{ + struct stmmac_priv *priv = netdev_priv(ndev); + + netdev_reset_tc(ndev); + netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use); + + stmmac_fpe_set_preemptible_tcs(priv, ndev, extack, 0); +} + +static int tc_setup_mqprio(struct stmmac_priv *priv, + struct tc_mqprio_qopt_offload *mqprio) +{ + struct tc_mqprio_qopt *qopt = &mqprio->qopt; + struct net_device *ndev = priv->dev; + int num_stack_tx_queues = 0; + int num_tc = qopt->num_tc; + u16 offset, count; + int tc, err; + + if (!num_tc) { + stmmac_reset_tc_mqprio(ndev, mqprio->extack); + return 0; + } + + err = netdev_set_num_tc(ndev, num_tc); + if (err) + return err; + + /* DWMAC CORE4+ can not programming TC:TXQ mapping to hardware. + * Synopsys Databook: + * "The number of Tx DMA channels is equal to the number of Tx queues, + * and is direct one-to-one mapping." + * + * Luckily, DWXGMAC CORE can. + * + * Thus preemptible_tcs should be handled in a per core manner. + */ + for (tc = 0; tc < num_tc; tc++) { + offset = qopt->offset[tc]; + count = qopt->count[tc]; + num_stack_tx_queues += count; + + err = netdev_set_tc_queue(ndev, tc, count, offset); + if (err) + goto err_reset_tc; + } + + err = netif_set_real_num_tx_queues(ndev, num_stack_tx_queues); + if (err) + goto err_reset_tc; + + err = stmmac_fpe_set_preemptible_tcs(priv, ndev, mqprio->extack, + mqprio->preemptible_tcs); + if (err) + goto err_reset_tc; + + return 0; + +err_reset_tc: + stmmac_reset_tc_mqprio(ndev, mqprio->extack); + + return err; +} + const struct stmmac_tc_ops dwmac510_tc_ops = { .init = tc_init, .setup_cls_u32 = tc_setup_cls_u32, @@ -1198,4 +1271,5 @@ const struct stmmac_tc_ops dwmac510_tc_ops = { .setup_taprio = tc_setup_taprio, .setup_etf = tc_setup_etf, .query_caps = tc_query_caps, + .setup_mqprio = tc_setup_mqprio, };