From patchwork Fri Apr 16 23:42:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12209313 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA800C433B4 for ; Fri, 16 Apr 2021 23:45:59 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 49745610FA for ; Fri, 16 Apr 2021 23:45:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 49745610FA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=zGED2BaueoFncdAaAAZ+19XjTytuDehyEEyY6IuLLls=; b=e8RnPDB5kIJ2fADuB2Oz4FHu2 dPIzIv3MfWGlcj0zIMIaT34oBnL7DCk1RjRUVlOJeDmEp3dJW9FQeSoTDz5AeIJYunYUtwolQqjwF cg585nGoEcRJQ1lDQGW3PE8ledvgweWZO1zPgz15TR/ZGvZVeRVsKDjC8LIlsGeRa/F+7WfKFySST HMb1j509PqDZJ8vpAPLuJI4HzmI2wb8CfSOo/a5rg66SqMmi9DiQ9KLUiVhpr4mtSvDHz2RrbqJDu GRbM0plTqvOqtEtb4kua0wo9SpwnQjbGJH1OEb6R2F37JUFQAtNmMZ4+eet4ZcCSDD4IVNhnL1RV7 aSP42E4nQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lXY8Q-003kB7-TA; Fri, 16 Apr 2021 23:44:27 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lXY7q-003k37-Nb for linux-arm-kernel@desiato.infradead.org; Fri, 16 Apr 2021 23:43:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=brzMZZzoip4/bMvEqdJjD4C2HN3Ucvxi1tHmkqgDBtE=; b=qn4CYqfgOwMG2GBrFvVk1GsM4V MPY539TbRfidk4T0/KUsRDYKfKcmdTid7Zj5W0mkkiZYTnHV+ixGE/oGoiuOLzfa33wi4Iy1NqAxu i2LW3d3KzFWwGkmsdkX46ZDQDC7cWEg4P3v7/gouzDQ5OPX/ff70xVuRvQb1rfnot+ue4eKiIVQ4N 4+l/IBpn1cvRJ9rvKxLhkiphuKIQYtyDd1877i53MwQNPkgGnkhO6kxy4yYftCU9cv4WjdGGu35+F tz8OIW1MfUkwm1Gpy/XZHHJT9rQDH8trnDxjnGRQkbhpl9EvmV7HkPFDZ/hHY5HDUgzoydqQpXeGj inEDG7rw==; Received: from mail-pf1-x42b.google.com ([2607:f8b0:4864:20::42b]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lXY7n-009mhg-TL for linux-arm-kernel@lists.infradead.org; Fri, 16 Apr 2021 23:43:49 +0000 Received: by mail-pf1-x42b.google.com with SMTP id 10so10460101pfl.1 for ; Fri, 16 Apr 2021 16:43:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=brzMZZzoip4/bMvEqdJjD4C2HN3Ucvxi1tHmkqgDBtE=; b=ccAjGC2R6HUdgHBzrom/EeJihy1BNRqdz9SA9KxuZ5anDN/SlJYBQvinmz09gGXdef zh+h4Ow0G5EHavLy0/u/DtajwBaQ4NVMQfwKg3U9O66g5YWykh2D7nP6/iD8ueZejvdY y9gvrsiwPc8UwcGibC5c0lYUXsjk6SKY/U61MHnKsc2QubEUnhF9BHxzx5hSiSH3iU90 ysYBSbCQu1Wsjob5SUgt6Q4GWAU+1ABgtexWpj9VC6YQdZBwJYc4pD6yZV4OCFPaAuMk 6OMAANBfFeVgNqrcuDs5MnVCI/RPaXQ+p4woZ2kTB7sdkPUlu7W5H2mY8XkMoYNajE+N jfpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=brzMZZzoip4/bMvEqdJjD4C2HN3Ucvxi1tHmkqgDBtE=; b=KC8VB7HuK6Tx9JBTTJ7KXSMpdq2pWHt5dDbA7X7KSPr6U4mgFh48Z0684/mv6qEZbo ETkMNSNAoDwvCV57e9zPITNAdVRXQ9glIc7ca1v+DTQiVsCnAWG3lxrCbdtCa/KES6cQ TS7abTyOFVhGZ00yWm7BwCVFSQa1EOxw5Fd5lXBb11+cKvOUhpghDYc7rHF5IQeRVi1R VQByGqF1z7CLkcpdvogYWJw7plNSj6pa0s1mWpudL1yTJBcV9AYqvuuXrEWgJBpB7ccu ++whEAMBhmXL6dyB241+IvmBQrydZFFr7dN4SKfvXMeVis8i4XiEUIv19vs6y3h9wLjl LMAw== X-Gm-Message-State: AOAM532I5wmgD6SvJFAFmiDWrblF1smrP6cfZPmdt8ZCfQKzVTIOxKtx YceYWZIaDtC/FspDsMq7sao= X-Google-Smtp-Source: ABdhPJwgTbe31odmYDdi1im3pBLV+1h9zpU/idH+cPrmho42I3xlzWB5f0AX/GYbxhxtMxqwR0YghQ== X-Received: by 2002:a63:220d:: with SMTP id i13mr1293107pgi.446.1618616627166; Fri, 16 Apr 2021 16:43:47 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id a185sm5623947pfd.70.2021.04.16.16.43.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Apr 2021 16:43:46 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org, Po Liu Cc: Claudiu Manoil , Alex Marginean , Rob Herring , Shawn Guo , linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, Russell King - ARM Linux admin , Andrew Lunn , Michael Walle , Vladimir Oltean Subject: [PATCH net-next 5/5] net: enetc: add support for flow control Date: Sat, 17 Apr 2021 02:42:25 +0300 Message-Id: <20210416234225.3715819-6-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210416234225.3715819-1-olteanv@gmail.com> References: <20210416234225.3715819-1-olteanv@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210416_164347_976813_9F77F83C X-CRM114-Status: GOOD ( 24.61 ) 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 From: Vladimir Oltean In the ENETC receive path, a frame received by the MAC is first stored in a 256KB 'FIFO' memory, then transferred to DRAM when enqueuing it to the RX ring. The FIFO is a shared resource for all ENETC ports, but every port keeps track of its own memory utilization, on RX and on TX. There is a setting for RX rings through which they can either operate in 'lossy' mode (where the lack of a free buffer causes an immediate discard of the frame) or in 'lossless' mode (where the lack of a free buffer in the ring makes the frame stay longer in the FIFO). In turn, when the memory utilization of the FIFO exceeds a certain margin, the MAC can be configured to emit PAUSE frames. There is enough FIFO memory to buffer up to 3 MTU-sized frames per RX port while not jeopardizing the other use cases (jumbo frames), and also not consume bytes from the port TX allocations. Also, 3 MTU-sized frames worth of memory is enough to ensure zero loss for 64 byte packets at 1G line rate. Signed-off-by: Vladimir Oltean Reviewed-by: Claudiu Manoil --- .../ethernet/freescale/enetc/enetc_ethtool.c | 18 ++++++ .../net/ethernet/freescale/enetc/enetc_hw.h | 9 +++ .../net/ethernet/freescale/enetc/enetc_pf.c | 60 ++++++++++++++++++- 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c index 49835e878bbb..ebccaf02411c 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c @@ -708,6 +708,22 @@ static int enetc_set_wol(struct net_device *dev, return ret; } +static void enetc_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct enetc_ndev_priv *priv = netdev_priv(dev); + + phylink_ethtool_get_pauseparam(priv->phylink, pause); +} + +static int enetc_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct enetc_ndev_priv *priv = netdev_priv(dev); + + return phylink_ethtool_set_pauseparam(priv->phylink, pause); +} + static int enetc_get_link_ksettings(struct net_device *dev, struct ethtool_link_ksettings *cmd) { @@ -754,6 +770,8 @@ static const struct ethtool_ops enetc_pf_ethtool_ops = { .get_ts_info = enetc_get_ts_info, .get_wol = enetc_get_wol, .set_wol = enetc_set_wol, + .get_pauseparam = enetc_get_pauseparam, + .set_pauseparam = enetc_set_pauseparam, }; static const struct ethtool_ops enetc_vf_ethtool_ops = { diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h index 04ac7fc23ead..0f5f081a5baf 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -109,6 +109,7 @@ enum enetc_bdr_type {TX, RX}; /* RX BDR reg offsets */ #define ENETC_RBMR 0 #define ENETC_RBMR_BDS BIT(2) +#define ENETC_RBMR_CM BIT(4) #define ENETC_RBMR_VTE BIT(5) #define ENETC_RBMR_EN BIT(31) #define ENETC_RBSR 0x4 @@ -180,6 +181,8 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PSIVLANR(n) (0x0240 + (n) * 4) /* n = SI index */ #define ENETC_PSIVLAN_EN BIT(31) #define ENETC_PSIVLAN_SET_QOS(val) ((u32)(val) << 12) +#define ENETC_PPAUONTR 0x0410 +#define ENETC_PPAUOFFTR 0x0414 #define ENETC_PTXMBAR 0x0608 #define ENETC_PCAPR0 0x0900 #define ENETC_PCAPR0_RXBDR(val) ((val) >> 24) @@ -227,6 +230,7 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PM0_TX_EN BIT(0) #define ENETC_PM0_RX_EN BIT(1) #define ENETC_PM0_PROMISC BIT(4) +#define ENETC_PM0_PAUSE_IGN BIT(8) #define ENETC_PM0_CMD_XGLP BIT(10) #define ENETC_PM0_CMD_TXP BIT(11) #define ENETC_PM0_CMD_PHY_TX_EN BIT(15) @@ -239,6 +243,11 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PM_IMDIO_BASE 0x8030 +#define ENETC_PM0_PAUSE_QUANTA 0x8054 +#define ENETC_PM0_PAUSE_THRESH 0x8064 +#define ENETC_PM1_PAUSE_QUANTA 0x9054 +#define ENETC_PM1_PAUSE_THRESH 0x9064 + #define ENETC_PM0_SINGLE_STEP 0x80c0 #define ENETC_PM1_SINGLE_STEP 0x90c0 #define ENETC_PM0_SINGLE_STEP_CH BIT(7) diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index 1ae2473cbc16..aff1339442cc 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -1015,7 +1015,12 @@ static void enetc_pl_mac_link_up(struct phylink_config *config, int duplex, bool tx_pause, bool rx_pause) { struct enetc_pf *pf = phylink_to_enetc_pf(config); + u32 pause_off_thresh = 0, pause_on_thresh = 0; + u32 init_quanta = 0, refresh_quanta = 0; + struct enetc_hw *hw = &pf->si->hw; struct enetc_ndev_priv *priv; + u32 rbmr, cmd_cfg; + int idx; priv = netdev_priv(pf->si->ndev); if (priv->active_offloads & ENETC_F_QBV) @@ -1023,9 +1028,60 @@ static void enetc_pl_mac_link_up(struct phylink_config *config, if (!phylink_autoneg_inband(mode) && phy_interface_mode_is_rgmii(interface)) - enetc_force_rgmii_mac(&pf->si->hw, speed, duplex); + enetc_force_rgmii_mac(hw, speed, duplex); + + /* Flow control */ + for (idx = 0; idx < priv->num_rx_rings; idx++) { + rbmr = enetc_rxbdr_rd(hw, idx, ENETC_RBMR); + + if (tx_pause) + rbmr |= ENETC_RBMR_CM; + else + rbmr &= ~ENETC_RBMR_CM; + + enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); + } + + if (tx_pause) { + /* When the port first enters congestion, send a PAUSE request + * with the maximum number of quanta. When the port exits + * congestion, it will automatically send a PAUSE frame with + * zero quanta. + */ + init_quanta = 0xffff; + + /* Also, set up the refresh timer to send follow-up PAUSE + * frames at half the quanta value, in case the congestion + * condition persists. + */ + refresh_quanta = 0xffff / 2; + + /* Start emitting PAUSE frames when 3 large frames (or more + * smaller frames) have accumulated in the FIFO waiting to be + * DMAed to the RX ring. + */ + pause_on_thresh = 3 * ENETC_MAC_MAXFRM_SIZE; + pause_off_thresh = 1 * ENETC_MAC_MAXFRM_SIZE; + } + + enetc_port_wr(hw, ENETC_PM0_PAUSE_QUANTA, init_quanta); + enetc_port_wr(hw, ENETC_PM1_PAUSE_QUANTA, init_quanta); + enetc_port_wr(hw, ENETC_PM0_PAUSE_THRESH, refresh_quanta); + enetc_port_wr(hw, ENETC_PM1_PAUSE_THRESH, refresh_quanta); + enetc_port_wr(hw, ENETC_PPAUONTR, pause_on_thresh); + enetc_port_wr(hw, ENETC_PPAUOFFTR, pause_off_thresh); + + cmd_cfg = enetc_port_rd(hw, ENETC_PM0_CMD_CFG); + + if (rx_pause) + cmd_cfg &= ~ENETC_PM0_PAUSE_IGN; + else + cmd_cfg |= ENETC_PM0_PAUSE_IGN; + + enetc_port_wr(hw, ENETC_PM0_CMD_CFG, cmd_cfg); + enetc_port_wr(hw, ENETC_PM1_CMD_CFG, cmd_cfg); - enetc_mac_enable(&pf->si->hw, true); + enetc_mac_enable(hw, true); } static void enetc_pl_mac_link_down(struct phylink_config *config,