From: Greg Kroah-Hartman Date: Fri, 12 Mar 2021 12:42:17 +0000 (+0100) Subject: 5.11-stable patches X-Git-Tag: v4.4.262~102 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=48aa6f9f1fb4cb77de9e3d8b585e53dd6a210280;p=thirdparty%2Fkernel%2Fstable-queue.git 5.11-stable patches added patches: net-dsa-tag_mtk-fix-802.1ad-vlan-egress.patch net-enetc-don-t-disable-vlan-filtering-in-iff_promisc-mode.patch net-enetc-fix-incorrect-tpid-when-receiving-802.1ad-tagged-packets.patch net-enetc-force-the-rgmii-speed-and-duplex-instead-of-operating-in-inband-mode.patch net-enetc-keep-rx-ring-consumer-index-in-sync-with-hardware.patch net-enetc-remove-bogus-write-to-sirxidr-from-enetc_setup_rxbdr.patch net-ethernet-mtk-star-emac-fix-wrong-unmap-in-rx-handling.patch net-mlx4_en-update-moderation-when-config-reset.patch net-stmmac-fix-incorrect-dma-channel-intr-enable-setting-of-eqos-v4.10.patch nexthop-do-not-flush-blackhole-nexthops-when-loopback-goes-down.patch --- diff --git a/queue-5.11/net-dsa-tag_mtk-fix-802.1ad-vlan-egress.patch b/queue-5.11/net-dsa-tag_mtk-fix-802.1ad-vlan-egress.patch new file mode 100644 index 00000000000..2fac7d6b3bd --- /dev/null +++ b/queue-5.11/net-dsa-tag_mtk-fix-802.1ad-vlan-egress.patch @@ -0,0 +1,79 @@ +From 9200f515c41f4cbaeffd8fdd1d8b6373a18b1b67 Mon Sep 17 00:00:00 2001 +From: DENG Qingfang +Date: Tue, 2 Mar 2021 00:01:59 +0800 +Subject: net: dsa: tag_mtk: fix 802.1ad VLAN egress + +From: DENG Qingfang + +commit 9200f515c41f4cbaeffd8fdd1d8b6373a18b1b67 upstream. + +A different TPID bit is used for 802.1ad VLAN frames. + +Reported-by: Ilario Gelmetti +Fixes: f0af34317f4b ("net: dsa: mediatek: combine MediaTek tag with VLAN tag") +Signed-off-by: DENG Qingfang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dsa/tag_mtk.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/net/dsa/tag_mtk.c ++++ b/net/dsa/tag_mtk.c +@@ -13,6 +13,7 @@ + #define MTK_HDR_LEN 4 + #define MTK_HDR_XMIT_UNTAGGED 0 + #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 ++#define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 + #define MTK_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0) + #define MTK_HDR_XMIT_DP_BIT_MASK GENMASK(5, 0) + #define MTK_HDR_XMIT_SA_DIS BIT(6) +@@ -21,8 +22,8 @@ static struct sk_buff *mtk_tag_xmit(stru + struct net_device *dev) + { + struct dsa_port *dp = dsa_slave_to_port(dev); ++ u8 xmit_tpid; + u8 *mtk_tag; +- bool is_vlan_skb = true; + unsigned char *dest = eth_hdr(skb)->h_dest; + bool is_multicast_skb = is_multicast_ether_addr(dest) && + !is_broadcast_ether_addr(dest); +@@ -33,10 +34,17 @@ static struct sk_buff *mtk_tag_xmit(stru + * the both special and VLAN tag at the same time and then look up VLAN + * table with VID. + */ +- if (!skb_vlan_tagged(skb)) { ++ switch (skb->protocol) { ++ case htons(ETH_P_8021Q): ++ xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100; ++ break; ++ case htons(ETH_P_8021AD): ++ xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8; ++ break; ++ default: ++ xmit_tpid = MTK_HDR_XMIT_UNTAGGED; + skb_push(skb, MTK_HDR_LEN); + memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); +- is_vlan_skb = false; + } + + mtk_tag = skb->data + 2 * ETH_ALEN; +@@ -44,8 +52,7 @@ static struct sk_buff *mtk_tag_xmit(stru + /* Mark tag attribute on special tag insertion to notify hardware + * whether that's a combined special tag with 802.1Q header. + */ +- mtk_tag[0] = is_vlan_skb ? MTK_HDR_XMIT_TAGGED_TPID_8100 : +- MTK_HDR_XMIT_UNTAGGED; ++ mtk_tag[0] = xmit_tpid; + mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; + + /* Disable SA learning for multicast frames */ +@@ -53,7 +60,7 @@ static struct sk_buff *mtk_tag_xmit(stru + mtk_tag[1] |= MTK_HDR_XMIT_SA_DIS; + + /* Tag control information is kept for 802.1Q */ +- if (!is_vlan_skb) { ++ if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) { + mtk_tag[2] = 0; + mtk_tag[3] = 0; + } diff --git a/queue-5.11/net-enetc-don-t-disable-vlan-filtering-in-iff_promisc-mode.patch b/queue-5.11/net-enetc-don-t-disable-vlan-filtering-in-iff_promisc-mode.patch new file mode 100644 index 00000000000..ef02f62b5e9 --- /dev/null +++ b/queue-5.11/net-enetc-don-t-disable-vlan-filtering-in-iff_promisc-mode.patch @@ -0,0 +1,79 @@ +From a74dbce9d4541888fe0d39afe69a3a95004669b4 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Mon, 1 Mar 2021 13:18:15 +0200 +Subject: net: enetc: don't disable VLAN filtering in IFF_PROMISC mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vladimir Oltean + +commit a74dbce9d4541888fe0d39afe69a3a95004669b4 upstream. + +Quoting from the blamed commit: + + In promiscuous mode, it is more intuitive that all traffic is received, + including VLAN tagged traffic. It appears that it is necessary to set + the flag in PSIPVMR for that to be the case, so VLAN promiscuous mode is + also temporarily enabled. On exit from promiscuous mode, the setting + made by ethtool is restored. + +Intuitive or not, there isn't any definition issued by a standards body +which says that promiscuity has anything to do with VLAN filtering - it +only has to do with accepting packets regardless of destination MAC address. + +In fact people are already trying to use this misunderstanding/bug of +the enetc driver as a justification to transform promiscuity into +something it never was about: accepting every packet (maybe that would +be the "rx-all" netdev feature?): +https://lore.kernel.org/netdev/20201110153958.ci5ekor3o2ekg3ky@ipetronik.com/ + +This is relevant because there are use cases in the kernel (such as +tc-flower rules with the protocol 802.1Q and a vlan_id key) which do not +(yet) use the vlan_vid_add API to be compatible with VLAN-filtering NICs +such as enetc, so for those, disabling rx-vlan-filter is currently the +only right solution to make these setups work: +https://lore.kernel.org/netdev/CA+h21hoxwRdhq4y+w8Kwgm74d4cA0xLeiHTrmT-VpSaM7obhkg@mail.gmail.com/ +The blamed patch has unintentionally introduced one more way for this to +work, which is to enable IFF_PROMISC, however this is non-portable +because port promiscuity is not meant to disable VLAN filtering. +Therefore, it could invite people to write broken scripts for enetc, and +then wonder why they are broken when migrating to other drivers that +don't handle promiscuity in the same way. + +Fixes: 7070eea5e95a ("enetc: permit configuration of rx-vlan-filter with ethtool") +Cc: Markus Blöchl +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/enetc/enetc_pf.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +@@ -190,7 +190,6 @@ static void enetc_pf_set_rx_mode(struct + { + struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_pf *pf = enetc_si_priv(priv->si); +- char vlan_promisc_simap = pf->vlan_promisc_simap; + struct enetc_hw *hw = &priv->si->hw; + bool uprom = false, mprom = false; + struct enetc_mac_filter *filter; +@@ -203,16 +202,12 @@ static void enetc_pf_set_rx_mode(struct + psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0); + uprom = true; + mprom = true; +- /* Enable VLAN promiscuous mode for SI0 (PF) */ +- vlan_promisc_simap |= BIT(0); + } else if (ndev->flags & IFF_ALLMULTI) { + /* enable multi cast promisc mode for SI0 (PF) */ + psipmr = ENETC_PSIPMR_SET_MP(0); + mprom = true; + } + +- enetc_set_vlan_promisc(&pf->si->hw, vlan_promisc_simap); +- + /* first 2 filter entries belong to PF */ + if (!uprom) { + /* Update unicast filters */ diff --git a/queue-5.11/net-enetc-fix-incorrect-tpid-when-receiving-802.1ad-tagged-packets.patch b/queue-5.11/net-enetc-fix-incorrect-tpid-when-receiving-802.1ad-tagged-packets.patch new file mode 100644 index 00000000000..69a9f59ce6e --- /dev/null +++ b/queue-5.11/net-enetc-fix-incorrect-tpid-when-receiving-802.1ad-tagged-packets.patch @@ -0,0 +1,93 @@ +From 827b6fd046516af605e190c872949f22208b5d41 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Mon, 1 Mar 2021 13:18:14 +0200 +Subject: net: enetc: fix incorrect TPID when receiving 802.1ad tagged packets + +From: Vladimir Oltean + +commit 827b6fd046516af605e190c872949f22208b5d41 upstream. + +When the enetc ports have rx-vlan-offload enabled, they report a TPID of +ETH_P_8021Q regardless of what was actually in the packet. When +rx-vlan-offload is disabled, packets have the proper TPID. Fix this +inconsistency by finishing the TODO left in the code. + +Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 34 ++++++++++++++++++------ + drivers/net/ethernet/freescale/enetc/enetc_hw.h | 3 ++ + 2 files changed, 29 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -523,9 +523,8 @@ static void enetc_get_rx_tstamp(struct n + static void enetc_get_offloads(struct enetc_bdr *rx_ring, + union enetc_rx_bd *rxbd, struct sk_buff *skb) + { +-#ifdef CONFIG_FSL_ENETC_PTP_CLOCK + struct enetc_ndev_priv *priv = netdev_priv(rx_ring->ndev); +-#endif ++ + /* TODO: hashing */ + if (rx_ring->ndev->features & NETIF_F_RXCSUM) { + u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum); +@@ -534,12 +533,31 @@ static void enetc_get_offloads(struct en + skb->ip_summed = CHECKSUM_COMPLETE; + } + +- /* copy VLAN to skb, if one is extracted, for now we assume it's a +- * standard TPID, but HW also supports custom values +- */ +- if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) +- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), +- le16_to_cpu(rxbd->r.vlan_opt)); ++ if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) { ++ __be16 tpid = 0; ++ ++ switch (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TPID) { ++ case 0: ++ tpid = htons(ETH_P_8021Q); ++ break; ++ case 1: ++ tpid = htons(ETH_P_8021AD); ++ break; ++ case 2: ++ tpid = htons(enetc_port_rd(&priv->si->hw, ++ ENETC_PCVLANR1)); ++ break; ++ case 3: ++ tpid = htons(enetc_port_rd(&priv->si->hw, ++ ENETC_PCVLANR2)); ++ break; ++ default: ++ break; ++ } ++ ++ __vlan_hwaccel_put_tag(skb, tpid, le16_to_cpu(rxbd->r.vlan_opt)); ++ } ++ + #ifdef CONFIG_FSL_ENETC_PTP_CLOCK + if (priv->active_offloads & ENETC_F_RX_TSTAMP) + enetc_get_rx_tstamp(rx_ring->ndev, rxbd, skb); +--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h ++++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h +@@ -172,6 +172,8 @@ enum enetc_bdr_type {TX, RX}; + #define ENETC_PSIPMAR0(n) (0x0100 + (n) * 0x8) /* n = SI index */ + #define ENETC_PSIPMAR1(n) (0x0104 + (n) * 0x8) + #define ENETC_PVCLCTR 0x0208 ++#define ENETC_PCVLANR1 0x0210 ++#define ENETC_PCVLANR2 0x0214 + #define ENETC_VLAN_TYPE_C BIT(0) + #define ENETC_VLAN_TYPE_S BIT(1) + #define ENETC_PVCLCTR_OVTPIDL(bmp) ((bmp) & 0xff) /* VLAN_TYPE */ +@@ -570,6 +572,7 @@ union enetc_rx_bd { + #define ENETC_RXBD_LSTATUS(flags) ((flags) << 16) + #define ENETC_RXBD_FLAG_VLAN BIT(9) + #define ENETC_RXBD_FLAG_TSTMP BIT(10) ++#define ENETC_RXBD_FLAG_TPID GENMASK(1, 0) + + #define ENETC_MAC_ADDR_FILT_CNT 8 /* # of supported entries per port */ + #define EMETC_MAC_ADDR_FILT_RES 3 /* # of reserved entries at the beginning */ diff --git a/queue-5.11/net-enetc-force-the-rgmii-speed-and-duplex-instead-of-operating-in-inband-mode.patch b/queue-5.11/net-enetc-force-the-rgmii-speed-and-duplex-instead-of-operating-in-inband-mode.patch new file mode 100644 index 00000000000..4987e0fc2a3 --- /dev/null +++ b/queue-5.11/net-enetc-force-the-rgmii-speed-and-duplex-instead-of-operating-in-inband-mode.patch @@ -0,0 +1,150 @@ +From c76a97218dcbb2cb7cec1404ace43ef96c87d874 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Mon, 1 Mar 2021 13:18:16 +0200 +Subject: net: enetc: force the RGMII speed and duplex instead of operating in inband mode + +From: Vladimir Oltean + +commit c76a97218dcbb2cb7cec1404ace43ef96c87d874 upstream. + +The ENETC port 0 MAC supports in-band status signaling coming from a PHY +when operating in RGMII mode, and this feature is enabled by default. + +It has been reported that RGMII is broken in fixed-link, and that is not +surprising considering the fact that no PHY is attached to the MAC in +that case, but a switch. + +This brings us to the topic of the patch: the enetc driver should have +not enabled the optional in-band status signaling for RGMII unconditionally, +but should have forced the speed and duplex to what was resolved by +phylink. + +Note that phylink does not accept the RGMII modes as valid for in-band +signaling, and these operate a bit differently than 1000base-x and SGMII +(notably there is no clause 37 state machine so no ACK required from the +MAC, instead the PHY sends extra code words on RXD[3:0] whenever it is +not transmitting something else, so it should be safe to leave a PHY +with this option unconditionally enabled even if we ignore it). The spec +talks about this here: +https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/138/RGMIIv1_5F00_3.pdf + +Fixes: 71b77a7a27a3 ("enetc: Migrate to PHYLINK and PCS_LYNX") +Cc: Florian Fainelli +Cc: Andrew Lunn +Cc: Russell King +Signed-off-by: Vladimir Oltean +Acked-by: Russell King +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/enetc/enetc_hw.h | 13 ++++- + drivers/net/ethernet/freescale/enetc/enetc_pf.c | 53 ++++++++++++++++++++---- + 2 files changed, 56 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h ++++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h +@@ -238,10 +238,17 @@ enum enetc_bdr_type {TX, RX}; + #define ENETC_PM_IMDIO_BASE 0x8030 + + #define ENETC_PM0_IF_MODE 0x8300 +-#define ENETC_PMO_IFM_RG BIT(2) ++#define ENETC_PM0_IFM_RG BIT(2) + #define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11)) +-#define ENETC_PM0_IFM_RGAUTO (BIT(15) | ENETC_PMO_IFM_RG | BIT(1)) +-#define ENETC_PM0_IFM_XGMII BIT(12) ++#define ENETC_PM0_IFM_EN_AUTO BIT(15) ++#define ENETC_PM0_IFM_SSP_MASK GENMASK(14, 13) ++#define ENETC_PM0_IFM_SSP_1000 (2 << 13) ++#define ENETC_PM0_IFM_SSP_100 (0 << 13) ++#define ENETC_PM0_IFM_SSP_10 (1 << 13) ++#define ENETC_PM0_IFM_FULL_DPX BIT(12) ++#define ENETC_PM0_IFM_IFMODE_MASK GENMASK(1, 0) ++#define ENETC_PM0_IFM_IFMODE_XGMII 0 ++#define ENETC_PM0_IFM_IFMODE_GMII 2 + #define ENETC_PSIDCAPR 0x1b08 + #define ENETC_PSIDCAPR_MSK GENMASK(15, 0) + #define ENETC_PSFCAPR 0x1b18 +--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c +@@ -315,7 +315,7 @@ static void enetc_set_loopback(struct ne + u32 reg; + + reg = enetc_port_rd(hw, ENETC_PM0_IF_MODE); +- if (reg & ENETC_PMO_IFM_RG) { ++ if (reg & ENETC_PM0_IFM_RG) { + /* RGMII mode */ + reg = (reg & ~ENETC_PM0_IFM_RLP) | + (en ? ENETC_PM0_IFM_RLP : 0); +@@ -494,13 +494,20 @@ static void enetc_configure_port_mac(str + + static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode) + { +- /* set auto-speed for RGMII */ +- if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || +- phy_interface_mode_is_rgmii(phy_mode)) +- enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); ++ u32 val; ++ ++ if (phy_interface_mode_is_rgmii(phy_mode)) { ++ val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); ++ val &= ~ENETC_PM0_IFM_EN_AUTO; ++ val &= ENETC_PM0_IFM_IFMODE_MASK; ++ val |= ENETC_PM0_IFM_IFMODE_GMII | ENETC_PM0_IFM_RG; ++ enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); ++ } + +- if (phy_mode == PHY_INTERFACE_MODE_USXGMII) +- enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); ++ if (phy_mode == PHY_INTERFACE_MODE_USXGMII) { ++ val = ENETC_PM0_IFM_FULL_DPX | ENETC_PM0_IFM_IFMODE_XGMII; ++ enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); ++ } + } + + static void enetc_mac_enable(struct enetc_hw *hw, bool en) +@@ -932,6 +939,34 @@ static void enetc_pl_mac_config(struct p + phylink_set_pcs(priv->phylink, &pf->pcs->pcs); + } + ++static void enetc_force_rgmii_mac(struct enetc_hw *hw, int speed, int duplex) ++{ ++ u32 old_val, val; ++ ++ old_val = val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); ++ ++ if (speed == SPEED_1000) { ++ val &= ~ENETC_PM0_IFM_SSP_MASK; ++ val |= ENETC_PM0_IFM_SSP_1000; ++ } else if (speed == SPEED_100) { ++ val &= ~ENETC_PM0_IFM_SSP_MASK; ++ val |= ENETC_PM0_IFM_SSP_100; ++ } else if (speed == SPEED_10) { ++ val &= ~ENETC_PM0_IFM_SSP_MASK; ++ val |= ENETC_PM0_IFM_SSP_10; ++ } ++ ++ if (duplex == DUPLEX_FULL) ++ val |= ENETC_PM0_IFM_FULL_DPX; ++ else ++ val &= ~ENETC_PM0_IFM_FULL_DPX; ++ ++ if (val == old_val) ++ return; ++ ++ enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); ++} ++ + static void enetc_pl_mac_link_up(struct phylink_config *config, + struct phy_device *phy, unsigned int mode, + phy_interface_t interface, int speed, +@@ -944,6 +979,10 @@ static void enetc_pl_mac_link_up(struct + if (priv->active_offloads & ENETC_F_QBV) + enetc_sched_speed_set(priv, speed); + ++ if (!phylink_autoneg_inband(mode) && ++ phy_interface_mode_is_rgmii(interface)) ++ enetc_force_rgmii_mac(&pf->si->hw, speed, duplex); ++ + enetc_mac_enable(&pf->si->hw, true); + } + diff --git a/queue-5.11/net-enetc-keep-rx-ring-consumer-index-in-sync-with-hardware.patch b/queue-5.11/net-enetc-keep-rx-ring-consumer-index-in-sync-with-hardware.patch new file mode 100644 index 00000000000..c5da702b973 --- /dev/null +++ b/queue-5.11/net-enetc-keep-rx-ring-consumer-index-in-sync-with-hardware.patch @@ -0,0 +1,242 @@ +From 3a5d12c9be6f30080600c8bacaf310194e37d029 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Mon, 1 Mar 2021 13:18:18 +0200 +Subject: net: enetc: keep RX ring consumer index in sync with hardware + +From: Vladimir Oltean + +commit 3a5d12c9be6f30080600c8bacaf310194e37d029 upstream. + +The RX rings have a producer index owned by hardware, where newly +received frame buffers are placed, and a consumer index owned by +software, where newly allocated buffers are placed, in expectation of +hardware being able to place frame data in them. + +Hardware increments the producer index when a frame is received, however +it is not allowed to increment the producer index to match the consumer +index (RBCIR) since the ring can hold at most RBLENR[LENGTH]-1 received +BDs. Whenever the producer index matches the value of the consumer +index, the ring has no unprocessed received frames and all BDs in the +ring have been initialized/prepared by software, i.e. hardware owns all +BDs in the ring. + +The code uses the next_to_clean variable to keep track of the producer +index, and the next_to_use variable to keep track of the consumer index. + +The RX rings are seeded from enetc_refill_rx_ring, which is called from +two places: + +1. initially the ring is seeded until full with enetc_bd_unused(rx_ring), + i.e. with 511 buffers. This will make next_to_clean=0 and next_to_use=511: + +.ndo_open +-> enetc_open + -> enetc_setup_bdrs + -> enetc_setup_rxbdr + -> enetc_refill_rx_ring + +2. then during the data path processing, it is refilled with 16 buffers + at a time: + +enetc_msix +-> napi_schedule + -> enetc_poll + -> enetc_clean_rx_ring + -> enetc_refill_rx_ring + +There is just one problem: the initial seeding done during .ndo_open +updates just the producer index (ENETC_RBPIR) with 0, and the software +next_to_clean and next_to_use variables. Notably, it will not update the +consumer index to make the hardware aware of the newly added buffers. + +Wait, what? So how does it work? + +Well, the reset values of the producer index and of the consumer index +of a ring are both zero. As per the description in the second paragraph, +it means that the ring is full of buffers waiting for hardware to put +frames in them, which by coincidence is almost true, because we have in +fact seeded 511 buffers into the ring. + +But will the hardware attempt to access the 512th entry of the ring, +which has an invalid BD in it? Well, no, because in order to do that, it +would have to first populate the first 511 entries, and the NAPI +enetc_poll will kick in by then. Eventually, after 16 processed slots +have become available in the RX ring, enetc_clean_rx_ring will call +enetc_refill_rx_ring and then will [ finally ] update the consumer index +with the new software next_to_use variable. From now on, the +next_to_clean and next_to_use variables are in sync with the producer +and consumer ring indices. + +So the day is saved, right? Well, not quite. Freeing the memory +allocated for the rings is done in: + +enetc_close +-> enetc_clear_bdrs + -> enetc_clear_rxbdr + -> this just disables the ring +-> enetc_free_rxtx_rings + -> enetc_free_rx_ring + -> sets next_to_clean and next_to_use to 0 + +but again, nothing is committed to the hardware producer and consumer +indices (yay!). The assumption is that the ring is disabled, so the +indices don't matter anyway, and it's the responsibility of the "open" +code path to set those up. + +.. Except that the "open" code path does not set those up properly. + +While initially, things almost work, during subsequent enetc_close -> +enetc_open sequences, we have problems. To be precise, the enetc_open +that is subsequent to enetc_close will again refill the ring with 511 +entries, but it will leave the consumer index untouched. Untouched +means, of course, equal to the value it had before disabling the ring +and draining the old buffers in enetc_close. + +But as mentioned, enetc_setup_rxbdr will at least update the producer +index though, through this line of code: + + enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0); + +so at this stage we'll have: + +next_to_clean=0 (in hardware 0) +next_to_use=511 (in hardware we'll have the refill index prior to enetc_close) + +Again, the next_to_clean and producer index are in sync and set to +correct values, so the driver manages to limp on. Eventually, 16 ring +entries will be consumed by enetc_poll, and the savior +enetc_clean_rx_ring will come and call enetc_refill_rx_ring, and then +update the hardware consumer ring based upon the new next_to_use. + +So.. it works? +Well, by coincidence, it almost does, but there's a circumstance where +enetc_clean_rx_ring won't be there to save us. If the previous value of +the consumer index was 15, there's a problem, because the NAPI poll +sequence will only issue a refill when 16 or more buffers have been +consumed. + +It's easiest to illustrate this with an example: + +ip link set eno0 up +ip addr add 192.168.100.1/24 dev eno0 +ping 192.168.100.1 -c 20 # ping this port from another board +ip link set eno0 down +ip link set eno0 up +ping 192.168.100.1 -c 20 # ping it again from the same other board + +One by one: + +1. ip link set eno0 up +-> calls enetc_setup_rxbdr: + -> calls enetc_refill_rx_ring(511 buffers) + -> next_to_clean=0 (in hw 0) + -> next_to_use=511 (in hw 0) + +2. ping 192.168.100.1 -c 20 # ping this port from another board +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=1 next_to_clean 0 (in hw 1) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=2 next_to_clean 1 (in hw 2) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=3 next_to_clean 2 (in hw 3) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=4 next_to_clean 3 (in hw 4) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=5 next_to_clean 4 (in hw 5) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=6 next_to_clean 5 (in hw 6) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=7 next_to_clean 6 (in hw 7) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=8 next_to_clean 7 (in hw 8) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=9 next_to_clean 8 (in hw 9) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=10 next_to_clean 9 (in hw 10) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=11 next_to_clean 10 (in hw 11) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=12 next_to_clean 11 (in hw 12) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=13 next_to_clean 12 (in hw 13) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=14 next_to_clean 13 (in hw 14) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=15 next_to_clean 14 (in hw 15) next_to_use 511 (in hw 0) +enetc_clean_rx_ring: enetc_refill_rx_ring(16) increments next_to_use by 16 (mod 512) and writes it to hw +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=0 next_to_clean 15 (in hw 16) next_to_use 15 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=1 next_to_clean 16 (in hw 17) next_to_use 15 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=2 next_to_clean 17 (in hw 18) next_to_use 15 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=3 next_to_clean 18 (in hw 19) next_to_use 15 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=4 next_to_clean 19 (in hw 20) next_to_use 15 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=5 next_to_clean 20 (in hw 21) next_to_use 15 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=6 next_to_clean 21 (in hw 22) next_to_use 15 (in hw 15) + +20 packets transmitted, 20 packets received, 0% packet loss + +3. ip link set eno0 down +enetc_free_rx_ring: next_to_clean 0 (in hw 22), next_to_use 0 (in hw 15) + +4. ip link set eno0 up +-> calls enetc_setup_rxbdr: + -> calls enetc_refill_rx_ring(511 buffers) + -> next_to_clean=0 (in hw 0) + -> next_to_use=511 (in hw 15) + +5. ping 192.168.100.1 -c 20 # ping it again from the same other board +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=1 next_to_clean 0 (in hw 1) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=2 next_to_clean 1 (in hw 2) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=3 next_to_clean 2 (in hw 3) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=4 next_to_clean 3 (in hw 4) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=5 next_to_clean 4 (in hw 5) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=6 next_to_clean 5 (in hw 6) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=7 next_to_clean 6 (in hw 7) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=8 next_to_clean 7 (in hw 8) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=9 next_to_clean 8 (in hw 9) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=10 next_to_clean 9 (in hw 10) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=11 next_to_clean 10 (in hw 11) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=12 next_to_clean 11 (in hw 12) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=13 next_to_clean 12 (in hw 13) next_to_use 511 (in hw 15) +enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=14 next_to_clean 13 (in hw 14) next_to_use 511 (in hw 15) + +20 packets transmitted, 12 packets received, 40% packet loss + +And there it dies. No enetc_refill_rx_ring (because cleaned_cnt must be equal +to 15 for that to happen), no nothing. The hardware enters the condition where +the producer (14) + 1 is equal to the consumer (15) index, which makes it +believe it has no more free buffers to put packets in, so it starts discarding +them: + +ip netns exec ns0 ethtool -S eno0 | grep -v ': 0' +NIC statistics: + Rx ring 0 discarded frames: 8 + +Summarized, if the interface receives between 16 and 32 (mod 512) frames +and then there is a link flap, then the port will eventually die with no +way to recover. If it receives less than 16 (mod 512) frames, then the +initial NAPI poll [ before the link flap ] will not update the consumer +index in hardware (it will remain zero) which will be ok when the buffers +are later reinitialized. If more than 32 (mod 512) frames are received, +the initial NAPI poll has the chance to refill the ring twice, updating +the consumer index to at least 32. So after the link flap, the consumer +index is still wrong, but the post-flap NAPI poll gets a chance to +refill the ring once (because it passes through cleaned_cnt=15) and +makes the consumer index be again back in sync with next_to_use. + +The solution to this problem is actually simple, we just need to write +next_to_use into the hardware consumer index at enetc_open time, which +always brings it back in sync after an initial buffer seeding process. + +The simpler thing would be to put the write to the consumer index into +enetc_refill_rx_ring directly, but there are issues with the MDIO +locking: in the NAPI poll code we have the enetc_lock_mdio() taken from +top-level and we use the unlocked enetc_wr_reg_hot, whereas in +enetc_open, the enetc_lock_mdio() is not taken at the top level, but +instead by each individual enetc_wr_reg, so we are forced to put an +additional enetc_wr_reg in enetc_setup_rxbdr. Better organization of +the code is left as a refactoring exercise. + +Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -1212,6 +1212,8 @@ static void enetc_setup_rxbdr(struct ene + rx_ring->idr = hw->reg + ENETC_SIRXIDR; + + enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); ++ /* update ENETC's consumer index */ ++ enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use); + + /* enable ring */ + enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); diff --git a/queue-5.11/net-enetc-remove-bogus-write-to-sirxidr-from-enetc_setup_rxbdr.patch b/queue-5.11/net-enetc-remove-bogus-write-to-sirxidr-from-enetc_setup_rxbdr.patch new file mode 100644 index 00000000000..16f9d812635 --- /dev/null +++ b/queue-5.11/net-enetc-remove-bogus-write-to-sirxidr-from-enetc_setup_rxbdr.patch @@ -0,0 +1,53 @@ +From 96a5223b918c8b79270fc0fec235a7ebad459098 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Mon, 1 Mar 2021 13:18:17 +0200 +Subject: net: enetc: remove bogus write to SIRXIDR from enetc_setup_rxbdr + +From: Vladimir Oltean + +commit 96a5223b918c8b79270fc0fec235a7ebad459098 upstream. + +The Station Interface Receive Interrupt Detect Register (SIRXIDR) +contains a 16-bit wide mask of 'interrupt detected' events for each ring +associated with a port. Bit i is write-1-to-clean for RX ring i. + +I have no explanation whatsoever how this line of code came to be +inserted in the blamed commit. I checked the downstream versions of that +patch and none of them have it. + +The somewhat comical aspect of it is that we're writing a binary number +to the SIRXIDR register, which is derived from enetc_bd_unused(rx_ring). +Since the RX rings have 512 buffer descriptors, we end up writing 511 to +this register, which is 0x1ff, so we are effectively clearing the +'interrupt detected' event for rings 0-8. + +This register is not what is used for interrupt handling though - it +only provides a summary for the entire SI. The hardware provides one +separate Interrupt Detect Register per RX ring, which auto-clears upon +read. So there doesn't seem to be any adverse effect caused by this +bogus write. + +There is, however, one reason why this should be handled as a bugfix: +next_to_clean _should_ be committed to hardware, just not to that +register, and this was obscuring the fact that it wasn't. This is fixed +in the next patch, and removing the bogus line now allows the fix patch +to be backported beyond that point. + +Fixes: fd5736bf9f23 ("enetc: Workaround for MDIO register access issue") +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -1212,7 +1212,6 @@ static void enetc_setup_rxbdr(struct ene + rx_ring->idr = hw->reg + ENETC_SIRXIDR; + + enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); +- enetc_wr(hw, ENETC_SIRXIDR, rx_ring->next_to_use); + + /* enable ring */ + enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); diff --git a/queue-5.11/net-ethernet-mtk-star-emac-fix-wrong-unmap-in-rx-handling.patch b/queue-5.11/net-ethernet-mtk-star-emac-fix-wrong-unmap-in-rx-handling.patch new file mode 100644 index 00000000000..3f75fdd7d3d --- /dev/null +++ b/queue-5.11/net-ethernet-mtk-star-emac-fix-wrong-unmap-in-rx-handling.patch @@ -0,0 +1,43 @@ +From 95b39f07a17faef3a9b225248ba449b976e529c8 Mon Sep 17 00:00:00 2001 +From: Biao Huang +Date: Tue, 2 Mar 2021 11:33:23 +0800 +Subject: net: ethernet: mtk-star-emac: fix wrong unmap in RX handling + +From: Biao Huang + +commit 95b39f07a17faef3a9b225248ba449b976e529c8 upstream. + +mtk_star_dma_unmap_rx() should unmap the dma_addr of old skb rather than +that of new skb. +Assign new_dma_addr to desc_data.dma_addr after all handling of old skb +ends to avoid unexpected receive side error. + +Fixes: f96e9641e92b ("net: ethernet: mtk-star-emac: fix error path in RX handling") +Signed-off-by: Biao Huang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mediatek/mtk_star_emac.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c ++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c +@@ -1225,8 +1225,6 @@ static int mtk_star_receive_packet(struc + goto push_new_skb; + } + +- desc_data.dma_addr = new_dma_addr; +- + /* We can't fail anymore at this point: it's safe to unmap the skb. */ + mtk_star_dma_unmap_rx(priv, &desc_data); + +@@ -1236,6 +1234,9 @@ static int mtk_star_receive_packet(struc + desc_data.skb->dev = ndev; + netif_receive_skb(desc_data.skb); + ++ /* update dma_addr for new skb */ ++ desc_data.dma_addr = new_dma_addr; ++ + push_new_skb: + desc_data.len = skb_tailroom(new_skb); + desc_data.skb = new_skb; diff --git a/queue-5.11/net-mlx4_en-update-moderation-when-config-reset.patch b/queue-5.11/net-mlx4_en-update-moderation-when-config-reset.patch new file mode 100644 index 00000000000..4402e99eff9 --- /dev/null +++ b/queue-5.11/net-mlx4_en-update-moderation-when-config-reset.patch @@ -0,0 +1,80 @@ +From 00ff801bb8ce6711e919af4530b6ffa14a22390a Mon Sep 17 00:00:00 2001 +From: "Kevin(Yudong) Yang" +Date: Wed, 3 Mar 2021 09:43:54 -0500 +Subject: net/mlx4_en: update moderation when config reset + +From: Kevin(Yudong) Yang + +commit 00ff801bb8ce6711e919af4530b6ffa14a22390a upstream. + +This patch fixes a bug that the moderation config will not be +applied when calling mlx4_en_reset_config. For example, when +turning on rx timestamping, mlx4_en_reset_config() will be called, +causing the NIC to forget previous moderation config. + +This fix is in phase with a previous fix: +commit 79c54b6bbf06 ("net/mlx4_en: Fix TX moderation info loss +after set_ringparam is called") + +Tested: Before this patch, on a host with NIC using mlx4, run +netserver and stream TCP to the host at full utilization. +$ sar -I SUM 1 + INTR intr/s +14:03:56 sum 48758.00 + +After rx hwtstamp is enabled: +$ sar -I SUM 1 +14:10:38 sum 317771.00 +We see the moderation is not working properly and issued 7x more +interrupts. + +After the patch, and turned on rx hwtstamp, the rate of interrupts +is as expected: +$ sar -I SUM 1 +14:52:11 sum 49332.00 + +Fixes: 79c54b6bbf06 ("net/mlx4_en: Fix TX moderation info loss after set_ringparam is called") +Signed-off-by: Kevin(Yudong) Yang +Reviewed-by: Eric Dumazet +Reviewed-by: Neal Cardwell +CC: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- + drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 ++ + drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + + 3 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -47,7 +47,7 @@ + #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) + #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) + +-static int mlx4_en_moderation_update(struct mlx4_en_priv *priv) ++int mlx4_en_moderation_update(struct mlx4_en_priv *priv) + { + int i, t; + int err = 0; +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -3558,6 +3558,8 @@ int mlx4_en_reset_config(struct net_devi + en_err(priv, "Failed starting port\n"); + } + ++ if (!err) ++ err = mlx4_en_moderation_update(priv); + out: + mutex_unlock(&mdev->state_lock); + kfree(tmp); +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +@@ -775,6 +775,7 @@ void mlx4_en_ptp_overflow_check(struct m + #define DEV_FEATURE_CHANGED(dev, new_features, feature) \ + ((dev->features & feature) ^ (new_features & feature)) + ++int mlx4_en_moderation_update(struct mlx4_en_priv *priv); + int mlx4_en_reset_config(struct net_device *dev, + struct hwtstamp_config ts_config, + netdev_features_t new_features); diff --git a/queue-5.11/net-stmmac-fix-incorrect-dma-channel-intr-enable-setting-of-eqos-v4.10.patch b/queue-5.11/net-stmmac-fix-incorrect-dma-channel-intr-enable-setting-of-eqos-v4.10.patch new file mode 100644 index 00000000000..ba068de3441 --- /dev/null +++ b/queue-5.11/net-stmmac-fix-incorrect-dma-channel-intr-enable-setting-of-eqos-v4.10.patch @@ -0,0 +1,57 @@ +From 879c348c35bb5fb758dd881d8a97409c1862dae8 Mon Sep 17 00:00:00 2001 +From: Ong Boon Leong +Date: Wed, 3 Mar 2021 20:38:40 +0530 +Subject: net: stmmac: fix incorrect DMA channel intr enable setting of EQoS v4.10 + +From: Ong Boon Leong + +commit 879c348c35bb5fb758dd881d8a97409c1862dae8 upstream. + +We introduce dwmac410_dma_init_channel() here for both EQoS v4.10 and +above which use different DMA_CH(n)_Interrupt_Enable bit definitions for +NIE and AIE. + +Fixes: 48863ce5940f ("stmmac: add DMA support for GMAC 4.xx") +Signed-off-by: Ong Boon Leong +Signed-off-by: Ramesh Babu B +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +@@ -124,6 +124,23 @@ static void dwmac4_dma_init_channel(void + ioaddr + DMA_CHAN_INTR_ENA(chan)); + } + ++static void dwmac410_dma_init_channel(void __iomem *ioaddr, ++ struct stmmac_dma_cfg *dma_cfg, u32 chan) ++{ ++ u32 value; ++ ++ /* common channel control register config */ ++ value = readl(ioaddr + DMA_CHAN_CONTROL(chan)); ++ if (dma_cfg->pblx8) ++ value = value | DMA_BUS_MODE_PBL; ++ ++ writel(value, ioaddr + DMA_CHAN_CONTROL(chan)); ++ ++ /* Mask interrupts by writing to CSR7 */ ++ writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10, ++ ioaddr + DMA_CHAN_INTR_ENA(chan)); ++} ++ + static void dwmac4_dma_init(void __iomem *ioaddr, + struct stmmac_dma_cfg *dma_cfg, int atds) + { +@@ -523,7 +540,7 @@ const struct stmmac_dma_ops dwmac4_dma_o + const struct stmmac_dma_ops dwmac410_dma_ops = { + .reset = dwmac4_dma_reset, + .init = dwmac4_dma_init, +- .init_chan = dwmac4_dma_init_channel, ++ .init_chan = dwmac410_dma_init_channel, + .init_rx_chan = dwmac4_dma_init_rx_chan, + .init_tx_chan = dwmac4_dma_init_tx_chan, + .axi = dwmac4_dma_axi, diff --git a/queue-5.11/nexthop-do-not-flush-blackhole-nexthops-when-loopback-goes-down.patch b/queue-5.11/nexthop-do-not-flush-blackhole-nexthops-when-loopback-goes-down.patch new file mode 100644 index 00000000000..90da295be31 --- /dev/null +++ b/queue-5.11/nexthop-do-not-flush-blackhole-nexthops-when-loopback-goes-down.patch @@ -0,0 +1,81 @@ +From 76c03bf8e2624076b88d93542d78e22d5345c88e Mon Sep 17 00:00:00 2001 +From: Ido Schimmel +Date: Thu, 4 Mar 2021 10:57:53 +0200 +Subject: nexthop: Do not flush blackhole nexthops when loopback goes down + +From: Ido Schimmel + +commit 76c03bf8e2624076b88d93542d78e22d5345c88e upstream. + +As far as user space is concerned, blackhole nexthops do not have a +nexthop device and therefore should not be affected by the +administrative or carrier state of any netdev. + +However, when the loopback netdev goes down all the blackhole nexthops +are flushed. This happens because internally the kernel associates +blackhole nexthops with the loopback netdev. + +This behavior is both confusing to those not familiar with kernel +internals and also diverges from the legacy API where blackhole IPv4 +routes are not flushed when the loopback netdev goes down: + + # ip route add blackhole 198.51.100.0/24 + # ip link set dev lo down + # ip route show 198.51.100.0/24 + blackhole 198.51.100.0/24 + +Blackhole IPv6 routes are flushed, but at least user space knows that +they are associated with the loopback netdev: + + # ip -6 route show 2001:db8:1::/64 + blackhole 2001:db8:1::/64 dev lo metric 1024 pref medium + +Fix this by only flushing blackhole nexthops when the loopback netdev is +unregistered. + +Fixes: ab84be7e54fc ("net: Initial nexthop code") +Signed-off-by: Ido Schimmel +Reported-by: Donald Sharp +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/nexthop.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/net/ipv4/nexthop.c ++++ b/net/ipv4/nexthop.c +@@ -1364,7 +1364,7 @@ out: + + /* rtnl */ + /* remove all nexthops tied to a device being deleted */ +-static void nexthop_flush_dev(struct net_device *dev) ++static void nexthop_flush_dev(struct net_device *dev, unsigned long event) + { + unsigned int hash = nh_dev_hashfn(dev->ifindex); + struct net *net = dev_net(dev); +@@ -1376,6 +1376,10 @@ static void nexthop_flush_dev(struct net + if (nhi->fib_nhc.nhc_dev != dev) + continue; + ++ if (nhi->reject_nh && ++ (event == NETDEV_DOWN || event == NETDEV_CHANGE)) ++ continue; ++ + remove_nexthop(net, nhi->nh_parent, NULL); + } + } +@@ -2122,11 +2126,11 @@ static int nh_netdev_event(struct notifi + switch (event) { + case NETDEV_DOWN: + case NETDEV_UNREGISTER: +- nexthop_flush_dev(dev); ++ nexthop_flush_dev(dev, event); + break; + case NETDEV_CHANGE: + if (!(dev_get_flags(dev) & (IFF_RUNNING | IFF_LOWER_UP))) +- nexthop_flush_dev(dev); ++ nexthop_flush_dev(dev, event); + break; + case NETDEV_CHANGEMTU: + info_ext = ptr; diff --git a/queue-5.11/series b/queue-5.11/series index 1e99ea7f8b1..18db8ad5be6 100644 --- a/queue-5.11/series +++ b/queue-5.11/series @@ -46,3 +46,13 @@ sh_eth-fix-trscer-mask-for-sh771x.patch net-enetc-don-t-overwrite-the-rss-indirection-table-when-initializing.patch net-enetc-initialize-rfs-rss-memories-for-unused-ports-too.patch net-enetc-take-the-mdio-lock-only-once-per-napi-poll-cycle.patch +net-enetc-fix-incorrect-tpid-when-receiving-802.1ad-tagged-packets.patch +net-enetc-don-t-disable-vlan-filtering-in-iff_promisc-mode.patch +net-enetc-force-the-rgmii-speed-and-duplex-instead-of-operating-in-inband-mode.patch +net-enetc-remove-bogus-write-to-sirxidr-from-enetc_setup_rxbdr.patch +net-enetc-keep-rx-ring-consumer-index-in-sync-with-hardware.patch +net-dsa-tag_mtk-fix-802.1ad-vlan-egress.patch +net-ethernet-mtk-star-emac-fix-wrong-unmap-in-rx-handling.patch +net-mlx4_en-update-moderation-when-config-reset.patch +net-stmmac-fix-incorrect-dma-channel-intr-enable-setting-of-eqos-v4.10.patch +nexthop-do-not-flush-blackhole-nexthops-when-loopback-goes-down.patch