--- /dev/null
+From a74dbce9d4541888fe0d39afe69a3a95004669b4 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+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 <vladimir.oltean@nxp.com>
+
+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 <Markus.Bloechl@ipetronik.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 */
--- /dev/null
+From 827b6fd046516af605e190c872949f22208b5d41 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Mon, 1 Mar 2021 13:18:14 +0200
+Subject: net: enetc: fix incorrect TPID when receiving 802.1ad tagged packets
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+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 <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -563,9 +563,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);
+@@ -574,12 +573,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 */
+@@ -575,6 +577,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 */
--- /dev/null
+From c76a97218dcbb2cb7cec1404ace43ef96c87d874 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+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 <vladimir.oltean@nxp.com>
+
+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 <f.fainelli@gmail.com>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Cc: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
+@@ -939,6 +946,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,
+@@ -951,6 +986,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);
+ }
+
--- /dev/null
+From 3a5d12c9be6f30080600c8bacaf310194e37d029 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Mon, 1 Mar 2021 13:18:18 +0200
+Subject: net: enetc: keep RX ring consumer index in sync with hardware
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+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 <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -1252,6 +1252,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);
--- /dev/null
+From 96a5223b918c8b79270fc0fec235a7ebad459098 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Mon, 1 Mar 2021 13:18:17 +0200
+Subject: net: enetc: remove bogus write to SIRXIDR from enetc_setup_rxbdr
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+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 <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -1252,7 +1252,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);
--- /dev/null
+From 95b39f07a17faef3a9b225248ba449b976e529c8 Mon Sep 17 00:00:00 2001
+From: Biao Huang <biao.huang@mediatek.com>
+Date: Tue, 2 Mar 2021 11:33:23 +0800
+Subject: net: ethernet: mtk-star-emac: fix wrong unmap in RX handling
+
+From: Biao Huang <biao.huang@mediatek.com>
+
+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 <biao.huang@mediatek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From 00ff801bb8ce6711e919af4530b6ffa14a22390a Mon Sep 17 00:00:00 2001
+From: "Kevin(Yudong) Yang" <yyd@google.com>
+Date: Wed, 3 Mar 2021 09:43:54 -0500
+Subject: net/mlx4_en: update moderation when config reset
+
+From: Kevin(Yudong) Yang <yyd@google.com>
+
+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 <yyd@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Neal Cardwell <ncardwell@google.com>
+CC: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -3559,6 +3559,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
+@@ -795,6 +795,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);
--- /dev/null
+From 879c348c35bb5fb758dd881d8a97409c1862dae8 Mon Sep 17 00:00:00 2001
+From: Ong Boon Leong <boon.leong.ong@intel.com>
+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 <boon.leong.ong@intel.com>
+
+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 <boon.leong.ong@intel.com>
+Signed-off-by: Ramesh Babu B <ramesh.babu.b@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
--- /dev/null
+From 76c03bf8e2624076b88d93542d78e22d5345c88e Mon Sep 17 00:00:00 2001
+From: Ido Schimmel <idosch@nvidia.com>
+Date: Thu, 4 Mar 2021 10:57:53 +0200
+Subject: nexthop: Do not flush blackhole nexthops when loopback goes down
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+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 <idosch@nvidia.com>
+Reported-by: Donald Sharp <sharpd@nvidia.com>
+Reviewed-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/nexthop.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -1182,7 +1182,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);
+@@ -1194,6 +1194,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);
+ }
+ }
+@@ -1940,11 +1944,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;
sh_eth-fix-trscer-mask-for-sh771x.patch
net-enetc-don-t-overwrite-the-rss-indirection-table-when-initializing.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-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