kernel: backport phylink changes from mainline Linux
authorDaniel Golle <daniel@makrotopia.org>
Sun, 28 Jan 2024 03:36:40 +0000 (03:36 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Thu, 15 Feb 2024 19:06:36 +0000 (19:06 +0000)
Let's pick a bunch of useful phylink changes which allow us to keep
drivers in sync with mainline Linux.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
93 files changed:
target/linux/bcm27xx/patches-6.1/950-0864-net-macb-Also-set-DMA-coherent-mask.patch
target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch [deleted file]
target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch
target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch
target/linux/generic/backport-6.1/723-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch [deleted file]
target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch
target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch
target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch
target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch
target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch
target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch
target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch
target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch
target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch
target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch
target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch
target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch
target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch
target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch
target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch
target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch
target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch
target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch
target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch
target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch
target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch
target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch
target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch
target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch
target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch
target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch
target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch
target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch
target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch
target/linux/mediatek/patches-6.1/961-net-ethernet-mediatek-split-tx-and-rx-fields-in-mtk_.patch
target/linux/mediatek/patches-6.1/962-net-ethernet-mediatek-use-QDMA-instead-of-ADMAv2-on-.patch
target/linux/mvebu/patches-6.1/700-mvneta-tx-queue-workaround.patch
target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch

index 88d92fbb20ad52a051fc911c8496031e97058973..7c8c49a3b5dd8c29ed143d8ee6a8112674cdf15f 100644 (file)
@@ -191,7 +191,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
  static void macb_init_buffers(struct macb *bp)
  {
        struct macb_queue *queue;
-@@ -915,6 +931,7 @@ static int macb_mii_init(struct macb *bp
+@@ -914,6 +930,7 @@ static int macb_mii_init(struct macb *bp
        bp->mii_bus->name = "MACB_mii_bus";
        bp->mii_bus->read = &macb_mdio_read;
        bp->mii_bus->write = &macb_mdio_write;
@@ -199,7 +199,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
                 bp->pdev->name, bp->pdev->id);
        bp->mii_bus->priv = bp;
-@@ -1584,6 +1601,11 @@ static int macb_rx(struct macb_queue *qu
+@@ -1583,6 +1600,11 @@ static int macb_rx(struct macb_queue *qu
  
                macb_init_rx_ring(queue);
                queue_writel(queue, RBQP, queue->rx_ring_dma);
@@ -211,7 +211,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
  
                macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
  
-@@ -1884,8 +1906,9 @@ static irqreturn_t macb_interrupt(int ir
+@@ -1883,8 +1905,9 @@ static irqreturn_t macb_interrupt(int ir
                                queue_writel(queue, ISR, MACB_BIT(TCOMP) |
                                                         MACB_BIT(TXUBR));
  
@@ -222,7 +222,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
                                wmb(); // ensure softirq can see update
                        }
  
-@@ -2332,6 +2355,11 @@ static netdev_tx_t macb_start_xmit(struc
+@@ -2331,6 +2354,11 @@ static netdev_tx_t macb_start_xmit(struc
        skb_tx_timestamp(skb);
  
        spin_lock_irq(&bp->lock);
@@ -234,7 +234,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
        spin_unlock_irq(&bp->lock);
  
-@@ -2699,6 +2727,37 @@ static void macb_configure_dma(struct ma
+@@ -2698,6 +2726,37 @@ static void macb_configure_dma(struct ma
        }
  }
  
@@ -272,7 +272,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
  static void macb_init_hw(struct macb *bp)
  {
        u32 config;
-@@ -2727,6 +2786,11 @@ static void macb_init_hw(struct macb *bp
+@@ -2726,6 +2785,11 @@ static void macb_init_hw(struct macb *bp
        if (bp->caps & MACB_CAPS_JUMBO)
                bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK;
  
@@ -284,7 +284,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        macb_configure_dma(bp);
  }
  
-@@ -3072,6 +3136,52 @@ static void gem_get_ethtool_strings(stru
+@@ -3071,6 +3135,52 @@ static void gem_get_ethtool_strings(stru
        }
  }
  
@@ -337,7 +337,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
  static struct net_device_stats *macb_get_stats(struct net_device *dev)
  {
        struct macb *bp = netdev_priv(dev);
-@@ -3664,6 +3774,8 @@ static const struct ethtool_ops macb_eth
+@@ -3663,6 +3773,8 @@ static const struct ethtool_ops macb_eth
  };
  
  static const struct ethtool_ops gem_ethtool_ops = {
@@ -346,7 +346,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        .get_regs_len           = macb_get_regs_len,
        .get_regs               = macb_get_regs,
        .get_wol                = macb_get_wol,
-@@ -3673,6 +3785,8 @@ static const struct ethtool_ops gem_etht
+@@ -3672,6 +3784,8 @@ static const struct ethtool_ops gem_etht
        .get_ethtool_stats      = gem_get_ethtool_stats,
        .get_strings            = gem_get_ethtool_strings,
        .get_sset_count         = gem_get_sset_count,
@@ -355,7 +355,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        .get_link_ksettings     = macb_get_link_ksettings,
        .set_link_ksettings     = macb_set_link_ksettings,
        .get_ringparam          = macb_get_ringparam,
-@@ -4940,6 +5054,10 @@ static int macb_probe(struct platform_de
+@@ -4939,6 +5053,10 @@ static int macb_probe(struct platform_de
  
        bp->usrio = macb_config->usrio;
  
@@ -366,7 +366,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        spin_lock_init(&bp->lock);
  
        /* setup capabilities */
-@@ -4995,6 +5113,21 @@ static int macb_probe(struct platform_de
+@@ -4994,6 +5112,21 @@ static int macb_probe(struct platform_de
        else
                bp->phy_interface = interface;
  
@@ -388,7 +388,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
        /* IP specific init */
        err = init(pdev);
        if (err)
-@@ -5071,6 +5204,19 @@ static int macb_remove(struct platform_d
+@@ -5070,6 +5203,19 @@ static int macb_remove(struct platform_d
        return 0;
  }
  
@@ -408,7 +408,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
  static int __maybe_unused macb_suspend(struct device *dev)
  {
        struct net_device *netdev = dev_get_drvdata(dev);
-@@ -5285,6 +5431,7 @@ static const struct dev_pm_ops macb_pm_o
+@@ -5284,6 +5430,7 @@ static const struct dev_pm_ops macb_pm_o
  static struct platform_driver macb_driver = {
        .probe          = macb_probe,
        .remove         = macb_remove,
diff --git a/target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch b/target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch
deleted file mode 100644 (file)
index 81c14a0..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 9c5a170677c3c8facc83e931a57f4c99c0511ae0 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 27 Oct 2022 14:10:37 +0100
-Subject: [PATCH] net: phylink: add phylink_get_link_timer_ns() helper
-
-Add a helper to convert the PHY interface mode to the required link
-timer setting as stated by the appropriate standard. Inappropriate
-interface modes return an error.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/linux/phylink.h | 24 ++++++++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -614,6 +614,30 @@ int phylink_speed_up(struct phylink *pl)
- void phylink_set_port_modes(unsigned long *bits);
-+/**
-+ * phylink_get_link_timer_ns - return the PCS link timer value
-+ * @interface: link &typedef phy_interface_t mode
-+ *
-+ * Return the PCS link timer setting in nanoseconds for the PHY @interface
-+ * mode, or -EINVAL if not appropriate.
-+ */
-+static inline int phylink_get_link_timer_ns(phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              return 1600000;
-+
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              return 10000000;
-+
-+      default:
-+              return -EINVAL;
-+      }
-+}
-+
- void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
-                                     u16 bmsr, u16 lpa);
- void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
diff --git a/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch
new file mode 100644 (file)
index 0000000..d56a142
--- /dev/null
@@ -0,0 +1,394 @@
+From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 19 Mar 2023 12:57:50 +0000
+Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS
+
+The SGMII core found in several MediaTek SoCs is identical to what can
+also be found in MediaTek's MT7531 Ethernet switch IC.
+As this has not always been clear, both drivers developed different
+implementations to deal with the PCS.
+Recently Alexander Couzens pointed out this fact which lead to the
+development of this shared driver.
+
+Add a dedicated driver, mostly by copying the code now found in the
+Ethernet driver. The now redundant code will be removed by a follow-up
+commit.
+
+Suggested-by: Alexander Couzens <lynxis@fe80.eu>
+Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ MAINTAINERS                       |   8 +
+ drivers/net/pcs/Kconfig           |   7 +
+ drivers/net/pcs/Makefile          |   1 +
+ drivers/net/pcs/pcs-mtk-lynxi.c   | 305 ++++++++++++++++++++++++++++++
+ include/linux/pcs/pcs-mtk-lynxi.h |  13 ++
+ 5 files changed, 334 insertions(+)
+ create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
+ create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -12928,6 +12928,14 @@ L:    netdev@vger.kernel.org
+ S:    Maintained
+ F:    drivers/net/ethernet/mediatek/
++MEDIATEK ETHERNET PCS DRIVER
++M:    Alexander Couzens <lynxis@fe80.eu>
++M:    Daniel Golle <daniel@makrotopia.org>
++L:    netdev@vger.kernel.org
++S:    Maintained
++F:    drivers/net/pcs/pcs-mtk-lynxi.c
++F:    include/linux/pcs/pcs-mtk-lynxi.h
++
+ MEDIATEK I2C CONTROLLER DRIVER
+ M:    Qii Wang <qii.wang@mediatek.com>
+ L:    linux-i2c@vger.kernel.org
+--- a/drivers/net/pcs/Kconfig
++++ b/drivers/net/pcs/Kconfig
+@@ -32,4 +32,11 @@ config PCS_ALTERA_TSE
+         This module provides helper functions for the Altera Triple Speed
+         Ethernet SGMII PCS, that can be found on the Intel Socfpga family.
++config PCS_MTK_LYNXI
++      tristate
++      select REGMAP
++      help
++        This module provides helpers to phylink for managing the LynxI PCS
++        which is part of MediaTek's SoC and Ethernet switch ICs.
++
+ endmenu
+--- a/drivers/net/pcs/Makefile
++++ b/drivers/net/pcs/Makefile
+@@ -7,3 +7,4 @@ obj-$(CONFIG_PCS_XPCS)         += pcs_xpcs.o
+ obj-$(CONFIG_PCS_LYNX)                += pcs-lynx.o
+ obj-$(CONFIG_PCS_RZN1_MIIC)   += pcs-rzn1-miic.o
+ obj-$(CONFIG_PCS_ALTERA_TSE)  += pcs-altera-tse.o
++obj-$(CONFIG_PCS_MTK_LYNXI)   += pcs-mtk-lynxi.o
+--- /dev/null
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -0,0 +1,305 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2018-2019 MediaTek Inc.
++/* A library for MediaTek SGMII circuit
++ *
++ * Author: Sean Wang <sean.wang@mediatek.com>
++ * Author: Alexander Couzens <lynxis@fe80.eu>
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ *
++ */
++
++#include <linux/mdio.h>
++#include <linux/of.h>
++#include <linux/pcs/pcs-mtk-lynxi.h>
++#include <linux/phylink.h>
++#include <linux/regmap.h>
++
++/* SGMII subsystem config registers */
++/* BMCR (low 16) BMSR (high 16) */
++#define SGMSYS_PCS_CONTROL_1          0x0
++#define SGMII_BMCR                    GENMASK(15, 0)
++#define SGMII_BMSR                    GENMASK(31, 16)
++
++#define SGMSYS_PCS_DEVICE_ID          0x4
++#define SGMII_LYNXI_DEV_ID            0x4d544950
++
++#define SGMSYS_PCS_ADVERTISE          0x8
++#define SGMII_ADVERTISE                       GENMASK(15, 0)
++#define SGMII_LPA                     GENMASK(31, 16)
++
++#define SGMSYS_PCS_SCRATCH            0x14
++#define SGMII_DEV_VERSION             GENMASK(31, 16)
++
++/* Register to programmable link timer, the unit in 2 * 8ns */
++#define SGMSYS_PCS_LINK_TIMER         0x18
++#define SGMII_LINK_TIMER_MASK         GENMASK(19, 0)
++#define SGMII_LINK_TIMER_VAL(ns)      FIELD_PREP(SGMII_LINK_TIMER_MASK, \
++                                                 ((ns) / 2 / 8))
++
++/* Register to control remote fault */
++#define SGMSYS_SGMII_MODE             0x20
++#define SGMII_IF_MODE_SGMII           BIT(0)
++#define SGMII_SPEED_DUPLEX_AN         BIT(1)
++#define SGMII_SPEED_MASK              GENMASK(3, 2)
++#define SGMII_SPEED_10                        FIELD_PREP(SGMII_SPEED_MASK, 0)
++#define SGMII_SPEED_100                       FIELD_PREP(SGMII_SPEED_MASK, 1)
++#define SGMII_SPEED_1000              FIELD_PREP(SGMII_SPEED_MASK, 2)
++#define SGMII_DUPLEX_HALF             BIT(4)
++#define SGMII_REMOTE_FAULT_DIS                BIT(8)
++
++/* Register to reset SGMII design */
++#define SGMSYS_RESERVED_0             0x34
++#define SGMII_SW_RESET                        BIT(0)
++
++/* Register to set SGMII speed, ANA RG_ Control Signals III */
++#define SGMII_PHY_SPEED_MASK          GENMASK(3, 2)
++#define SGMII_PHY_SPEED_1_25G         FIELD_PREP(SGMII_PHY_SPEED_MASK, 0)
++#define SGMII_PHY_SPEED_3_125G                FIELD_PREP(SGMII_PHY_SPEED_MASK, 1)
++
++/* Register to power up QPHY */
++#define SGMSYS_QPHY_PWR_STATE_CTRL    0xe8
++#define       SGMII_PHYA_PWD                  BIT(4)
++
++/* Register to QPHY wrapper control */
++#define SGMSYS_QPHY_WRAP_CTRL         0xec
++#define SGMII_PN_SWAP_MASK            GENMASK(1, 0)
++#define SGMII_PN_SWAP_TX_RX           (BIT(0) | BIT(1))
++
++/* struct mtk_pcs_lynxi -  This structure holds each sgmii regmap andassociated
++ *                         data
++ * @regmap:                The register map pointing at the range used to setup
++ *                         SGMII modes
++ * @dev:                   Pointer to device owning the PCS
++ * @ana_rgc3:              The offset of register ANA_RGC3 relative to regmap
++ * @interface:             Currently configured interface mode
++ * @pcs:                   Phylink PCS structure
++ * @flags:                 Flags indicating hardware properties
++ */
++struct mtk_pcs_lynxi {
++      struct regmap           *regmap;
++      u32                     ana_rgc3;
++      phy_interface_t         interface;
++      struct                  phylink_pcs pcs;
++      u32                     flags;
++};
++
++static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
++{
++      return container_of(pcs, struct mtk_pcs_lynxi, pcs);
++}
++
++static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
++                                  struct phylink_link_state *state)
++{
++      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
++      unsigned int bm, adv;
++
++      /* Read the BMSR and LPA */
++      regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
++      regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
++
++      phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
++                                       FIELD_GET(SGMII_LPA, adv));
++}
++
++static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
++                              phy_interface_t interface,
++                              const unsigned long *advertising,
++                              bool permit_pause_to_mac)
++{
++      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
++      bool mode_changed = false, changed, use_an;
++      unsigned int rgc3, sgm_mode, bmcr;
++      int advertise, link_timer;
++
++      advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
++                                                           advertising);
++      if (advertise < 0)
++              return advertise;
++
++      /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
++       * we assume that fixes it's speed at bitrate = line rate (in
++       * other words, 1000Mbps or 2500Mbps).
++       */
++      if (interface == PHY_INTERFACE_MODE_SGMII) {
++              sgm_mode = SGMII_IF_MODE_SGMII;
++              if (phylink_autoneg_inband(mode)) {
++                      sgm_mode |= SGMII_REMOTE_FAULT_DIS |
++                                  SGMII_SPEED_DUPLEX_AN;
++                      use_an = true;
++              } else {
++                      use_an = false;
++              }
++      } else if (phylink_autoneg_inband(mode)) {
++              /* 1000base-X or 2500base-X autoneg */
++              sgm_mode = SGMII_REMOTE_FAULT_DIS;
++              use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                                         advertising);
++      } else {
++              /* 1000base-X or 2500base-X without autoneg */
++              sgm_mode = 0;
++              use_an = false;
++      }
++
++      if (use_an)
++              bmcr = BMCR_ANENABLE;
++      else
++              bmcr = 0;
++
++      if (mpcs->interface != interface) {
++              link_timer = phylink_get_link_timer_ns(interface);
++              if (link_timer < 0)
++                      return link_timer;
++
++              /* PHYA power down */
++              regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
++                              SGMII_PHYA_PWD);
++
++              /* Reset SGMII PCS state */
++              regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
++                              SGMII_SW_RESET);
++
++              if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
++                      regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
++                                         SGMII_PN_SWAP_MASK,
++                                         SGMII_PN_SWAP_TX_RX);
++
++              if (interface == PHY_INTERFACE_MODE_2500BASEX)
++                      rgc3 = SGMII_PHY_SPEED_3_125G;
++              else
++                      rgc3 = SGMII_PHY_SPEED_1_25G;
++
++              /* Configure the underlying interface speed */
++              regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
++                                 SGMII_PHY_SPEED_MASK, rgc3);
++
++              /* Setup the link timer */
++              regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
++                           SGMII_LINK_TIMER_VAL(link_timer));
++
++              mpcs->interface = interface;
++              mode_changed = true;
++      }
++
++      /* Update the advertisement, noting whether it has changed */
++      regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
++                               SGMII_ADVERTISE, advertise, &changed);
++
++      /* Update the sgmsys mode register */
++      regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++                         SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
++                         SGMII_IF_MODE_SGMII, sgm_mode);
++
++      /* Update the BMCR */
++      regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
++                         BMCR_ANENABLE, bmcr);
++
++      /* Release PHYA power down state
++       * Only removing bit SGMII_PHYA_PWD isn't enough.
++       * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
++       * prevents SGMII from working. The SGMII still shows link but no traffic
++       * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
++       * taken from a good working state of the SGMII interface.
++       * Unknown how much the QPHY needs but it is racy without a sleep.
++       * Tested on mt7622 & mt7986.
++       */
++      usleep_range(50, 100);
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
++
++      return changed || mode_changed;
++}
++
++static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs)
++{
++      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
++
++      regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
++}
++
++static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
++                                phy_interface_t interface, int speed,
++                                int duplex)
++{
++      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
++      unsigned int sgm_mode;
++
++      if (!phylink_autoneg_inband(mode)) {
++              /* Force the speed and duplex setting */
++              if (speed == SPEED_10)
++                      sgm_mode = SGMII_SPEED_10;
++              else if (speed == SPEED_100)
++                      sgm_mode = SGMII_SPEED_100;
++              else
++                      sgm_mode = SGMII_SPEED_1000;
++
++              if (duplex != DUPLEX_FULL)
++                      sgm_mode |= SGMII_DUPLEX_HALF;
++
++              regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++                                 SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
++                                 sgm_mode);
++      }
++}
++
++static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
++      .pcs_get_state = mtk_pcs_lynxi_get_state,
++      .pcs_config = mtk_pcs_lynxi_config,
++      .pcs_an_restart = mtk_pcs_lynxi_restart_an,
++      .pcs_link_up = mtk_pcs_lynxi_link_up,
++};
++
++struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
++                                       struct regmap *regmap, u32 ana_rgc3,
++                                       u32 flags)
++{
++      struct mtk_pcs_lynxi *mpcs;
++      u32 id, ver;
++      int ret;
++
++      ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id);
++      if (ret < 0)
++              return NULL;
++
++      if (id != SGMII_LYNXI_DEV_ID) {
++              dev_err(dev, "unknown PCS device id %08x\n", id);
++              return NULL;
++      }
++
++      ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver);
++      if (ret < 0)
++              return NULL;
++
++      ver = FIELD_GET(SGMII_DEV_VERSION, ver);
++      if (ver != 0x1) {
++              dev_err(dev, "unknown PCS device version %04x\n", ver);
++              return NULL;
++      }
++
++      dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id,
++              ver);
++
++      mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL);
++      if (!mpcs)
++              return NULL;
++
++      mpcs->ana_rgc3 = ana_rgc3;
++      mpcs->regmap = regmap;
++      mpcs->flags = flags;
++      mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
++      mpcs->pcs.poll = true;
++      mpcs->interface = PHY_INTERFACE_MODE_NA;
++
++      return &mpcs->pcs;
++}
++EXPORT_SYMBOL(mtk_pcs_lynxi_create);
++
++void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs)
++{
++      if (!pcs)
++              return;
++
++      kfree(pcs_to_mtk_pcs_lynxi(pcs));
++}
++EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
++
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/include/linux/pcs/pcs-mtk-lynxi.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __LINUX_PCS_MTK_LYNXI_H
++#define __LINUX_PCS_MTK_LYNXI_H
++
++#include <linux/phylink.h>
++#include <linux/regmap.h>
++
++#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
++struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
++                                       struct regmap *regmap,
++                                       u32 ana_rgc3, u32 flags);
++void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
++#endif
diff --git a/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch b/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch
new file mode 100644 (file)
index 0000000..2886123
--- /dev/null
@@ -0,0 +1,103 @@
+From affa013f494486079c3c5ad2d00cebc41a3d7445 Mon Sep 17 00:00:00 2001
+From: Sean Anderson <sean.anderson@seco.com>
+Date: Mon, 17 Oct 2022 16:22:36 -0400
+Subject: [PATCH 01/21] net: fman: memac: Add serdes support
+
+This adds support for using a serdes which has to be configured. This is
+primarly in preparation for phylink conversion, which will then change the
+serdes mode dynamically.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/freescale/fman/fman_memac.c  | 49 ++++++++++++++++++-
+ 1 file changed, 47 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
++++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
+@@ -13,6 +13,7 @@
+ #include <linux/io.h>
+ #include <linux/phy.h>
+ #include <linux/phy_fixed.h>
++#include <linux/phy/phy.h>
+ #include <linux/of_mdio.h>
+ /* PCS registers */
+@@ -324,6 +325,7 @@ struct fman_mac {
+       void *fm;
+       struct fman_rev_info fm_rev_info;
+       bool basex_if;
++      struct phy *serdes;
+       struct phy_device *pcsphy;
+       bool allmulti_enabled;
+ };
+@@ -1203,17 +1205,56 @@ int memac_initialization(struct mac_devi
+               }
+       }
++      memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
++      err = PTR_ERR(memac->serdes);
++      if (err == -ENODEV || err == -ENOSYS) {
++              dev_dbg(mac_dev->dev, "could not get (optional) serdes\n");
++              memac->serdes = NULL;
++      } else if (IS_ERR(memac->serdes)) {
++              dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
++              goto _return_fm_mac_free;
++      } else {
++              err = phy_init(memac->serdes);
++              if (err) {
++                      dev_err_probe(mac_dev->dev, err,
++                                    "could not initialize serdes\n");
++                      goto _return_fm_mac_free;
++              }
++
++              err = phy_power_on(memac->serdes);
++              if (err) {
++                      dev_err_probe(mac_dev->dev, err,
++                                    "could not power on serdes\n");
++                      goto _return_phy_exit;
++              }
++
++              if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
++                  memac->phy_if == PHY_INTERFACE_MODE_1000BASEX ||
++                  memac->phy_if == PHY_INTERFACE_MODE_2500BASEX ||
++                  memac->phy_if == PHY_INTERFACE_MODE_QSGMII ||
++                  memac->phy_if == PHY_INTERFACE_MODE_XGMII) {
++                      err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
++                                             memac->phy_if);
++                      if (err) {
++                              dev_err_probe(mac_dev->dev, err,
++                                            "could not set serdes mode to %s\n",
++                                            phy_modes(memac->phy_if));
++                              goto _return_phy_power_off;
++                      }
++              }
++      }
++
+       if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
+               struct phy_device *phy;
+               err = of_phy_register_fixed_link(mac_node);
+               if (err)
+-                      goto _return_fm_mac_free;
++                      goto _return_phy_power_off;
+               fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
+               if (!fixed_link) {
+                       err = -ENOMEM;
+-                      goto _return_fm_mac_free;
++                      goto _return_phy_power_off;
+               }
+               mac_dev->phy_node = of_node_get(mac_node);
+@@ -1242,6 +1283,10 @@ int memac_initialization(struct mac_devi
+       goto _return;
++_return_phy_power_off:
++      phy_power_off(memac->serdes);
++_return_phy_exit:
++      phy_exit(memac->serdes);
+ _return_fixed_link_free:
+       kfree(fixed_link);
+ _return_fm_mac_free:
diff --git a/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch b/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch
new file mode 100644 (file)
index 0000000..873debc
--- /dev/null
@@ -0,0 +1,384 @@
+From fe60e7154d3a35af975c5e6570d6ec31aab9a731 Mon Sep 17 00:00:00 2001
+From: Sean Anderson <sean.anderson@seco.com>
+Date: Mon, 17 Oct 2022 16:22:37 -0400
+Subject: [PATCH 02/21] net: fman: memac: Use lynx pcs driver
+
+Although not stated in the datasheet, as far as I can tell PCS for mEMACs
+is a "Lynx." By reusing the existing driver, we can remove the PCS
+management code from the memac driver. This requires calling some PCS
+functions manually which phylink would usually do for us, but we will let
+it do that soon.
+
+One problem is that we don't actually have a PCS for QSGMII. We pretend
+that each mEMAC's MDIO bus has four QSGMII PCSs, but this is not the case.
+Only the "base" mEMAC's MDIO bus has the four QSGMII PCSs. This is not an
+issue yet, because we never get the PCS state. However, it will be once the
+conversion to phylink is complete, since the links will appear to never
+come up. To get around this, we allow specifying multiple PCSs in pcsphy.
+This breaks backwards compatibility with old device trees, but only for
+QSGMII. IMO this is the only reasonable way to figure out what the actual
+QSGMII PCS is.
+
+Additionally, we now also support a separate XFI PCS. This can allow the
+SerDes driver to set different addresses for the SGMII and XFI PCSs so they
+can be accessed at the same time.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/freescale/fman/Kconfig   |   3 +
+ .../net/ethernet/freescale/fman/fman_memac.c  | 258 +++++++-----------
+ 2 files changed, 105 insertions(+), 156 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/fman/Kconfig
++++ b/drivers/net/ethernet/freescale/fman/Kconfig
+@@ -4,6 +4,9 @@ config FSL_FMAN
+       depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
+       select GENERIC_ALLOCATOR
+       select PHYLIB
++      select PHYLINK
++      select PCS
++      select PCS_LYNX
+       select CRC32
+       default n
+       help
+--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
++++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
+@@ -11,43 +11,12 @@
+ #include <linux/slab.h>
+ #include <linux/io.h>
++#include <linux/pcs-lynx.h>
+ #include <linux/phy.h>
+ #include <linux/phy_fixed.h>
+ #include <linux/phy/phy.h>
+ #include <linux/of_mdio.h>
+-/* PCS registers */
+-#define MDIO_SGMII_CR                 0x00
+-#define MDIO_SGMII_DEV_ABIL_SGMII     0x04
+-#define MDIO_SGMII_LINK_TMR_L         0x12
+-#define MDIO_SGMII_LINK_TMR_H         0x13
+-#define MDIO_SGMII_IF_MODE            0x14
+-
+-/* SGMII Control defines */
+-#define SGMII_CR_AN_EN                        0x1000
+-#define SGMII_CR_RESTART_AN           0x0200
+-#define SGMII_CR_FD                   0x0100
+-#define SGMII_CR_SPEED_SEL1_1G                0x0040
+-#define SGMII_CR_DEF_VAL              (SGMII_CR_AN_EN | SGMII_CR_FD | \
+-                                       SGMII_CR_SPEED_SEL1_1G)
+-
+-/* SGMII Device Ability for SGMII defines */
+-#define MDIO_SGMII_DEV_ABIL_SGMII_MODE        0x4001
+-#define MDIO_SGMII_DEV_ABIL_BASEX_MODE        0x01A0
+-
+-/* Link timer define */
+-#define LINK_TMR_L                    0xa120
+-#define LINK_TMR_H                    0x0007
+-#define LINK_TMR_L_BASEX              0xaf08
+-#define LINK_TMR_H_BASEX              0x002f
+-
+-/* SGMII IF Mode defines */
+-#define IF_MODE_USE_SGMII_AN          0x0002
+-#define IF_MODE_SGMII_EN              0x0001
+-#define IF_MODE_SGMII_SPEED_100M      0x0004
+-#define IF_MODE_SGMII_SPEED_1G                0x0008
+-#define IF_MODE_SGMII_DUPLEX_HALF     0x0010
+-
+ /* Num of additional exact match MAC adr regs */
+ #define MEMAC_NUM_OF_PADDRS 7
+@@ -326,7 +295,9 @@ struct fman_mac {
+       struct fman_rev_info fm_rev_info;
+       bool basex_if;
+       struct phy *serdes;
+-      struct phy_device *pcsphy;
++      struct phylink_pcs *sgmii_pcs;
++      struct phylink_pcs *qsgmii_pcs;
++      struct phylink_pcs *xfi_pcs;
+       bool allmulti_enabled;
+ };
+@@ -487,91 +458,22 @@ static u32 get_mac_addr_hash_code(u64 et
+       return xor_val;
+ }
+-static void setup_sgmii_internal_phy(struct fman_mac *memac,
+-                                   struct fixed_phy_status *fixed_link)
+-{
+-      u16 tmp_reg16;
+-
+-      if (WARN_ON(!memac->pcsphy))
+-              return;
+-
+-      /* SGMII mode */
+-      tmp_reg16 = IF_MODE_SGMII_EN;
+-      if (!fixed_link)
+-              /* AN enable */
+-              tmp_reg16 |= IF_MODE_USE_SGMII_AN;
+-      else {
+-              switch (fixed_link->speed) {
+-              case 10:
+-                      /* For 10M: IF_MODE[SPEED_10M] = 0 */
+-              break;
+-              case 100:
+-                      tmp_reg16 |= IF_MODE_SGMII_SPEED_100M;
+-              break;
+-              case 1000:
+-              default:
+-                      tmp_reg16 |= IF_MODE_SGMII_SPEED_1G;
+-              break;
+-              }
+-              if (!fixed_link->duplex)
+-                      tmp_reg16 |= IF_MODE_SGMII_DUPLEX_HALF;
+-      }
+-      phy_write(memac->pcsphy, MDIO_SGMII_IF_MODE, tmp_reg16);
+-
+-      /* Device ability according to SGMII specification */
+-      tmp_reg16 = MDIO_SGMII_DEV_ABIL_SGMII_MODE;
+-      phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16);
+-
+-      /* Adjust link timer for SGMII  -
+-       * According to Cisco SGMII specification the timer should be 1.6 ms.
+-       * The link_timer register is configured in units of the clock.
+-       * - When running as 1G SGMII, Serdes clock is 125 MHz, so
+-       * unit = 1 / (125*10^6 Hz) = 8 ns.
+-       * 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2*10^5 = 0x30d40
+-       * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
+-       * unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
+-       * 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5*10^5 = 0x7a120.
+-       * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
+-       * we always set up here a value of 2.5 SGMII.
+-       */
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H);
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L);
+-
+-      if (!fixed_link)
+-              /* Restart AN */
+-              tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN;
++static void setup_sgmii_internal(struct fman_mac *memac,
++                               struct phylink_pcs *pcs,
++                               struct fixed_phy_status *fixed_link)
++{
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
++      phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX :
++                              PHY_INTERFACE_MODE_SGMII;
++      unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND;
++
++      linkmode_set_pause(advertising, true, true);
++      pcs->ops->pcs_config(pcs, mode, iface, advertising, true);
++      if (fixed_link)
++              pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed,
++                                    fixed_link->duplex);
+       else
+-              /* AN disabled */
+-              tmp_reg16 = SGMII_CR_DEF_VAL & ~SGMII_CR_AN_EN;
+-      phy_write(memac->pcsphy, 0x0, tmp_reg16);
+-}
+-
+-static void setup_sgmii_internal_phy_base_x(struct fman_mac *memac)
+-{
+-      u16 tmp_reg16;
+-
+-      /* AN Device capability  */
+-      tmp_reg16 = MDIO_SGMII_DEV_ABIL_BASEX_MODE;
+-      phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16);
+-
+-      /* Adjust link timer for SGMII  -
+-       * For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
+-       * The link_timer register is configured in units of the clock.
+-       * - When running as 1G SGMII, Serdes clock is 125 MHz, so
+-       * unit = 1 / (125*10^6 Hz) = 8 ns.
+-       * 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
+-       * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
+-       * unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
+-       * 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
+-       * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
+-       * we always set up here a value of 2.5 SGMII.
+-       */
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H_BASEX);
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L_BASEX);
+-
+-      /* Restart AN */
+-      tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN;
+-      phy_write(memac->pcsphy, 0x0, tmp_reg16);
++              pcs->ops->pcs_an_restart(pcs);
+ }
+ static int check_init_parameters(struct fman_mac *memac)
+@@ -983,7 +885,6 @@ static int memac_set_exception(struct fm
+ static int memac_init(struct fman_mac *memac)
+ {
+       struct memac_cfg *memac_drv_param;
+-      u8 i;
+       enet_addr_t eth_addr;
+       bool slow_10g_if = false;
+       struct fixed_phy_status *fixed_link = NULL;
+@@ -1036,32 +937,10 @@ static int memac_init(struct fman_mac *m
+               iowrite32be(reg32, &memac->regs->command_config);
+       }
+-      if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) {
+-              /* Configure internal SGMII PHY */
+-              if (memac->basex_if)
+-                      setup_sgmii_internal_phy_base_x(memac);
+-              else
+-                      setup_sgmii_internal_phy(memac, fixed_link);
+-      } else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
+-              /* Configure 4 internal SGMII PHYs */
+-              for (i = 0; i < 4; i++) {
+-                      u8 qsmgii_phy_addr, phy_addr;
+-                      /* QSGMII PHY address occupies 3 upper bits of 5-bit
+-                       * phy_address; the lower 2 bits are used to extend
+-                       * register address space and access each one of 4
+-                       * ports inside QSGMII.
+-                       */
+-                      phy_addr = memac->pcsphy->mdio.addr;
+-                      qsmgii_phy_addr = (u8)((phy_addr << 2) | i);
+-                      memac->pcsphy->mdio.addr = qsmgii_phy_addr;
+-                      if (memac->basex_if)
+-                              setup_sgmii_internal_phy_base_x(memac);
+-                      else
+-                              setup_sgmii_internal_phy(memac, fixed_link);
+-
+-                      memac->pcsphy->mdio.addr = phy_addr;
+-              }
+-      }
++      if (memac->phy_if == PHY_INTERFACE_MODE_SGMII)
++              setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link);
++      else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII)
++              setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link);
+       /* Max Frame Length */
+       err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
+@@ -1097,12 +976,25 @@ static int memac_init(struct fman_mac *m
+       return 0;
+ }
++static void pcs_put(struct phylink_pcs *pcs)
++{
++      struct mdio_device *mdiodev;
++
++      if (IS_ERR_OR_NULL(pcs))
++              return;
++
++      mdiodev = lynx_get_mdio_device(pcs);
++      lynx_pcs_destroy(pcs);
++      mdio_device_free(mdiodev);
++}
++
+ static int memac_free(struct fman_mac *memac)
+ {
+       free_init_resources(memac);
+-      if (memac->pcsphy)
+-              put_device(&memac->pcsphy->mdio.dev);
++      pcs_put(memac->sgmii_pcs);
++      pcs_put(memac->qsgmii_pcs);
++      pcs_put(memac->xfi_pcs);
+       kfree(memac->memac_drv_param);
+       kfree(memac);
+@@ -1153,12 +1045,31 @@ static struct fman_mac *memac_config(str
+       return memac;
+ }
++static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node,
++                                          int index)
++{
++      struct device_node *node;
++      struct mdio_device *mdiodev = NULL;
++      struct phylink_pcs *pcs;
++
++      node = of_parse_phandle(mac_node, "pcsphy-handle", index);
++      if (node && of_device_is_available(node))
++              mdiodev = of_mdio_find_device(node);
++      of_node_put(node);
++
++      if (!mdiodev)
++              return ERR_PTR(-EPROBE_DEFER);
++
++      pcs = lynx_pcs_create(mdiodev);
++      return pcs;
++}
++
+ int memac_initialization(struct mac_device *mac_dev,
+                        struct device_node *mac_node,
+                        struct fman_mac_params *params)
+ {
+       int                      err;
+-      struct device_node      *phy_node;
++      struct phylink_pcs      *pcs;
+       struct fixed_phy_status *fixed_link;
+       struct fman_mac         *memac;
+@@ -1188,23 +1099,58 @@ int memac_initialization(struct mac_devi
+       memac = mac_dev->fman_mac;
+       memac->memac_drv_param->max_frame_length = fman_get_max_frm();
+       memac->memac_drv_param->reset_on_init = true;
+-      if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
+-          memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
+-              phy_node = of_parse_phandle(mac_node, "pcsphy-handle", 0);
+-              if (!phy_node) {
+-                      pr_err("PCS PHY node is not available\n");
+-                      err = -EINVAL;
++
++      err = of_property_match_string(mac_node, "pcs-handle-names", "xfi");
++      if (err >= 0) {
++              memac->xfi_pcs = memac_pcs_create(mac_node, err);
++              if (IS_ERR(memac->xfi_pcs)) {
++                      err = PTR_ERR(memac->xfi_pcs);
++                      dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n");
+                       goto _return_fm_mac_free;
+               }
++      } else if (err != -EINVAL && err != -ENODATA) {
++              goto _return_fm_mac_free;
++      }
+-              memac->pcsphy = of_phy_find_device(phy_node);
+-              if (!memac->pcsphy) {
+-                      pr_err("of_phy_find_device (PCS PHY) failed\n");
+-                      err = -EINVAL;
++      err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii");
++      if (err >= 0) {
++              memac->qsgmii_pcs = memac_pcs_create(mac_node, err);
++              if (IS_ERR(memac->qsgmii_pcs)) {
++                      err = PTR_ERR(memac->qsgmii_pcs);
++                      dev_err_probe(mac_dev->dev, err,
++                                    "missing qsgmii pcs\n");
+                       goto _return_fm_mac_free;
+               }
++      } else if (err != -EINVAL && err != -ENODATA) {
++              goto _return_fm_mac_free;
++      }
++
++      /* For compatibility, if pcs-handle-names is missing, we assume this
++       * phy is the first one in pcsphy-handle
++       */
++      err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii");
++      if (err == -EINVAL || err == -ENODATA)
++              pcs = memac_pcs_create(mac_node, 0);
++      else if (err < 0)
++              goto _return_fm_mac_free;
++      else
++              pcs = memac_pcs_create(mac_node, err);
++
++      if (!pcs) {
++              dev_err(mac_dev->dev, "missing pcs\n");
++              err = -ENOENT;
++              goto _return_fm_mac_free;
+       }
++      /* If err is set here, it means that pcs-handle-names was missing above
++       * (and therefore that xfi_pcs cannot be set). If we are defaulting to
++       * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII.
++       */
++      if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
++              memac->xfi_pcs = pcs;
++      else
++              memac->sgmii_pcs = pcs;
++
+       memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
+       err = PTR_ERR(memac->serdes);
+       if (err == -ENODEV || err == -ENOSYS) {
diff --git a/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch b/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch
new file mode 100644 (file)
index 0000000..63b651b
--- /dev/null
@@ -0,0 +1,2451 @@
+From 38e50fc3d43882a43115b4f1ca3eb88255163c5b Mon Sep 17 00:00:00 2001
+From: Sean Anderson <sean.anderson@seco.com>
+Date: Mon, 17 Oct 2022 16:22:38 -0400
+Subject: [PATCH 03/21] net: dpaa: Convert to phylink
+
+This converts DPAA to phylink. All macs are converted. This should work
+with no device tree modifications (including those made in this series),
+except for QSGMII (as noted previously).
+
+The mEMAC configuration is one of the tricker areas. I have tried to
+capture all the restrictions across the various models. Most of the time,
+we assume that if the serdes supports a mode or the phy-interface-mode
+specifies it, then we support it. The only place we can't do this is
+(RG)MII, since there's no serdes. In that case, we rely on a (new)
+devicetree property. There are also several cases where half-duplex is
+broken. Unfortunately, only a single compatible is used for the MAC, so we
+have to use the board compatible instead.
+
+The 10GEC conversion is very straightforward, since it only supports XAUI.
+There is generally nothing to configure.
+
+The dTSEC conversion is broadly similar to mEMAC, but is simpler because we
+don't support configuring the SerDes (though this can be easily added) and
+we don't have multiple PCSs. From what I can tell, there's nothing
+different in the driver or documentation between SGMII and 1000BASE-X
+except for the advertising. Similarly, I couldn't find anything about
+2500BASE-X. In both cases, I treat them like SGMII. These modes aren't used
+by any in-tree boards. Similarly, despite being mentioned in the driver, I
+couldn't find any documented SoCs which supported QSGMII.  I have left it
+unimplemented for now.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/freescale/dpaa/Kconfig   |   4 +-
+ .../net/ethernet/freescale/dpaa/dpaa_eth.c    |  89 +--
+ .../ethernet/freescale/dpaa/dpaa_ethtool.c    |  90 +--
+ drivers/net/ethernet/freescale/fman/Kconfig   |   1 -
+ .../net/ethernet/freescale/fman/fman_dtsec.c  | 458 +++++++--------
+ .../net/ethernet/freescale/fman/fman_mac.h    |  10 -
+ .../net/ethernet/freescale/fman/fman_memac.c  | 547 +++++++++---------
+ .../net/ethernet/freescale/fman/fman_tgec.c   | 131 ++---
+ drivers/net/ethernet/freescale/fman/mac.c     | 168 +-----
+ drivers/net/ethernet/freescale/fman/mac.h     |  23 +-
+ 10 files changed, 612 insertions(+), 909 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/dpaa/Kconfig
++++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
+@@ -2,8 +2,8 @@
+ menuconfig FSL_DPAA_ETH
+       tristate "DPAA Ethernet"
+       depends on FSL_DPAA && FSL_FMAN
+-      select PHYLIB
+-      select FIXED_PHY
++      select PHYLINK
++      select PCS_LYNX
+       help
+         Data Path Acceleration Architecture Ethernet driver,
+         supporting the Freescale QorIQ chips.
+--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+@@ -264,8 +264,19 @@ static int dpaa_netdev_init(struct net_d
+       net_dev->needed_headroom = priv->tx_headroom;
+       net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
+-      mac_dev->net_dev = net_dev;
++      /* The rest of the config is filled in by the mac device already */
++      mac_dev->phylink_config.dev = &net_dev->dev;
++      mac_dev->phylink_config.type = PHYLINK_NETDEV;
+       mac_dev->update_speed = dpaa_eth_cgr_set_speed;
++      mac_dev->phylink = phylink_create(&mac_dev->phylink_config,
++                                        dev_fwnode(mac_dev->dev),
++                                        mac_dev->phy_if,
++                                        mac_dev->phylink_ops);
++      if (IS_ERR(mac_dev->phylink)) {
++              err = PTR_ERR(mac_dev->phylink);
++              dev_err_probe(dev, err, "Could not create phylink\n");
++              return err;
++      }
+       /* start without the RUNNING flag, phylib controls it later */
+       netif_carrier_off(net_dev);
+@@ -273,6 +284,7 @@ static int dpaa_netdev_init(struct net_d
+       err = register_netdev(net_dev);
+       if (err < 0) {
+               dev_err(dev, "register_netdev() = %d\n", err);
++              phylink_destroy(mac_dev->phylink);
+               return err;
+       }
+@@ -295,8 +307,7 @@ static int dpaa_stop(struct net_device *
+        */
+       msleep(200);
+-      if (mac_dev->phy_dev)
+-              phy_stop(mac_dev->phy_dev);
++      phylink_stop(mac_dev->phylink);
+       mac_dev->disable(mac_dev->fman_mac);
+       for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
+@@ -305,8 +316,7 @@ static int dpaa_stop(struct net_device *
+                       err = error;
+       }
+-      if (net_dev->phydev)
+-              phy_disconnect(net_dev->phydev);
++      phylink_disconnect_phy(mac_dev->phylink);
+       net_dev->phydev = NULL;
+       msleep(200);
+@@ -834,10 +844,10 @@ static int dpaa_eth_cgr_init(struct dpaa
+       /* Set different thresholds based on the configured MAC speed.
+        * This may turn suboptimal if the MAC is reconfigured at another
+-       * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
++       * speed, so MACs must call dpaa_eth_cgr_set_speed in their link_up
+        * callback.
+        */
+-      if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
++      if (priv->mac_dev->phylink_config.mac_capabilities & MAC_10000FD)
+               cs_th = DPAA_CS_THRESHOLD_10G;
+       else
+               cs_th = DPAA_CS_THRESHOLD_1G;
+@@ -866,7 +876,7 @@ out_error:
+ static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
+ {
+-      struct net_device *net_dev = mac_dev->net_dev;
++      struct net_device *net_dev = to_net_dev(mac_dev->phylink_config.dev);
+       struct dpaa_priv *priv = netdev_priv(net_dev);
+       struct qm_mcc_initcgr opts = { };
+       u32 cs_th;
+@@ -2905,58 +2915,6 @@ static void dpaa_eth_napi_disable(struct
+       }
+ }
+-static void dpaa_adjust_link(struct net_device *net_dev)
+-{
+-      struct mac_device *mac_dev;
+-      struct dpaa_priv *priv;
+-
+-      priv = netdev_priv(net_dev);
+-      mac_dev = priv->mac_dev;
+-      mac_dev->adjust_link(mac_dev);
+-}
+-
+-/* The Aquantia PHYs are capable of performing rate adaptation */
+-#define PHY_VEND_AQUANTIA     0x03a1b400
+-#define PHY_VEND_AQUANTIA2    0x31c31c00
+-
+-static int dpaa_phy_init(struct net_device *net_dev)
+-{
+-      __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+-      struct mac_device *mac_dev;
+-      struct phy_device *phy_dev;
+-      struct dpaa_priv *priv;
+-      u32 phy_vendor;
+-
+-      priv = netdev_priv(net_dev);
+-      mac_dev = priv->mac_dev;
+-
+-      phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
+-                               &dpaa_adjust_link, 0,
+-                               mac_dev->phy_if);
+-      if (!phy_dev) {
+-              netif_err(priv, ifup, net_dev, "init_phy() failed\n");
+-              return -ENODEV;
+-      }
+-
+-      phy_vendor = phy_dev->drv->phy_id & GENMASK(31, 10);
+-      /* Unless the PHY is capable of rate adaptation */
+-      if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII ||
+-          (phy_vendor != PHY_VEND_AQUANTIA &&
+-           phy_vendor != PHY_VEND_AQUANTIA2)) {
+-              /* remove any features not supported by the controller */
+-              ethtool_convert_legacy_u32_to_link_mode(mask,
+-                                                      mac_dev->if_support);
+-              linkmode_and(phy_dev->supported, phy_dev->supported, mask);
+-      }
+-
+-      phy_support_asym_pause(phy_dev);
+-
+-      mac_dev->phy_dev = phy_dev;
+-      net_dev->phydev = phy_dev;
+-
+-      return 0;
+-}
+-
+ static int dpaa_open(struct net_device *net_dev)
+ {
+       struct mac_device *mac_dev;
+@@ -2967,7 +2925,8 @@ static int dpaa_open(struct net_device *
+       mac_dev = priv->mac_dev;
+       dpaa_eth_napi_enable(priv);
+-      err = dpaa_phy_init(net_dev);
++      err = phylink_of_phy_connect(mac_dev->phylink,
++                                   mac_dev->dev->of_node, 0);
+       if (err)
+               goto phy_init_failed;
+@@ -2982,7 +2941,7 @@ static int dpaa_open(struct net_device *
+               netif_err(priv, ifup, net_dev, "mac_dev->enable() = %d\n", err);
+               goto mac_start_failed;
+       }
+-      phy_start(priv->mac_dev->phy_dev);
++      phylink_start(mac_dev->phylink);
+       netif_tx_start_all_queues(net_dev);
+@@ -2991,6 +2950,7 @@ static int dpaa_open(struct net_device *
+ mac_start_failed:
+       for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++)
+               fman_port_disable(mac_dev->port[i]);
++      phylink_disconnect_phy(mac_dev->phylink);
+ phy_init_failed:
+       dpaa_eth_napi_disable(priv);
+@@ -3146,10 +3106,12 @@ static int dpaa_ts_ioctl(struct net_devi
+ static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
+ {
+       int ret = -EINVAL;
++      struct dpaa_priv *priv = netdev_priv(net_dev);
+       if (cmd == SIOCGMIIREG) {
+               if (net_dev->phydev)
+-                      return phy_mii_ioctl(net_dev->phydev, rq, cmd);
++                      return phylink_mii_ioctl(priv->mac_dev->phylink, rq,
++                                               cmd);
+       }
+       if (cmd == SIOCSHWTSTAMP)
+@@ -3552,6 +3514,7 @@ static int dpaa_remove(struct platform_d
+       dev_set_drvdata(dev, NULL);
+       unregister_netdev(net_dev);
++      phylink_destroy(priv->mac_dev->phylink);
+       err = dpaa_fq_free(dev, &priv->dpaa_fq_list);
+--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+@@ -54,27 +54,19 @@ static char dpaa_stats_global[][ETH_GSTR
+ static int dpaa_get_link_ksettings(struct net_device *net_dev,
+                                  struct ethtool_link_ksettings *cmd)
+ {
+-      if (!net_dev->phydev)
+-              return 0;
++      struct dpaa_priv *priv = netdev_priv(net_dev);
++      struct mac_device *mac_dev = priv->mac_dev;
+-      phy_ethtool_ksettings_get(net_dev->phydev, cmd);
+-
+-      return 0;
++      return phylink_ethtool_ksettings_get(mac_dev->phylink, cmd);
+ }
+ static int dpaa_set_link_ksettings(struct net_device *net_dev,
+                                  const struct ethtool_link_ksettings *cmd)
+ {
+-      int err;
+-
+-      if (!net_dev->phydev)
+-              return -ENODEV;
++      struct dpaa_priv *priv = netdev_priv(net_dev);
++      struct mac_device *mac_dev = priv->mac_dev;
+-      err = phy_ethtool_ksettings_set(net_dev->phydev, cmd);
+-      if (err < 0)
+-              netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", err);
+-
+-      return err;
++      return phylink_ethtool_ksettings_set(mac_dev->phylink, cmd);
+ }
+ static void dpaa_get_drvinfo(struct net_device *net_dev,
+@@ -99,80 +91,28 @@ static void dpaa_set_msglevel(struct net
+ static int dpaa_nway_reset(struct net_device *net_dev)
+ {
+-      int err;
+-
+-      if (!net_dev->phydev)
+-              return -ENODEV;
++      struct dpaa_priv *priv = netdev_priv(net_dev);
++      struct mac_device *mac_dev = priv->mac_dev;
+-      err = 0;
+-      if (net_dev->phydev->autoneg) {
+-              err = phy_start_aneg(net_dev->phydev);
+-              if (err < 0)
+-                      netdev_err(net_dev, "phy_start_aneg() = %d\n",
+-                                 err);
+-      }
+-
+-      return err;
++      return phylink_ethtool_nway_reset(mac_dev->phylink);
+ }
+ static void dpaa_get_pauseparam(struct net_device *net_dev,
+                               struct ethtool_pauseparam *epause)
+ {
+-      struct mac_device *mac_dev;
+-      struct dpaa_priv *priv;
+-
+-      priv = netdev_priv(net_dev);
+-      mac_dev = priv->mac_dev;
+-
+-      if (!net_dev->phydev)
+-              return;
++      struct dpaa_priv *priv = netdev_priv(net_dev);
++      struct mac_device *mac_dev = priv->mac_dev;
+-      epause->autoneg = mac_dev->autoneg_pause;
+-      epause->rx_pause = mac_dev->rx_pause_active;
+-      epause->tx_pause = mac_dev->tx_pause_active;
++      phylink_ethtool_get_pauseparam(mac_dev->phylink, epause);
+ }
+ static int dpaa_set_pauseparam(struct net_device *net_dev,
+                              struct ethtool_pauseparam *epause)
+ {
+-      struct mac_device *mac_dev;
+-      struct phy_device *phydev;
+-      bool rx_pause, tx_pause;
+-      struct dpaa_priv *priv;
+-      int err;
+-
+-      priv = netdev_priv(net_dev);
+-      mac_dev = priv->mac_dev;
+-
+-      phydev = net_dev->phydev;
+-      if (!phydev) {
+-              netdev_err(net_dev, "phy device not initialized\n");
+-              return -ENODEV;
+-      }
+-
+-      if (!phy_validate_pause(phydev, epause))
+-              return -EINVAL;
+-
+-      /* The MAC should know how to handle PAUSE frame autonegotiation before
+-       * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
+-       * settings.
+-       */
+-      mac_dev->autoneg_pause = !!epause->autoneg;
+-      mac_dev->rx_pause_req = !!epause->rx_pause;
+-      mac_dev->tx_pause_req = !!epause->tx_pause;
+-
+-      /* Determine the sym/asym advertised PAUSE capabilities from the desired
+-       * rx/tx pause settings.
+-       */
+-
+-      phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause);
+-
+-      fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
+-      err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
+-      if (err < 0)
+-              netdev_err(net_dev, "set_mac_active_pause() = %d\n", err);
++      struct dpaa_priv *priv = netdev_priv(net_dev);
++      struct mac_device *mac_dev = priv->mac_dev;
+-      return err;
++      return phylink_ethtool_set_pauseparam(mac_dev->phylink, epause);
+ }
+ static int dpaa_get_sset_count(struct net_device *net_dev, int type)
+--- a/drivers/net/ethernet/freescale/fman/Kconfig
++++ b/drivers/net/ethernet/freescale/fman/Kconfig
+@@ -3,7 +3,6 @@ config FSL_FMAN
+       tristate "FMan support"
+       depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
+       select GENERIC_ALLOCATOR
+-      select PHYLIB
+       select PHYLINK
+       select PCS
+       select PCS_LYNX
+--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
++++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+@@ -17,6 +17,7 @@
+ #include <linux/crc32.h>
+ #include <linux/of_mdio.h>
+ #include <linux/mii.h>
++#include <linux/netdevice.h>
+ /* TBI register addresses */
+ #define MII_TBICON            0x11
+@@ -29,9 +30,6 @@
+ #define TBICON_CLK_SELECT     0x0020  /* Clock select */
+ #define TBICON_MI_MODE                0x0010  /* GMII mode (TBI if not set) */
+-#define TBIANA_SGMII          0x4001
+-#define TBIANA_1000X          0x01a0
+-
+ /* Interrupt Mask Register (IMASK) */
+ #define DTSEC_IMASK_BREN      0x80000000
+ #define DTSEC_IMASK_RXCEN     0x40000000
+@@ -92,9 +90,10 @@
+ #define DTSEC_ECNTRL_GMIIM            0x00000040
+ #define DTSEC_ECNTRL_TBIM             0x00000020
+-#define DTSEC_ECNTRL_SGMIIM           0x00000002
+ #define DTSEC_ECNTRL_RPM              0x00000010
+ #define DTSEC_ECNTRL_R100M            0x00000008
++#define DTSEC_ECNTRL_RMM              0x00000004
++#define DTSEC_ECNTRL_SGMIIM           0x00000002
+ #define DTSEC_ECNTRL_QSGMIIM          0x00000001
+ #define TCTRL_TTSE                    0x00000040
+@@ -318,7 +317,8 @@ struct fman_mac {
+       void *fm;
+       struct fman_rev_info fm_rev_info;
+       bool basex_if;
+-      struct phy_device *tbiphy;
++      struct mdio_device *tbidev;
++      struct phylink_pcs pcs;
+ };
+ static void set_dflts(struct dtsec_cfg *cfg)
+@@ -356,56 +356,14 @@ static int init(struct dtsec_regs __iome
+               phy_interface_t iface, u16 iface_speed, u64 addr,
+               u32 exception_mask, u8 tbi_addr)
+ {
+-      bool is_rgmii, is_sgmii, is_qsgmii;
+       enet_addr_t eth_addr;
+-      u32 tmp;
++      u32 tmp = 0;
+       int i;
+       /* Soft reset */
+       iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
+       iowrite32be(0, &regs->maccfg1);
+-      /* dtsec_id2 */
+-      tmp = ioread32be(&regs->tsec_id2);
+-
+-      /* check RGMII support */
+-      if (iface == PHY_INTERFACE_MODE_RGMII ||
+-          iface == PHY_INTERFACE_MODE_RGMII_ID ||
+-          iface == PHY_INTERFACE_MODE_RGMII_RXID ||
+-          iface == PHY_INTERFACE_MODE_RGMII_TXID ||
+-          iface == PHY_INTERFACE_MODE_RMII)
+-              if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
+-                      return -EINVAL;
+-
+-      if (iface == PHY_INTERFACE_MODE_SGMII ||
+-          iface == PHY_INTERFACE_MODE_MII)
+-              if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
+-                      return -EINVAL;
+-
+-      is_rgmii = iface == PHY_INTERFACE_MODE_RGMII ||
+-                 iface == PHY_INTERFACE_MODE_RGMII_ID ||
+-                 iface == PHY_INTERFACE_MODE_RGMII_RXID ||
+-                 iface == PHY_INTERFACE_MODE_RGMII_TXID;
+-      is_sgmii = iface == PHY_INTERFACE_MODE_SGMII;
+-      is_qsgmii = iface == PHY_INTERFACE_MODE_QSGMII;
+-
+-      tmp = 0;
+-      if (is_rgmii || iface == PHY_INTERFACE_MODE_GMII)
+-              tmp |= DTSEC_ECNTRL_GMIIM;
+-      if (is_sgmii)
+-              tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
+-      if (is_qsgmii)
+-              tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
+-                      DTSEC_ECNTRL_QSGMIIM);
+-      if (is_rgmii)
+-              tmp |= DTSEC_ECNTRL_RPM;
+-      if (iface_speed == SPEED_100)
+-              tmp |= DTSEC_ECNTRL_R100M;
+-
+-      iowrite32be(tmp, &regs->ecntrl);
+-
+-      tmp = 0;
+-
+       if (cfg->tx_pause_time)
+               tmp |= cfg->tx_pause_time;
+       if (cfg->tx_pause_time_extd)
+@@ -446,17 +404,10 @@ static int init(struct dtsec_regs __iome
+       tmp = 0;
+-      if (iface_speed < SPEED_1000)
+-              tmp |= MACCFG2_NIBBLE_MODE;
+-      else if (iface_speed == SPEED_1000)
+-              tmp |= MACCFG2_BYTE_MODE;
+-
+       tmp |= (cfg->preamble_len << MACCFG2_PREAMBLE_LENGTH_SHIFT) &
+               MACCFG2_PREAMBLE_LENGTH_MASK;
+       if (cfg->tx_pad_crc)
+               tmp |= MACCFG2_PAD_CRC_EN;
+-      /* Full Duplex */
+-      tmp |= MACCFG2_FULL_DUPLEX;
+       iowrite32be(tmp, &regs->maccfg2);
+       tmp = (((cfg->non_back_to_back_ipg1 <<
+@@ -525,10 +476,6 @@ static void set_bucket(struct dtsec_regs
+ static int check_init_parameters(struct fman_mac *dtsec)
+ {
+-      if (dtsec->max_speed >= SPEED_10000) {
+-              pr_err("1G MAC driver supports 1G or lower speeds\n");
+-              return -EINVAL;
+-      }
+       if ((dtsec->dtsec_drv_param)->rx_prepend >
+           MAX_PACKET_ALIGNMENT) {
+               pr_err("packetAlignmentPadding can't be > than %d\n",
+@@ -630,22 +577,10 @@ static int get_exception_flag(enum fman_
+       return bit_mask;
+ }
+-static bool is_init_done(struct dtsec_cfg *dtsec_drv_params)
+-{
+-      /* Checks if dTSEC driver parameters were initialized */
+-      if (!dtsec_drv_params)
+-              return true;
+-
+-      return false;
+-}
+-
+ static u16 dtsec_get_max_frame_length(struct fman_mac *dtsec)
+ {
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+-      if (is_init_done(dtsec->dtsec_drv_param))
+-              return 0;
+-
+       return (u16)ioread32be(&regs->maxfrm);
+ }
+@@ -682,6 +617,7 @@ static void dtsec_isr(void *handle)
+               dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_COL_RET_LMT);
+       if (event & DTSEC_IMASK_XFUNEN) {
+               /* FM_TX_LOCKUP_ERRATA_DTSEC6 Errata workaround */
++              /* FIXME: This races with the rest of the driver! */
+               if (dtsec->fm_rev_info.major == 2) {
+                       u32 tpkt1, tmp_reg1, tpkt2, tmp_reg2, i;
+                       /* a. Write 0x00E0_0C00 to DTSEC_ID
+@@ -814,6 +750,43 @@ static void free_init_resources(struct f
+       dtsec->unicast_addr_hash = NULL;
+ }
++static struct fman_mac *pcs_to_dtsec(struct phylink_pcs *pcs)
++{
++      return container_of(pcs, struct fman_mac, pcs);
++}
++
++static void dtsec_pcs_get_state(struct phylink_pcs *pcs,
++                              struct phylink_link_state *state)
++{
++      struct fman_mac *dtsec = pcs_to_dtsec(pcs);
++
++      phylink_mii_c22_pcs_get_state(dtsec->tbidev, state);
++}
++
++static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++                          phy_interface_t interface,
++                          const unsigned long *advertising,
++                          bool permit_pause_to_mac)
++{
++      struct fman_mac *dtsec = pcs_to_dtsec(pcs);
++
++      return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface,
++                                        advertising);
++}
++
++static void dtsec_pcs_an_restart(struct phylink_pcs *pcs)
++{
++      struct fman_mac *dtsec = pcs_to_dtsec(pcs);
++
++      phylink_mii_c22_pcs_an_restart(dtsec->tbidev);
++}
++
++static const struct phylink_pcs_ops dtsec_pcs_ops = {
++      .pcs_get_state = dtsec_pcs_get_state,
++      .pcs_config = dtsec_pcs_config,
++      .pcs_an_restart = dtsec_pcs_an_restart,
++};
++
+ static void graceful_start(struct fman_mac *dtsec)
+ {
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+@@ -854,36 +827,11 @@ static void graceful_stop(struct fman_ma
+ static int dtsec_enable(struct fman_mac *dtsec)
+ {
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      /* Enable */
+-      tmp = ioread32be(&regs->maccfg1);
+-      tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN;
+-      iowrite32be(tmp, &regs->maccfg1);
+-
+-      /* Graceful start - clear the graceful Rx/Tx stop bit */
+-      graceful_start(dtsec);
+-
+       return 0;
+ }
+ static void dtsec_disable(struct fman_mac *dtsec)
+ {
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      WARN_ON_ONCE(!is_init_done(dtsec->dtsec_drv_param));
+-
+-      /* Graceful stop - Assert the graceful Rx/Tx stop bit */
+-      graceful_stop(dtsec);
+-
+-      tmp = ioread32be(&regs->maccfg1);
+-      tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
+-      iowrite32be(tmp, &regs->maccfg1);
+ }
+ static int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
+@@ -894,11 +842,6 @@ static int dtsec_set_tx_pause_frames(str
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+       u32 ptv = 0;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      graceful_stop(dtsec);
+-
+       if (pause_time) {
+               /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 Errata workaround */
+               if (dtsec->fm_rev_info.major == 2 && pause_time <= 320) {
+@@ -919,8 +862,6 @@ static int dtsec_set_tx_pause_frames(str
+               iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
+                           &regs->maccfg1);
+-      graceful_start(dtsec);
+-
+       return 0;
+ }
+@@ -929,11 +870,6 @@ static int dtsec_accept_rx_pause_frames(
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+       u32 tmp;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      graceful_stop(dtsec);
+-
+       tmp = ioread32be(&regs->maccfg1);
+       if (en)
+               tmp |= MACCFG1_RX_FLOW;
+@@ -941,17 +877,125 @@ static int dtsec_accept_rx_pause_frames(
+               tmp &= ~MACCFG1_RX_FLOW;
+       iowrite32be(tmp, &regs->maccfg1);
++      return 0;
++}
++
++static struct phylink_pcs *dtsec_select_pcs(struct phylink_config *config,
++                                          phy_interface_t iface)
++{
++      struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac;
++
++      switch (iface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              return &dtsec->pcs;
++      default:
++              return NULL;
++      }
++}
++
++static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
++                           const struct phylink_link_state *state)
++{
++      struct mac_device *mac_dev = fman_config_to_mac(config);
++      struct dtsec_regs __iomem *regs = mac_dev->fman_mac->regs;
++      u32 tmp;
++
++      switch (state->interface) {
++      case PHY_INTERFACE_MODE_RMII:
++              tmp = DTSEC_ECNTRL_RMM;
++              break;
++      case PHY_INTERFACE_MODE_RGMII:
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++              tmp = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              tmp = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
++              break;
++      default:
++              dev_warn(mac_dev->dev, "cannot configure dTSEC for %s\n",
++                       phy_modes(state->interface));
++              return;
++      }
++
++      iowrite32be(tmp, &regs->ecntrl);
++}
++
++static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
++                        unsigned int mode, phy_interface_t interface,
++                        int speed, int duplex, bool tx_pause, bool rx_pause)
++{
++      struct mac_device *mac_dev = fman_config_to_mac(config);
++      struct fman_mac *dtsec = mac_dev->fman_mac;
++      struct dtsec_regs __iomem *regs = dtsec->regs;
++      u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
++                       FSL_FM_PAUSE_TIME_DISABLE;
++      u32 tmp;
++
++      dtsec_set_tx_pause_frames(dtsec, 0, pause_time, 0);
++      dtsec_accept_rx_pause_frames(dtsec, rx_pause);
++
++      tmp = ioread32be(&regs->ecntrl);
++      if (speed == SPEED_100)
++              tmp |= DTSEC_ECNTRL_R100M;
++      else
++              tmp &= ~DTSEC_ECNTRL_R100M;
++      iowrite32be(tmp, &regs->ecntrl);
++
++      tmp = ioread32be(&regs->maccfg2);
++      tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE | MACCFG2_FULL_DUPLEX);
++      if (speed >= SPEED_1000)
++              tmp |= MACCFG2_BYTE_MODE;
++      else
++              tmp |= MACCFG2_NIBBLE_MODE;
++
++      if (duplex == DUPLEX_FULL)
++              tmp |= MACCFG2_FULL_DUPLEX;
++
++      iowrite32be(tmp, &regs->maccfg2);
++
++      mac_dev->update_speed(mac_dev, speed);
++
++      /* Enable */
++      tmp = ioread32be(&regs->maccfg1);
++      tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN;
++      iowrite32be(tmp, &regs->maccfg1);
++
++      /* Graceful start - clear the graceful Rx/Tx stop bit */
+       graceful_start(dtsec);
++}
+-      return 0;
++static void dtsec_link_down(struct phylink_config *config, unsigned int mode,
++                          phy_interface_t interface)
++{
++      struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac;
++      struct dtsec_regs __iomem *regs = dtsec->regs;
++      u32 tmp;
++
++      /* Graceful stop - Assert the graceful Rx/Tx stop bit */
++      graceful_stop(dtsec);
++
++      tmp = ioread32be(&regs->maccfg1);
++      tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
++      iowrite32be(tmp, &regs->maccfg1);
+ }
++static const struct phylink_mac_ops dtsec_mac_ops = {
++      .validate = phylink_generic_validate,
++      .mac_select_pcs = dtsec_select_pcs,
++      .mac_config = dtsec_mac_config,
++      .mac_link_up = dtsec_link_up,
++      .mac_link_down = dtsec_link_down,
++};
++
+ static int dtsec_modify_mac_address(struct fman_mac *dtsec,
+                                   const enet_addr_t *enet_addr)
+ {
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       graceful_stop(dtsec);
+       /* Initialize MAC Station Address registers (1 & 2)
+@@ -975,9 +1019,6 @@ static int dtsec_add_hash_mac_address(st
+       u32 crc = 0xFFFFFFFF;
+       bool mcast, ghtx;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       addr = ENET_ADDR_TO_UINT64(*eth_addr);
+       ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? true : false);
+@@ -1037,9 +1078,6 @@ static int dtsec_set_allmulti(struct fma
+       u32 tmp;
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->rctrl);
+       if (enable)
+               tmp |= RCTRL_MPROM;
+@@ -1056,9 +1094,6 @@ static int dtsec_set_tstamp(struct fman_
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+       u32 rctrl, tctrl;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       rctrl = ioread32be(&regs->rctrl);
+       tctrl = ioread32be(&regs->tctrl);
+@@ -1087,9 +1122,6 @@ static int dtsec_del_hash_mac_address(st
+       u32 crc = 0xFFFFFFFF;
+       bool mcast, ghtx;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       addr = ENET_ADDR_TO_UINT64(*eth_addr);
+       ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? true : false);
+@@ -1153,9 +1185,6 @@ static int dtsec_set_promiscuous(struct
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+       u32 tmp;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       /* Set unicast promiscuous */
+       tmp = ioread32be(&regs->rctrl);
+       if (new_val)
+@@ -1177,90 +1206,12 @@ static int dtsec_set_promiscuous(struct
+       return 0;
+ }
+-static int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      graceful_stop(dtsec);
+-
+-      tmp = ioread32be(&regs->maccfg2);
+-
+-      /* Full Duplex */
+-      tmp |= MACCFG2_FULL_DUPLEX;
+-
+-      tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
+-      if (speed < SPEED_1000)
+-              tmp |= MACCFG2_NIBBLE_MODE;
+-      else if (speed == SPEED_1000)
+-              tmp |= MACCFG2_BYTE_MODE;
+-      iowrite32be(tmp, &regs->maccfg2);
+-
+-      tmp = ioread32be(&regs->ecntrl);
+-      if (speed == SPEED_100)
+-              tmp |= DTSEC_ECNTRL_R100M;
+-      else
+-              tmp &= ~DTSEC_ECNTRL_R100M;
+-      iowrite32be(tmp, &regs->ecntrl);
+-
+-      graceful_start(dtsec);
+-
+-      return 0;
+-}
+-
+-static int dtsec_restart_autoneg(struct fman_mac *dtsec)
+-{
+-      u16 tmp_reg16;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      tmp_reg16 = phy_read(dtsec->tbiphy, MII_BMCR);
+-
+-      tmp_reg16 &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
+-      tmp_reg16 |= (BMCR_ANENABLE | BMCR_ANRESTART |
+-                    BMCR_FULLDPLX | BMCR_SPEED1000);
+-
+-      phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
+-
+-      return 0;
+-}
+-
+-static void adjust_link_dtsec(struct mac_device *mac_dev)
+-{
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      struct fman_mac *fman_mac;
+-      bool rx_pause, tx_pause;
+-      int err;
+-
+-      fman_mac = mac_dev->fman_mac;
+-      if (!phy_dev->link) {
+-              dtsec_restart_autoneg(fman_mac);
+-
+-              return;
+-      }
+-
+-      dtsec_adjust_link(fman_mac, phy_dev->speed);
+-      mac_dev->update_speed(mac_dev, phy_dev->speed);
+-      fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
+-      err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
+-      if (err < 0)
+-              dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
+-                      err);
+-}
+-
+ static int dtsec_set_exception(struct fman_mac *dtsec,
+                              enum fman_mac_exceptions exception, bool enable)
+ {
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+       u32 bit_mask = 0;
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       if (exception != FM_MAC_EX_1G_1588_TS_RX_ERR) {
+               bit_mask = get_exception_flag(exception);
+               if (bit_mask) {
+@@ -1310,12 +1261,9 @@ static int dtsec_init(struct fman_mac *d
+ {
+       struct dtsec_regs __iomem *regs = dtsec->regs;
+       struct dtsec_cfg *dtsec_drv_param;
+-      u16 max_frm_ln;
++      u16 max_frm_ln, tbicon;
+       int err;
+-      if (is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+       if (DEFAULT_RESET_ON_INIT &&
+           (fman_reset_mac(dtsec->fm, dtsec->mac_id) != 0)) {
+               pr_err("Can't reset MAC!\n");
+@@ -1330,38 +1278,19 @@ static int dtsec_init(struct fman_mac *d
+       err = init(dtsec->regs, dtsec_drv_param, dtsec->phy_if,
+                  dtsec->max_speed, dtsec->addr, dtsec->exceptions,
+-                 dtsec->tbiphy->mdio.addr);
++                 dtsec->tbidev->addr);
+       if (err) {
+               free_init_resources(dtsec);
+               pr_err("DTSEC version doesn't support this i/f mode\n");
+               return err;
+       }
+-      if (dtsec->phy_if == PHY_INTERFACE_MODE_SGMII) {
+-              u16 tmp_reg16;
+-
+-              /* Configure the TBI PHY Control Register */
+-              tmp_reg16 = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
+-              phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
+-
+-              tmp_reg16 = TBICON_CLK_SELECT;
+-              phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
+-
+-              tmp_reg16 = (BMCR_RESET | BMCR_ANENABLE |
+-                           BMCR_FULLDPLX | BMCR_SPEED1000);
+-              phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
+-
+-              if (dtsec->basex_if)
+-                      tmp_reg16 = TBIANA_1000X;
+-              else
+-                      tmp_reg16 = TBIANA_SGMII;
+-              phy_write(dtsec->tbiphy, MII_ADVERTISE, tmp_reg16);
++      /* Configure the TBI PHY Control Register */
++      tbicon = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
++      mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon);
+-              tmp_reg16 = (BMCR_ANENABLE | BMCR_ANRESTART |
+-                           BMCR_FULLDPLX | BMCR_SPEED1000);
+-
+-              phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
+-      }
++      tbicon = TBICON_CLK_SELECT;
++      mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon);
+       /* Max Frame Length */
+       max_frm_ln = (u16)ioread32be(&regs->maxfrm);
+@@ -1406,6 +1335,8 @@ static int dtsec_free(struct fman_mac *d
+       kfree(dtsec->dtsec_drv_param);
+       dtsec->dtsec_drv_param = NULL;
++      if (!IS_ERR_OR_NULL(dtsec->tbidev))
++              put_device(&dtsec->tbidev->dev);
+       kfree(dtsec);
+       return 0;
+@@ -1434,7 +1365,6 @@ static struct fman_mac *dtsec_config(str
+       dtsec->regs = mac_dev->vaddr;
+       dtsec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
+-      dtsec->max_speed = params->max_speed;
+       dtsec->phy_if = mac_dev->phy_if;
+       dtsec->mac_id = params->mac_id;
+       dtsec->exceptions = (DTSEC_IMASK_BREN   |
+@@ -1457,7 +1387,6 @@ static struct fman_mac *dtsec_config(str
+       dtsec->en_tsu_err_exception = dtsec->dtsec_drv_param->ptp_exception_en;
+       dtsec->fm = params->fm;
+-      dtsec->basex_if = params->basex_if;
+       /* Save FMan revision */
+       fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
+@@ -1476,18 +1405,18 @@ int dtsec_initialization(struct mac_devi
+       int                     err;
+       struct fman_mac         *dtsec;
+       struct device_node      *phy_node;
++      unsigned long            capabilities;
++      unsigned long           *supported;
++      mac_dev->phylink_ops            = &dtsec_mac_ops;
+       mac_dev->set_promisc            = dtsec_set_promiscuous;
+       mac_dev->change_addr            = dtsec_modify_mac_address;
+       mac_dev->add_hash_mac_addr      = dtsec_add_hash_mac_address;
+       mac_dev->remove_hash_mac_addr   = dtsec_del_hash_mac_address;
+-      mac_dev->set_tx_pause           = dtsec_set_tx_pause_frames;
+-      mac_dev->set_rx_pause           = dtsec_accept_rx_pause_frames;
+       mac_dev->set_exception          = dtsec_set_exception;
+       mac_dev->set_allmulti           = dtsec_set_allmulti;
+       mac_dev->set_tstamp             = dtsec_set_tstamp;
+       mac_dev->set_multi              = fman_set_multi;
+-      mac_dev->adjust_link            = adjust_link_dtsec;
+       mac_dev->enable                 = dtsec_enable;
+       mac_dev->disable                = dtsec_disable;
+@@ -1502,19 +1431,56 @@ int dtsec_initialization(struct mac_devi
+       dtsec->dtsec_drv_param->tx_pad_crc = true;
+       phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
+-      if (!phy_node) {
+-              pr_err("TBI PHY node is not available\n");
++      if (!phy_node || of_device_is_available(phy_node)) {
++              of_node_put(phy_node);
+               err = -EINVAL;
++              dev_err_probe(mac_dev->dev, err,
++                            "TBI PCS node is not available\n");
+               goto _return_fm_mac_free;
+       }
+-      dtsec->tbiphy = of_phy_find_device(phy_node);
+-      if (!dtsec->tbiphy) {
+-              pr_err("of_phy_find_device (TBI PHY) failed\n");
+-              err = -EINVAL;
++      dtsec->tbidev = of_mdio_find_device(phy_node);
++      of_node_put(phy_node);
++      if (!dtsec->tbidev) {
++              err = -EPROBE_DEFER;
++              dev_err_probe(mac_dev->dev, err,
++                            "could not find mdiodev for PCS\n");
+               goto _return_fm_mac_free;
+       }
+-      put_device(&dtsec->tbiphy->mdio.dev);
++      dtsec->pcs.ops = &dtsec_pcs_ops;
++      dtsec->pcs.poll = true;
++
++      supported = mac_dev->phylink_config.supported_interfaces;
++
++      /* FIXME: Can we use DTSEC_ID2_INT_FULL_OFF to determine if these are
++       * supported? If not, we can determine support via the phy if SerDes
++       * support is added.
++       */
++      if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII ||
++          mac_dev->phy_if == PHY_INTERFACE_MODE_1000BASEX) {
++              __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
++              __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
++      } else if (mac_dev->phy_if == PHY_INTERFACE_MODE_2500BASEX) {
++              __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
++      }
++
++      if (!(ioread32be(&dtsec->regs->tsec_id2) & DTSEC_ID2_INT_REDUCED_OFF)) {
++              phy_interface_set_rgmii(supported);
++
++              /* DTSEC_ID2_INT_REDUCED_OFF indicates that the dTSEC supports
++               * RMII and RGMII. However, the only SoCs which support RMII
++               * are the P1017 and P1023. Avoid advertising this mode on
++               * other SoCs. This is a bit of a moot point, since there's no
++               * in-tree support for ethernet on these platforms...
++               */
++              if (of_machine_is_compatible("fsl,P1023") ||
++                  of_machine_is_compatible("fsl,P1023RDB"))
++                      __set_bit(PHY_INTERFACE_MODE_RMII, supported);
++      }
++
++      capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
++      capabilities |= MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
++      mac_dev->phylink_config.mac_capabilities = capabilities;
+       err = dtsec_init(dtsec);
+       if (err < 0)
+--- a/drivers/net/ethernet/freescale/fman/fman_mac.h
++++ b/drivers/net/ethernet/freescale/fman/fman_mac.h
+@@ -170,20 +170,10 @@ struct fman_mac_params {
+        * 0 - FM_MAX_NUM_OF_10G_MACS
+        */
+       u8 mac_id;
+-      /* Note that the speed should indicate the maximum rate that
+-       * this MAC should support rather than the actual speed;
+-       */
+-      u16 max_speed;
+       /* A handle to the FM object this port related to */
+       void *fm;
+       fman_mac_exception_cb *event_cb;    /* MDIO Events Callback Routine */
+       fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
+-      /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
+-       * and phy or backplane; Note: 1000BaseX auto-negotiation relates only
+-       * to interface between MAC and phy/backplane, SGMII phy can still
+-       * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps
+-      */
+-      bool basex_if;
+ };
+ struct eth_hash_t {
+--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
++++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
+@@ -278,9 +278,6 @@ struct fman_mac {
+       struct memac_regs __iomem *regs;
+       /* MAC address of device */
+       u64 addr;
+-      /* Ethernet physical interface */
+-      phy_interface_t phy_if;
+-      u16 max_speed;
+       struct mac_device *dev_id; /* device cookie used by the exception cbs */
+       fman_mac_exception_cb *exception_cb;
+       fman_mac_exception_cb *event_cb;
+@@ -293,12 +290,12 @@ struct fman_mac {
+       struct memac_cfg *memac_drv_param;
+       void *fm;
+       struct fman_rev_info fm_rev_info;
+-      bool basex_if;
+       struct phy *serdes;
+       struct phylink_pcs *sgmii_pcs;
+       struct phylink_pcs *qsgmii_pcs;
+       struct phylink_pcs *xfi_pcs;
+       bool allmulti_enabled;
++      bool rgmii_no_half_duplex;
+ };
+ static void add_addr_in_paddr(struct memac_regs __iomem *regs, const u8 *adr,
+@@ -356,7 +353,6 @@ static void set_exception(struct memac_r
+ }
+ static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg,
+-              phy_interface_t phy_if, u16 speed, bool slow_10g_if,
+               u32 exceptions)
+ {
+       u32 tmp;
+@@ -384,41 +380,6 @@ static int init(struct memac_regs __iome
+       iowrite32be((u32)cfg->pause_quanta, &regs->pause_quanta[0]);
+       iowrite32be((u32)0, &regs->pause_thresh[0]);
+-      /* IF_MODE */
+-      tmp = 0;
+-      switch (phy_if) {
+-      case PHY_INTERFACE_MODE_XGMII:
+-              tmp |= IF_MODE_10G;
+-              break;
+-      case PHY_INTERFACE_MODE_MII:
+-              tmp |= IF_MODE_MII;
+-              break;
+-      default:
+-              tmp |= IF_MODE_GMII;
+-              if (phy_if == PHY_INTERFACE_MODE_RGMII ||
+-                  phy_if == PHY_INTERFACE_MODE_RGMII_ID ||
+-                  phy_if == PHY_INTERFACE_MODE_RGMII_RXID ||
+-                  phy_if == PHY_INTERFACE_MODE_RGMII_TXID)
+-                      tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
+-      }
+-      iowrite32be(tmp, &regs->if_mode);
+-
+-      /* TX_FIFO_SECTIONS */
+-      tmp = 0;
+-      if (phy_if == PHY_INTERFACE_MODE_XGMII) {
+-              if (slow_10g_if) {
+-                      tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
+-                              TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
+-              } else {
+-                      tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
+-                              TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
+-              }
+-      } else {
+-              tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
+-                      TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
+-      }
+-      iowrite32be(tmp, &regs->tx_fifo_sections);
+-
+       /* clear all pending events and set-up interrupts */
+       iowrite32be(0xffffffff, &regs->ievent);
+       set_exception(regs, exceptions, true);
+@@ -458,24 +419,6 @@ static u32 get_mac_addr_hash_code(u64 et
+       return xor_val;
+ }
+-static void setup_sgmii_internal(struct fman_mac *memac,
+-                               struct phylink_pcs *pcs,
+-                               struct fixed_phy_status *fixed_link)
+-{
+-      __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
+-      phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX :
+-                              PHY_INTERFACE_MODE_SGMII;
+-      unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND;
+-
+-      linkmode_set_pause(advertising, true, true);
+-      pcs->ops->pcs_config(pcs, mode, iface, advertising, true);
+-      if (fixed_link)
+-              pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed,
+-                                    fixed_link->duplex);
+-      else
+-              pcs->ops->pcs_an_restart(pcs);
+-}
+-
+ static int check_init_parameters(struct fman_mac *memac)
+ {
+       if (!memac->exception_cb) {
+@@ -581,41 +524,31 @@ static void free_init_resources(struct f
+       memac->unicast_addr_hash = NULL;
+ }
+-static bool is_init_done(struct memac_cfg *memac_drv_params)
+-{
+-      /* Checks if mEMAC driver parameters were initialized */
+-      if (!memac_drv_params)
+-              return true;
+-
+-      return false;
+-}
+-
+ static int memac_enable(struct fman_mac *memac)
+ {
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
++      int ret;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
++      ret = phy_init(memac->serdes);
++      if (ret) {
++              dev_err(memac->dev_id->dev,
++                      "could not initialize serdes: %pe\n", ERR_PTR(ret));
++              return ret;
++      }
+-      tmp = ioread32be(&regs->command_config);
+-      tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
+-      iowrite32be(tmp, &regs->command_config);
++      ret = phy_power_on(memac->serdes);
++      if (ret) {
++              dev_err(memac->dev_id->dev,
++                      "could not power on serdes: %pe\n", ERR_PTR(ret));
++              phy_exit(memac->serdes);
++      }
+-      return 0;
++      return ret;
+ }
+ static void memac_disable(struct fman_mac *memac)
+-
+ {
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      WARN_ON_ONCE(!is_init_done(memac->memac_drv_param));
+-
+-      tmp = ioread32be(&regs->command_config);
+-      tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
+-      iowrite32be(tmp, &regs->command_config);
++      phy_power_off(memac->serdes);
++      phy_exit(memac->serdes);
+ }
+ static int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
+@@ -623,9 +556,6 @@ static int memac_set_promiscuous(struct
+       struct memac_regs __iomem *regs = memac->regs;
+       u32 tmp;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->command_config);
+       if (new_val)
+               tmp |= CMD_CFG_PROMIS_EN;
+@@ -637,73 +567,12 @@ static int memac_set_promiscuous(struct
+       return 0;
+ }
+-static int memac_adjust_link(struct fman_mac *memac, u16 speed)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->if_mode);
+-
+-      /* Set full duplex */
+-      tmp &= ~IF_MODE_HD;
+-
+-      if (phy_interface_mode_is_rgmii(memac->phy_if)) {
+-              /* Configure RGMII in manual mode */
+-              tmp &= ~IF_MODE_RGMII_AUTO;
+-              tmp &= ~IF_MODE_RGMII_SP_MASK;
+-              /* Full duplex */
+-              tmp |= IF_MODE_RGMII_FD;
+-
+-              switch (speed) {
+-              case SPEED_1000:
+-                      tmp |= IF_MODE_RGMII_1000;
+-                      break;
+-              case SPEED_100:
+-                      tmp |= IF_MODE_RGMII_100;
+-                      break;
+-              case SPEED_10:
+-                      tmp |= IF_MODE_RGMII_10;
+-                      break;
+-              default:
+-                      break;
+-              }
+-      }
+-
+-      iowrite32be(tmp, &regs->if_mode);
+-
+-      return 0;
+-}
+-
+-static void adjust_link_memac(struct mac_device *mac_dev)
+-{
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      struct fman_mac *fman_mac;
+-      bool rx_pause, tx_pause;
+-      int err;
+-
+-      fman_mac = mac_dev->fman_mac;
+-      memac_adjust_link(fman_mac, phy_dev->speed);
+-      mac_dev->update_speed(mac_dev, phy_dev->speed);
+-
+-      fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
+-      err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
+-      if (err < 0)
+-              dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
+-                      err);
+-}
+-
+ static int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
+                                    u16 pause_time, u16 thresh_time)
+ {
+       struct memac_regs __iomem *regs = memac->regs;
+       u32 tmp;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->tx_fifo_sections);
+       GET_TX_EMPTY_DEFAULT_VALUE(tmp);
+@@ -738,9 +607,6 @@ static int memac_accept_rx_pause_frames(
+       struct memac_regs __iomem *regs = memac->regs;
+       u32 tmp;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->command_config);
+       if (en)
+               tmp &= ~CMD_CFG_PAUSE_IGNORE;
+@@ -752,12 +618,175 @@ static int memac_accept_rx_pause_frames(
+       return 0;
+ }
++static void memac_validate(struct phylink_config *config,
++                         unsigned long *supported,
++                         struct phylink_link_state *state)
++{
++      struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
++      unsigned long caps = config->mac_capabilities;
++
++      if (phy_interface_mode_is_rgmii(state->interface) &&
++          memac->rgmii_no_half_duplex)
++              caps &= ~(MAC_10HD | MAC_100HD);
++
++      phylink_validate_mask_caps(supported, state, caps);
++}
++
++/**
++ * memac_if_mode() - Convert an interface mode into an IF_MODE config
++ * @interface: A phy interface mode
++ *
++ * Return: A configuration word, suitable for programming into the lower bits
++ *         of %IF_MODE.
++ */
++static u32 memac_if_mode(phy_interface_t interface)
++{
++      switch (interface) {
++      case PHY_INTERFACE_MODE_MII:
++              return IF_MODE_MII;
++      case PHY_INTERFACE_MODE_RGMII:
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++              return IF_MODE_GMII | IF_MODE_RGMII;
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_QSGMII:
++              return IF_MODE_GMII;
++      case PHY_INTERFACE_MODE_10GBASER:
++              return IF_MODE_10G;
++      default:
++              WARN_ON_ONCE(1);
++              return 0;
++      }
++}
++
++static struct phylink_pcs *memac_select_pcs(struct phylink_config *config,
++                                          phy_interface_t iface)
++{
++      struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
++
++      switch (iface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX:
++              return memac->sgmii_pcs;
++      case PHY_INTERFACE_MODE_QSGMII:
++              return memac->qsgmii_pcs;
++      case PHY_INTERFACE_MODE_10GBASER:
++              return memac->xfi_pcs;
++      default:
++              return NULL;
++      }
++}
++
++static int memac_prepare(struct phylink_config *config, unsigned int mode,
++                       phy_interface_t iface)
++{
++      struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
++
++      switch (iface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_QSGMII:
++      case PHY_INTERFACE_MODE_10GBASER:
++              return phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
++                                      iface);
++      default:
++              return 0;
++      }
++}
++
++static void memac_mac_config(struct phylink_config *config, unsigned int mode,
++                           const struct phylink_link_state *state)
++{
++      struct mac_device *mac_dev = fman_config_to_mac(config);
++      struct memac_regs __iomem *regs = mac_dev->fman_mac->regs;
++      u32 tmp = ioread32be(&regs->if_mode);
++
++      tmp &= ~(IF_MODE_MASK | IF_MODE_RGMII);
++      tmp |= memac_if_mode(state->interface);
++      if (phylink_autoneg_inband(mode))
++              tmp |= IF_MODE_RGMII_AUTO;
++      iowrite32be(tmp, &regs->if_mode);
++}
++
++static void memac_link_up(struct phylink_config *config, struct phy_device *phy,
++                        unsigned int mode, phy_interface_t interface,
++                        int speed, int duplex, bool tx_pause, bool rx_pause)
++{
++      struct mac_device *mac_dev = fman_config_to_mac(config);
++      struct fman_mac *memac = mac_dev->fman_mac;
++      struct memac_regs __iomem *regs = memac->regs;
++      u32 tmp = memac_if_mode(interface);
++      u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
++                       FSL_FM_PAUSE_TIME_DISABLE;
++
++      memac_set_tx_pause_frames(memac, 0, pause_time, 0);
++      memac_accept_rx_pause_frames(memac, rx_pause);
++
++      if (duplex == DUPLEX_HALF)
++              tmp |= IF_MODE_HD;
++
++      switch (speed) {
++      case SPEED_1000:
++              tmp |= IF_MODE_RGMII_1000;
++              break;
++      case SPEED_100:
++              tmp |= IF_MODE_RGMII_100;
++              break;
++      case SPEED_10:
++              tmp |= IF_MODE_RGMII_10;
++              break;
++      }
++      iowrite32be(tmp, &regs->if_mode);
++
++      /* TODO: EEE? */
++
++      if (speed == SPEED_10000) {
++              if (memac->fm_rev_info.major == 6 &&
++                  memac->fm_rev_info.minor == 4)
++                      tmp = TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G;
++              else
++                      tmp = TX_FIFO_SECTIONS_TX_AVAIL_10G;
++              tmp |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G;
++      } else {
++              tmp = TX_FIFO_SECTIONS_TX_AVAIL_1G |
++                    TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G;
++      }
++      iowrite32be(tmp, &regs->tx_fifo_sections);
++
++      mac_dev->update_speed(mac_dev, speed);
++
++      tmp = ioread32be(&regs->command_config);
++      tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
++      iowrite32be(tmp, &regs->command_config);
++}
++
++static void memac_link_down(struct phylink_config *config, unsigned int mode,
++                          phy_interface_t interface)
++{
++      struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
++      struct memac_regs __iomem *regs = memac->regs;
++      u32 tmp;
++
++      /* TODO: graceful */
++      tmp = ioread32be(&regs->command_config);
++      tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
++      iowrite32be(tmp, &regs->command_config);
++}
++
++static const struct phylink_mac_ops memac_mac_ops = {
++      .validate = memac_validate,
++      .mac_select_pcs = memac_select_pcs,
++      .mac_prepare = memac_prepare,
++      .mac_config = memac_mac_config,
++      .mac_link_up = memac_link_up,
++      .mac_link_down = memac_link_down,
++};
++
+ static int memac_modify_mac_address(struct fman_mac *memac,
+                                   const enet_addr_t *enet_addr)
+ {
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       add_addr_in_paddr(memac->regs, (const u8 *)(*enet_addr), 0);
+       return 0;
+@@ -771,9 +800,6 @@ static int memac_add_hash_mac_address(st
+       u32 hash;
+       u64 addr;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       addr = ENET_ADDR_TO_UINT64(*eth_addr);
+       if (!(addr & GROUP_ADDRESS)) {
+@@ -802,9 +828,6 @@ static int memac_set_allmulti(struct fma
+       u32 entry;
+       struct memac_regs __iomem *regs = memac->regs;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       if (enable) {
+               for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
+                       iowrite32be(entry | HASH_CTRL_MCAST_EN,
+@@ -834,9 +857,6 @@ static int memac_del_hash_mac_address(st
+       u32 hash;
+       u64 addr;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       addr = ENET_ADDR_TO_UINT64(*eth_addr);
+       hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
+@@ -864,9 +884,6 @@ static int memac_set_exception(struct fm
+ {
+       u32 bit_mask = 0;
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       bit_mask = get_exception_flag(exception);
+       if (bit_mask) {
+               if (enable)
+@@ -886,23 +903,15 @@ static int memac_init(struct fman_mac *m
+ {
+       struct memac_cfg *memac_drv_param;
+       enet_addr_t eth_addr;
+-      bool slow_10g_if = false;
+-      struct fixed_phy_status *fixed_link = NULL;
+       int err;
+       u32 reg32 = 0;
+-      if (is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+       err = check_init_parameters(memac);
+       if (err)
+               return err;
+       memac_drv_param = memac->memac_drv_param;
+-      if (memac->fm_rev_info.major == 6 && memac->fm_rev_info.minor == 4)
+-              slow_10g_if = true;
+-
+       /* First, reset the MAC if desired. */
+       if (memac_drv_param->reset_on_init) {
+               err = reset(memac->regs);
+@@ -918,10 +927,7 @@ static int memac_init(struct fman_mac *m
+               add_addr_in_paddr(memac->regs, (const u8 *)eth_addr, 0);
+       }
+-      fixed_link = memac_drv_param->fixed_link;
+-
+-      init(memac->regs, memac->memac_drv_param, memac->phy_if,
+-           memac->max_speed, slow_10g_if, memac->exceptions);
++      init(memac->regs, memac->memac_drv_param, memac->exceptions);
+       /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround
+        * Exists only in FMan 6.0 and 6.3.
+@@ -937,11 +943,6 @@ static int memac_init(struct fman_mac *m
+               iowrite32be(reg32, &memac->regs->command_config);
+       }
+-      if (memac->phy_if == PHY_INTERFACE_MODE_SGMII)
+-              setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link);
+-      else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII)
+-              setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link);
+-
+       /* Max Frame Length */
+       err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
+                                    memac_drv_param->max_frame_length);
+@@ -970,9 +971,6 @@ static int memac_init(struct fman_mac *m
+       fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
+                          FMAN_INTR_TYPE_NORMAL, memac_exception, memac);
+-      kfree(memac_drv_param);
+-      memac->memac_drv_param = NULL;
+-
+       return 0;
+ }
+@@ -995,7 +993,6 @@ static int memac_free(struct fman_mac *m
+       pcs_put(memac->sgmii_pcs);
+       pcs_put(memac->qsgmii_pcs);
+       pcs_put(memac->xfi_pcs);
+-
+       kfree(memac->memac_drv_param);
+       kfree(memac);
+@@ -1028,8 +1025,6 @@ static struct fman_mac *memac_config(str
+       memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
+       memac->regs = mac_dev->vaddr;
+-      memac->max_speed = params->max_speed;
+-      memac->phy_if = mac_dev->phy_if;
+       memac->mac_id = params->mac_id;
+       memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER |
+                            MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI);
+@@ -1037,7 +1032,6 @@ static struct fman_mac *memac_config(str
+       memac->event_cb = params->event_cb;
+       memac->dev_id = mac_dev;
+       memac->fm = params->fm;
+-      memac->basex_if = params->basex_if;
+       /* Save FMan revision */
+       fman_get_revision(memac->fm, &memac->fm_rev_info);
+@@ -1064,37 +1058,44 @@ static struct phylink_pcs *memac_pcs_cre
+       return pcs;
+ }
++static bool memac_supports(struct mac_device *mac_dev, phy_interface_t iface)
++{
++      /* If there's no serdes device, assume that it's been configured for
++       * whatever the default interface mode is.
++       */
++      if (!mac_dev->fman_mac->serdes)
++              return mac_dev->phy_if == iface;
++      /* Otherwise, ask the serdes */
++      return !phy_validate(mac_dev->fman_mac->serdes, PHY_MODE_ETHERNET,
++                           iface, NULL);
++}
++
+ int memac_initialization(struct mac_device *mac_dev,
+                        struct device_node *mac_node,
+                        struct fman_mac_params *params)
+ {
+       int                      err;
++      struct device_node      *fixed;
+       struct phylink_pcs      *pcs;
+-      struct fixed_phy_status *fixed_link;
+       struct fman_mac         *memac;
++      unsigned long            capabilities;
++      unsigned long           *supported;
++      mac_dev->phylink_ops            = &memac_mac_ops;
+       mac_dev->set_promisc            = memac_set_promiscuous;
+       mac_dev->change_addr            = memac_modify_mac_address;
+       mac_dev->add_hash_mac_addr      = memac_add_hash_mac_address;
+       mac_dev->remove_hash_mac_addr   = memac_del_hash_mac_address;
+-      mac_dev->set_tx_pause           = memac_set_tx_pause_frames;
+-      mac_dev->set_rx_pause           = memac_accept_rx_pause_frames;
+       mac_dev->set_exception          = memac_set_exception;
+       mac_dev->set_allmulti           = memac_set_allmulti;
+       mac_dev->set_tstamp             = memac_set_tstamp;
+       mac_dev->set_multi              = fman_set_multi;
+-      mac_dev->adjust_link            = adjust_link_memac;
+       mac_dev->enable                 = memac_enable;
+       mac_dev->disable                = memac_disable;
+-      if (params->max_speed == SPEED_10000)
+-              mac_dev->phy_if = PHY_INTERFACE_MODE_XGMII;
+-
+       mac_dev->fman_mac = memac_config(mac_dev, params);
+-      if (!mac_dev->fman_mac) {
+-              err = -EINVAL;
+-              goto _return;
+-      }
++      if (!mac_dev->fman_mac)
++              return -EINVAL;
+       memac = mac_dev->fman_mac;
+       memac->memac_drv_param->max_frame_length = fman_get_max_frm();
+@@ -1136,9 +1137,9 @@ int memac_initialization(struct mac_devi
+       else
+               pcs = memac_pcs_create(mac_node, err);
+-      if (!pcs) {
+-              dev_err(mac_dev->dev, "missing pcs\n");
+-              err = -ENOENT;
++      if (IS_ERR(pcs)) {
++              err = PTR_ERR(pcs);
++              dev_err_probe(mac_dev->dev, err, "missing pcs\n");
+               goto _return_fm_mac_free;
+       }
+@@ -1159,84 +1160,100 @@ int memac_initialization(struct mac_devi
+       } else if (IS_ERR(memac->serdes)) {
+               dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
+               goto _return_fm_mac_free;
+-      } else {
+-              err = phy_init(memac->serdes);
+-              if (err) {
+-                      dev_err_probe(mac_dev->dev, err,
+-                                    "could not initialize serdes\n");
+-                      goto _return_fm_mac_free;
+-              }
+-
+-              err = phy_power_on(memac->serdes);
+-              if (err) {
+-                      dev_err_probe(mac_dev->dev, err,
+-                                    "could not power on serdes\n");
+-                      goto _return_phy_exit;
+-              }
+-
+-              if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
+-                  memac->phy_if == PHY_INTERFACE_MODE_1000BASEX ||
+-                  memac->phy_if == PHY_INTERFACE_MODE_2500BASEX ||
+-                  memac->phy_if == PHY_INTERFACE_MODE_QSGMII ||
+-                  memac->phy_if == PHY_INTERFACE_MODE_XGMII) {
+-                      err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
+-                                             memac->phy_if);
+-                      if (err) {
+-                              dev_err_probe(mac_dev->dev, err,
+-                                            "could not set serdes mode to %s\n",
+-                                            phy_modes(memac->phy_if));
+-                              goto _return_phy_power_off;
+-                      }
+-              }
+       }
+-      if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
+-              struct phy_device *phy;
+-
+-              err = of_phy_register_fixed_link(mac_node);
+-              if (err)
+-                      goto _return_phy_power_off;
+-
+-              fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
+-              if (!fixed_link) {
+-                      err = -ENOMEM;
+-                      goto _return_phy_power_off;
+-              }
++      /* The internal connection to the serdes is XGMII, but this isn't
++       * really correct for the phy mode (which is the external connection).
++       * However, this is how all older device trees say that they want
++       * 10GBASE-R (aka XFI), so just convert it for them.
++       */
++      if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
++              mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
+-              mac_dev->phy_node = of_node_get(mac_node);
+-              phy = of_phy_find_device(mac_dev->phy_node);
+-              if (!phy) {
+-                      err = -EINVAL;
+-                      of_node_put(mac_dev->phy_node);
+-                      goto _return_fixed_link_free;
+-              }
++      /* TODO: The following interface modes are supported by (some) hardware
++       * but not by this driver:
++       * - 1000BASE-KX
++       * - 10GBASE-KR
++       * - XAUI/HiGig
++       */
++      supported = mac_dev->phylink_config.supported_interfaces;
+-              fixed_link->link = phy->link;
+-              fixed_link->speed = phy->speed;
+-              fixed_link->duplex = phy->duplex;
+-              fixed_link->pause = phy->pause;
+-              fixed_link->asym_pause = phy->asym_pause;
++      /* Note that half duplex is only supported on 10/100M interfaces. */
+-              put_device(&phy->mdio.dev);
+-              memac->memac_drv_param->fixed_link = fixed_link;
++      if (memac->sgmii_pcs &&
++          (memac_supports(mac_dev, PHY_INTERFACE_MODE_SGMII) ||
++           memac_supports(mac_dev, PHY_INTERFACE_MODE_1000BASEX))) {
++              __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
++              __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
++      }
++
++      if (memac->sgmii_pcs &&
++          memac_supports(mac_dev, PHY_INTERFACE_MODE_2500BASEX))
++              __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
++
++      if (memac->qsgmii_pcs &&
++          memac_supports(mac_dev, PHY_INTERFACE_MODE_QSGMII))
++              __set_bit(PHY_INTERFACE_MODE_QSGMII, supported);
++      else if (mac_dev->phy_if == PHY_INTERFACE_MODE_QSGMII)
++              dev_warn(mac_dev->dev, "no QSGMII pcs specified\n");
++
++      if (memac->xfi_pcs &&
++          memac_supports(mac_dev, PHY_INTERFACE_MODE_10GBASER)) {
++              __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
++      } else {
++              /* From what I can tell, no 10g macs support RGMII. */
++              phy_interface_set_rgmii(supported);
++              __set_bit(PHY_INTERFACE_MODE_MII, supported);
+       }
++      capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 | MAC_100;
++      capabilities |= MAC_1000FD | MAC_2500FD | MAC_10000FD;
++
++      /* These SoCs don't support half duplex at all; there's no different
++       * FMan version or compatible, so we just have to check the machine
++       * compatible instead
++       */
++      if (of_machine_is_compatible("fsl,ls1043a") ||
++          of_machine_is_compatible("fsl,ls1046a") ||
++          of_machine_is_compatible("fsl,B4QDS"))
++              capabilities &= ~(MAC_10HD | MAC_100HD);
++
++      mac_dev->phylink_config.mac_capabilities = capabilities;
++
++      /* The T2080 and T4240 don't support half duplex RGMII. There is no
++       * other way to identify these SoCs, so just use the machine
++       * compatible.
++       */
++      if (of_machine_is_compatible("fsl,T2080QDS") ||
++          of_machine_is_compatible("fsl,T2080RDB") ||
++          of_machine_is_compatible("fsl,T2081QDS") ||
++          of_machine_is_compatible("fsl,T4240QDS") ||
++          of_machine_is_compatible("fsl,T4240RDB"))
++              memac->rgmii_no_half_duplex = true;
++
++      /* Most boards should use MLO_AN_INBAND, but existing boards don't have
++       * a managed property. Default to MLO_AN_INBAND if nothing else is
++       * specified. We need to be careful and not enable this if we have a
++       * fixed link or if we are using MII or RGMII, since those
++       * configurations modes don't use in-band autonegotiation.
++       */
++      fixed = of_get_child_by_name(mac_node, "fixed-link");
++      if (!fixed && !of_property_read_bool(mac_node, "fixed-link") &&
++          !of_property_read_bool(mac_node, "managed") &&
++          mac_dev->phy_if != PHY_INTERFACE_MODE_MII &&
++          !phy_interface_mode_is_rgmii(mac_dev->phy_if))
++              mac_dev->phylink_config.ovr_an_inband = true;
++      of_node_put(fixed);
++
+       err = memac_init(mac_dev->fman_mac);
+       if (err < 0)
+-              goto _return_fixed_link_free;
++              goto _return_fm_mac_free;
+       dev_info(mac_dev->dev, "FMan MEMAC\n");
+-      goto _return;
++      return 0;
+-_return_phy_power_off:
+-      phy_power_off(memac->serdes);
+-_return_phy_exit:
+-      phy_exit(memac->serdes);
+-_return_fixed_link_free:
+-      kfree(fixed_link);
+ _return_fm_mac_free:
+       memac_free(mac_dev->fman_mac);
+-_return:
+       return err;
+ }
+--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
++++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
+@@ -13,6 +13,7 @@
+ #include <linux/bitrev.h>
+ #include <linux/io.h>
+ #include <linux/crc32.h>
++#include <linux/netdevice.h>
+ /* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
+ #define TGEC_TX_IPG_LENGTH_MASK       0x000003ff
+@@ -243,10 +244,6 @@ static int init(struct tgec_regs __iomem
+ static int check_init_parameters(struct fman_mac *tgec)
+ {
+-      if (tgec->max_speed < SPEED_10000) {
+-              pr_err("10G MAC driver only support 10G speed\n");
+-              return -EINVAL;
+-      }
+       if (!tgec->exception_cb) {
+               pr_err("uninitialized exception_cb\n");
+               return -EINVAL;
+@@ -384,40 +381,13 @@ static void free_init_resources(struct f
+       tgec->unicast_addr_hash = NULL;
+ }
+-static bool is_init_done(struct tgec_cfg *cfg)
+-{
+-      /* Checks if tGEC driver parameters were initialized */
+-      if (!cfg)
+-              return true;
+-
+-      return false;
+-}
+-
+ static int tgec_enable(struct fman_mac *tgec)
+ {
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
+-      iowrite32be(tmp, &regs->command_config);
+-
+       return 0;
+ }
+ static void tgec_disable(struct fman_mac *tgec)
+ {
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 tmp;
+-
+-      WARN_ON_ONCE(!is_init_done(tgec->cfg));
+-
+-      tmp = ioread32be(&regs->command_config);
+-      tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
+-      iowrite32be(tmp, &regs->command_config);
+ }
+ static int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
+@@ -425,9 +395,6 @@ static int tgec_set_promiscuous(struct f
+       struct tgec_regs __iomem *regs = tgec->regs;
+       u32 tmp;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->command_config);
+       if (new_val)
+               tmp |= CMD_CFG_PROMIS_EN;
+@@ -444,9 +411,6 @@ static int tgec_set_tx_pause_frames(stru
+ {
+       struct tgec_regs __iomem *regs = tgec->regs;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       iowrite32be((u32)pause_time, &regs->pause_quant);
+       return 0;
+@@ -457,9 +421,6 @@ static int tgec_accept_rx_pause_frames(s
+       struct tgec_regs __iomem *regs = tgec->regs;
+       u32 tmp;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->command_config);
+       if (!en)
+               tmp |= CMD_CFG_PAUSE_IGNORE;
+@@ -470,12 +431,53 @@ static int tgec_accept_rx_pause_frames(s
+       return 0;
+ }
++static void tgec_mac_config(struct phylink_config *config, unsigned int mode,
++                          const struct phylink_link_state *state)
++{
++}
++
++static void tgec_link_up(struct phylink_config *config, struct phy_device *phy,
++                       unsigned int mode, phy_interface_t interface,
++                       int speed, int duplex, bool tx_pause, bool rx_pause)
++{
++      struct mac_device *mac_dev = fman_config_to_mac(config);
++      struct fman_mac *tgec = mac_dev->fman_mac;
++      struct tgec_regs __iomem *regs = tgec->regs;
++      u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
++                       FSL_FM_PAUSE_TIME_DISABLE;
++      u32 tmp;
++
++      tgec_set_tx_pause_frames(tgec, 0, pause_time, 0);
++      tgec_accept_rx_pause_frames(tgec, rx_pause);
++      mac_dev->update_speed(mac_dev, speed);
++
++      tmp = ioread32be(&regs->command_config);
++      tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
++      iowrite32be(tmp, &regs->command_config);
++}
++
++static void tgec_link_down(struct phylink_config *config, unsigned int mode,
++                         phy_interface_t interface)
++{
++      struct fman_mac *tgec = fman_config_to_mac(config)->fman_mac;
++      struct tgec_regs __iomem *regs = tgec->regs;
++      u32 tmp;
++
++      tmp = ioread32be(&regs->command_config);
++      tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
++      iowrite32be(tmp, &regs->command_config);
++}
++
++static const struct phylink_mac_ops tgec_mac_ops = {
++      .validate = phylink_generic_validate,
++      .mac_config = tgec_mac_config,
++      .mac_link_up = tgec_link_up,
++      .mac_link_down = tgec_link_down,
++};
++
+ static int tgec_modify_mac_address(struct fman_mac *tgec,
+                                  const enet_addr_t *p_enet_addr)
+ {
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       tgec->addr = ENET_ADDR_TO_UINT64(*p_enet_addr);
+       set_mac_address(tgec->regs, (const u8 *)(*p_enet_addr));
+@@ -490,9 +492,6 @@ static int tgec_add_hash_mac_address(str
+       u32 crc = 0xFFFFFFFF, hash;
+       u64 addr;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       addr = ENET_ADDR_TO_UINT64(*eth_addr);
+       if (!(addr & GROUP_ADDRESS)) {
+@@ -525,9 +524,6 @@ static int tgec_set_allmulti(struct fman
+       u32 entry;
+       struct tgec_regs __iomem *regs = tgec->regs;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       if (enable) {
+               for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
+                       iowrite32be(entry | TGEC_HASH_MCAST_EN,
+@@ -548,9 +544,6 @@ static int tgec_set_tstamp(struct fman_m
+       struct tgec_regs __iomem *regs = tgec->regs;
+       u32 tmp;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       tmp = ioread32be(&regs->command_config);
+       if (enable)
+@@ -572,9 +565,6 @@ static int tgec_del_hash_mac_address(str
+       u32 crc = 0xFFFFFFFF, hash;
+       u64 addr;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       addr = ((*(u64 *)eth_addr) >> 16);
+       /* CRC calculation */
+@@ -601,22 +591,12 @@ static int tgec_del_hash_mac_address(str
+       return 0;
+ }
+-static void tgec_adjust_link(struct mac_device *mac_dev)
+-{
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-
+-      mac_dev->update_speed(mac_dev, phy_dev->speed);
+-}
+-
+ static int tgec_set_exception(struct fman_mac *tgec,
+                             enum fman_mac_exceptions exception, bool enable)
+ {
+       struct tgec_regs __iomem *regs = tgec->regs;
+       u32 bit_mask = 0;
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       bit_mask = get_exception_flag(exception);
+       if (bit_mask) {
+               if (enable)
+@@ -641,9 +621,6 @@ static int tgec_init(struct fman_mac *tg
+       enet_addr_t eth_addr;
+       int err;
+-      if (is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+       if (DEFAULT_RESET_ON_INIT &&
+           (fman_reset_mac(tgec->fm, tgec->mac_id) != 0)) {
+               pr_err("Can't reset MAC!\n");
+@@ -753,7 +730,6 @@ static struct fman_mac *tgec_config(stru
+       tgec->regs = mac_dev->vaddr;
+       tgec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
+-      tgec->max_speed = params->max_speed;
+       tgec->mac_id = params->mac_id;
+       tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT  |
+                           TGEC_IMASK_REM_FAULT        |
+@@ -788,17 +764,15 @@ int tgec_initialization(struct mac_devic
+       int err;
+       struct fman_mac         *tgec;
++      mac_dev->phylink_ops            = &tgec_mac_ops;
+       mac_dev->set_promisc            = tgec_set_promiscuous;
+       mac_dev->change_addr            = tgec_modify_mac_address;
+       mac_dev->add_hash_mac_addr      = tgec_add_hash_mac_address;
+       mac_dev->remove_hash_mac_addr   = tgec_del_hash_mac_address;
+-      mac_dev->set_tx_pause           = tgec_set_tx_pause_frames;
+-      mac_dev->set_rx_pause           = tgec_accept_rx_pause_frames;
+       mac_dev->set_exception          = tgec_set_exception;
+       mac_dev->set_allmulti           = tgec_set_allmulti;
+       mac_dev->set_tstamp             = tgec_set_tstamp;
+       mac_dev->set_multi              = fman_set_multi;
+-      mac_dev->adjust_link            = tgec_adjust_link;
+       mac_dev->enable                 = tgec_enable;
+       mac_dev->disable                = tgec_disable;
+@@ -808,6 +782,19 @@ int tgec_initialization(struct mac_devic
+               goto _return;
+       }
++      /* The internal connection to the serdes is XGMII, but this isn't
++       * really correct for the phy mode (which is the external connection).
++       * However, this is how all older device trees say that they want
++       * XAUI, so just convert it for them.
++       */
++      if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
++              mac_dev->phy_if = PHY_INTERFACE_MODE_XAUI;
++
++      __set_bit(PHY_INTERFACE_MODE_XAUI,
++                mac_dev->phylink_config.supported_interfaces);
++      mac_dev->phylink_config.mac_capabilities =
++              MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10000FD;
++
+       tgec = mac_dev->fman_mac;
+       tgec->cfg->max_frame_length = fman_get_max_frm();
+       err = tgec_init(tgec);
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ b/drivers/net/ethernet/freescale/fman/mac.c
+@@ -15,6 +15,7 @@
+ #include <linux/phy.h>
+ #include <linux/netdevice.h>
+ #include <linux/phy_fixed.h>
++#include <linux/phylink.h>
+ #include <linux/etherdevice.h>
+ #include <linux/libfdt_env.h>
+@@ -93,130 +94,8 @@ int fman_set_multi(struct net_device *ne
+       return 0;
+ }
+-/**
+- * fman_set_mac_active_pause
+- * @mac_dev:  A pointer to the MAC device
+- * @rx:               Pause frame setting for RX
+- * @tx:               Pause frame setting for TX
+- *
+- * Set the MAC RX/TX PAUSE frames settings
+- *
+- * Avoid redundant calls to FMD, if the MAC driver already contains the desired
+- * active PAUSE settings. Otherwise, the new active settings should be reflected
+- * in FMan.
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
+-{
+-      struct fman_mac *fman_mac = mac_dev->fman_mac;
+-      int err = 0;
+-
+-      if (rx != mac_dev->rx_pause_active) {
+-              err = mac_dev->set_rx_pause(fman_mac, rx);
+-              if (likely(err == 0))
+-                      mac_dev->rx_pause_active = rx;
+-      }
+-
+-      if (tx != mac_dev->tx_pause_active) {
+-              u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE :
+-                                       FSL_FM_PAUSE_TIME_DISABLE);
+-
+-              err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0);
+-
+-              if (likely(err == 0))
+-                      mac_dev->tx_pause_active = tx;
+-      }
+-
+-      return err;
+-}
+-EXPORT_SYMBOL(fman_set_mac_active_pause);
+-
+-/**
+- * fman_get_pause_cfg
+- * @mac_dev:  A pointer to the MAC device
+- * @rx_pause: Return value for RX setting
+- * @tx_pause: Return value for TX setting
+- *
+- * Determine the MAC RX/TX PAUSE frames settings based on PHY
+- * autonegotiation or values set by eththool.
+- *
+- * Return: Pointer to FMan device.
+- */
+-void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
+-                      bool *tx_pause)
+-{
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      u16 lcl_adv, rmt_adv;
+-      u8 flowctrl;
+-
+-      *rx_pause = *tx_pause = false;
+-
+-      if (!phy_dev->duplex)
+-              return;
+-
+-      /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
+-       * are those set by ethtool.
+-       */
+-      if (!mac_dev->autoneg_pause) {
+-              *rx_pause = mac_dev->rx_pause_req;
+-              *tx_pause = mac_dev->tx_pause_req;
+-              return;
+-      }
+-
+-      /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
+-       * settings depend on the result of the link negotiation.
+-       */
+-
+-      /* get local capabilities */
+-      lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising);
+-
+-      /* get link partner capabilities */
+-      rmt_adv = 0;
+-      if (phy_dev->pause)
+-              rmt_adv |= LPA_PAUSE_CAP;
+-      if (phy_dev->asym_pause)
+-              rmt_adv |= LPA_PAUSE_ASYM;
+-
+-      /* Calculate TX/RX settings based on local and peer advertised
+-       * symmetric/asymmetric PAUSE capabilities.
+-       */
+-      flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+-      if (flowctrl & FLOW_CTRL_RX)
+-              *rx_pause = true;
+-      if (flowctrl & FLOW_CTRL_TX)
+-              *tx_pause = true;
+-}
+-EXPORT_SYMBOL(fman_get_pause_cfg);
+-
+-#define DTSEC_SUPPORTED \
+-      (SUPPORTED_10baseT_Half \
+-      | SUPPORTED_10baseT_Full \
+-      | SUPPORTED_100baseT_Half \
+-      | SUPPORTED_100baseT_Full \
+-      | SUPPORTED_Autoneg \
+-      | SUPPORTED_Pause \
+-      | SUPPORTED_Asym_Pause \
+-      | SUPPORTED_FIBRE \
+-      | SUPPORTED_MII)
+-
+ static DEFINE_MUTEX(eth_lock);
+-static const u16 phy2speed[] = {
+-      [PHY_INTERFACE_MODE_MII]                = SPEED_100,
+-      [PHY_INTERFACE_MODE_GMII]               = SPEED_1000,
+-      [PHY_INTERFACE_MODE_SGMII]              = SPEED_1000,
+-      [PHY_INTERFACE_MODE_TBI]                = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RMII]               = SPEED_100,
+-      [PHY_INTERFACE_MODE_RGMII]              = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RGMII_ID]           = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RTBI]               = SPEED_1000,
+-      [PHY_INTERFACE_MODE_QSGMII]             = SPEED_1000,
+-      [PHY_INTERFACE_MODE_XGMII]              = SPEED_10000
+-};
+-
+ static struct platform_device *dpaa_eth_add_device(int fman_id,
+                                                  struct mac_device *mac_dev)
+ {
+@@ -263,8 +142,8 @@ no_mem:
+ }
+ static const struct of_device_id mac_match[] = {
+-      { .compatible   = "fsl,fman-dtsec", .data = dtsec_initialization },
+-      { .compatible   = "fsl,fman-xgec", .data = tgec_initialization },
++      { .compatible   = "fsl,fman-dtsec", .data = dtsec_initialization },
++      { .compatible   = "fsl,fman-xgec", .data = tgec_initialization },
+       { .compatible   = "fsl,fman-memac", .data = memac_initialization },
+       {}
+ };
+@@ -295,6 +174,7 @@ static int mac_probe(struct platform_dev
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
++      platform_set_drvdata(_of_dev, mac_dev);
+       /* Save private information */
+       mac_dev->priv = priv;
+@@ -424,57 +304,21 @@ static int mac_probe(struct platform_dev
+       }
+       mac_dev->phy_if = phy_if;
+-      priv->speed             = phy2speed[mac_dev->phy_if];
+-      params.max_speed        = priv->speed;
+-      mac_dev->if_support     = DTSEC_SUPPORTED;
+-      /* We don't support half-duplex in SGMII mode */
+-      if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
+-              mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
+-                                      SUPPORTED_100baseT_Half);
+-
+-      /* Gigabit support (no half-duplex) */
+-      if (params.max_speed == 1000)
+-              mac_dev->if_support |= SUPPORTED_1000baseT_Full;
+-
+-      /* The 10G interface only supports one mode */
+-      if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
+-              mac_dev->if_support = SUPPORTED_10000baseT_Full;
+-
+-      /* Get the rest of the PHY information */
+-      mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
+-
+-      params.basex_if         = false;
+       params.mac_id           = priv->cell_index;
+       params.fm               = (void *)priv->fman;
+       params.exception_cb     = mac_exception;
+       params.event_cb         = mac_exception;
+       err = init(mac_dev, mac_node, &params);
+-      if (err < 0) {
+-              dev_err(dev, "mac_dev->init() = %d\n", err);
+-              of_node_put(mac_dev->phy_node);
+-              return err;
+-      }
+-
+-      /* pause frame autonegotiation enabled */
+-      mac_dev->autoneg_pause = true;
+-
+-      /* By intializing the values to false, force FMD to enable PAUSE frames
+-       * on RX and TX
+-       */
+-      mac_dev->rx_pause_req = true;
+-      mac_dev->tx_pause_req = true;
+-      mac_dev->rx_pause_active = false;
+-      mac_dev->tx_pause_active = false;
+-      err = fman_set_mac_active_pause(mac_dev, true, true);
+       if (err < 0)
+-              dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
++              return err;
+       if (!is_zero_ether_addr(mac_dev->addr))
+               dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
+       priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
+       if (IS_ERR(priv->eth_dev)) {
++              err = PTR_ERR(priv->eth_dev);
+               dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
+                       priv->cell_index);
+               priv->eth_dev = NULL;
+--- a/drivers/net/ethernet/freescale/fman/mac.h
++++ b/drivers/net/ethernet/freescale/fman/mac.h
+@@ -9,6 +9,7 @@
+ #include <linux/device.h>
+ #include <linux/if_ether.h>
+ #include <linux/phy.h>
++#include <linux/phylink.h>
+ #include <linux/list.h>
+ #include "fman_port.h"
+@@ -24,32 +25,22 @@ struct mac_device {
+       struct resource         *res;
+       u8                       addr[ETH_ALEN];
+       struct fman_port        *port[2];
+-      u32                      if_support;
+-      struct phy_device       *phy_dev;
++      struct phylink          *phylink;
++      struct phylink_config   phylink_config;
+       phy_interface_t         phy_if;
+-      struct device_node      *phy_node;
+-      struct net_device       *net_dev;
+-      bool autoneg_pause;
+-      bool rx_pause_req;
+-      bool tx_pause_req;
+-      bool rx_pause_active;
+-      bool tx_pause_active;
+       bool promisc;
+       bool allmulti;
++      const struct phylink_mac_ops *phylink_ops;
+       int (*enable)(struct fman_mac *mac_dev);
+       void (*disable)(struct fman_mac *mac_dev);
+-      void (*adjust_link)(struct mac_device *mac_dev);
+       int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
+       int (*change_addr)(struct fman_mac *mac_dev, const enet_addr_t *enet_addr);
+       int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
+       int (*set_tstamp)(struct fman_mac *mac_dev, bool enable);
+       int (*set_multi)(struct net_device *net_dev,
+                        struct mac_device *mac_dev);
+-      int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
+-      int (*set_tx_pause)(struct fman_mac *mac_dev, u8 priority,
+-                          u16 pause_time, u16 thresh_time);
+       int (*set_exception)(struct fman_mac *mac_dev,
+                            enum fman_mac_exceptions exception, bool enable);
+       int (*add_hash_mac_addr)(struct fman_mac *mac_dev,
+@@ -63,6 +54,12 @@ struct mac_device {
+       struct mac_priv_s       *priv;
+ };
++static inline struct mac_device
++*fman_config_to_mac(struct phylink_config *config)
++{
++      return container_of(config, struct mac_device, phylink_config);
++}
++
+ struct dpaa_eth_data {
+       struct mac_device *mac_dev;
+       int mac_hw_id;
diff --git a/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch b/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch
new file mode 100644 (file)
index 0000000..06c348b
--- /dev/null
@@ -0,0 +1,93 @@
+From bf4de031052fe7c5309e8956c342d4e5ce79038e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 17 Oct 2022 16:22:35 -0400
+Subject: [PATCH 04/21] net: phylink: provide phylink_validate_mask_caps()
+ helper
+
+Provide a helper that restricts the link modes according to the
+phylink capabilities.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+[rebased on net-next/master and added documentation]
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 41 +++++++++++++++++++++++++++------------
+ include/linux/phylink.h   |  3 +++
+ 2 files changed, 32 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -564,31 +564,48 @@ unsigned long phylink_get_capabilities(p
+ EXPORT_SYMBOL_GPL(phylink_get_capabilities);
+ /**
+- * phylink_generic_validate() - generic validate() callback implementation
+- * @config: a pointer to a &struct phylink_config.
++ * phylink_validate_mask_caps() - Restrict link modes based on caps
+  * @supported: ethtool bitmask for supported link modes.
+- * @state: a pointer to a &struct phylink_link_state.
++ * @state: an (optional) pointer to a &struct phylink_link_state.
++ * @mac_capabilities: bitmask of MAC capabilities
+  *
+- * Generic implementation of the validate() callback that MAC drivers can
+- * use when they pass the range of supported interfaces and MAC capabilities.
+- * This makes use of phylink_get_linkmodes().
++ * Calculate the supported link modes based on @mac_capabilities, and restrict
++ * @supported and @state based on that. Use this function if your capabiliies
++ * aren't constant, such as if they vary depending on the interface.
+  */
+-void phylink_generic_validate(struct phylink_config *config,
+-                            unsigned long *supported,
+-                            struct phylink_link_state *state)
++void phylink_validate_mask_caps(unsigned long *supported,
++                              struct phylink_link_state *state,
++                              unsigned long mac_capabilities)
+ {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+       unsigned long caps;
+       phylink_set_port_modes(mask);
+       phylink_set(mask, Autoneg);
+-      caps = phylink_get_capabilities(state->interface,
+-                                      config->mac_capabilities,
++      caps = phylink_get_capabilities(state->interface, mac_capabilities,
+                                       state->rate_matching);
+       phylink_caps_to_linkmodes(mask, caps);
+       linkmode_and(supported, supported, mask);
+-      linkmode_and(state->advertising, state->advertising, mask);
++      if (state)
++              linkmode_and(state->advertising, state->advertising, mask);
++}
++EXPORT_SYMBOL_GPL(phylink_validate_mask_caps);
++
++/**
++ * phylink_generic_validate() - generic validate() callback implementation
++ * @config: a pointer to a &struct phylink_config.
++ * @supported: ethtool bitmask for supported link modes.
++ * @state: a pointer to a &struct phylink_link_state.
++ *
++ * Generic implementation of the validate() callback that MAC drivers can
++ * use when they pass the range of supported interfaces and MAC capabilities.
++ */
++void phylink_generic_validate(struct phylink_config *config,
++                            unsigned long *supported,
++                            struct phylink_link_state *state)
++{
++      phylink_validate_mask_caps(supported, state, config->mac_capabilities);
+ }
+ EXPORT_SYMBOL_GPL(phylink_generic_validate);
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -558,6 +558,9 @@ void phylink_caps_to_linkmodes(unsigned
+ unsigned long phylink_get_capabilities(phy_interface_t interface,
+                                      unsigned long mac_capabilities,
+                                      int rate_matching);
++void phylink_validate_mask_caps(unsigned long *supported,
++                              struct phylink_link_state *state,
++                              unsigned long caps);
+ void phylink_generic_validate(struct phylink_config *config,
+                             unsigned long *supported,
+                             struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch b/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch
new file mode 100644 (file)
index 0000000..e3a1dda
--- /dev/null
@@ -0,0 +1,39 @@
+From 2bf7e4a68c42eed909f3c29582e1fb85cb157e35 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Tue, 25 Oct 2022 11:51:26 -0700
+Subject: [PATCH 05/21] phylink: require valid state argument to
+ phylink_validate_mask_caps()
+
+state is deferenced earlier in the function, the NULL check
+is pointless. Since we don't have any crash reports presumably
+it's safe to assume state is not NULL.
+
+Fixes: f392a1846489 ("net: phylink: provide phylink_validate_mask_caps() helper")
+Reviewed-by: Sean Anderson <sean.anderson@seco.com>
+Link: https://lore.kernel.org/r/20221025185126.1720553-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -566,7 +566,7 @@ EXPORT_SYMBOL_GPL(phylink_get_capabiliti
+ /**
+  * phylink_validate_mask_caps() - Restrict link modes based on caps
+  * @supported: ethtool bitmask for supported link modes.
+- * @state: an (optional) pointer to a &struct phylink_link_state.
++ * @state: pointer to a &struct phylink_link_state.
+  * @mac_capabilities: bitmask of MAC capabilities
+  *
+  * Calculate the supported link modes based on @mac_capabilities, and restrict
+@@ -587,8 +587,7 @@ void phylink_validate_mask_caps(unsigned
+       phylink_caps_to_linkmodes(mask, caps);
+       linkmode_and(supported, supported, mask);
+-      if (state)
+-              linkmode_and(state->advertising, state->advertising, mask);
++      linkmode_and(state->advertising, state->advertising, mask);
+ }
+ EXPORT_SYMBOL_GPL(phylink_validate_mask_caps);
diff --git a/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch b/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch
new file mode 100644 (file)
index 0000000..c217ed8
--- /dev/null
@@ -0,0 +1,48 @@
+From f8fc363bf0c023e4736a0328174b4a24b44ab23a Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 27 Oct 2022 14:10:37 +0100
+Subject: [PATCH 06/21] net: phylink: add phylink_get_link_timer_ns() helper
+
+Add a helper to convert the PHY interface mode to the required link
+timer setting as stated by the appropriate standard. Inappropriate
+interface modes return an error.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/linux/phylink.h | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -617,6 +617,30 @@ int phylink_speed_up(struct phylink *pl)
+ void phylink_set_port_modes(unsigned long *bits);
++/**
++ * phylink_get_link_timer_ns - return the PCS link timer value
++ * @interface: link &typedef phy_interface_t mode
++ *
++ * Return the PCS link timer setting in nanoseconds for the PHY @interface
++ * mode, or -EINVAL if not appropriate.
++ */
++static inline int phylink_get_link_timer_ns(phy_interface_t interface)
++{
++      switch (interface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_QSGMII:
++      case PHY_INTERFACE_MODE_USXGMII:
++              return 1600000;
++
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              return 10000000;
++
++      default:
++              return -EINVAL;
++      }
++}
++
+ void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
+                                     u16 bmsr, u16 lpa);
+ void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
diff --git a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch b/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch
new file mode 100644 (file)
index 0000000..28154af
--- /dev/null
@@ -0,0 +1,250 @@
+From b45b773a96b0e9e8d51e5d005485f4e376d6ce9a Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 4 Nov 2022 17:13:01 +0000
+Subject: [PATCH 07/21] net: remove explicit phylink_generic_validate()
+ references
+
+Virtually all conventional network drivers are now converted to use
+phylink_generic_validate() - only DSA drivers and fman_memac remain,
+so lets remove the necessity for network drivers to explicitly set
+this member, and default to phylink_generic_validate() when unset.
+This is possible as .validate must currently be set.
+
+Any remaining instances that have not been addressed by this patch can
+be fixed up later.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/E1or0FZ-001tRa-DI@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/altera/altera_tse_main.c            | 1 -
+ drivers/net/ethernet/atheros/ag71xx.c                    | 1 -
+ drivers/net/ethernet/cadence/macb_main.c                 | 1 -
+ drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c         | 1 -
+ drivers/net/ethernet/freescale/enetc/enetc_pf.c          | 1 -
+ drivers/net/ethernet/freescale/fman/fman_dtsec.c         | 1 -
+ drivers/net/ethernet/freescale/fman/fman_tgec.c          | 1 -
+ drivers/net/ethernet/marvell/mvneta.c                    | 1 -
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c          | 1 -
+ drivers/net/ethernet/marvell/prestera/prestera_main.c    | 1 -
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c              | 1 -
+ drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c | 1 -
+ drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c   | 1 -
+ drivers/net/ethernet/mscc/ocelot_net.c                   | 1 -
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c        | 1 -
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c                 | 1 -
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c        | 1 -
+ drivers/net/phy/phylink.c                                | 5 ++++-
+ drivers/net/usb/asix_devices.c                           | 1 -
+ include/linux/phylink.h                                  | 5 +++++
+ 20 files changed, 9 insertions(+), 19 deletions(-)
+
+--- a/drivers/net/ethernet/altera/altera_tse_main.c
++++ b/drivers/net/ethernet/altera/altera_tse_main.c
+@@ -1096,7 +1096,6 @@ static struct phylink_pcs *alt_tse_selec
+ }
+ static const struct phylink_mac_ops alt_tse_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_an_restart = alt_tse_mac_an_restart,
+       .mac_config = alt_tse_mac_config,
+       .mac_link_down = alt_tse_mac_link_down,
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -1086,7 +1086,6 @@ static void ag71xx_mac_link_up(struct ph
+ }
+ static const struct phylink_mac_ops ag71xx_phylink_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_config = ag71xx_mac_config,
+       .mac_link_down = ag71xx_mac_link_down,
+       .mac_link_up = ag71xx_mac_link_up,
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -752,7 +752,6 @@ static struct phylink_pcs *macb_mac_sele
+ }
+ static const struct phylink_mac_ops macb_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = macb_mac_select_pcs,
+       .mac_config = macb_mac_config,
+       .mac_link_down = macb_mac_link_down,
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+@@ -235,7 +235,6 @@ static void dpaa2_mac_link_down(struct p
+ }
+ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = dpaa2_mac_select_pcs,
+       .mac_config = dpaa2_mac_config,
+       .mac_link_up = dpaa2_mac_link_up,
+--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+@@ -1111,7 +1111,6 @@ static void enetc_pl_mac_link_down(struc
+ }
+ static const struct phylink_mac_ops enetc_mac_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = enetc_pl_mac_select_pcs,
+       .mac_config = enetc_pl_mac_config,
+       .mac_link_up = enetc_pl_mac_link_up,
+--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
++++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+@@ -986,7 +986,6 @@ static void dtsec_link_down(struct phyli
+ }
+ static const struct phylink_mac_ops dtsec_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = dtsec_select_pcs,
+       .mac_config = dtsec_mac_config,
+       .mac_link_up = dtsec_link_up,
+--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
++++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
+@@ -469,7 +469,6 @@ static void tgec_link_down(struct phylin
+ }
+ static const struct phylink_mac_ops tgec_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_config = tgec_mac_config,
+       .mac_link_up = tgec_link_up,
+       .mac_link_down = tgec_link_down,
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -4228,7 +4228,6 @@ static void mvneta_mac_link_up(struct ph
+ }
+ static const struct phylink_mac_ops mvneta_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = mvneta_mac_select_pcs,
+       .mac_prepare = mvneta_mac_prepare,
+       .mac_config = mvneta_mac_config,
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -6633,7 +6633,6 @@ static void mvpp2_mac_link_down(struct p
+ }
+ static const struct phylink_mac_ops mvpp2_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = mvpp2_select_pcs,
+       .mac_prepare = mvpp2_mac_prepare,
+       .mac_config = mvpp2_mac_config,
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -360,7 +360,6 @@ static void prestera_pcs_an_restart(stru
+ }
+ static const struct phylink_mac_ops prestera_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = prestera_mac_select_pcs,
+       .mac_config = prestera_mac_config,
+       .mac_link_down = prestera_mac_link_down,
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -654,7 +654,6 @@ static void mtk_mac_link_up(struct phyli
+ }
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = mtk_mac_select_pcs,
+       .mac_pcs_get_state = mtk_mac_pcs_get_state,
+       .mac_config = mtk_mac_config,
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c
+@@ -125,7 +125,6 @@ static void lan966x_pcs_aneg_restart(str
+ }
+ const struct phylink_mac_ops lan966x_phylink_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = lan966x_phylink_mac_select,
+       .mac_config = lan966x_phylink_mac_config,
+       .mac_prepare = lan966x_phylink_mac_prepare,
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
+@@ -138,7 +138,6 @@ const struct phylink_pcs_ops sparx5_phyl
+ };
+ const struct phylink_mac_ops sparx5_phylink_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = sparx5_phylink_mac_select_pcs,
+       .mac_config = sparx5_phylink_mac_config,
+       .mac_link_down = sparx5_phylink_mac_link_down,
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -1737,7 +1737,6 @@ static void vsc7514_phylink_mac_link_up(
+ }
+ static const struct phylink_mac_ops ocelot_phylink_ops = {
+-      .validate               = phylink_generic_validate,
+       .mac_config             = vsc7514_phylink_mac_config,
+       .mac_link_down          = vsc7514_phylink_mac_link_down,
+       .mac_link_up            = vsc7514_phylink_mac_link_up,
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1090,7 +1090,6 @@ static void stmmac_mac_link_up(struct ph
+ }
+ static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = stmmac_mac_select_pcs,
+       .mac_config = stmmac_mac_config,
+       .mac_link_down = stmmac_mac_link_down,
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1493,7 +1493,6 @@ static void am65_cpsw_nuss_mac_link_up(s
+ }
+ static const struct phylink_mac_ops am65_cpsw_phylink_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_config = am65_cpsw_nuss_mac_config,
+       .mac_link_down = am65_cpsw_nuss_mac_link_down,
+       .mac_link_up = am65_cpsw_nuss_mac_link_up,
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -1736,7 +1736,6 @@ static void axienet_mac_link_up(struct p
+ }
+ static const struct phylink_mac_ops axienet_phylink_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_select_pcs = axienet_mac_select_pcs,
+       .mac_config = axienet_mac_config,
+       .mac_link_down = axienet_mac_link_down,
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -651,7 +651,10 @@ static int phylink_validate_mac_and_pcs(
+       }
+       /* Then validate the link parameters with the MAC */
+-      pl->mac_ops->validate(pl->config, supported, state);
++      if (pl->mac_ops->validate)
++              pl->mac_ops->validate(pl->config, supported, state);
++      else
++              phylink_generic_validate(pl->config, supported, state);
+       return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
+ }
+--- a/drivers/net/usb/asix_devices.c
++++ b/drivers/net/usb/asix_devices.c
+@@ -787,7 +787,6 @@ static void ax88772_mac_link_up(struct p
+ }
+ static const struct phylink_mac_ops ax88772_phylink_mac_ops = {
+-      .validate = phylink_generic_validate,
+       .mac_config = ax88772_mac_config,
+       .mac_link_down = ax88772_mac_link_down,
+       .mac_link_up = ax88772_mac_link_up,
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -207,6 +207,11 @@ struct phylink_mac_ops {
+  *
+  * If the @state->interface mode is not supported, then the @supported
+  * mask must be cleared.
++ *
++ * This member is optional; if not set, the generic validator will be
++ * used making use of @config->mac_capabilities and
++ * @config->supported_interfaces to determine which link modes are
++ * supported.
+  */
+ void validate(struct phylink_config *config, unsigned long *supported,
+             struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch b/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch
new file mode 100644 (file)
index 0000000..37d82b2
--- /dev/null
@@ -0,0 +1,48 @@
+From a90ac762d345890b40d88a1385a34a2449c2d75e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 24 Mar 2023 09:23:42 +0000
+Subject: [PATCH] net: sfp: make sfp_bus_find_fwnode() take a const fwnode
+
+sfp_bus_find_fwnode() does not write to the fwnode, so let's make it
+const.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/sfp-bus.c | 2 +-
+ include/linux/sfp.h       | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -603,7 +603,7 @@ static void sfp_upstream_clear(struct sf
+  *    - %-ENOMEM if we failed to allocate the bus.
+  *    - an error from the upstream's connect_phy() method.
+  */
+-struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
++struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
+ {
+       struct fwnode_reference_args ref;
+       struct sfp_bus *bus;
+--- a/include/linux/sfp.h
++++ b/include/linux/sfp.h
+@@ -548,7 +548,7 @@ int sfp_get_module_eeprom_by_page(struct
+ void sfp_upstream_start(struct sfp_bus *bus);
+ void sfp_upstream_stop(struct sfp_bus *bus);
+ void sfp_bus_put(struct sfp_bus *bus);
+-struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode);
++struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
+ int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
+                        const struct sfp_upstream_ops *ops);
+ void sfp_bus_del_upstream(struct sfp_bus *bus);
+@@ -610,7 +610,8 @@ static inline void sfp_bus_put(struct sf
+ {
+ }
+-static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
++static inline struct sfp_bus *
++sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
+ {
+       return NULL;
+ }
diff --git a/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch b/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch
new file mode 100644 (file)
index 0000000..290cb8d
--- /dev/null
@@ -0,0 +1,31 @@
+From ecec0ebbc6381a5a375f1cf10c4858f24e91e2ef Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 15 Mar 2023 14:46:49 +0000
+Subject: [PATCH] net: pcs: lynx: don't print an_enabled in pcs_get_state()
+
+an_enabled will be going away, and in any case, pcs_get_state() should
+not be updating this member. Remove the print.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/pcs/pcs-lynx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/pcs/pcs-lynx.c
++++ b/drivers/net/pcs/pcs-lynx.c
+@@ -115,11 +115,11 @@ static void lynx_pcs_get_state(struct ph
+       }
+       dev_dbg(&lynx->mdio->dev,
+-              "mode=%s/%s/%s link=%u an_enabled=%u an_complete=%u\n",
++              "mode=%s/%s/%s link=%u an_complete=%u\n",
+               phy_modes(state->interface),
+               phy_speed_to_str(state->speed),
+               phy_duplex_to_str(state->duplex),
+-              state->link, state->an_enabled, state->an_complete);
++              state->link, state->an_complete);
+ }
+ static int lynx_pcs_config_giga(struct mdio_device *pcs, unsigned int mode,
diff --git a/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch b/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch
new file mode 100644 (file)
index 0000000..38ea265
--- /dev/null
@@ -0,0 +1,32 @@
+From 99d0f3a1095f4c938b1665025c29411edafe8a01 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 21 Mar 2023 15:58:44 +0000
+Subject: [PATCH] net: dpaa2-mac: use Autoneg bit rather than an_enabled
+
+The Autoneg bit in the advertising bitmap and state->an_enabled are
+always identical. Thus, we will be removing state->an_enabled.
+
+Use the Autoneg bit in the advertising bitmap to indicate whether
+autonegotiation should be used, rather than using the an_enabled
+member which will be going away. This means we use the same condition
+as phylink_mii_c22_pcs_config().
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+@@ -158,7 +158,8 @@ static void dpaa2_mac_config(struct phyl
+       struct dpmac_link_state *dpmac_state = &mac->state;
+       int err;
+-      if (state->an_enabled)
++      if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                            state->advertising))
+               dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
+       else
+               dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG;
diff --git a/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch b/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch
new file mode 100644 (file)
index 0000000..cb9c411
--- /dev/null
@@ -0,0 +1,64 @@
+From 471c40bde606ec0b1ce8c616f7998739c7a783a6 Mon Sep 17 00:00:00 2001
+From: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+Date: Fri, 10 Feb 2023 18:46:27 +0300
+Subject: [PATCH 10/21] net: phylink: support validated pause and autoneg in
+ fixed-link
+
+In fixed-link setup phylink_parse_fixedlink() unconditionally sets
+Pause, Asym_Pause and Autoneg bits to "supported" bitmap, while MAC may
+not support these.
+
+This leads to ethtool reporting:
+
+ > Supported pause frame use: Symmetric Receive-only
+ > Supports auto-negotiation: Yes
+
+regardless of what is actually supported.
+
+Instead of unconditionally set Pause, Asym_Pause and Autoneg it is
+sensible to set them according to validated "supported" bitmap, i.e. the
+result of phylink_validate().
+
+Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -709,6 +709,7 @@ static int phylink_parse_fixedlink(struc
+                                  struct fwnode_handle *fwnode)
+ {
+       struct fwnode_handle *fixed_node;
++      bool pause, asym_pause, autoneg;
+       const struct phy_setting *s;
+       struct gpio_desc *desc;
+       u32 speed;
+@@ -781,13 +782,23 @@ static int phylink_parse_fixedlink(struc
+       linkmode_copy(pl->link_config.advertising, pl->supported);
+       phylink_validate(pl, pl->supported, &pl->link_config);
++      pause = phylink_test(pl->supported, Pause);
++      asym_pause = phylink_test(pl->supported, Asym_Pause);
++      autoneg = phylink_test(pl->supported, Autoneg);
+       s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
+                              pl->supported, true);
+       linkmode_zero(pl->supported);
+       phylink_set(pl->supported, MII);
+-      phylink_set(pl->supported, Pause);
+-      phylink_set(pl->supported, Asym_Pause);
+-      phylink_set(pl->supported, Autoneg);
++
++      if (pause)
++              phylink_set(pl->supported, Pause);
++
++      if (asym_pause)
++              phylink_set(pl->supported, Asym_Pause);
++
++      if (autoneg)
++              phylink_set(pl->supported, Autoneg);
++
+       if (s) {
+               __set_bit(s->bit, pl->supported);
+               __set_bit(s->bit, pl->link_config.lp_advertising);
diff --git a/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch b/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch
new file mode 100644 (file)
index 0000000..03b4f9d
--- /dev/null
@@ -0,0 +1,177 @@
+From 7211ffd70941933a7825a56cf480f07ee81c321c Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 21 Mar 2023 15:58:54 +0000
+Subject: [PATCH 11/21] net: phylink: remove an_enabled
+
+The Autoneg bit in the advertising bitmap and state->an_enabled are
+always identical. state->an_enabled is now no longer used by any
+drivers, so lets kill this duplication.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 37 +++++++++++++++++--------------------
+ include/linux/phylink.h   |  2 --
+ 2 files changed, 17 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -841,7 +841,6 @@ static int phylink_parse_mode(struct phy
+               phylink_set(pl->supported, Autoneg);
+               phylink_set(pl->supported, Asym_Pause);
+               phylink_set(pl->supported, Pause);
+-              pl->link_config.an_enabled = true;
+               pl->cfg_link_an_mode = MLO_AN_INBAND;
+               switch (pl->link_config.interface) {
+@@ -944,9 +943,6 @@ static int phylink_parse_mode(struct phy
+                                   "failed to validate link configuration for in-band status\n");
+                       return -EINVAL;
+               }
+-
+-              /* Check if MAC/PCS also supports Autoneg. */
+-              pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg);
+       }
+       return 0;
+@@ -956,7 +952,8 @@ static void phylink_apply_manual_flow(st
+                                     struct phylink_link_state *state)
+ {
+       /* If autoneg is disabled, pause AN is also disabled */
+-      if (!state->an_enabled)
++      if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                             state->advertising))
+               state->pause &= ~MLO_PAUSE_AN;
+       /* Manual configuration of pause modes */
+@@ -996,21 +993,22 @@ static void phylink_mac_config(struct ph
+                              const struct phylink_link_state *state)
+ {
+       phylink_dbg(pl,
+-                  "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
++                  "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u\n",
+                   __func__, phylink_an_mode_str(pl->cur_link_an_mode),
+                   phy_modes(state->interface),
+                   phy_speed_to_str(state->speed),
+                   phy_duplex_to_str(state->duplex),
+                   phy_rate_matching_to_str(state->rate_matching),
+                   __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
+-                  state->pause, state->link, state->an_enabled);
++                  state->pause, state->link);
+       pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state);
+ }
+ static void phylink_mac_pcs_an_restart(struct phylink *pl)
+ {
+-      if (pl->link_config.an_enabled &&
++      if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                            pl->link_config.advertising) &&
+           phy_interface_mode_is_8023z(pl->link_config.interface) &&
+           phylink_autoneg_inband(pl->cur_link_an_mode)) {
+               if (pl->pcs)
+@@ -1137,9 +1135,9 @@ static void phylink_mac_pcs_get_state(st
+       linkmode_copy(state->advertising, pl->link_config.advertising);
+       linkmode_zero(state->lp_advertising);
+       state->interface = pl->link_config.interface;
+-      state->an_enabled = pl->link_config.an_enabled;
+       state->rate_matching = pl->link_config.rate_matching;
+-      if (state->an_enabled) {
++      if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                            state->advertising)) {
+               state->speed = SPEED_UNKNOWN;
+               state->duplex = DUPLEX_UNKNOWN;
+               state->pause = MLO_PAUSE_NONE;
+@@ -1531,7 +1529,6 @@ struct phylink *phylink_create(struct ph
+       pl->link_config.pause = MLO_PAUSE_AN;
+       pl->link_config.speed = SPEED_UNKNOWN;
+       pl->link_config.duplex = DUPLEX_UNKNOWN;
+-      pl->link_config.an_enabled = true;
+       pl->mac_ops = mac_ops;
+       __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+       timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
+@@ -2155,8 +2152,9 @@ static void phylink_get_ksettings(const
+               kset->base.speed = state->speed;
+               kset->base.duplex = state->duplex;
+       }
+-      kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE :
+-                              AUTONEG_DISABLE;
++      kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                                             state->advertising) ?
++                              AUTONEG_ENABLE : AUTONEG_DISABLE;
+ }
+ /**
+@@ -2303,9 +2301,8 @@ int phylink_ethtool_ksettings_set(struct
+       /* We have ruled out the case with a PHY attached, and the
+        * fixed-link cases.  All that is left are in-band links.
+        */
+-      config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE;
+       linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising,
+-                       config.an_enabled);
++                       kset->base.autoneg == AUTONEG_ENABLE);
+       /* If this link is with an SFP, ensure that changes to advertised modes
+        * also cause the associated interface to be selected such that the
+@@ -2339,13 +2336,14 @@ int phylink_ethtool_ksettings_set(struct
+       }
+       /* If autonegotiation is enabled, we must have an advertisement */
+-      if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
++      if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                            config.advertising) &&
++          phylink_is_empty_linkmode(config.advertising))
+               return -EINVAL;
+       mutex_lock(&pl->state_mutex);
+       pl->link_config.speed = config.speed;
+       pl->link_config.duplex = config.duplex;
+-      pl->link_config.an_enabled = config.an_enabled;
+       if (pl->link_config.interface != config.interface) {
+               /* The interface changed, e.g. 1000base-X <-> 2500base-X */
+@@ -2951,7 +2949,6 @@ static int phylink_sfp_config_phy(struct
+       config.speed = SPEED_UNKNOWN;
+       config.duplex = DUPLEX_UNKNOWN;
+       config.pause = MLO_PAUSE_AN;
+-      config.an_enabled = pl->link_config.an_enabled;
+       /* Ignore errors if we're expecting a PHY to attach later */
+       ret = phylink_validate(pl, support, &config);
+@@ -3020,7 +3017,6 @@ static int phylink_sfp_config_optical(st
+       config.speed = SPEED_UNKNOWN;
+       config.duplex = DUPLEX_UNKNOWN;
+       config.pause = MLO_PAUSE_AN;
+-      config.an_enabled = true;
+       /* For all the interfaces that are supported, reduce the sfp_support
+        * mask to only those link modes that can be supported.
+@@ -3354,7 +3350,8 @@ void phylink_mii_c22_pcs_decode_state(st
+       /* If there is no link or autonegotiation is disabled, the LP advertisement
+        * data is not meaningful, so don't go any further.
+        */
+-      if (!state->link || !state->an_enabled)
++      if (!state->link || !linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                                             state->advertising))
+               return;
+       switch (state->interface) {
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -93,7 +93,6 @@ static inline bool phylink_autoneg_inban
+  *   the medium link mode (@speed and @duplex) and the speed/duplex of the phy
+  *   interface mode (@interface) are different.
+  * @link: true if the link is up.
+- * @an_enabled: true if autonegotiation is enabled/desired.
+  * @an_complete: true if autonegotiation has completed.
+  */
+ struct phylink_link_state {
+@@ -105,7 +104,6 @@ struct phylink_link_state {
+       int pause;
+       int rate_matching;
+       unsigned int link:1;
+-      unsigned int an_enabled:1;
+       unsigned int an_complete:1;
+ };
diff --git a/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch b/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch
new file mode 100644 (file)
index 0000000..c06a367
--- /dev/null
@@ -0,0 +1,88 @@
+From a3555d1f5c208f0a63eafee77381f68d304a0512 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 12 May 2023 17:58:37 +0100
+Subject: [PATCH 12/21] net: phylink: constify fwnode arguments
+
+Both phylink_create() and phylink_fwnode_phy_connect() do not modify
+the fwnode argument that they are passed, so lets constify these.
+
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 11 ++++++-----
+ include/linux/phylink.h   |  9 +++++----
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -706,7 +706,7 @@ static int phylink_validate(struct phyli
+ }
+ static int phylink_parse_fixedlink(struct phylink *pl,
+-                                 struct fwnode_handle *fwnode)
++                                 const struct fwnode_handle *fwnode)
+ {
+       struct fwnode_handle *fixed_node;
+       bool pause, asym_pause, autoneg;
+@@ -817,7 +817,8 @@ static int phylink_parse_fixedlink(struc
+       return 0;
+ }
+-static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
++static int phylink_parse_mode(struct phylink *pl,
++                            const struct fwnode_handle *fwnode)
+ {
+       struct fwnode_handle *dn;
+       const char *managed;
+@@ -1440,7 +1441,7 @@ static void phylink_fixed_poll(struct ti
+ static const struct sfp_upstream_ops sfp_phylink_ops;
+ static int phylink_register_sfp(struct phylink *pl,
+-                              struct fwnode_handle *fwnode)
++                              const struct fwnode_handle *fwnode)
+ {
+       struct sfp_bus *bus;
+       int ret;
+@@ -1479,7 +1480,7 @@ static int phylink_register_sfp(struct p
+  * must use IS_ERR() to check for errors from this function.
+  */
+ struct phylink *phylink_create(struct phylink_config *config,
+-                             struct fwnode_handle *fwnode,
++                             const struct fwnode_handle *fwnode,
+                              phy_interface_t iface,
+                              const struct phylink_mac_ops *mac_ops)
+ {
+@@ -1809,7 +1810,7 @@ EXPORT_SYMBOL_GPL(phylink_of_phy_connect
+  * Returns 0 on success or a negative errno.
+  */
+ int phylink_fwnode_phy_connect(struct phylink *pl,
+-                             struct fwnode_handle *fwnode,
++                             const struct fwnode_handle *fwnode,
+                              u32 flags)
+ {
+       struct fwnode_handle *phy_fwnode;
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -568,16 +568,17 @@ void phylink_generic_validate(struct phy
+                             unsigned long *supported,
+                             struct phylink_link_state *state);
+-struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
+-                             phy_interface_t iface,
+-                             const struct phylink_mac_ops *mac_ops);
++struct phylink *phylink_create(struct phylink_config *,
++                             const struct fwnode_handle *,
++                             phy_interface_t,
++                             const struct phylink_mac_ops *);
+ void phylink_destroy(struct phylink *);
+ bool phylink_expects_phy(struct phylink *pl);
+ int phylink_connect_phy(struct phylink *, struct phy_device *);
+ int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags);
+ int phylink_fwnode_phy_connect(struct phylink *pl,
+-                             struct fwnode_handle *fwnode,
++                             const struct fwnode_handle *fwnode,
+                              u32 flags);
+ void phylink_disconnect_phy(struct phylink *);
diff --git a/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch b/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch
new file mode 100644 (file)
index 0000000..2649634
--- /dev/null
@@ -0,0 +1,38 @@
+From 4a0faa02d419a6728abef0f1d8a32d8c35ef95e6 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 24 Mar 2023 09:23:53 +0000
+Subject: [PATCH] net: phy: constify fwnode_get_phy_node() fwnode argument
+
+fwnode_get_phy_node() does not motify the fwnode structure, so make
+the argument const,
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phy_device.c | 2 +-
+ include/linux/phy.h          | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -3003,7 +3003,7 @@ EXPORT_SYMBOL_GPL(device_phy_find_device
+  * and "phy-device" are not supported in ACPI. DT supports all the three
+  * named references to the phy node.
+  */
+-struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode)
++struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode)
+ {
+       struct fwnode_handle *phy_node;
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -1473,7 +1473,7 @@ int fwnode_get_phy_id(struct fwnode_hand
+ struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode);
+ struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode);
+ struct phy_device *device_phy_find_device(struct device *dev);
+-struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode);
++struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode);
+ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
+ int phy_device_register(struct phy_device *phy);
+ void phy_device_free(struct phy_device *phydev);
diff --git a/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch b/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch
new file mode 100644 (file)
index 0000000..5eba18b
--- /dev/null
@@ -0,0 +1,44 @@
+From cc73de0411f7d3cdd157564a78f7a39058420ff8 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Sat, 13 May 2023 22:03:45 +0100
+Subject: [PATCH 13/21] net: phylink: fix ksettings_set() ethtool call
+
+While testing a Fiberstore SFP-10G-T module (which uses 10GBASE-R with
+rate adaption) in a Clearfog platform (which can't do that) it was
+found that the PHYs advertisement was not limited according to the
+hosts capabilities when using ethtool to change it.
+
+Fix this by ensuring that we mask the advertisement with the computed
+support mask as the very first thing we do.
+
+Fixes: cbc1bb1e4689 ("net: phylink: simplify phy case for ksettings_set method")
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -2226,6 +2226,10 @@ int phylink_ethtool_ksettings_set(struct
+       ASSERT_RTNL();
++      /* Mask out unsupported advertisements */
++      linkmode_and(config.advertising, kset->link_modes.advertising,
++                   pl->supported);
++
+       if (pl->phydev) {
+               /* We can rely on phylib for this update; we also do not need
+                * to update the pl->link_config settings:
+@@ -2250,10 +2254,6 @@ int phylink_ethtool_ksettings_set(struct
+       config = pl->link_config;
+-      /* Mask out unsupported advertisements */
+-      linkmode_and(config.advertising, kset->link_modes.advertising,
+-                   pl->supported);
+-
+       /* FIXME: should we reject autoneg if phy/mac does not support it? */
+       switch (kset->base.autoneg) {
+       case AUTONEG_DISABLE:
diff --git a/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch b/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch
new file mode 100644 (file)
index 0000000..79de612
--- /dev/null
@@ -0,0 +1,149 @@
+From 0100d1c5789018ba77bf2f4fab3bd91ecece7b3b Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 17 May 2023 11:38:12 +0100
+Subject: [PATCH 14/21] net: sfp: add support for setting signalling rate
+
+Add support to the SFP layer to allow phylink to set the signalling
+rate for a SFP module. The rate given will be in units of kilo-baud
+(1000 baud).
+
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 24 ++++++++++++++++++++++++
+ drivers/net/phy/sfp-bus.c | 20 ++++++++++++++++++++
+ drivers/net/phy/sfp.c     |  5 +++++
+ drivers/net/phy/sfp.h     |  1 +
+ include/linux/sfp.h       |  6 ++++++
+ 5 files changed, 56 insertions(+)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -156,6 +156,23 @@ static const char *phylink_an_mode_str(u
+       return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
+ }
++static unsigned int phylink_interface_signal_rate(phy_interface_t interface)
++{
++      switch (interface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX: /* 1.25Mbd */
++              return 1250;
++      case PHY_INTERFACE_MODE_2500BASEX: /* 3.125Mbd */
++              return 3125;
++      case PHY_INTERFACE_MODE_5GBASER: /* 5.15625Mbd */
++              return 5156;
++      case PHY_INTERFACE_MODE_10GBASER: /* 10.3125Mbd */
++              return 10313;
++      default:
++              return 0;
++      }
++}
++
+ /**
+  * phylink_interface_max_speed() - get the maximum speed of a phy interface
+  * @interface: phy interface mode defined by &typedef phy_interface_t
+@@ -1024,6 +1041,7 @@ static void phylink_major_config(struct
+ {
+       struct phylink_pcs *pcs = NULL;
+       bool pcs_changed = false;
++      unsigned int rate_kbd;
+       int err;
+       phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
+@@ -1083,6 +1101,12 @@ static void phylink_major_config(struct
+                                   ERR_PTR(err));
+       }
++      if (pl->sfp_bus) {
++              rate_kbd = phylink_interface_signal_rate(state->interface);
++              if (rate_kbd)
++                      sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd);
++      }
++
+       phylink_pcs_poll_start(pl);
+ }
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -586,6 +586,26 @@ static void sfp_upstream_clear(struct sf
+ }
+ /**
++ * sfp_upstream_set_signal_rate() - set data signalling rate
++ * @bus: a pointer to the &struct sfp_bus structure for the sfp module
++ * @rate_kbd: signalling rate in units of 1000 baud
++ *
++ * Configure the rate select settings on the SFP module for the signalling
++ * rate (not the same as the data rate).
++ *
++ * Locks that may be held:
++ *  Phylink's state_mutex
++ *  rtnl lock
++ *  SFP's sm_mutex
++ */
++void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd)
++{
++      if (bus->registered)
++              bus->socket_ops->set_signal_rate(bus->sfp, rate_kbd);
++}
++EXPORT_SYMBOL_GPL(sfp_upstream_set_signal_rate);
++
++/**
+  * sfp_bus_find_fwnode() - parse and locate the SFP bus from fwnode
+  * @fwnode: firmware node for the parent device (MAC or PHY)
+  *
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -2474,6 +2474,10 @@ static void sfp_stop(struct sfp *sfp)
+       sfp_sm_event(sfp, SFP_E_DEV_DOWN);
+ }
++static void sfp_set_signal_rate(struct sfp *sfp, unsigned int rate_kbd)
++{
++}
++
+ static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo)
+ {
+       /* locking... and check module is present */
+@@ -2552,6 +2556,7 @@ static const struct sfp_socket_ops sfp_m
+       .detach = sfp_detach,
+       .start = sfp_start,
+       .stop = sfp_stop,
++      .set_signal_rate = sfp_set_signal_rate,
+       .module_info = sfp_module_info,
+       .module_eeprom = sfp_module_eeprom,
+       .module_eeprom_by_page = sfp_module_eeprom_by_page,
+--- a/drivers/net/phy/sfp.h
++++ b/drivers/net/phy/sfp.h
+@@ -19,6 +19,7 @@ struct sfp_socket_ops {
+       void (*detach)(struct sfp *sfp);
+       void (*start)(struct sfp *sfp);
+       void (*stop)(struct sfp *sfp);
++      void (*set_signal_rate)(struct sfp *sfp, unsigned int rate_kbd);
+       int (*module_info)(struct sfp *sfp, struct ethtool_modinfo *modinfo);
+       int (*module_eeprom)(struct sfp *sfp, struct ethtool_eeprom *ee,
+                            u8 *data);
+--- a/include/linux/sfp.h
++++ b/include/linux/sfp.h
+@@ -547,6 +547,7 @@ int sfp_get_module_eeprom_by_page(struct
+                                 struct netlink_ext_ack *extack);
+ void sfp_upstream_start(struct sfp_bus *bus);
+ void sfp_upstream_stop(struct sfp_bus *bus);
++void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd);
+ void sfp_bus_put(struct sfp_bus *bus);
+ struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
+ int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
+@@ -606,6 +607,11 @@ static inline void sfp_upstream_stop(str
+ {
+ }
++static inline void sfp_upstream_set_signal_rate(struct sfp_bus *bus,
++                                              unsigned int rate_kbd)
++{
++}
++
+ static inline void sfp_bus_put(struct sfp_bus *bus)
+ {
+ }
diff --git a/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch b/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch
new file mode 100644 (file)
index 0000000..8a694c8
--- /dev/null
@@ -0,0 +1,147 @@
+From b84acdb07222a701bfc6403b374249c86f97d18d Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri, 19 May 2023 14:03:59 +0100
+Subject: [PATCH 15/21] net: phy: add helpers for comparing phy IDs
+
+There are several places which open code comparing PHY IDs. Provide a
+couple of helpers to assist with this, using a slightly simpler test
+than the original:
+
+- phy_id_compare() compares two arbitary PHY IDs and a mask of the
+  significant bits in the ID.
+- phydev_id_compare() compares the bound phydev with the specified
+  PHY ID, using the bound driver's mask.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/micrel.c     |  6 +++---
+ drivers/net/phy/phy_device.c | 16 +++++++---------
+ drivers/net/phy/phylink.c    |  4 ++--
+ include/linux/phy.h          | 28 ++++++++++++++++++++++++++++
+ 4 files changed, 40 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -620,7 +620,7 @@ static int ksz8051_ksz8795_match_phy_dev
+ {
+       int ret;
+-      if ((phydev->phy_id & MICREL_PHY_ID_MASK) != PHY_ID_KSZ8051)
++      if (!phy_id_compare(phydev->phy_id, PHY_ID_KSZ8051, MICREL_PHY_ID_MASK))
+               return 0;
+       ret = phy_read(phydev, MII_BMSR);
+@@ -1455,7 +1455,7 @@ static int ksz9x31_cable_test_fault_leng
+        *
+        * distance to fault = (VCT_DATA - 22) * 4 / cable propagation velocity
+        */
+-      if ((phydev->phy_id & MICREL_PHY_ID_MASK) == PHY_ID_KSZ9131)
++      if (phydev_id_compare(phydev, PHY_ID_KSZ9131))
+               dt = clamp(dt - 22, 0, 255);
+       return (dt * 400) / 10;
+@@ -1887,7 +1887,7 @@ static __always_inline int ksz886x_cable
+        */
+       dt = FIELD_GET(data_mask, status);
+-      if ((phydev->phy_id & MICREL_PHY_ID_MASK) == PHY_ID_LAN8814)
++      if (phydev_id_compare(phydev, PHY_ID_LAN8814))
+               return ((dt - 22) * 800) / 10;
+       else
+               return (dt * 400) / 10;
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -422,8 +422,7 @@ int phy_unregister_fixup(const char *bus
+               fixup = list_entry(pos, struct phy_fixup, list);
+               if ((!strcmp(fixup->bus_id, bus_id)) &&
+-                  ((fixup->phy_uid & phy_uid_mask) ==
+-                   (phy_uid & phy_uid_mask))) {
++                  phy_id_compare(fixup->phy_uid, phy_uid, phy_uid_mask)) {
+                       list_del(&fixup->list);
+                       kfree(fixup);
+                       ret = 0;
+@@ -459,8 +458,8 @@ static int phy_needs_fixup(struct phy_de
+               if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
+                       return 0;
+-      if ((fixup->phy_uid & fixup->phy_uid_mask) !=
+-          (phydev->phy_id & fixup->phy_uid_mask))
++      if (!phy_id_compare(phydev->phy_id, fixup->phy_uid,
++                          fixup->phy_uid_mask))
+               if (fixup->phy_uid != PHY_ANY_UID)
+                       return 0;
+@@ -507,15 +506,14 @@ static int phy_bus_match(struct device *
+                       if (phydev->c45_ids.device_ids[i] == 0xffffffff)
+                               continue;
+-                      if ((phydrv->phy_id & phydrv->phy_id_mask) ==
+-                          (phydev->c45_ids.device_ids[i] &
+-                           phydrv->phy_id_mask))
++                      if (phy_id_compare(phydev->c45_ids.device_ids[i],
++                                         phydrv->phy_id, phydrv->phy_id_mask))
+                               return 1;
+               }
+               return 0;
+       } else {
+-              return (phydrv->phy_id & phydrv->phy_id_mask) ==
+-                      (phydev->phy_id & phydrv->phy_id_mask);
++              return phy_id_compare(phydev->phy_id, phydrv->phy_id,
++                                    phydrv->phy_id_mask);
+       }
+ }
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -3151,8 +3151,8 @@ static void phylink_sfp_link_up(void *up
+  */
+ static bool phylink_phy_no_inband(struct phy_device *phy)
+ {
+-      return phy->is_c45 &&
+-              (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150;
++      return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1],
++                                           0xae025150, 0xfffffff0);
+ }
+ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -993,6 +993,34 @@ struct phy_driver {
+ #define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 4)
+ #define PHY_ID_MATCH_VENDOR(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 10)
++/**
++ * phy_id_compare - compare @id1 with @id2 taking account of @mask
++ * @id1: first PHY ID
++ * @id2: second PHY ID
++ * @mask: the PHY ID mask, set bits are significant in matching
++ *
++ * Return true if the bits from @id1 and @id2 specified by @mask match.
++ * This uses an equivalent test to (@id & @mask) == (@phy_id & @mask).
++ */
++static inline bool phy_id_compare(u32 id1, u32 id2, u32 mask)
++{
++      return !((id1 ^ id2) & mask);
++}
++
++/**
++ * phydev_id_compare - compare @id with the PHY's Clause 22 ID
++ * @phydev: the PHY device
++ * @id: the PHY ID to be matched
++ *
++ * Compare the @phydev clause 22 ID with the provided @id and return true or
++ * false depending whether it matches, using the bound driver mask. The
++ * @phydev must be bound to a driver.
++ */
++static inline bool phydev_id_compare(struct phy_device *phydev, u32 id)
++{
++      return phy_id_compare(id, phydev->phy_id, phydev->drv->phy_id_mask);
++}
++
+ /* A Structure for boards to register fixups with the PHY Lib */
+ struct phy_fixup {
+       struct list_head list;
diff --git a/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch b/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch
new file mode 100644 (file)
index 0000000..5970355
--- /dev/null
@@ -0,0 +1,71 @@
+From 441e1e44301fc5762a06737f8ec04bf1ce3fb039 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Sat, 20 May 2023 11:41:42 +0100
+Subject: [PATCH 16/21] net: phylink: require supported_interfaces to be filled
+
+We have been requiring the supported_interfaces bitmap to be filled in
+by MAC drivers that have a mac_select_pcs() method. Now that all MAC
+drivers fill in the supported_interfaces bitmap, it is time to enforce
+this. We have already required supported_interfaces to be set in order
+for optical SFPs to be configured in commit f81fa96d8a6c ("net: phylink:
+use phy_interface_t bitmaps for optical modules").
+
+Refuse phylink creation if supported_interfaces is empty, and remove
+code to deal with cases where this mask is empty.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/E1q0K1u-006EIP-ET@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 26 +++++++++++---------------
+ 1 file changed, 11 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -710,14 +710,11 @@ static int phylink_validate(struct phyli
+ {
+       const unsigned long *interfaces = pl->config->supported_interfaces;
+-      if (!phy_interface_empty(interfaces)) {
+-              if (state->interface == PHY_INTERFACE_MODE_NA)
+-                      return phylink_validate_mask(pl, supported, state,
+-                                                   interfaces);
++      if (state->interface == PHY_INTERFACE_MODE_NA)
++              return phylink_validate_mask(pl, supported, state, interfaces);
+-              if (!test_bit(state->interface, interfaces))
+-                      return -EINVAL;
+-      }
++      if (!test_bit(state->interface, interfaces))
++              return -EINVAL;
+       return phylink_validate_mac_and_pcs(pl, supported, state);
+ }
+@@ -1512,19 +1509,18 @@ struct phylink *phylink_create(struct ph
+       struct phylink *pl;
+       int ret;
+-      if (mac_ops->mac_select_pcs &&
+-          mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) !=
+-            ERR_PTR(-EOPNOTSUPP))
+-              using_mac_select_pcs = true;
+-
+       /* Validate the supplied configuration */
+-      if (using_mac_select_pcs &&
+-          phy_interface_empty(config->supported_interfaces)) {
++      if (phy_interface_empty(config->supported_interfaces)) {
+               dev_err(config->dev,
+-                      "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n");
++                      "phylink: error: empty supported_interfaces\n");
+               return ERR_PTR(-EINVAL);
+       }
++      if (mac_ops->mac_select_pcs &&
++          mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) !=
++            ERR_PTR(-EOPNOTSUPP))
++              using_mac_select_pcs = true;
++
+       pl = kzalloc(sizeof(*pl), GFP_KERNEL);
+       if (!pl)
+               return ERR_PTR(-ENOMEM);
diff --git a/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch b/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch
new file mode 100644 (file)
index 0000000..3a26b4b
--- /dev/null
@@ -0,0 +1,64 @@
+From 4b624a39f2ab523ca6a6ad9448fab1deb7b101e2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 23 May 2023 11:15:53 +0100
+Subject: [PATCH 17/21] net: phylink: remove duplicated linkmode pause
+ resolution
+
+Phylink had two chunks of code virtually the same for resolving the
+negotiated pause modes. Factor this down to one function.
+
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -976,11 +976,10 @@ static void phylink_apply_manual_flow(st
+               state->pause = pl->link_config.pause;
+ }
+-static void phylink_resolve_flow(struct phylink_link_state *state)
++static void phylink_resolve_an_pause(struct phylink_link_state *state)
+ {
+       bool tx_pause, rx_pause;
+-      state->pause = MLO_PAUSE_NONE;
+       if (state->duplex == DUPLEX_FULL) {
+               linkmode_resolve_pause(state->advertising,
+                                      state->lp_advertising,
+@@ -1192,7 +1191,8 @@ static void phylink_get_fixed_state(stru
+       else if (pl->link_gpio)
+               state->link = !!gpiod_get_value_cansleep(pl->link_gpio);
+-      phylink_resolve_flow(state);
++      state->pause = MLO_PAUSE_NONE;
++      phylink_resolve_an_pause(state);
+ }
+ static void phylink_mac_initial_config(struct phylink *pl, bool force_restart)
+@@ -3215,7 +3215,6 @@ static const struct sfp_upstream_ops sfp
+ static void phylink_decode_c37_word(struct phylink_link_state *state,
+                                   uint16_t config_reg, int speed)
+ {
+-      bool tx_pause, rx_pause;
+       int fd_bit;
+       if (speed == SPEED_2500)
+@@ -3234,13 +3233,7 @@ static void phylink_decode_c37_word(stru
+               state->link = false;
+       }
+-      linkmode_resolve_pause(state->advertising, state->lp_advertising,
+-                             &tx_pause, &rx_pause);
+-
+-      if (tx_pause)
+-              state->pause |= MLO_PAUSE_TX;
+-      if (rx_pause)
+-              state->pause |= MLO_PAUSE_RX;
++      phylink_resolve_an_pause(state);
+ }
+ static void phylink_decode_sgmii_word(struct phylink_link_state *state,
diff --git a/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch b/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch
new file mode 100644 (file)
index 0000000..2b2634f
--- /dev/null
@@ -0,0 +1,76 @@
+From aa8b6bd2b1f235b262bd27f317a0516f196c2c6a Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 23 May 2023 11:15:58 +0100
+Subject: [PATCH 18/21] net: phylink: add function to resolve clause 73
+ negotiation
+
+Add a function to resolve clause 73 negotiation according to the
+priority resolution function described in clause 73.3.6.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 39 +++++++++++++++++++++++++++++++++++++++
+ include/linux/phylink.h   |  2 ++
+ 2 files changed, 41 insertions(+)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -3212,6 +3212,45 @@ static const struct sfp_upstream_ops sfp
+ /* Helpers for MAC drivers */
++static struct {
++      int bit;
++      int speed;
++} phylink_c73_priority_resolution[] = {
++      { ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, SPEED_100000 },
++      { ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, SPEED_100000 },
++      /* 100GBASE-KP4 and 100GBASE-CR10 not supported */
++      { ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, SPEED_40000 },
++      { ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, SPEED_40000 },
++      { ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, SPEED_10000 },
++      { ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, SPEED_10000 },
++      /* 5GBASE-KR not supported */
++      { ETHTOOL_LINK_MODE_2500baseX_Full_BIT, SPEED_2500 },
++      { ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, SPEED_1000 },
++};
++
++void phylink_resolve_c73(struct phylink_link_state *state)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(phylink_c73_priority_resolution); i++) {
++              int bit = phylink_c73_priority_resolution[i].bit;
++              if (linkmode_test_bit(bit, state->advertising) &&
++                  linkmode_test_bit(bit, state->lp_advertising))
++                      break;
++      }
++
++      if (i < ARRAY_SIZE(phylink_c73_priority_resolution)) {
++              state->speed = phylink_c73_priority_resolution[i].speed;
++              state->duplex = DUPLEX_FULL;
++      } else {
++              /* negotiation failure */
++              state->link = false;
++      }
++
++      phylink_resolve_an_pause(state);
++}
++EXPORT_SYMBOL_GPL(phylink_resolve_c73);
++
+ static void phylink_decode_c37_word(struct phylink_link_state *state,
+                                   uint16_t config_reg, int speed)
+ {
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -656,6 +656,8 @@ int phylink_mii_c22_pcs_config(struct md
+                              const unsigned long *advertising);
+ void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs);
++void phylink_resolve_c73(struct phylink_link_state *state);
++
+ void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs,
+                                  struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch b/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch
new file mode 100644 (file)
index 0000000..eea99a5
--- /dev/null
@@ -0,0 +1,100 @@
+From 796d709363135a6bd6a8ccc07b509c939e5b855f Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 23 May 2023 16:31:50 +0100
+Subject: [PATCH 19/21] net: phylink: provide phylink_pcs_config() and
+ phylink_pcs_link_up()
+
+Add two helper functions for calling PCS methods. phylink_pcs_config()
+allows us to handle PCS configuration specifics in one location, rather
+than the two call sites. phylink_pcs_link_up() gives us consistency.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/E1q1TzK-007Exd-Rs@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 53 ++++++++++++++++++++++++---------------
+ 1 file changed, 33 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -991,6 +991,25 @@ static void phylink_resolve_an_pause(str
+       }
+ }
++static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++                            const struct phylink_link_state *state,
++                            bool permit_pause_to_mac)
++{
++      if (!pcs)
++              return 0;
++
++      return pcs->ops->pcs_config(pcs, mode, state->interface,
++                                  state->advertising, permit_pause_to_mac);
++}
++
++static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++                              phy_interface_t interface, int speed,
++                              int duplex)
++{
++      if (pcs && pcs->ops->pcs_link_up)
++              pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
++}
++
+ static void phylink_pcs_poll_stop(struct phylink *pl)
+ {
+       if (pl->cfg_link_an_mode == MLO_AN_INBAND)
+@@ -1074,18 +1093,15 @@ static void phylink_major_config(struct
+       phylink_mac_config(pl, state);
+-      if (pl->pcs) {
+-              err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+-                                             state->interface,
+-                                             state->advertising,
+-                                             !!(pl->link_config.pause &
+-                                                MLO_PAUSE_AN));
+-              if (err < 0)
+-                      phylink_err(pl, "pcs_config failed: %pe\n",
+-                                  ERR_PTR(err));
+-              if (err > 0)
+-                      restart = true;
+-      }
++      err = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, state,
++                               !!(pl->link_config.pause &
++                                  MLO_PAUSE_AN));
++      if (err < 0)
++              phylink_err(pl, "pcs_config failed: %pe\n",
++                          ERR_PTR(err));
++      else if (err > 0)
++              restart = true;
++
+       if (restart)
+               phylink_mac_pcs_an_restart(pl);
+@@ -1136,11 +1152,9 @@ static int phylink_change_inband_advert(
+        * restart negotiation if the pcs_config() helper indicates that
+        * the programmed advertisement has changed.
+        */
+-      ret = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+-                                     pl->link_config.interface,
+-                                     pl->link_config.advertising,
+-                                     !!(pl->link_config.pause &
+-                                        MLO_PAUSE_AN));
++      ret = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode,
++                               &pl->link_config,
++                               !!(pl->link_config.pause & MLO_PAUSE_AN));
+       if (ret < 0)
+               return ret;
+@@ -1272,9 +1286,8 @@ static void phylink_link_up(struct phyli
+       pl->cur_interface = link_state.interface;
+-      if (pl->pcs && pl->pcs->ops->pcs_link_up)
+-              pl->pcs->ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode,
+-                                        pl->cur_interface, speed, duplex);
++      phylink_pcs_link_up(pl->pcs, pl->cur_link_an_mode, pl->cur_interface,
++                          speed, duplex);
+       pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
+                                pl->cur_interface, speed, duplex,
diff --git a/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch b/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch
new file mode 100644 (file)
index 0000000..2f7f7a5
--- /dev/null
@@ -0,0 +1,55 @@
+From 11933aa76865621d8e82553c8f3bc07796a5aaa2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 1 Jun 2023 10:12:06 +0100
+Subject: [PATCH 20/21] net: phylink: actually fix ksettings_set() ethtool call
+
+Raju Lakkaraju reported that the below commit caused a regression
+with Lan743x drivers and a 2.5G SFP. Sadly, this is because the commit
+was utterly wrong. Let's fix this properly by not moving the
+linkmode_and(), but instead copying the link ksettings and then
+modifying the advertising mask before passing the modified link
+ksettings to phylib.
+
+Fixes: df0acdc59b09 ("net: phylink: fix ksettings_set() ethtool call")
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/E1q4eLm-00Ayxk-GZ@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -2259,11 +2259,13 @@ int phylink_ethtool_ksettings_set(struct
+       ASSERT_RTNL();
+-      /* Mask out unsupported advertisements */
+-      linkmode_and(config.advertising, kset->link_modes.advertising,
+-                   pl->supported);
+-
+       if (pl->phydev) {
++              struct ethtool_link_ksettings phy_kset = *kset;
++
++              linkmode_and(phy_kset.link_modes.advertising,
++                           phy_kset.link_modes.advertising,
++                           pl->supported);
++
+               /* We can rely on phylib for this update; we also do not need
+                * to update the pl->link_config settings:
+                * - the configuration returned via ksettings_get() will come
+@@ -2282,10 +2284,13 @@ int phylink_ethtool_ksettings_set(struct
+                *   the presence of a PHY, this should not be changed as that
+                *   should be determined from the media side advertisement.
+                */
+-              return phy_ethtool_ksettings_set(pl->phydev, kset);
++              return phy_ethtool_ksettings_set(pl->phydev, &phy_kset);
+       }
+       config = pl->link_config;
++      /* Mask out unsupported advertisements */
++      linkmode_and(config.advertising, kset->link_modes.advertising,
++                   pl->supported);
+       /* FIXME: should we reject autoneg if phy/mac does not support it? */
+       switch (kset->base.autoneg) {
diff --git a/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch b/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch
new file mode 100644 (file)
index 0000000..e1a8539
--- /dev/null
@@ -0,0 +1,324 @@
+From 79b07c3e9c4a2272927be8848c26b372516e1958 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 16 Jun 2023 13:06:22 +0100
+Subject: [PATCH 21/21] net: phylink: add PCS negotiation mode
+
+PCS have to work out whether they should enable PCS negotiation by
+looking at the "mode" and "interface" arguments, and the Autoneg bit
+in the advertising mask.
+
+This leads to some complex logic, so lets pull that out into phylink
+and instead pass a "neg_mode" argument to the PCS configuration and
+link up methods, instead of the "mode" argument.
+
+In order to transition drivers, add a "neg_mode" flag to the phylink
+PCS structure to PCS can indicate whether they want to be passed the
+neg_mode or the old mode argument.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/E1qA8De-00EaFA-Ht@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c |  45 +++++++++++++----
+ include/linux/phylink.h   | 104 +++++++++++++++++++++++++++++++++++---
+ 2 files changed, 132 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -71,6 +71,7 @@ struct phylink {
+       struct mutex state_mutex;
+       struct phylink_link_state phy_state;
+       struct work_struct resolve;
++      unsigned int pcs_neg_mode;
+       bool mac_link_dropped;
+       bool using_mac_select_pcs;
+@@ -991,23 +992,23 @@ static void phylink_resolve_an_pause(str
+       }
+ }
+-static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+                             const struct phylink_link_state *state,
+                             bool permit_pause_to_mac)
+ {
+       if (!pcs)
+               return 0;
+-      return pcs->ops->pcs_config(pcs, mode, state->interface,
++      return pcs->ops->pcs_config(pcs, neg_mode, state->interface,
+                                   state->advertising, permit_pause_to_mac);
+ }
+-static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
+                               phy_interface_t interface, int speed,
+                               int duplex)
+ {
+       if (pcs && pcs->ops->pcs_link_up)
+-              pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
++              pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex);
+ }
+ static void phylink_pcs_poll_stop(struct phylink *pl)
+@@ -1057,10 +1058,15 @@ static void phylink_major_config(struct
+       struct phylink_pcs *pcs = NULL;
+       bool pcs_changed = false;
+       unsigned int rate_kbd;
++      unsigned int neg_mode;
+       int err;
+       phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
++      pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
++                                              state->interface,
++                                              state->advertising);
++
+       if (pl->using_mac_select_pcs) {
+               pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
+               if (IS_ERR(pcs)) {
+@@ -1093,9 +1099,12 @@ static void phylink_major_config(struct
+       phylink_mac_config(pl, state);
+-      err = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, state,
+-                               !!(pl->link_config.pause &
+-                                  MLO_PAUSE_AN));
++      neg_mode = pl->cur_link_an_mode;
++      if (pl->pcs && pl->pcs->neg_mode)
++              neg_mode = pl->pcs_neg_mode;
++
++      err = phylink_pcs_config(pl->pcs, neg_mode, state,
++                               !!(pl->link_config.pause & MLO_PAUSE_AN));
+       if (err < 0)
+               phylink_err(pl, "pcs_config failed: %pe\n",
+                           ERR_PTR(err));
+@@ -1130,6 +1139,7 @@ static void phylink_major_config(struct
+  */
+ static int phylink_change_inband_advert(struct phylink *pl)
+ {
++      unsigned int neg_mode;
+       int ret;
+       if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
+@@ -1148,12 +1158,20 @@ static int phylink_change_inband_advert(
+                   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
+                   pl->link_config.pause);
++      /* Recompute the PCS neg mode */
++      pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
++                                      pl->link_config.interface,
++                                      pl->link_config.advertising);
++
++      neg_mode = pl->cur_link_an_mode;
++      if (pl->pcs->neg_mode)
++              neg_mode = pl->pcs_neg_mode;
++
+       /* Modern PCS-based method; update the advert at the PCS, and
+        * restart negotiation if the pcs_config() helper indicates that
+        * the programmed advertisement has changed.
+        */
+-      ret = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode,
+-                               &pl->link_config,
++      ret = phylink_pcs_config(pl->pcs, neg_mode, &pl->link_config,
+                                !!(pl->link_config.pause & MLO_PAUSE_AN));
+       if (ret < 0)
+               return ret;
+@@ -1256,6 +1274,7 @@ static void phylink_link_up(struct phyli
+                           struct phylink_link_state link_state)
+ {
+       struct net_device *ndev = pl->netdev;
++      unsigned int neg_mode;
+       int speed, duplex;
+       bool rx_pause;
+@@ -1286,8 +1305,12 @@ static void phylink_link_up(struct phyli
+       pl->cur_interface = link_state.interface;
+-      phylink_pcs_link_up(pl->pcs, pl->cur_link_an_mode, pl->cur_interface,
+-                          speed, duplex);
++      neg_mode = pl->cur_link_an_mode;
++      if (pl->pcs && pl->pcs->neg_mode)
++              neg_mode = pl->pcs_neg_mode;
++
++      phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed,
++                          duplex);
+       pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
+                                pl->cur_interface, speed, duplex,
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -21,6 +21,24 @@ enum {
+       MLO_AN_FIXED,   /* Fixed-link mode */
+       MLO_AN_INBAND,  /* In-band protocol */
++      /* PCS "negotiation" mode.
++       *  PHYLINK_PCS_NEG_NONE - protocol has no inband capability
++       *  PHYLINK_PCS_NEG_OUTBAND - some out of band or fixed link setting
++       *  PHYLINK_PCS_NEG_INBAND_DISABLED - inband mode disabled, e.g.
++       *                                    1000base-X with autoneg off
++       *  PHYLINK_PCS_NEG_INBAND_ENABLED - inband mode enabled
++       * Additionally, this can be tested using bitmasks:
++       *  PHYLINK_PCS_NEG_INBAND - inband mode selected
++       *  PHYLINK_PCS_NEG_ENABLED - negotiation mode enabled
++       */
++      PHYLINK_PCS_NEG_NONE = 0,
++      PHYLINK_PCS_NEG_ENABLED = BIT(4),
++      PHYLINK_PCS_NEG_OUTBAND = BIT(5),
++      PHYLINK_PCS_NEG_INBAND = BIT(6),
++      PHYLINK_PCS_NEG_INBAND_DISABLED = PHYLINK_PCS_NEG_INBAND,
++      PHYLINK_PCS_NEG_INBAND_ENABLED = PHYLINK_PCS_NEG_INBAND |
++                                       PHYLINK_PCS_NEG_ENABLED,
++
+       /* MAC_SYM_PAUSE and MAC_ASYM_PAUSE are used when configuring our
+        * autonegotiation advertisement. They correspond to the PAUSE and
+        * ASM_DIR bits defined by 802.3, respectively.
+@@ -80,6 +98,70 @@ static inline bool phylink_autoneg_inban
+ }
+ /**
++ * phylink_pcs_neg_mode() - helper to determine PCS inband mode
++ * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
++ * @interface: interface mode to be used
++ * @advertising: adertisement ethtool link mode mask
++ *
++ * Determines the negotiation mode to be used by the PCS, and returns
++ * one of:
++ * %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
++ * %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
++ *   will be used.
++ * %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg disabled
++ * %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
++ *
++ * Note: this is for cases where the PCS itself is involved in negotiation
++ * (e.g. Clause 37, SGMII and similar) not Clause 73.
++ */
++static inline unsigned int phylink_pcs_neg_mode(unsigned int mode,
++                                              phy_interface_t interface,
++                                              const unsigned long *advertising)
++{
++      unsigned int neg_mode;
++
++      switch (interface) {
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_QSGMII:
++      case PHY_INTERFACE_MODE_QUSGMII:
++      case PHY_INTERFACE_MODE_USXGMII:
++              /* These protocols are designed for use with a PHY which
++               * communicates its negotiation result back to the MAC via
++               * inband communication. Note: there exist PHYs that run
++               * with SGMII but do not send the inband data.
++               */
++              if (!phylink_autoneg_inband(mode))
++                      neg_mode = PHYLINK_PCS_NEG_OUTBAND;
++              else
++                      neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
++              break;
++
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              /* 1000base-X is designed for use media-side for Fibre
++               * connections, and thus the Autoneg bit needs to be
++               * taken into account. We also do this for 2500base-X
++               * as well, but drivers may not support this, so may
++               * need to override this.
++               */
++              if (!phylink_autoneg_inband(mode))
++                      neg_mode = PHYLINK_PCS_NEG_OUTBAND;
++              else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                                         advertising))
++                      neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
++              else
++                      neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED;
++              break;
++
++      default:
++              neg_mode = PHYLINK_PCS_NEG_NONE;
++              break;
++      }
++
++      return neg_mode;
++}
++
++/**
+  * struct phylink_link_state - link state structure
+  * @advertising: ethtool bitmask containing advertised link modes
+  * @lp_advertising: ethtool bitmask containing link partner advertised link
+@@ -436,6 +518,7 @@ struct phylink_pcs_ops;
+ /**
+  * struct phylink_pcs - PHYLINK PCS instance
+  * @ops: a pointer to the &struct phylink_pcs_ops structure
++ * @neg_mode: provide PCS neg mode via "mode" argument
+  * @poll: poll the PCS for link changes
+  *
+  * This structure is designed to be embedded within the PCS private data,
+@@ -443,6 +526,7 @@ struct phylink_pcs_ops;
+  */
+ struct phylink_pcs {
+       const struct phylink_pcs_ops *ops;
++      bool neg_mode;
+       bool poll;
+ };
+@@ -460,12 +544,12 @@ struct phylink_pcs_ops {
+                           const struct phylink_link_state *state);
+       void (*pcs_get_state)(struct phylink_pcs *pcs,
+                             struct phylink_link_state *state);
+-      int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
++      int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode,
+                         phy_interface_t interface,
+                         const unsigned long *advertising,
+                         bool permit_pause_to_mac);
+       void (*pcs_an_restart)(struct phylink_pcs *pcs);
+-      void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int mode,
++      void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
+                           phy_interface_t interface, int speed, int duplex);
+ };
+@@ -508,7 +592,7 @@ void pcs_get_state(struct phylink_pcs *p
+ /**
+  * pcs_config() - Configure the PCS mode and advertisement
+  * @pcs: a pointer to a &struct phylink_pcs.
+- * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
++ * @neg_mode: link negotiation mode (see below)
+  * @interface: interface mode to be used
+  * @advertising: adertisement ethtool link mode mask
+  * @permit_pause_to_mac: permit forwarding pause resolution to MAC
+@@ -526,8 +610,12 @@ void pcs_get_state(struct phylink_pcs *p
+  * For 1000BASE-X, the advertisement should be programmed into the PCS.
+  *
+  * For most 10GBASE-R, there is no advertisement.
++ *
++ * The %neg_mode argument should be tested via the phylink_mode_*() family of
++ * functions, or for PCS that set pcs->neg_mode true, should be tested
++ * against the %PHYLINK_PCS_NEG_* definitions.
+  */
+-int pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++int pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+              phy_interface_t interface, const unsigned long *advertising,
+              bool permit_pause_to_mac);
+@@ -543,7 +631,7 @@ void pcs_an_restart(struct phylink_pcs *
+ /**
+  * pcs_link_up() - program the PCS for the resolved link configuration
+  * @pcs: a pointer to a &struct phylink_pcs.
+- * @mode: link autonegotiation mode
++ * @neg_mode: link negotiation mode (see below)
+  * @interface: link &typedef phy_interface_t mode
+  * @speed: link speed
+  * @duplex: link duplex
+@@ -552,8 +640,12 @@ void pcs_an_restart(struct phylink_pcs *
+  * the resolved link parameters. For example, a PCS operating in SGMII
+  * mode without in-band AN needs to be manually configured for the link
+  * and duplex setting. Otherwise, this should be a no-op.
++ *
++ * The %mode argument should be tested via the phylink_mode_*() family of
++ * functions, or for PCS that set pcs->neg_mode true, should be tested
++ * against the %PHYLINK_PCS_NEG_* definitions.
+  */
+-void pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
+                phy_interface_t interface, int speed, int duplex);
+ #endif
diff --git a/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch b/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch
new file mode 100644 (file)
index 0000000..473e9d5
--- /dev/null
@@ -0,0 +1,45 @@
+From cdb08aa0473730315dbc088d5394e59622314034 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 16 Jun 2023 13:06:27 +0100
+Subject: [PATCH 1/2] net: phylink: convert phylink_mii_c22_pcs_config() to
+ neg_mode
+
+Use phylink_pcs_neg_mode() for phylink_mii_c22_pcs_config(). This
+results in no functional change.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/E1qA8Dj-00EaFG-Mt@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -3558,6 +3558,7 @@ int phylink_mii_c22_pcs_config(struct md
+                              phy_interface_t interface,
+                              const unsigned long *advertising)
+ {
++      unsigned int neg_mode;
+       bool changed = 0;
+       u16 bmcr;
+       int ret, adv;
+@@ -3571,15 +3572,13 @@ int phylink_mii_c22_pcs_config(struct md
+               changed = ret;
+       }
+-      /* Ensure ISOLATE bit is disabled */
+-      if (mode == MLO_AN_INBAND &&
+-          (interface == PHY_INTERFACE_MODE_SGMII ||
+-           interface == PHY_INTERFACE_MODE_QSGMII ||
+-           linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising)))
++      neg_mode = phylink_pcs_neg_mode(mode, interface, advertising);
++      if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+               bmcr = BMCR_ANENABLE;
+       else
+               bmcr = 0;
++      /* Configure the inband state. Ensure ISOLATE bit is disabled */
+       ret = mdiodev_modify(pcs, MII_BMCR, BMCR_ANENABLE | BMCR_ISOLATE, bmcr);
+       if (ret < 0)
+               return ret;
diff --git a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch b/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch
new file mode 100644 (file)
index 0000000..5572850
--- /dev/null
@@ -0,0 +1,187 @@
+From febf2aaf05641f3258cc30e072aff65cffc7c82c Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 16 Jun 2023 13:06:32 +0100
+Subject: [PATCH 2/2] net: phylink: pass neg_mode into
+ phylink_mii_c22_pcs_config()
+
+Convert fman_dtsec, xilinx_axienet and pcs-lynx to pass the neg_mode
+into phylink_mii_c22_pcs_config(). Where appropriate, drivers are
+updated to have neg_mode passed into their pcs_config() and
+pcs_link_up() functions. For other drivers, we just hoist the call
+to phylink_pcs_neg_mode() to their pcs_config() method out of
+phylink_mii_c22_pcs_config().
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/E1qA8Do-00EaFM-Ra@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ .../net/ethernet/freescale/fman/fman_dtsec.c   |  7 ++++---
+ .../net/ethernet/xilinx/xilinx_axienet_main.c  |  6 ++++--
+ drivers/net/pcs/pcs-lynx.c                     | 18 ++++++++++++------
+ drivers/net/phy/phylink.c                      |  9 ++++-----
+ include/linux/phylink.h                        |  5 +++--
+ 5 files changed, 27 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
++++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+@@ -763,15 +763,15 @@ static void dtsec_pcs_get_state(struct p
+       phylink_mii_c22_pcs_get_state(dtsec->tbidev, state);
+ }
+-static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+                           phy_interface_t interface,
+                           const unsigned long *advertising,
+                           bool permit_pause_to_mac)
+ {
+       struct fman_mac *dtsec = pcs_to_dtsec(pcs);
+-      return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface,
+-                                        advertising);
++      return phylink_mii_c22_pcs_config(dtsec->tbidev, interface,
++                                        advertising, neg_mode);
+ }
+ static void dtsec_pcs_an_restart(struct phylink_pcs *pcs)
+@@ -1447,6 +1447,7 @@ int dtsec_initialization(struct mac_devi
+               goto _return_fm_mac_free;
+       }
+       dtsec->pcs.ops = &dtsec_pcs_ops;
++      dtsec->pcs.neg_mode = true;
+       dtsec->pcs.poll = true;
+       supported = mac_dev->phylink_config.supported_interfaces;
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -1631,7 +1631,7 @@ static void axienet_pcs_an_restart(struc
+       phylink_mii_c22_pcs_an_restart(pcs_phy);
+ }
+-static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+                             phy_interface_t interface,
+                             const unsigned long *advertising,
+                             bool permit_pause_to_mac)
+@@ -1653,7 +1653,8 @@ static int axienet_pcs_config(struct phy
+               }
+       }
+-      ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising);
++      ret = phylink_mii_c22_pcs_config(pcs_phy, interface, advertising,
++                                       neg_mode);
+       if (ret < 0)
+               netdev_warn(ndev, "Failed to configure PCS: %d\n", ret);
+@@ -2129,6 +2130,7 @@ static int axienet_probe(struct platform
+               }
+               of_node_put(np);
+               lp->pcs.ops = &axienet_pcs_ops;
++              lp->pcs.neg_mode = true;
+               lp->pcs.poll = true;
+       }
+--- a/drivers/net/pcs/pcs-lynx.c
++++ b/drivers/net/pcs/pcs-lynx.c
+@@ -122,9 +122,10 @@ static void lynx_pcs_get_state(struct ph
+               state->link, state->an_complete);
+ }
+-static int lynx_pcs_config_giga(struct mdio_device *pcs, unsigned int mode,
++static int lynx_pcs_config_giga(struct mdio_device *pcs,
+                               phy_interface_t interface,
+-                              const unsigned long *advertising)
++                              const unsigned long *advertising,
++                              unsigned int neg_mode)
+ {
+       u32 link_timer;
+       u16 if_mode;
+@@ -137,8 +138,9 @@ static int lynx_pcs_config_giga(struct m
+               if_mode = 0;
+       } else {
++              /* SGMII and QSGMII */
+               if_mode = IF_MODE_SGMII_EN;
+-              if (mode == MLO_AN_INBAND) {
++              if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+                       if_mode |= IF_MODE_USE_SGMII_AN;
+                       /* Adjust link timer for SGMII */
+@@ -154,7 +156,8 @@ static int lynx_pcs_config_giga(struct m
+       if (err)
+               return err;
+-      return phylink_mii_c22_pcs_config(pcs, mode, interface, advertising);
++      return phylink_mii_c22_pcs_config(pcs, interface, advertising,
++                                        neg_mode);
+ }
+ static int lynx_pcs_config_usxgmii(struct mdio_device *pcs, unsigned int mode,
+@@ -181,13 +184,16 @@ static int lynx_pcs_config(struct phylin
+                          bool permit)
+ {
+       struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
++      unsigned int neg_mode;
++
++      neg_mode = phylink_pcs_neg_mode(mode, ifmode, advertising);
+       switch (ifmode) {
+       case PHY_INTERFACE_MODE_1000BASEX:
+       case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_QSGMII:
+-              return lynx_pcs_config_giga(lynx->mdio, mode, ifmode,
+-                                          advertising);
++              return lynx_pcs_config_giga(lynx->mdio, ifmode, advertising,
++                                          neg_mode);
+       case PHY_INTERFACE_MODE_2500BASEX:
+               if (phylink_autoneg_inband(mode)) {
+                       dev_err(&lynx->mdio->dev,
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -3545,20 +3545,20 @@ EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_en
+ /**
+  * phylink_mii_c22_pcs_config() - configure clause 22 PCS
+  * @pcs: a pointer to a &struct mdio_device.
+- * @mode: link autonegotiation mode
+  * @interface: the PHY interface mode being configured
+  * @advertising: the ethtool advertisement mask
++ * @neg_mode: PCS negotiation mode
+  *
+  * Configure a Clause 22 PCS PHY with the appropriate negotiation
+  * parameters for the @mode, @interface and @advertising parameters.
+  * Returns negative error number on failure, zero if the advertisement
+  * has not changed, or positive if there is a change.
+  */
+-int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
++int phylink_mii_c22_pcs_config(struct mdio_device *pcs,
+                              phy_interface_t interface,
+-                             const unsigned long *advertising)
++                             const unsigned long *advertising,
++                             unsigned int neg_mode)
+ {
+-      unsigned int neg_mode;
+       bool changed = 0;
+       u16 bmcr;
+       int ret, adv;
+@@ -3572,7 +3572,6 @@ int phylink_mii_c22_pcs_config(struct md
+               changed = ret;
+       }
+-      neg_mode = phylink_pcs_neg_mode(mode, interface, advertising);
+       if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+               bmcr = BMCR_ANENABLE;
+       else
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -743,9 +743,10 @@ void phylink_mii_c22_pcs_get_state(struc
+                                  struct phylink_link_state *state);
+ int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
+                                            const unsigned long *advertising);
+-int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode,
++int phylink_mii_c22_pcs_config(struct mdio_device *pcs,
+                              phy_interface_t interface,
+-                             const unsigned long *advertising);
++                             const unsigned long *advertising,
++                             unsigned int neg_mode);
+ void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs);
+ void phylink_resolve_c73(struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch b/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch
new file mode 100644 (file)
index 0000000..5e01287
--- /dev/null
@@ -0,0 +1,101 @@
+From 3b2de56a146f34e3f70a84cc3a1897064e445d16 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 16 Jun 2023 13:06:43 +0100
+Subject: [PATCH] net: pcs: lynxi: update PCS driver to use neg_mode
+
+Update the Lynxi PCS driver to use neg_mode rather than the mode
+argument. This ensures that the link_up() method will always program
+the speed and duplex when negotiation is disabled.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://lore.kernel.org/r/E1qA8Dz-00EaFY-5A@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/pcs/pcs-mtk-lynxi.c | 39 ++++++++++++++-------------------
+ 1 file changed, 16 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -102,13 +102,13 @@ static void mtk_pcs_lynxi_get_state(stru
+                                        FIELD_GET(SGMII_LPA, adv));
+ }
+-static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
++static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+                               phy_interface_t interface,
+                               const unsigned long *advertising,
+                               bool permit_pause_to_mac)
+ {
+       struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+-      bool mode_changed = false, changed, use_an;
++      bool mode_changed = false, changed;
+       unsigned int rgc3, sgm_mode, bmcr;
+       int advertise, link_timer;
+@@ -121,30 +121,22 @@ static int mtk_pcs_lynxi_config(struct p
+        * we assume that fixes it's speed at bitrate = line rate (in
+        * other words, 1000Mbps or 2500Mbps).
+        */
+-      if (interface == PHY_INTERFACE_MODE_SGMII) {
++      if (interface == PHY_INTERFACE_MODE_SGMII)
+               sgm_mode = SGMII_IF_MODE_SGMII;
+-              if (phylink_autoneg_inband(mode)) {
+-                      sgm_mode |= SGMII_REMOTE_FAULT_DIS |
+-                                  SGMII_SPEED_DUPLEX_AN;
+-                      use_an = true;
+-              } else {
+-                      use_an = false;
+-              }
+-      } else if (phylink_autoneg_inband(mode)) {
+-              /* 1000base-X or 2500base-X autoneg */
+-              sgm_mode = SGMII_REMOTE_FAULT_DIS;
+-              use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+-                                         advertising);
+-      } else {
++      else
+               /* 1000base-X or 2500base-X without autoneg */
+               sgm_mode = 0;
+-              use_an = false;
+-      }
+-      if (use_an)
++      if (neg_mode & PHYLINK_PCS_NEG_INBAND)
++              sgm_mode |= SGMII_REMOTE_FAULT_DIS;
++
++      if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
++              if (interface == PHY_INTERFACE_MODE_SGMII)
++                      sgm_mode |= SGMII_SPEED_DUPLEX_AN;
+               bmcr = BMCR_ANENABLE;
+-      else
++      } else {
+               bmcr = 0;
++      }
+       if (mpcs->interface != interface) {
+               link_timer = phylink_get_link_timer_ns(interface);
+@@ -216,14 +208,15 @@ static void mtk_pcs_lynxi_restart_an(str
+       regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
+ }
+-static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
++static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs,
++                                unsigned int neg_mode,
+                                 phy_interface_t interface, int speed,
+                                 int duplex)
+ {
+       struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+       unsigned int sgm_mode;
+-      if (!phylink_autoneg_inband(mode)) {
++      if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
+               /* Force the speed and duplex setting */
+               if (speed == SPEED_10)
+                       sgm_mode = SGMII_SPEED_10;
+@@ -286,6 +279,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create
+       mpcs->regmap = regmap;
+       mpcs->flags = flags;
+       mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
++      mpcs->pcs.neg_mode = true;
+       mpcs->pcs.poll = true;
+       mpcs->interface = PHY_INTERFACE_MODE_NA;
diff --git a/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch b/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch
new file mode 100644 (file)
index 0000000..3dd22d2
--- /dev/null
@@ -0,0 +1,55 @@
+From 459fd2f11204c962e3153020f4f56748e0e10afb Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 21 Mar 2023 15:58:49 +0000
+Subject: [PATCH] net: pcs: xpcs: use Autoneg bit rather than an_enabled
+
+The Autoneg bit in the advertising bitmap and state->an_enabled are
+always identical. Thus, we will be removing state->an_enabled.
+
+Use the Autoneg bit in the advertising bitmap to indicate whether
+autonegotiation should be used, rather than using the an_enabled
+member which will be going away.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/pcs/pcs-xpcs.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/pcs/pcs-xpcs.c
++++ b/drivers/net/pcs/pcs-xpcs.c
+@@ -931,6 +931,7 @@ static int xpcs_get_state_c73(struct dw_
+                             struct phylink_link_state *state,
+                             const struct xpcs_compat *compat)
+ {
++      bool an_enabled;
+       int ret;
+       /* Link needs to be read first ... */
+@@ -948,11 +949,13 @@ static int xpcs_get_state_c73(struct dw_
+               return xpcs_do_config(xpcs, state->interface, MLO_AN_INBAND, NULL);
+       }
+-      if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) {
++      an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                                     state->advertising);
++      if (an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) {
+               state->an_complete = true;
+               xpcs_read_lpa_c73(xpcs, state);
+               xpcs_resolve_lpa_c73(xpcs, state);
+-      } else if (state->an_enabled) {
++      } else if (an_enabled) {
+               state->link = 0;
+       } else if (state->link) {
+               xpcs_resolve_pma(xpcs, state);
+@@ -1007,7 +1010,8 @@ static int xpcs_get_state_c37_1000basex(
+ {
+       int lpa, bmsr;
+-      if (state->an_enabled) {
++      if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
++                            state->advertising)) {
+               /* Reset link state */
+               state->link = false;
diff --git a/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch b/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch
new file mode 100644 (file)
index 0000000..7cae851
--- /dev/null
@@ -0,0 +1,30 @@
+From 43fb622d91a9f408322735d2f736495c1009f575 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 9 May 2023 12:50:04 +0100
+Subject: [PATCH] net: pcs: xpcs: fix incorrect number of interfaces
+
+In synopsys_xpcs_compat[], the DW_XPCS_2500BASEX entry was setting
+the number of interfaces using the xpcs_2500basex_features array
+rather than xpcs_2500basex_interfaces. This causes us to overflow
+the array of interfaces. Fix this.
+
+Fixes: f27abde3042a ("net: pcs: add 2500BASEX support for Intel mGbE controller")
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/pcs/pcs-xpcs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/pcs/pcs-xpcs.c
++++ b/drivers/net/pcs/pcs-xpcs.c
+@@ -1211,7 +1211,7 @@ static const struct xpcs_compat synopsys
+       [DW_XPCS_2500BASEX] = {
+               .supported = xpcs_2500basex_features,
+               .interface = xpcs_2500basex_interfaces,
+-              .num_interfaces = ARRAY_SIZE(xpcs_2500basex_features),
++              .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces),
+               .an_mode = DW_2500BASEX,
+       },
+ };
index 2e3826906079f1c47a9a60f33d8552aa57284369..3c7bf6c132ff5757a188895ece1d71523bdb7f87 100644 (file)
@@ -27,7 +27,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -1650,6 +1650,7 @@ int phy_package_join(struct phy_device *
+@@ -1648,6 +1648,7 @@ int phy_package_join(struct phy_device *
                        shared->priv_size = priv_size;
                }
                shared->base_addr = base_addr;
@@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
                refcount_set(&shared->refcnt, 1);
                bus->shared[base_addr] = shared;
        } else {
-@@ -1673,6 +1674,63 @@ err_unlock:
+@@ -1671,6 +1672,63 @@ err_unlock:
  EXPORT_SYMBOL_GPL(phy_package_join);
  
  /**
@@ -99,7 +99,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
   * phy_package_leave - leave a common PHY group
   * @phydev: target phy_device struct
   *
-@@ -1688,6 +1746,10 @@ void phy_package_leave(struct phy_device
+@@ -1686,6 +1744,10 @@ void phy_package_leave(struct phy_device
        if (!shared)
                return;
  
@@ -110,7 +110,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
                bus->shared[shared->base_addr] = NULL;
                mutex_unlock(&bus->shared_lock);
-@@ -1741,6 +1803,40 @@ int devm_phy_package_join(struct device
+@@ -1739,6 +1801,40 @@ int devm_phy_package_join(struct device
  EXPORT_SYMBOL_GPL(devm_phy_package_join);
  
  /**
@@ -170,7 +170,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        refcount_t refcnt;
        unsigned long flags;
        size_t priv_size;
-@@ -1765,9 +1768,12 @@ int phy_ethtool_set_link_ksettings(struc
+@@ -1793,9 +1796,12 @@ int phy_ethtool_set_link_ksettings(struc
                                   const struct ethtool_link_ksettings *cmd);
  int phy_ethtool_nway_reset(struct net_device *ndev);
  int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size);
index 4371599f4a085ee6e2b7f41e6538b461aa3deb98..acaa4a644ee419823684c7e2e9a893e2ae045f60 100644 (file)
@@ -41,7 +41,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -2551,12 +2551,15 @@ EXPORT_SYMBOL(genphy_read_status);
+@@ -2549,12 +2549,15 @@ EXPORT_SYMBOL(genphy_read_status);
  /**
   * genphy_c37_read_status - check the link status and update current link state
   * @phydev: target phy_device struct
@@ -58,7 +58,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  {
        int lpa, err, old_link = phydev->link;
  
-@@ -2566,9 +2569,13 @@ int genphy_c37_read_status(struct phy_de
+@@ -2564,9 +2567,13 @@ int genphy_c37_read_status(struct phy_de
                return err;
  
        /* why bother the PHY if nothing can have changed */
@@ -89,7 +89,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  }
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
-@@ -1660,7 +1660,7 @@ int genphy_write_mmd_unsupported(struct
+@@ -1688,7 +1688,7 @@ int genphy_write_mmd_unsupported(struct
  
  /* Clause 37 */
  int genphy_c37_config_aneg(struct phy_device *phydev);
diff --git a/target/linux/generic/backport-6.1/723-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-6.1/723-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch
deleted file mode 100644 (file)
index d56a142..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:50 +0000
-Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS
-
-The SGMII core found in several MediaTek SoCs is identical to what can
-also be found in MediaTek's MT7531 Ethernet switch IC.
-As this has not always been clear, both drivers developed different
-implementations to deal with the PCS.
-Recently Alexander Couzens pointed out this fact which lead to the
-development of this shared driver.
-
-Add a dedicated driver, mostly by copying the code now found in the
-Ethernet driver. The now redundant code will be removed by a follow-up
-commit.
-
-Suggested-by: Alexander Couzens <lynxis@fe80.eu>
-Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Tested-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- MAINTAINERS                       |   8 +
- drivers/net/pcs/Kconfig           |   7 +
- drivers/net/pcs/Makefile          |   1 +
- drivers/net/pcs/pcs-mtk-lynxi.c   | 305 ++++++++++++++++++++++++++++++
- include/linux/pcs/pcs-mtk-lynxi.h |  13 ++
- 5 files changed, 334 insertions(+)
- create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
- create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -12928,6 +12928,14 @@ L:    netdev@vger.kernel.org
- S:    Maintained
- F:    drivers/net/ethernet/mediatek/
-+MEDIATEK ETHERNET PCS DRIVER
-+M:    Alexander Couzens <lynxis@fe80.eu>
-+M:    Daniel Golle <daniel@makrotopia.org>
-+L:    netdev@vger.kernel.org
-+S:    Maintained
-+F:    drivers/net/pcs/pcs-mtk-lynxi.c
-+F:    include/linux/pcs/pcs-mtk-lynxi.h
-+
- MEDIATEK I2C CONTROLLER DRIVER
- M:    Qii Wang <qii.wang@mediatek.com>
- L:    linux-i2c@vger.kernel.org
---- a/drivers/net/pcs/Kconfig
-+++ b/drivers/net/pcs/Kconfig
-@@ -32,4 +32,11 @@ config PCS_ALTERA_TSE
-         This module provides helper functions for the Altera Triple Speed
-         Ethernet SGMII PCS, that can be found on the Intel Socfpga family.
-+config PCS_MTK_LYNXI
-+      tristate
-+      select REGMAP
-+      help
-+        This module provides helpers to phylink for managing the LynxI PCS
-+        which is part of MediaTek's SoC and Ethernet switch ICs.
-+
- endmenu
---- a/drivers/net/pcs/Makefile
-+++ b/drivers/net/pcs/Makefile
-@@ -7,3 +7,4 @@ obj-$(CONFIG_PCS_XPCS)         += pcs_xpcs.o
- obj-$(CONFIG_PCS_LYNX)                += pcs-lynx.o
- obj-$(CONFIG_PCS_RZN1_MIIC)   += pcs-rzn1-miic.o
- obj-$(CONFIG_PCS_ALTERA_TSE)  += pcs-altera-tse.o
-+obj-$(CONFIG_PCS_MTK_LYNXI)   += pcs-mtk-lynxi.o
---- /dev/null
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -0,0 +1,305 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (c) 2018-2019 MediaTek Inc.
-+/* A library for MediaTek SGMII circuit
-+ *
-+ * Author: Sean Wang <sean.wang@mediatek.com>
-+ * Author: Alexander Couzens <lynxis@fe80.eu>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ *
-+ */
-+
-+#include <linux/mdio.h>
-+#include <linux/of.h>
-+#include <linux/pcs/pcs-mtk-lynxi.h>
-+#include <linux/phylink.h>
-+#include <linux/regmap.h>
-+
-+/* SGMII subsystem config registers */
-+/* BMCR (low 16) BMSR (high 16) */
-+#define SGMSYS_PCS_CONTROL_1          0x0
-+#define SGMII_BMCR                    GENMASK(15, 0)
-+#define SGMII_BMSR                    GENMASK(31, 16)
-+
-+#define SGMSYS_PCS_DEVICE_ID          0x4
-+#define SGMII_LYNXI_DEV_ID            0x4d544950
-+
-+#define SGMSYS_PCS_ADVERTISE          0x8
-+#define SGMII_ADVERTISE                       GENMASK(15, 0)
-+#define SGMII_LPA                     GENMASK(31, 16)
-+
-+#define SGMSYS_PCS_SCRATCH            0x14
-+#define SGMII_DEV_VERSION             GENMASK(31, 16)
-+
-+/* Register to programmable link timer, the unit in 2 * 8ns */
-+#define SGMSYS_PCS_LINK_TIMER         0x18
-+#define SGMII_LINK_TIMER_MASK         GENMASK(19, 0)
-+#define SGMII_LINK_TIMER_VAL(ns)      FIELD_PREP(SGMII_LINK_TIMER_MASK, \
-+                                                 ((ns) / 2 / 8))
-+
-+/* Register to control remote fault */
-+#define SGMSYS_SGMII_MODE             0x20
-+#define SGMII_IF_MODE_SGMII           BIT(0)
-+#define SGMII_SPEED_DUPLEX_AN         BIT(1)
-+#define SGMII_SPEED_MASK              GENMASK(3, 2)
-+#define SGMII_SPEED_10                        FIELD_PREP(SGMII_SPEED_MASK, 0)
-+#define SGMII_SPEED_100                       FIELD_PREP(SGMII_SPEED_MASK, 1)
-+#define SGMII_SPEED_1000              FIELD_PREP(SGMII_SPEED_MASK, 2)
-+#define SGMII_DUPLEX_HALF             BIT(4)
-+#define SGMII_REMOTE_FAULT_DIS                BIT(8)
-+
-+/* Register to reset SGMII design */
-+#define SGMSYS_RESERVED_0             0x34
-+#define SGMII_SW_RESET                        BIT(0)
-+
-+/* Register to set SGMII speed, ANA RG_ Control Signals III */
-+#define SGMII_PHY_SPEED_MASK          GENMASK(3, 2)
-+#define SGMII_PHY_SPEED_1_25G         FIELD_PREP(SGMII_PHY_SPEED_MASK, 0)
-+#define SGMII_PHY_SPEED_3_125G                FIELD_PREP(SGMII_PHY_SPEED_MASK, 1)
-+
-+/* Register to power up QPHY */
-+#define SGMSYS_QPHY_PWR_STATE_CTRL    0xe8
-+#define       SGMII_PHYA_PWD                  BIT(4)
-+
-+/* Register to QPHY wrapper control */
-+#define SGMSYS_QPHY_WRAP_CTRL         0xec
-+#define SGMII_PN_SWAP_MASK            GENMASK(1, 0)
-+#define SGMII_PN_SWAP_TX_RX           (BIT(0) | BIT(1))
-+
-+/* struct mtk_pcs_lynxi -  This structure holds each sgmii regmap andassociated
-+ *                         data
-+ * @regmap:                The register map pointing at the range used to setup
-+ *                         SGMII modes
-+ * @dev:                   Pointer to device owning the PCS
-+ * @ana_rgc3:              The offset of register ANA_RGC3 relative to regmap
-+ * @interface:             Currently configured interface mode
-+ * @pcs:                   Phylink PCS structure
-+ * @flags:                 Flags indicating hardware properties
-+ */
-+struct mtk_pcs_lynxi {
-+      struct regmap           *regmap;
-+      u32                     ana_rgc3;
-+      phy_interface_t         interface;
-+      struct                  phylink_pcs pcs;
-+      u32                     flags;
-+};
-+
-+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
-+{
-+      return container_of(pcs, struct mtk_pcs_lynxi, pcs);
-+}
-+
-+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
-+                                  struct phylink_link_state *state)
-+{
-+      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+      unsigned int bm, adv;
-+
-+      /* Read the BMSR and LPA */
-+      regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-+      regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-+
-+      phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-+                                       FIELD_GET(SGMII_LPA, adv));
-+}
-+
-+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
-+                              phy_interface_t interface,
-+                              const unsigned long *advertising,
-+                              bool permit_pause_to_mac)
-+{
-+      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+      bool mode_changed = false, changed, use_an;
-+      unsigned int rgc3, sgm_mode, bmcr;
-+      int advertise, link_timer;
-+
-+      advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-+                                                           advertising);
-+      if (advertise < 0)
-+              return advertise;
-+
-+      /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
-+       * we assume that fixes it's speed at bitrate = line rate (in
-+       * other words, 1000Mbps or 2500Mbps).
-+       */
-+      if (interface == PHY_INTERFACE_MODE_SGMII) {
-+              sgm_mode = SGMII_IF_MODE_SGMII;
-+              if (phylink_autoneg_inband(mode)) {
-+                      sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-+                                  SGMII_SPEED_DUPLEX_AN;
-+                      use_an = true;
-+              } else {
-+                      use_an = false;
-+              }
-+      } else if (phylink_autoneg_inband(mode)) {
-+              /* 1000base-X or 2500base-X autoneg */
-+              sgm_mode = SGMII_REMOTE_FAULT_DIS;
-+              use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+                                         advertising);
-+      } else {
-+              /* 1000base-X or 2500base-X without autoneg */
-+              sgm_mode = 0;
-+              use_an = false;
-+      }
-+
-+      if (use_an)
-+              bmcr = BMCR_ANENABLE;
-+      else
-+              bmcr = 0;
-+
-+      if (mpcs->interface != interface) {
-+              link_timer = phylink_get_link_timer_ns(interface);
-+              if (link_timer < 0)
-+                      return link_timer;
-+
-+              /* PHYA power down */
-+              regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-+                              SGMII_PHYA_PWD);
-+
-+              /* Reset SGMII PCS state */
-+              regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
-+                              SGMII_SW_RESET);
-+
-+              if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-+                      regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-+                                         SGMII_PN_SWAP_MASK,
-+                                         SGMII_PN_SWAP_TX_RX);
-+
-+              if (interface == PHY_INTERFACE_MODE_2500BASEX)
-+                      rgc3 = SGMII_PHY_SPEED_3_125G;
-+              else
-+                      rgc3 = SGMII_PHY_SPEED_1_25G;
-+
-+              /* Configure the underlying interface speed */
-+              regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-+                                 SGMII_PHY_SPEED_MASK, rgc3);
-+
-+              /* Setup the link timer */
-+              regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
-+                           SGMII_LINK_TIMER_VAL(link_timer));
-+
-+              mpcs->interface = interface;
-+              mode_changed = true;
-+      }
-+
-+      /* Update the advertisement, noting whether it has changed */
-+      regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-+                               SGMII_ADVERTISE, advertise, &changed);
-+
-+      /* Update the sgmsys mode register */
-+      regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+                         SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-+                         SGMII_IF_MODE_SGMII, sgm_mode);
-+
-+      /* Update the BMCR */
-+      regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-+                         BMCR_ANENABLE, bmcr);
-+
-+      /* Release PHYA power down state
-+       * Only removing bit SGMII_PHYA_PWD isn't enough.
-+       * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-+       * prevents SGMII from working. The SGMII still shows link but no traffic
-+       * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-+       * taken from a good working state of the SGMII interface.
-+       * Unknown how much the QPHY needs but it is racy without a sleep.
-+       * Tested on mt7622 & mt7986.
-+       */
-+      usleep_range(50, 100);
-+      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-+
-+      return changed || mode_changed;
-+}
-+
-+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs)
-+{
-+      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+
-+      regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
-+}
-+
-+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+                                phy_interface_t interface, int speed,
-+                                int duplex)
-+{
-+      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-+      unsigned int sgm_mode;
-+
-+      if (!phylink_autoneg_inband(mode)) {
-+              /* Force the speed and duplex setting */
-+              if (speed == SPEED_10)
-+                      sgm_mode = SGMII_SPEED_10;
-+              else if (speed == SPEED_100)
-+                      sgm_mode = SGMII_SPEED_100;
-+              else
-+                      sgm_mode = SGMII_SPEED_1000;
-+
-+              if (duplex != DUPLEX_FULL)
-+                      sgm_mode |= SGMII_DUPLEX_HALF;
-+
-+              regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-+                                 SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
-+                                 sgm_mode);
-+      }
-+}
-+
-+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
-+      .pcs_get_state = mtk_pcs_lynxi_get_state,
-+      .pcs_config = mtk_pcs_lynxi_config,
-+      .pcs_an_restart = mtk_pcs_lynxi_restart_an,
-+      .pcs_link_up = mtk_pcs_lynxi_link_up,
-+};
-+
-+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
-+                                       struct regmap *regmap, u32 ana_rgc3,
-+                                       u32 flags)
-+{
-+      struct mtk_pcs_lynxi *mpcs;
-+      u32 id, ver;
-+      int ret;
-+
-+      ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id);
-+      if (ret < 0)
-+              return NULL;
-+
-+      if (id != SGMII_LYNXI_DEV_ID) {
-+              dev_err(dev, "unknown PCS device id %08x\n", id);
-+              return NULL;
-+      }
-+
-+      ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver);
-+      if (ret < 0)
-+              return NULL;
-+
-+      ver = FIELD_GET(SGMII_DEV_VERSION, ver);
-+      if (ver != 0x1) {
-+              dev_err(dev, "unknown PCS device version %04x\n", ver);
-+              return NULL;
-+      }
-+
-+      dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id,
-+              ver);
-+
-+      mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL);
-+      if (!mpcs)
-+              return NULL;
-+
-+      mpcs->ana_rgc3 = ana_rgc3;
-+      mpcs->regmap = regmap;
-+      mpcs->flags = flags;
-+      mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
-+      mpcs->pcs.poll = true;
-+      mpcs->interface = PHY_INTERFACE_MODE_NA;
-+
-+      return &mpcs->pcs;
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_create);
-+
-+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs)
-+{
-+      if (!pcs)
-+              return;
-+
-+      kfree(pcs_to_mtk_pcs_lynxi(pcs));
-+}
-+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/include/linux/pcs/pcs-mtk-lynxi.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __LINUX_PCS_MTK_LYNXI_H
-+#define __LINUX_PCS_MTK_LYNXI_H
-+
-+#include <linux/phylink.h>
-+#include <linux/regmap.h>
-+
-+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
-+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
-+                                       struct regmap *regmap,
-+                                       u32 ana_rgc3, u32 flags);
-+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
-+#endif
index 55267916242a99d89e3ffa8f05a69040c4eb8fa4..816aa67787d5f8715f9d889f47990aecfc0dc10a 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4334,6 +4334,7 @@ static const struct mtk_soc_data mt7986_
+@@ -4333,6 +4333,7 @@ static const struct mtk_soc_data mt7986_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7986_CLKS_BITMAP,
        .required_pctl = false,
index 95a21e1c9a39d7bf9e41abfa4758e11ea94ece3d..cefe1eefff2ca7847ed689d20e8b7b13e8e1eab7 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3481,11 +3481,8 @@ static void mtk_pending_work(struct work
+@@ -3480,11 +3480,8 @@ static void mtk_pending_work(struct work
        rtnl_lock();
  
        dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
@@ -25,7 +25,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        /* stop all devices to make sure that dma is properly shut down */
        for (i = 0; i < MTK_MAC_COUNT; i++) {
                if (!eth->netdev[i])
-@@ -3519,7 +3516,7 @@ static void mtk_pending_work(struct work
+@@ -3518,7 +3515,7 @@ static void mtk_pending_work(struct work
  
        dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
  
index 8bdbfc292799821d386128bbb32864221d97f6a5..c91861a8f11a3ec91121a3fee2acd4b5d1fb0bd0 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3257,6 +3257,27 @@ static void mtk_set_mcr_max_rx(struct mt
+@@ -3256,6 +3256,27 @@ static void mtk_set_mcr_max_rx(struct mt
                mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
  }
  
@@ -44,7 +44,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  static int mtk_hw_init(struct mtk_eth *eth)
  {
        u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3296,22 +3317,9 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3295,22 +3316,9 @@ static int mtk_hw_init(struct mtk_eth *e
                return 0;
        }
  
index 712b6a2d3afeee02ecb1d6200bc4a527cd48a5e7..6597eb5b7468c2d97ebe836f1159398d68e9fb04 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3278,7 +3278,54 @@ static void mtk_hw_reset(struct mtk_eth
+@@ -3277,7 +3277,54 @@ static void mtk_hw_reset(struct mtk_eth
                             0x3ffffff);
  }
  
@@ -73,7 +73,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  {
        u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
                       ETHSYS_DMA_AG_MAP_PPE;
-@@ -3317,7 +3364,12 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3316,7 +3363,12 @@ static int mtk_hw_init(struct mtk_eth *e
                return 0;
        }
  
@@ -87,7 +87,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
                /* Set FE to PDMAv2 if necessary */
-@@ -3508,7 +3560,7 @@ static void mtk_pending_work(struct work
+@@ -3507,7 +3559,7 @@ static void mtk_pending_work(struct work
        if (eth->dev->pins)
                pinctrl_select_state(eth->dev->pins->p,
                                     eth->dev->pins->default_state);
@@ -96,7 +96,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        /* restart DMA and enable IRQs */
        for (i = 0; i < MTK_MAC_COUNT; i++) {
-@@ -4110,7 +4162,7 @@ static int mtk_probe(struct platform_dev
+@@ -4109,7 +4161,7 @@ static int mtk_probe(struct platform_dev
        eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
        INIT_WORK(&eth->pending_work, mtk_pending_work);
  
index 9da16ec56ccd8f8dacf6432cfe51eb8b68d8c02d..55ab19f4c8df690bade4c41acbe8be3a8c95bd75 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2845,14 +2845,29 @@ static void mtk_dma_free(struct mtk_eth
+@@ -2844,14 +2844,29 @@ static void mtk_dma_free(struct mtk_eth
        kfree(eth->scratch_head);
  }
  
@@ -48,7 +48,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
        schedule_work(&eth->pending_work);
  }
  
-@@ -3332,15 +3347,17 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3331,15 +3346,17 @@ static int mtk_hw_init(struct mtk_eth *e
        const struct mtk_reg_map *reg_map = eth->soc->reg_map;
        int i, val, ret;
  
@@ -72,7 +72,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        if (eth->ethsys)
                regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask,
-@@ -3469,8 +3486,10 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3468,8 +3485,10 @@ static int mtk_hw_init(struct mtk_eth *e
        return 0;
  
  err_disable_pm:
@@ -85,7 +85,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        return ret;
  }
-@@ -3532,30 +3551,53 @@ static int mtk_do_ioctl(struct net_devic
+@@ -3531,30 +3550,53 @@ static int mtk_do_ioctl(struct net_devic
        return -EOPNOTSUPP;
  }
  
@@ -148,7 +148,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        if (eth->dev->pins)
                pinctrl_select_state(eth->dev->pins->p,
-@@ -3566,15 +3608,19 @@ static void mtk_pending_work(struct work
+@@ -3565,15 +3607,19 @@ static void mtk_pending_work(struct work
        for (i = 0; i < MTK_MAC_COUNT; i++) {
                if (!test_bit(i, &restart))
                        continue;
index 96ebc874814fb83b6a2a2c86e183a9d3cbd1ff1e..d5a7c0eba2a0e416a3a7d7bd5c0e3adc44fd8d48 100644 (file)
@@ -49,7 +49,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  };
  
  /* strings used by ethtool */
-@@ -3340,6 +3346,102 @@ static void mtk_hw_warm_reset(struct mtk
+@@ -3339,6 +3345,102 @@ static void mtk_hw_warm_reset(struct mtk
                        val, rst_mask);
  }
  
@@ -152,7 +152,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  static int mtk_hw_init(struct mtk_eth *eth, bool reset)
  {
        u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
-@@ -3658,6 +3760,7 @@ static int mtk_cleanup(struct mtk_eth *e
+@@ -3657,6 +3759,7 @@ static int mtk_cleanup(struct mtk_eth *e
        mtk_unreg_dev(eth);
        mtk_free_dev(eth);
        cancel_work_sync(&eth->pending_work);
@@ -160,7 +160,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        return 0;
  }
-@@ -4095,6 +4198,7 @@ static int mtk_probe(struct platform_dev
+@@ -4094,6 +4197,7 @@ static int mtk_probe(struct platform_dev
  
        eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
        INIT_WORK(&eth->rx_dim.work, mtk_dim_rx);
@@ -168,7 +168,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
        INIT_WORK(&eth->tx_dim.work, mtk_dim_tx);
-@@ -4297,6 +4401,8 @@ static int mtk_probe(struct platform_dev
+@@ -4296,6 +4400,8 @@ static int mtk_probe(struct platform_dev
        netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx);
  
        platform_set_drvdata(pdev, eth);
index da1ce24b8ffe4b61950934f850cf991661a304f4..c21d094ae849ba46c2cf65a7b334fe1da9e604ff 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3689,6 +3689,11 @@ static void mtk_pending_work(struct work
+@@ -3688,6 +3688,11 @@ static void mtk_pending_work(struct work
        set_bit(MTK_RESETTING, &eth->state);
  
        mtk_prepare_for_reset(eth);
@@ -26,7 +26,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        /* stop all devices to make sure that dma is properly shut down */
        for (i = 0; i < MTK_MAC_COUNT; i++) {
-@@ -3726,6 +3731,8 @@ static void mtk_pending_work(struct work
+@@ -3725,6 +3730,8 @@ static void mtk_pending_work(struct work
  
        clear_bit(MTK_RESETTING, &eth->state);
  
index c3b8af0b2b7fe9a13a1163133663f8e17b22c223..046a5812247a99bc9f9318b3c4fbaba5f0dcdf7f 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -945,7 +945,7 @@ static int mtk_init_fq_dma(struct mtk_et
+@@ -944,7 +944,7 @@ static int mtk_init_fq_dma(struct mtk_et
  {
        const struct mtk_soc_data *soc = eth->soc;
        dma_addr_t phy_ring_tail;
@@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        dma_addr_t dma_addr;
        int i;
  
-@@ -2209,19 +2209,25 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2208,19 +2208,25 @@ static int mtk_tx_alloc(struct mtk_eth *
        struct mtk_tx_ring *ring = &eth->tx_ring;
        int i, sz = soc->txrx.txd_size;
        struct mtk_tx_dma_v2 *txd;
@@ -51,7 +51,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                u32 next_ptr = ring->phys + next * sz;
  
                txd = ring->dma + i * sz;
-@@ -2241,22 +2247,22 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2240,22 +2246,22 @@ static int mtk_tx_alloc(struct mtk_eth *
         * descriptors in ring->dma_pdma.
         */
        if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
@@ -79,7 +79,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        ring->thresh = MAX_SKB_FRAGS;
  
        /* make sure that all changes to the dma ring are flushed before we
-@@ -2268,14 +2274,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2267,14 +2273,14 @@ static int mtk_tx_alloc(struct mtk_eth *
                mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr);
                mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr);
                mtk_w32(eth,
@@ -96,7 +96,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                mtk_w32(eth, 0, MT7628_TX_CTX_IDX0);
                mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx);
        }
-@@ -2293,7 +2299,7 @@ static void mtk_tx_clean(struct mtk_eth
+@@ -2292,7 +2298,7 @@ static void mtk_tx_clean(struct mtk_eth
        int i;
  
        if (ring->buf) {
@@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        mtk_tx_unmap(eth, &ring->buf[i], NULL, false);
                kfree(ring->buf);
                ring->buf = NULL;
-@@ -2301,14 +2307,14 @@ static void mtk_tx_clean(struct mtk_eth
+@@ -2300,14 +2306,14 @@ static void mtk_tx_clean(struct mtk_eth
  
        if (ring->dma) {
                dma_free_coherent(eth->dma_dev,
@@ -122,7 +122,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                                  ring->dma_pdma, ring->phys_pdma);
                ring->dma_pdma = NULL;
        }
-@@ -2833,7 +2839,7 @@ static void mtk_dma_free(struct mtk_eth
+@@ -2832,7 +2838,7 @@ static void mtk_dma_free(struct mtk_eth
                        netdev_reset_queue(eth->netdev[i]);
        if (eth->scratch_ring) {
                dma_free_coherent(eth->dma_dev,
index bc794a5c8a0f9be9635868b9ba3ea8d626365b1c..7e879ca1d5aad818bf5ba6ddc50edf5f82454438 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4480,7 +4480,7 @@ static const struct mtk_soc_data mt7621_
+@@ -4479,7 +4479,7 @@ static const struct mtk_soc_data mt7621_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7621_CLKS_BITMAP,
        .required_pctl = false,
@@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        .hash_offset = 2,
        .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
        .txrx = {
-@@ -4519,7 +4519,7 @@ static const struct mtk_soc_data mt7623_
+@@ -4518,7 +4518,7 @@ static const struct mtk_soc_data mt7623_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
index 48d9b31fef4300facb075c704ca3d84c96115b8e..8ceba7831e02ce368d984b83157c6877ec16cb3d 100644 (file)
@@ -139,7 +139,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        /* Configure duplex */
        if (duplex == DUPLEX_FULL)
                mcr |= MAC_MCR_FORCE_DPX;
-@@ -1106,7 +1181,8 @@ static void mtk_tx_set_dma_desc_v1(struc
+@@ -1105,7 +1180,8 @@ static void mtk_tx_set_dma_desc_v1(struc
  
        WRITE_ONCE(desc->txd1, info->addr);
  
@@ -149,7 +149,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        if (info->last)
                data |= TX_DMA_LS0;
        WRITE_ONCE(desc->txd3, data);
-@@ -1140,9 +1216,6 @@ static void mtk_tx_set_dma_desc_v2(struc
+@@ -1139,9 +1215,6 @@ static void mtk_tx_set_dma_desc_v2(struc
                data |= TX_DMA_LS0;
        WRITE_ONCE(desc->txd3, data);
  
@@ -159,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
        data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
        WRITE_ONCE(desc->txd4, data);
-@@ -1186,11 +1259,12 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1185,11 +1258,12 @@ static int mtk_tx_map(struct sk_buff *sk
                .gso = gso,
                .csum = skb->ip_summed == CHECKSUM_PARTIAL,
                .vlan = skb_vlan_tag_present(skb),
@@ -173,7 +173,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct mtk_mac *mac = netdev_priv(dev);
        struct mtk_eth *eth = mac->hw;
        const struct mtk_soc_data *soc = eth->soc;
-@@ -1198,8 +1272,10 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1197,8 +1271,10 @@ static int mtk_tx_map(struct sk_buff *sk
        struct mtk_tx_dma *itxd_pdma, *txd_pdma;
        struct mtk_tx_buf *itx_buf, *tx_buf;
        int i, n_desc = 1;
@@ -184,7 +184,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        itxd = ring->next_free;
        itxd_pdma = qdma_to_pdma(ring, itxd);
        if (itxd == ring->last_free)
-@@ -1248,7 +1324,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1247,7 +1323,7 @@ static int mtk_tx_map(struct sk_buff *sk
                        memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
                        txd_info.size = min_t(unsigned int, frag_size,
                                              soc->txrx.dma_max_len);
@@ -193,7 +193,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
                                        !(frag_size - txd_info.size);
                        txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag,
-@@ -1287,7 +1363,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1286,7 +1362,7 @@ static int mtk_tx_map(struct sk_buff *sk
                        txd_pdma->txd2 |= TX_DMA_LS1;
        }
  
@@ -202,7 +202,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        skb_tx_timestamp(skb);
  
        ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -1299,8 +1375,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1298,8 +1374,7 @@ static int mtk_tx_map(struct sk_buff *sk
        wmb();
  
        if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
@@ -212,7 +212,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr);
        } else {
                int next_idx;
-@@ -1369,7 +1444,7 @@ static void mtk_wake_queue(struct mtk_et
+@@ -1368,7 +1443,7 @@ static void mtk_wake_queue(struct mtk_et
        for (i = 0; i < MTK_MAC_COUNT; i++) {
                if (!eth->netdev[i])
                        continue;
@@ -221,7 +221,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  }
  
-@@ -1393,7 +1468,7 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1392,7 +1467,7 @@ static netdev_tx_t mtk_start_xmit(struct
  
        tx_num = mtk_cal_txd_req(eth, skb);
        if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
@@ -230,7 +230,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                netif_err(eth, tx_queued, dev,
                          "Tx Ring full when queue awake!\n");
                spin_unlock(&eth->page_lock);
-@@ -1419,7 +1494,7 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1418,7 +1493,7 @@ static netdev_tx_t mtk_start_xmit(struct
                goto drop;
  
        if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
@@ -239,7 +239,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        spin_unlock(&eth->page_lock);
  
-@@ -1586,10 +1661,12 @@ static int mtk_xdp_submit_frame(struct m
+@@ -1585,10 +1660,12 @@ static int mtk_xdp_submit_frame(struct m
        struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf);
        const struct mtk_soc_data *soc = eth->soc;
        struct mtk_tx_ring *ring = &eth->tx_ring;
@@ -252,7 +252,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        };
        int err, index = 0, n_desc = 1, nr_frags;
        struct mtk_tx_buf *htx_buf, *tx_buf;
-@@ -1639,6 +1716,7 @@ static int mtk_xdp_submit_frame(struct m
+@@ -1638,6 +1715,7 @@ static int mtk_xdp_submit_frame(struct m
                memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
                txd_info.size = skb_frag_size(&sinfo->frags[index]);
                txd_info.last = index + 1 == nr_frags;
@@ -260,7 +260,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                data = skb_frag_address(&sinfo->frags[index]);
  
                index++;
-@@ -1993,8 +2071,46 @@ rx_done:
+@@ -1992,8 +2070,46 @@ rx_done:
        return done;
  }
  
@@ -308,7 +308,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  {
        const struct mtk_reg_map *reg_map = eth->soc->reg_map;
        struct mtk_tx_ring *ring = &eth->tx_ring;
-@@ -2026,12 +2142,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
+@@ -2025,12 +2141,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
                        break;
  
                if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
@@ -323,7 +323,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        budget--;
                }
                mtk_tx_unmap(eth, tx_buf, &bq, true);
-@@ -2050,7 +2163,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+@@ -2049,7 +2162,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
  }
  
  static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget,
@@ -332,7 +332,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  {
        struct mtk_tx_ring *ring = &eth->tx_ring;
        struct mtk_tx_buf *tx_buf;
-@@ -2068,12 +2181,8 @@ static int mtk_poll_tx_pdma(struct mtk_e
+@@ -2067,12 +2180,8 @@ static int mtk_poll_tx_pdma(struct mtk_e
                        break;
  
                if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
@@ -347,7 +347,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        budget--;
                }
                mtk_tx_unmap(eth, tx_buf, &bq, true);
-@@ -2095,26 +2204,15 @@ static int mtk_poll_tx(struct mtk_eth *e
+@@ -2094,26 +2203,15 @@ static int mtk_poll_tx(struct mtk_eth *e
  {
        struct mtk_tx_ring *ring = &eth->tx_ring;
        struct dim_sample dim_sample = {};
@@ -379,7 +379,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes,
                          &dim_sample);
-@@ -2124,7 +2222,7 @@ static int mtk_poll_tx(struct mtk_eth *e
+@@ -2123,7 +2221,7 @@ static int mtk_poll_tx(struct mtk_eth *e
            (atomic_read(&ring->free_count) > ring->thresh))
                mtk_wake_queue(eth);
  
@@ -388,7 +388,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  }
  
  static void mtk_handle_status_irq(struct mtk_eth *eth)
-@@ -2210,6 +2308,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2209,6 +2307,7 @@ static int mtk_tx_alloc(struct mtk_eth *
        int i, sz = soc->txrx.txd_size;
        struct mtk_tx_dma_v2 *txd;
        int ring_size;
@@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
                ring_size = MTK_QDMA_RING_SIZE;
-@@ -2277,8 +2376,25 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2276,8 +2375,25 @@ static int mtk_tx_alloc(struct mtk_eth *
                        ring->phys + ((ring_size - 1) * sz),
                        soc->reg_map->qdma.crx_ptr);
                mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr);
@@ -424,7 +424,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        } else {
                mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
                mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0);
-@@ -2963,7 +3079,7 @@ static int mtk_start_dma(struct mtk_eth
+@@ -2962,7 +3078,7 @@ static int mtk_start_dma(struct mtk_eth
                if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
                        val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
                               MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
@@ -433,7 +433,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                else
                        val |= MTK_RX_BT_32DWORDS;
                mtk_w32(eth, val, reg_map->qdma.glo_cfg);
-@@ -3009,6 +3125,45 @@ static void mtk_gdm_config(struct mtk_et
+@@ -3008,6 +3124,45 @@ static void mtk_gdm_config(struct mtk_et
        mtk_w32(eth, 0, MTK_RST_GL);
  }
  
@@ -479,7 +479,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  static int mtk_open(struct net_device *dev)
  {
        struct mtk_mac *mac = netdev_priv(dev);
-@@ -3051,7 +3206,8 @@ static int mtk_open(struct net_device *d
+@@ -3050,7 +3205,8 @@ static int mtk_open(struct net_device *d
                refcount_inc(&eth->dma_refcnt);
  
        phylink_start(mac->phylink);
@@ -489,7 +489,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        return 0;
  }
  
-@@ -3760,8 +3916,12 @@ static int mtk_unreg_dev(struct mtk_eth
+@@ -3759,8 +3915,12 @@ static int mtk_unreg_dev(struct mtk_eth
        int i;
  
        for (i = 0; i < MTK_MAC_COUNT; i++) {
@@ -502,7 +502,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                unregister_netdev(eth->netdev[i]);
        }
  
-@@ -3978,6 +4138,23 @@ static int mtk_set_rxnfc(struct net_devi
+@@ -3977,6 +4137,23 @@ static int mtk_set_rxnfc(struct net_devi
        return ret;
  }
  
@@ -526,7 +526,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  static const struct ethtool_ops mtk_ethtool_ops = {
        .get_link_ksettings     = mtk_get_link_ksettings,
        .set_link_ksettings     = mtk_set_link_ksettings,
-@@ -4012,6 +4189,7 @@ static const struct net_device_ops mtk_n
+@@ -4011,6 +4188,7 @@ static const struct net_device_ops mtk_n
        .ndo_setup_tc           = mtk_eth_setup_tc,
        .ndo_bpf                = mtk_xdp,
        .ndo_xdp_xmit           = mtk_xdp_xmit,
@@ -534,7 +534,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  };
  
  static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
-@@ -4021,6 +4199,7 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4020,6 +4198,7 @@ static int mtk_add_mac(struct mtk_eth *e
        struct phylink *phylink;
        struct mtk_mac *mac;
        int id, err;
@@ -542,7 +542,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        if (!_id) {
                dev_err(eth->dev, "missing mac id\n");
-@@ -4038,7 +4217,10 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4037,7 +4216,10 @@ static int mtk_add_mac(struct mtk_eth *e
                return -EINVAL;
        }
  
@@ -554,7 +554,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        if (!eth->netdev[id]) {
                dev_err(eth->dev, "alloc_etherdev failed\n");
                return -ENOMEM;
-@@ -4146,6 +4328,11 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4145,6 +4327,11 @@ static int mtk_add_mac(struct mtk_eth *e
        else
                eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
  
index b45a33c4cb53880a9207dd7a908ad1b0cad844a0..b8e3452f300b0d126901e013a1567088ce4bf8b7 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
  #include "mtk_eth_soc.h"
  #include "mtk_wed.h"
-@@ -2022,16 +2023,22 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2021,16 +2022,22 @@ static int mtk_poll_rx(struct napi_struc
                                                htons(RX_DMA_VPID(trxd.rxd4)),
                                                RX_DMA_VID(trxd.rxd4));
                        } else if (trxd.rxd2 & RX_DMA_VTAG) {
@@ -52,7 +52,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                }
  
                skb_record_rx_queue(skb, 0);
-@@ -2859,15 +2866,30 @@ static netdev_features_t mtk_fix_feature
+@@ -2858,15 +2865,30 @@ static netdev_features_t mtk_fix_feature
  
  static int mtk_set_features(struct net_device *dev, netdev_features_t features)
  {
@@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  }
  
  /* wait for DMA to finish whatever it is doing before we start using it again */
-@@ -3164,11 +3186,45 @@ found:
+@@ -3163,11 +3185,45 @@ found:
        return NOTIFY_DONE;
  }
  
@@ -135,7 +135,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
        if (err) {
-@@ -3689,6 +3745,10 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3688,6 +3744,10 @@ static int mtk_hw_init(struct mtk_eth *e
         */
        val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
        mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
@@ -146,7 +146,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        /* Enable RX VLan Offloading */
        mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-@@ -3908,6 +3968,12 @@ static int mtk_free_dev(struct mtk_eth *
+@@ -3907,6 +3967,12 @@ static int mtk_free_dev(struct mtk_eth *
                free_netdev(eth->netdev[i]);
        }
  
index 42c745d02fa9a0d34dc2951cf45e7b0f8ebc17c9..a88df2b8e3a22755e529e5d4a61095b1025eba07 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3202,7 +3202,8 @@ static int mtk_open(struct net_device *d
+@@ -3201,7 +3201,8 @@ static int mtk_open(struct net_device *d
        struct mtk_eth *eth = mac->hw;
        int i, err;
  
@@ -30,7 +30,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
                        struct metadata_dst *md_dst = eth->dsa_meta[i];
  
-@@ -3219,7 +3220,8 @@ static int mtk_open(struct net_device *d
+@@ -3218,7 +3219,8 @@ static int mtk_open(struct net_device *d
                }
        } else {
                /* Hardware special tag parsing needs to be disabled if at least
index 39874c9d1c09597013b0e6d5236d1e2fc130b9ab..8da728b9e9d479401eb3fbd7a689f9bdbc96ff6d 100644 (file)
@@ -23,7 +23,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3137,7 +3137,7 @@ static void mtk_gdm_config(struct mtk_et
+@@ -3136,7 +3136,7 @@ static void mtk_gdm_config(struct mtk_et
  
                val |= config;
  
@@ -32,7 +32,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
                        val |= MTK_GDMA_SPECIAL_TAG;
  
                mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-@@ -3202,8 +3202,7 @@ static int mtk_open(struct net_device *d
+@@ -3201,8 +3201,7 @@ static int mtk_open(struct net_device *d
        struct mtk_eth *eth = mac->hw;
        int i, err;
  
@@ -42,7 +42,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
                for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
                        struct metadata_dst *md_dst = eth->dsa_meta[i];
  
-@@ -3220,8 +3219,7 @@ static int mtk_open(struct net_device *d
+@@ -3219,8 +3218,7 @@ static int mtk_open(struct net_device *d
                }
        } else {
                /* Hardware special tag parsing needs to be disabled if at least
index a9879ebfa9d21bd0664f4c2c6bd13510131fcf86..51cd572ab245af2470c4a20e09f1fd60bc2aec79 100644 (file)
@@ -77,7 +77,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1878,7 +1878,9 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1877,7 +1877,9 @@ static int mtk_poll_rx(struct napi_struc
  
        while (done < budget) {
                unsigned int pktlen, *rxdcsum;
@@ -87,7 +87,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
                dma_addr_t dma_addr;
                u32 hash, reason;
                int mac = 0;
-@@ -2018,27 +2020,29 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2017,27 +2019,29 @@ static int mtk_poll_rx(struct napi_struc
  
                if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
                        if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
index 089f25545d60f46dd2c72511324d9da4e973ea41..a1247218b0928ba0c3622bad49b2f2e86940a2ad 100644 (file)
@@ -57,7 +57,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                mtk_eth_path_name(path), __func__, updated);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4804,6 +4804,26 @@ static const struct mtk_soc_data mt7629_
+@@ -4803,6 +4803,26 @@ static const struct mtk_soc_data mt7629_
        },
  };
  
@@ -84,7 +84,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  static const struct mtk_soc_data mt7986_data = {
        .reg_map = &mt7986_reg_map,
        .ana_rgc3 = 0x128,
-@@ -4846,6 +4866,7 @@ const struct of_device_id of_mtk_match[]
+@@ -4845,6 +4865,7 @@ const struct of_device_id of_mtk_match[]
        { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
        { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
        { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
index ea20bd87f7341784eb4830ef224c672abbaf67d3..1cb1f405385c3c586692f4de5b88d82316e86b7d 100644 (file)
@@ -21,7 +21,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -745,8 +745,10 @@ static const struct phylink_mac_ops mtk_
+@@ -744,8 +744,10 @@ static const struct phylink_mac_ops mtk_
  
  static int mtk_mdio_init(struct mtk_eth *eth)
  {
@@ -32,7 +32,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
        mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
        if (!mii_np) {
-@@ -773,6 +775,25 @@ static int mtk_mdio_init(struct mtk_eth
+@@ -772,6 +774,25 @@ static int mtk_mdio_init(struct mtk_eth
        eth->mii_bus->parent = eth->dev;
  
        snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
index 15295959c11ad9028b6cc37ee56137b8af7c82a3..110944658dee8088114834bf082cd0d22063662c 100644 (file)
@@ -60,7 +60,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
  
        return NULL;
-@@ -4017,8 +4018,17 @@ static int mtk_unreg_dev(struct mtk_eth
+@@ -4016,8 +4017,17 @@ static int mtk_unreg_dev(struct mtk_eth
        return 0;
  }
  
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        mtk_unreg_dev(eth);
        mtk_free_dev(eth);
        cancel_work_sync(&eth->pending_work);
-@@ -4458,6 +4468,36 @@ void mtk_eth_set_dma_device(struct mtk_e
+@@ -4457,6 +4467,36 @@ void mtk_eth_set_dma_device(struct mtk_e
        rtnl_unlock();
  }
  
@@ -115,7 +115,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  static int mtk_probe(struct platform_device *pdev)
  {
        struct resource *res = NULL;
-@@ -4521,13 +4561,7 @@ static int mtk_probe(struct platform_dev
+@@ -4520,13 +4560,7 @@ static int mtk_probe(struct platform_dev
        }
  
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
@@ -130,7 +130,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
                if (err)
                        return err;
-@@ -4538,14 +4572,17 @@ static int mtk_probe(struct platform_dev
+@@ -4537,14 +4571,17 @@ static int mtk_probe(struct platform_dev
                                                            "mediatek,pctl");
                if (IS_ERR(eth->pctl)) {
                        dev_err(&pdev->dev, "no pctl regmap found\n");
@@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
  
        if (eth->soc->offload_version) {
-@@ -4704,6 +4741,8 @@ err_deinit_hw:
+@@ -4703,6 +4740,8 @@ err_deinit_hw:
        mtk_hw_deinit(eth);
  err_wed_exit:
        mtk_wed_exit();
index df8d6427943c9d8331115753c4bd5db9b68d51ac..93eaffa19e77450100f2fa7ecac98a535b68ece8 100644 (file)
@@ -27,7 +27,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4692,8 +4692,8 @@ static int mtk_probe(struct platform_dev
+@@ -4691,8 +4691,8 @@ static int mtk_probe(struct platform_dev
                for (i = 0; i < num_ppe; i++) {
                        u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
  
@@ -38,7 +38,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        if (!eth->ppe[i]) {
                                err = -ENOMEM;
                                goto err_deinit_ppe;
-@@ -4817,6 +4817,7 @@ static const struct mtk_soc_data mt7622_
+@@ -4816,6 +4816,7 @@ static const struct mtk_soc_data mt7622_
        .required_pctl = false,
        .offload_version = 2,
        .hash_offset = 2,
@@ -46,7 +46,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4854,6 +4855,7 @@ static const struct mtk_soc_data mt7629_
+@@ -4853,6 +4854,7 @@ static const struct mtk_soc_data mt7629_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7629_CLKS_BITMAP,
        .required_pctl = false,
@@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
                .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4874,6 +4876,7 @@ static const struct mtk_soc_data mt7981_
+@@ -4873,6 +4875,7 @@ static const struct mtk_soc_data mt7981_
        .offload_version = 2,
        .hash_offset = 4,
        .foe_entry_size = sizeof(struct mtk_foe_entry),
@@ -62,7 +62,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma_v2),
                .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4894,6 +4897,7 @@ static const struct mtk_soc_data mt7986_
+@@ -4893,6 +4896,7 @@ static const struct mtk_soc_data mt7986_
        .offload_version = 2,
        .hash_offset = 4,
        .foe_entry_size = sizeof(struct mtk_foe_entry),
index d6309964c384bda00bb549d3f800df4b208d41d6..217e517c3af4c66a7cbb5875379adec3b56cf3d8 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1898,9 +1898,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1897,9 +1897,7 @@ static int mtk_poll_rx(struct napi_struc
  
        while (done < budget) {
                unsigned int pktlen, *rxdcsum;
@@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                dma_addr_t dma_addr;
                u32 hash, reason;
                int mac = 0;
-@@ -2035,36 +2033,21 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2034,36 +2032,21 @@ static int mtk_poll_rx(struct napi_struc
                        skb_checksum_none_assert(skb);
                skb->protocol = eth_type_trans(skb, netdev);
  
@@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                skb_record_rx_queue(skb, 0);
                napi_gro_receive(napi, skb);
  
-@@ -2890,29 +2873,11 @@ static netdev_features_t mtk_fix_feature
+@@ -2889,29 +2872,11 @@ static netdev_features_t mtk_fix_feature
  
  static int mtk_set_features(struct net_device *dev, netdev_features_t features)
  {
@@ -100,7 +100,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        return 0;
  }
  
-@@ -3226,30 +3191,6 @@ static int mtk_open(struct net_device *d
+@@ -3225,30 +3190,6 @@ static int mtk_open(struct net_device *d
        struct mtk_eth *eth = mac->hw;
        int i, err;
  
@@ -131,7 +131,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
        if (err) {
                netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3288,6 +3229,35 @@ static int mtk_open(struct net_device *d
+@@ -3287,6 +3228,35 @@ static int mtk_open(struct net_device *d
        phylink_start(mac->phylink);
        netif_tx_start_all_queues(dev);
  
@@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        return 0;
  }
  
-@@ -3772,10 +3742,9 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3771,10 +3741,9 @@ static int mtk_hw_init(struct mtk_eth *e
        if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
                val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
                mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
@@ -180,7 +180,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        /* set interrupt delays based on current Net DIM sample */
        mtk_dim_rx(&eth->rx_dim.work);
-@@ -4415,7 +4384,7 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4414,7 +4383,7 @@ static int mtk_add_mac(struct mtk_eth *e
                eth->netdev[id]->hw_features |= NETIF_F_LRO;
  
        eth->netdev[id]->vlan_features = eth->soc->hw_features &
index a0b9b6a299bc21c5f8509daddce2b36de77eca25..d7d1c08fce0dc8248dc4a755123d00b00220e0eb 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4766,7 +4766,7 @@ static const struct mtk_soc_data mt7621_
+@@ -4765,7 +4765,7 @@ static const struct mtk_soc_data mt7621_
        .required_pctl = false,
        .offload_version = 1,
        .hash_offset = 2,
@@ -26,7 +26,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
                .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4787,7 +4787,7 @@ static const struct mtk_soc_data mt7622_
+@@ -4786,7 +4786,7 @@ static const struct mtk_soc_data mt7622_
        .offload_version = 2,
        .hash_offset = 2,
        .has_accounting = true,
@@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
                .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4806,7 +4806,7 @@ static const struct mtk_soc_data mt7623_
+@@ -4805,7 +4805,7 @@ static const struct mtk_soc_data mt7623_
        .required_pctl = true,
        .offload_version = 1,
        .hash_offset = 2,
@@ -44,7 +44,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
                .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4844,8 +4844,8 @@ static const struct mtk_soc_data mt7981_
+@@ -4843,8 +4843,8 @@ static const struct mtk_soc_data mt7981_
        .required_pctl = false,
        .offload_version = 2,
        .hash_offset = 4,
@@ -54,7 +54,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma_v2),
                .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4865,8 +4865,8 @@ static const struct mtk_soc_data mt7986_
+@@ -4864,8 +4864,8 @@ static const struct mtk_soc_data mt7986_
        .required_pctl = false,
        .offload_version = 2,
        .hash_offset = 4,
index 8914e8da96d87cea7c75135e831b2d4c848d36dd..fb54f404b21a9ae12d1788ba198979b6610b0e7e 100644 (file)
@@ -95,7 +95,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
                                /* mt7623_pad_clk_setup */
                                for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
-@@ -4343,13 +4315,19 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4342,13 +4314,19 @@ static int mtk_add_mac(struct mtk_eth *e
        mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
                MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
  
@@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
                __set_bit(PHY_INTERFACE_MODE_TRGMII,
-@@ -4807,6 +4785,7 @@ static const struct mtk_soc_data mt7623_
+@@ -4806,6 +4784,7 @@ static const struct mtk_soc_data mt7623_
        .offload_version = 1,
        .hash_offset = 2,
        .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
index 351568f187ca9c9aa79ba7fd1542cbf29d8df588..293066fa9a05eeb81e242de21553e4b5328bc36a 100644 (file)
@@ -62,15 +62,15 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
                              phy_interface_t interface)
  {
-@@ -709,7 +677,6 @@ static void mtk_mac_link_up(struct phyli
+@@ -708,7 +676,6 @@ static void mtk_mac_link_up(struct phyli
  static const struct phylink_mac_ops mtk_phylink_ops = {
-       .validate = phylink_generic_validate,
        .mac_select_pcs = mtk_mac_select_pcs,
 -      .mac_pcs_get_state = mtk_mac_pcs_get_state,
        .mac_config = mtk_mac_config,
        .mac_finish = mtk_mac_finish,
        .mac_link_down = mtk_mac_link_down,
-@@ -4310,8 +4277,6 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4309,8 +4276,6 @@ static int mtk_add_mac(struct mtk_eth *e
  
        mac->phylink_config.dev = &eth->netdev[id]->dev;
        mac->phylink_config.type = PHYLINK_NETDEV;
index f479522339428311219d5f67ed7d998eca550363..25c87b0415e0ab13ef00b989cc93ee4350438488 100644 (file)
@@ -32,7 +32,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
  
        if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-@@ -956,7 +956,7 @@ static bool mtk_rx_get_desc(struct mtk_e
+@@ -955,7 +955,7 @@ static bool mtk_rx_get_desc(struct mtk_e
        rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
        rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
        rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
@@ -41,7 +41,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
                rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
        }
-@@ -1014,7 +1014,7 @@ static int mtk_init_fq_dma(struct mtk_et
+@@ -1013,7 +1013,7 @@ static int mtk_init_fq_dma(struct mtk_et
  
                txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
                txd->txd4 = 0;
@@ -50,7 +50,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        txd->txd5 = 0;
                        txd->txd6 = 0;
                        txd->txd7 = 0;
-@@ -1205,7 +1205,7 @@ static void mtk_tx_set_dma_desc(struct n
+@@ -1204,7 +1204,7 @@ static void mtk_tx_set_dma_desc(struct n
        struct mtk_mac *mac = netdev_priv(dev);
        struct mtk_eth *eth = mac->hw;
  
@@ -59,7 +59,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                mtk_tx_set_dma_desc_v2(dev, txd, info);
        else
                mtk_tx_set_dma_desc_v1(dev, txd, info);
-@@ -1512,7 +1512,7 @@ static void mtk_update_rx_cpu_idx(struct
+@@ -1511,7 +1511,7 @@ static void mtk_update_rx_cpu_idx(struct
  
  static bool mtk_page_pool_enabled(struct mtk_eth *eth)
  {
@@ -68,7 +68,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  }
  
  static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
-@@ -1854,7 +1854,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1853,7 +1853,7 @@ static int mtk_poll_rx(struct napi_struc
                        break;
  
                /* find out which mac the packet come from. values start at 1 */
@@ -77,7 +77,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
                else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
                         !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-@@ -1950,7 +1950,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1949,7 +1949,7 @@ static int mtk_poll_rx(struct napi_struc
                skb->dev = netdev;
                bytes += skb->len;
  
@@ -86,7 +86,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
                        hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
                        if (hash != MTK_RXD5_FOE_ENTRY)
-@@ -1975,8 +1975,8 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1974,8 +1974,8 @@ static int mtk_poll_rx(struct napi_struc
                /* When using VLAN untagging in combination with DSA, the
                 * hardware treats the MTK special tag as a VLAN and untags it.
                 */
@@ -97,7 +97,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
  
                        if (port < ARRAY_SIZE(eth->dsa_meta) &&
-@@ -2286,7 +2286,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2285,7 +2285,7 @@ static int mtk_tx_alloc(struct mtk_eth *
                txd->txd2 = next_ptr;
                txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
                txd->txd4 = 0;
@@ -106,7 +106,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        txd->txd5 = 0;
                        txd->txd6 = 0;
                        txd->txd7 = 0;
-@@ -2339,14 +2339,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2338,14 +2338,14 @@ static int mtk_tx_alloc(struct mtk_eth *
                              FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
                              FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
                              MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
@@ -123,7 +123,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
        } else {
                mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
-@@ -2475,7 +2475,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2474,7 +2474,7 @@ static int mtk_rx_alloc(struct mtk_eth *
  
                rxd->rxd3 = 0;
                rxd->rxd4 = 0;
@@ -132,7 +132,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        rxd->rxd5 = 0;
                        rxd->rxd6 = 0;
                        rxd->rxd7 = 0;
-@@ -3026,7 +3026,7 @@ static int mtk_start_dma(struct mtk_eth
+@@ -3025,7 +3025,7 @@ static int mtk_start_dma(struct mtk_eth
                       MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
                       MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
  
@@ -141,7 +141,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
                               MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
                               MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
-@@ -3168,7 +3168,7 @@ static int mtk_open(struct net_device *d
+@@ -3167,7 +3167,7 @@ static int mtk_open(struct net_device *d
        phylink_start(mac->phylink);
        netif_tx_start_all_queues(dev);
  
@@ -150,7 +150,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                return 0;
  
        if (mtk_uses_dsa(dev) && !eth->prog) {
-@@ -3433,7 +3433,7 @@ static void mtk_hw_reset(struct mtk_eth
+@@ -3432,7 +3432,7 @@ static void mtk_hw_reset(struct mtk_eth
  {
        u32 val;
  
@@ -159,7 +159,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
                val = RSTCTRL_PPE0_V2;
        } else {
-@@ -3445,7 +3445,7 @@ static void mtk_hw_reset(struct mtk_eth
+@@ -3444,7 +3444,7 @@ static void mtk_hw_reset(struct mtk_eth
  
        ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
  
@@ -168,7 +168,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
                             0x3ffffff);
  }
-@@ -3471,7 +3471,7 @@ static void mtk_hw_warm_reset(struct mtk
+@@ -3470,7 +3470,7 @@ static void mtk_hw_warm_reset(struct mtk
                return;
        }
  
@@ -177,7 +177,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
        else
                rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
-@@ -3641,7 +3641,7 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3640,7 +3640,7 @@ static int mtk_hw_init(struct mtk_eth *e
        else
                mtk_hw_reset(eth);
  
@@ -186,7 +186,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                /* Set FE to PDMAv2 if necessary */
                val = mtk_r32(eth, MTK_FE_GLO_MISC);
                mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
-@@ -3678,7 +3678,7 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3677,7 +3677,7 @@ static int mtk_hw_init(struct mtk_eth *e
         */
        val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
        mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
@@ -195,7 +195,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
                mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
  
-@@ -3700,7 +3700,7 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3699,7 +3699,7 @@ static int mtk_hw_init(struct mtk_eth *e
        mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
        mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
  
@@ -204,7 +204,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                /* PSE should not drop port8 and port9 packets from WDMA Tx */
                mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
  
-@@ -4489,7 +4489,7 @@ static int mtk_probe(struct platform_dev
+@@ -4488,7 +4488,7 @@ static int mtk_probe(struct platform_dev
                }
        }
  
@@ -213,7 +213,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                if (!res) {
                        err = -EINVAL;
-@@ -4597,9 +4597,8 @@ static int mtk_probe(struct platform_dev
+@@ -4596,9 +4596,8 @@ static int mtk_probe(struct platform_dev
        }
  
        if (eth->soc->offload_version) {
@@ -224,7 +224,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
                for (i = 0; i < num_ppe; i++) {
                        u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
-@@ -4691,6 +4690,7 @@ static const struct mtk_soc_data mt2701_
+@@ -4690,6 +4689,7 @@ static const struct mtk_soc_data mt2701_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
@@ -232,7 +232,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
                .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4707,6 +4707,7 @@ static const struct mtk_soc_data mt7621_
+@@ -4706,6 +4706,7 @@ static const struct mtk_soc_data mt7621_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7621_CLKS_BITMAP,
        .required_pctl = false,
@@ -240,7 +240,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .offload_version = 1,
        .hash_offset = 2,
        .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-@@ -4727,6 +4728,7 @@ static const struct mtk_soc_data mt7622_
+@@ -4726,6 +4727,7 @@ static const struct mtk_soc_data mt7622_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7622_CLKS_BITMAP,
        .required_pctl = false,
@@ -248,7 +248,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .offload_version = 2,
        .hash_offset = 2,
        .has_accounting = true,
-@@ -4747,6 +4749,7 @@ static const struct mtk_soc_data mt7623_
+@@ -4746,6 +4748,7 @@ static const struct mtk_soc_data mt7623_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
@@ -256,7 +256,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .offload_version = 1,
        .hash_offset = 2,
        .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-@@ -4769,6 +4772,7 @@ static const struct mtk_soc_data mt7629_
+@@ -4768,6 +4771,7 @@ static const struct mtk_soc_data mt7629_
        .required_clks = MT7629_CLKS_BITMAP,
        .required_pctl = false,
        .has_accounting = true,
@@ -264,7 +264,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .txrx = {
                .txd_size = sizeof(struct mtk_tx_dma),
                .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4786,6 +4790,7 @@ static const struct mtk_soc_data mt7981_
+@@ -4785,6 +4789,7 @@ static const struct mtk_soc_data mt7981_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7981_CLKS_BITMAP,
        .required_pctl = false,
@@ -272,7 +272,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .offload_version = 2,
        .hash_offset = 4,
        .has_accounting = true,
-@@ -4807,6 +4812,7 @@ static const struct mtk_soc_data mt7986_
+@@ -4806,6 +4811,7 @@ static const struct mtk_soc_data mt7986_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7986_CLKS_BITMAP,
        .required_pctl = false,
@@ -280,7 +280,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        .offload_version = 2,
        .hash_offset = 4,
        .has_accounting = true,
-@@ -4827,6 +4833,7 @@ static const struct mtk_soc_data rt5350_
+@@ -4826,6 +4832,7 @@ static const struct mtk_soc_data rt5350_
        .hw_features = MTK_HW_FEATURES_MT7628,
        .required_clks = MT7628_CLKS_BITMAP,
        .required_pctl = false,
index 5ac9d61ab424a761b123a0d319ce43e6a5e2b3bc..80716583134404c98e26acc14bce69567ab1d3c8 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -882,7 +882,7 @@ static void mtk_stats_update(struct mtk_
+@@ -881,7 +881,7 @@ static void mtk_stats_update(struct mtk_
  {
        int i;
  
@@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                if (!eth->mac[i] || !eth->mac[i]->hw_stats)
                        continue;
                if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
-@@ -1387,7 +1387,7 @@ static int mtk_queue_stopped(struct mtk_
+@@ -1386,7 +1386,7 @@ static int mtk_queue_stopped(struct mtk_
  {
        int i;
  
@@ -35,7 +35,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                if (!eth->netdev[i])
                        continue;
                if (netif_queue_stopped(eth->netdev[i]))
-@@ -1401,7 +1401,7 @@ static void mtk_wake_queue(struct mtk_et
+@@ -1400,7 +1400,7 @@ static void mtk_wake_queue(struct mtk_et
  {
        int i;
  
@@ -44,7 +44,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                if (!eth->netdev[i])
                        continue;
                netif_tx_wake_all_queues(eth->netdev[i]);
-@@ -1860,7 +1860,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1859,7 +1859,7 @@ static int mtk_poll_rx(struct napi_struc
                         !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
                        mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
  
@@ -53,7 +53,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                             !eth->netdev[mac]))
                        goto release_desc;
  
-@@ -2900,7 +2900,7 @@ static void mtk_dma_free(struct mtk_eth
+@@ -2899,7 +2899,7 @@ static void mtk_dma_free(struct mtk_eth
        const struct mtk_soc_data *soc = eth->soc;
        int i;
  
@@ -62,7 +62,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                if (eth->netdev[i])
                        netdev_reset_queue(eth->netdev[i]);
        if (eth->scratch_ring) {
-@@ -3054,8 +3054,13 @@ static void mtk_gdm_config(struct mtk_et
+@@ -3053,8 +3053,13 @@ static void mtk_gdm_config(struct mtk_et
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
                return;
  
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
                /* default setup the forward port to send frame to PDMA */
                val &= ~0xffff;
-@@ -3065,7 +3070,7 @@ static void mtk_gdm_config(struct mtk_et
+@@ -3064,7 +3069,7 @@ static void mtk_gdm_config(struct mtk_et
  
                val |= config;
  
@@ -87,7 +87,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        val |= MTK_GDMA_SPECIAL_TAG;
  
                mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-@@ -3662,15 +3667,15 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3661,15 +3666,15 @@ static int mtk_hw_init(struct mtk_eth *e
         * up with the more appropriate value when mtk_mac_config call is being
         * invoked.
         */
@@ -109,7 +109,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
  
        /* Indicates CDM to parse the MTK special tag from CPU
-@@ -3850,7 +3855,7 @@ static void mtk_pending_work(struct work
+@@ -3849,7 +3854,7 @@ static void mtk_pending_work(struct work
        mtk_prepare_for_reset(eth);
  
        /* stop all devices to make sure that dma is properly shut down */
@@ -118,7 +118,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
                        continue;
  
-@@ -3866,8 +3871,8 @@ static void mtk_pending_work(struct work
+@@ -3865,8 +3870,8 @@ static void mtk_pending_work(struct work
        mtk_hw_init(eth, true);
  
        /* restart DMA and enable IRQs */
@@ -129,7 +129,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                        continue;
  
                if (mtk_open(eth->netdev[i])) {
-@@ -3894,7 +3899,7 @@ static int mtk_free_dev(struct mtk_eth *
+@@ -3893,7 +3898,7 @@ static int mtk_free_dev(struct mtk_eth *
  {
        int i;
  
@@ -138,7 +138,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                if (!eth->netdev[i])
                        continue;
                free_netdev(eth->netdev[i]);
-@@ -3913,7 +3918,7 @@ static int mtk_unreg_dev(struct mtk_eth
+@@ -3912,7 +3917,7 @@ static int mtk_unreg_dev(struct mtk_eth
  {
        int i;
  
@@ -147,7 +147,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                struct mtk_mac *mac;
                if (!eth->netdev[i])
                        continue;
-@@ -4214,7 +4219,7 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4213,7 +4218,7 @@ static int mtk_add_mac(struct mtk_eth *e
        }
  
        id = be32_to_cpup(_id);
@@ -156,7 +156,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                dev_err(eth->dev, "%d is not a valid mac id\n", id);
                return -EINVAL;
        }
-@@ -4359,7 +4364,7 @@ void mtk_eth_set_dma_device(struct mtk_e
+@@ -4358,7 +4363,7 @@ void mtk_eth_set_dma_device(struct mtk_e
  
        rtnl_lock();
  
@@ -165,7 +165,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                dev = eth->netdev[i];
  
                if (!dev || !(dev->flags & IFF_UP))
-@@ -4665,7 +4670,7 @@ static int mtk_remove(struct platform_de
+@@ -4664,7 +4669,7 @@ static int mtk_remove(struct platform_de
        int i;
  
        /* stop all devices to make sure that dma is properly shut down */
index bf6ef4c137067657d29f01a68fe532fc7d7387d1..1a9b31f526b469e0a21961b820ca64b96c0574cd 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -862,17 +862,32 @@ void mtk_stats_update_mac(struct mtk_mac
+@@ -861,17 +861,32 @@ void mtk_stats_update_mac(struct mtk_mac
                        mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
                hw_stats->rx_flow_control_packets +=
                        mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
@@ -62,7 +62,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
  
        u64_stats_update_end(&hw_stats->syncp);
-@@ -1176,7 +1191,10 @@ static void mtk_tx_set_dma_desc_v2(struc
+@@ -1175,7 +1190,10 @@ static void mtk_tx_set_dma_desc_v2(struc
                data |= TX_DMA_LS0;
        WRITE_ONCE(desc->txd3, data);
  
@@ -74,7 +74,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
        WRITE_ONCE(desc->txd4, data);
  
-@@ -1187,6 +1205,8 @@ static void mtk_tx_set_dma_desc_v2(struc
+@@ -1186,6 +1204,8 @@ static void mtk_tx_set_dma_desc_v2(struc
                /* tx checksum offload */
                if (info->csum)
                        data |= TX_DMA_CHKSUM_V2;
@@ -83,7 +83,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
        WRITE_ONCE(desc->txd5, data);
  
-@@ -1252,8 +1272,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1251,8 +1271,7 @@ static int mtk_tx_map(struct sk_buff *sk
        mtk_tx_set_dma_desc(dev, itxd, &txd_info);
  
        itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
@@ -93,7 +93,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
                     k++);
  
-@@ -1301,8 +1320,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1300,8 +1319,7 @@ static int mtk_tx_map(struct sk_buff *sk
                                memset(tx_buf, 0, sizeof(*tx_buf));
                        tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
                        tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
@@ -103,7 +103,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
                        setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
                                     txd_info.size, k++);
-@@ -1604,7 +1622,7 @@ static int mtk_xdp_frame_map(struct mtk_
+@@ -1603,7 +1621,7 @@ static int mtk_xdp_frame_map(struct mtk_
        }
        mtk_tx_set_dma_desc(dev, txd, txd_info);
  
@@ -112,7 +112,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
        tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
  
-@@ -1854,11 +1872,24 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1853,11 +1871,24 @@ static int mtk_poll_rx(struct napi_struc
                        break;
  
                /* find out which mac the packet come from. values start at 1 */
@@ -141,7 +141,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
                if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
                             !eth->netdev[mac]))
-@@ -2080,7 +2111,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
+@@ -2079,7 +2110,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
  
        while ((cpu != dma) && budget) {
                u32 next_cpu = desc->txd2;
@@ -149,7 +149,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
                desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
                if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
-@@ -2088,15 +2118,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
+@@ -2087,15 +2117,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
  
                tx_buf = mtk_desc_to_tx_buf(ring, desc,
                                            eth->soc->txrx.txd_size);
@@ -167,7 +167,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
                        budget--;
                }
-@@ -3705,7 +3733,24 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -3704,7 +3732,24 @@ static int mtk_hw_init(struct mtk_eth *e
        mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
        mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
  
@@ -193,7 +193,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                /* PSE should not drop port8 and port9 packets from WDMA Tx */
                mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
  
-@@ -4267,7 +4312,11 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4266,7 +4311,11 @@ static int mtk_add_mac(struct mtk_eth *e
        }
        spin_lock_init(&mac->hw_stats->stats_lock);
        u64_stats_init(&mac->hw_stats->syncp);
index 97a2992cfedc7c194d71c6f5ea7601b76cd54012..8c24321dd4356fb0e826105fb972aae0555d4ed2 100644 (file)
@@ -219,7 +219,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        return;
  
  err_phy:
-@@ -726,11 +842,15 @@ static int mtk_mdio_init(struct mtk_eth
+@@ -725,11 +841,15 @@ static int mtk_mdio_init(struct mtk_eth
        }
        divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
  
@@ -239,7 +239,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
        dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
  
-@@ -1191,10 +1311,19 @@ static void mtk_tx_set_dma_desc_v2(struc
+@@ -1190,10 +1310,19 @@ static void mtk_tx_set_dma_desc_v2(struc
                data |= TX_DMA_LS0;
        WRITE_ONCE(desc->txd3, data);
  
@@ -263,7 +263,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
        WRITE_ONCE(desc->txd4, data);
  
-@@ -4361,6 +4490,17 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4360,6 +4489,17 @@ static int mtk_add_mac(struct mtk_eth *e
                          mac->phylink_config.supported_interfaces);
        }
  
@@ -281,7 +281,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        phylink = phylink_create(&mac->phylink_config,
                                 of_fwnode_handle(mac->of_node),
                                 phy_mode, &mtk_phylink_ops);
-@@ -4881,6 +5021,24 @@ static const struct mtk_soc_data mt7986_
+@@ -4880,6 +5020,24 @@ static const struct mtk_soc_data mt7986_
        },
  };
  
@@ -306,7 +306,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  static const struct mtk_soc_data rt5350_data = {
        .reg_map = &mt7628_reg_map,
        .caps = MT7628_CAPS,
-@@ -4899,14 +5057,15 @@ static const struct mtk_soc_data rt5350_
+@@ -4898,14 +5056,15 @@ static const struct mtk_soc_data rt5350_
  };
  
  const struct of_device_id of_mtk_match[] = {
index 62c38c7137f725c2933168be038bec2b2c6de634..3dc4662d1a547910a464f109138da48e8dc0032e 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1659,7 +1659,7 @@ static void mtk_update_rx_cpu_idx(struct
+@@ -1658,7 +1658,7 @@ static void mtk_update_rx_cpu_idx(struct
  
  static bool mtk_page_pool_enabled(struct mtk_eth *eth)
  {
index b175aedf0c43e2752f2d4a1669fc430c3320c5c6..32f26d7d27d0a6de86417d1788f2c5add01b0dfb 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5029,6 +5029,9 @@ static const struct mtk_soc_data mt7988_
+@@ -5028,6 +5028,9 @@ static const struct mtk_soc_data mt7988_
        .required_clks = MT7988_CLKS_BITMAP,
        .required_pctl = false,
        .version = 3,
index bf0a39b9d3fda8d653dde1258deab8a923554804..876bdd5dd31e65dcce387161a41b716364e5785a 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5031,6 +5031,7 @@ static const struct mtk_soc_data mt7988_
+@@ -5030,6 +5030,7 @@ static const struct mtk_soc_data mt7988_
        .version = 3,
        .offload_version = 2,
        .hash_offset = 4,
index a4ff5a292e7d8ea7620a8c76689e969ff9b457ce..05a18364d67968564b93620f44cd97810c2b13bb 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3595,19 +3595,34 @@ static void mtk_hw_reset(struct mtk_eth
+@@ -3594,19 +3594,34 @@ static void mtk_hw_reset(struct mtk_eth
  {
        u32 val;
  
@@ -56,7 +56,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
                             0x3ffffff);
  }
-@@ -3633,13 +3648,21 @@ static void mtk_hw_warm_reset(struct mtk
+@@ -3632,13 +3647,21 @@ static void mtk_hw_warm_reset(struct mtk
                return;
        }
  
@@ -83,7 +83,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
        regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
  
-@@ -3991,11 +4014,17 @@ static void mtk_prepare_for_reset(struct
+@@ -3990,11 +4013,17 @@ static void mtk_prepare_for_reset(struct
        u32 val;
        int i;
  
@@ -106,7 +106,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
        /* adjust PPE configurations to prepare for reset */
        for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
-@@ -4056,11 +4085,18 @@ static void mtk_pending_work(struct work
+@@ -4055,11 +4084,18 @@ static void mtk_pending_work(struct work
                }
        }
  
index 872262b0f82a80333ff5b4f9535d749170ee0303..74ac8dc89813a4389e8e22b01c97a6de1e3e7615 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1119,10 +1119,13 @@ static int mtk_init_fq_dma(struct mtk_et
+@@ -1118,10 +1118,13 @@ static int mtk_init_fq_dma(struct mtk_et
        dma_addr_t dma_addr;
        int i;
  
@@ -38,7 +38,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        if (unlikely(!eth->scratch_ring))
                return -ENOMEM;
  
-@@ -2430,8 +2433,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2429,8 +2432,14 @@ static int mtk_tx_alloc(struct mtk_eth *
        if (!ring->buf)
                goto no_tx_mem;
  
@@ -55,7 +55,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        if (!ring->dma)
                goto no_tx_mem;
  
-@@ -2530,8 +2539,7 @@ static void mtk_tx_clean(struct mtk_eth
+@@ -2529,8 +2538,7 @@ static void mtk_tx_clean(struct mtk_eth
                kfree(ring->buf);
                ring->buf = NULL;
        }
@@ -65,7 +65,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                dma_free_coherent(eth->dma_dev,
                                  ring->dma_size * soc->txrx.txd_size,
                                  ring->dma, ring->phys);
-@@ -2550,9 +2558,14 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2549,9 +2557,14 @@ static int mtk_rx_alloc(struct mtk_eth *
  {
        const struct mtk_reg_map *reg_map = eth->soc->reg_map;
        struct mtk_rx_ring *ring;
@@ -81,7 +81,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        if (rx_flag == MTK_RX_FLAGS_QDMA) {
                if (ring_no)
                        return -EINVAL;
-@@ -2587,9 +2600,20 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2586,9 +2599,20 @@ static int mtk_rx_alloc(struct mtk_eth *
                ring->page_pool = pp;
        }
  
@@ -105,7 +105,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        if (!ring->dma)
                return -ENOMEM;
  
-@@ -2674,7 +2698,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2673,7 +2697,7 @@ static int mtk_rx_alloc(struct mtk_eth *
        return 0;
  }
  
@@ -114,7 +114,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  {
        int i;
  
-@@ -2697,7 +2721,7 @@ static void mtk_rx_clean(struct mtk_eth
+@@ -2696,7 +2720,7 @@ static void mtk_rx_clean(struct mtk_eth
                ring->data = NULL;
        }
  
@@ -123,7 +123,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                dma_free_coherent(eth->dma_dev,
                                  ring->dma_size * eth->soc->txrx.rxd_size,
                                  ring->dma, ring->phys);
-@@ -3060,7 +3084,7 @@ static void mtk_dma_free(struct mtk_eth
+@@ -3059,7 +3083,7 @@ static void mtk_dma_free(struct mtk_eth
        for (i = 0; i < MTK_MAX_DEVS; i++)
                if (eth->netdev[i])
                        netdev_reset_queue(eth->netdev[i]);
@@ -132,7 +132,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                dma_free_coherent(eth->dma_dev,
                                  MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
                                  eth->scratch_ring, eth->phy_scratch_ring);
-@@ -3068,13 +3092,13 @@ static void mtk_dma_free(struct mtk_eth
+@@ -3067,13 +3091,13 @@ static void mtk_dma_free(struct mtk_eth
                eth->phy_scratch_ring = 0;
        }
        mtk_tx_clean(eth);
@@ -149,7 +149,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
  
        kfree(eth->scratch_head);
-@@ -4642,7 +4666,7 @@ static int mtk_sgmii_init(struct mtk_eth
+@@ -4641,7 +4665,7 @@ static int mtk_sgmii_init(struct mtk_eth
  
  static int mtk_probe(struct platform_device *pdev)
  {
@@ -158,7 +158,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        struct device_node *mac_np;
        struct mtk_eth *eth;
        int err, i;
-@@ -4662,6 +4686,20 @@ static int mtk_probe(struct platform_dev
+@@ -4661,6 +4685,20 @@ static int mtk_probe(struct platform_dev
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
                eth->ip_align = NET_IP_ALIGN;
  
@@ -179,7 +179,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        spin_lock_init(&eth->page_lock);
        spin_lock_init(&eth->tx_irq_lock);
        spin_lock_init(&eth->rx_irq_lock);
-@@ -4725,6 +4763,18 @@ static int mtk_probe(struct platform_dev
+@@ -4724,6 +4762,18 @@ static int mtk_probe(struct platform_dev
                        err = -EINVAL;
                        goto err_destroy_sgmii;
                }
index 9266c33f82554560e029da4c60861b797bb28917..1584dfd07c63fe5b568874ad0f682b9d3c6d7fcd 100644 (file)
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1312,6 +1312,10 @@ static void mtk_tx_set_dma_desc_v2(struc
+@@ -1311,6 +1311,10 @@ static void mtk_tx_set_dma_desc_v2(struc
        data = TX_DMA_PLEN0(info->size);
        if (info->last)
                data |= TX_DMA_LS0;
@@ -30,7 +30,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        WRITE_ONCE(desc->txd3, data);
  
         /* set forward port */
-@@ -1981,6 +1985,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1980,6 +1984,7 @@ static int mtk_poll_rx(struct napi_struc
        bool xdp_flush = false;
        int idx;
        struct sk_buff *skb;
@@ -38,7 +38,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        u8 *data, *new_data;
        struct mtk_rx_dma_v2 *rxd, trxd;
        int done = 0, bytes = 0;
-@@ -2096,7 +2101,10 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2095,7 +2100,10 @@ static int mtk_poll_rx(struct napi_struc
                                goto release_desc;
                        }
  
@@ -50,7 +50,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                                         ring->buf_size, DMA_FROM_DEVICE);
  
                        skb = build_skb(data, ring->frag_size);
-@@ -2162,6 +2170,9 @@ release_desc:
+@@ -2161,6 +2169,9 @@ release_desc:
                else
                        rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
  
@@ -60,7 +60,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                ring->calc_idx = idx;
                done++;
        }
-@@ -2654,6 +2665,9 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2653,6 +2664,9 @@ static int mtk_rx_alloc(struct mtk_eth *
                else
                        rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
  
@@ -70,7 +70,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                rxd->rxd3 = 0;
                rxd->rxd4 = 0;
                if (mtk_is_netsys_v2_or_greater(eth)) {
-@@ -2700,6 +2714,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2699,6 +2713,7 @@ static int mtk_rx_alloc(struct mtk_eth *
  
  static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
  {
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        int i;
  
        if (ring->data && ring->dma) {
-@@ -2713,7 +2728,10 @@ static void mtk_rx_clean(struct mtk_eth
+@@ -2712,7 +2727,10 @@ static void mtk_rx_clean(struct mtk_eth
                        if (!rxd->rxd1)
                                continue;
  
@@ -90,7 +90,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                                         ring->buf_size, DMA_FROM_DEVICE);
                        mtk_rx_put_buff(ring, ring->data[i], false);
                }
-@@ -4700,6 +4718,14 @@ static int mtk_probe(struct platform_dev
+@@ -4699,6 +4717,14 @@ static int mtk_probe(struct platform_dev
                }
        }
  
index 697c2db1451907b565b4b9c4b2e6a6edc73517ad..5b27458eb8e186eb11b9434599a876322eda7a7c 100644 (file)
@@ -19,7 +19,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1989,11 +1989,11 @@ static int mtk_poll_rx(struct napi_struc
+@@ -1988,11 +1988,11 @@ static int mtk_poll_rx(struct napi_struc
        u8 *data, *new_data;
        struct mtk_rx_dma_v2 *rxd, trxd;
        int done = 0, bytes = 0;
@@ -32,7 +32,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
                u32 hash, reason;
                int mac = 0;
  
-@@ -2170,7 +2170,8 @@ release_desc:
+@@ -2169,7 +2169,8 @@ release_desc:
                else
                        rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
  
index 07c087260c257d4d8fdc1158100ab47c761b6cff..aa0d730bc8a0faebd9939a27e783cf7d3bb45660 100644 (file)
@@ -46,7 +46,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -2975,13 +2975,25 @@ static void stmmac_tx_timer_arm(struct s
+@@ -2974,13 +2974,25 @@ static void stmmac_tx_timer_arm(struct s
  {
        struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
        u32 tx_coal_timer = priv->tx_coal_timer[queue];
index e94a2ca819d660cc781a2a70bd52c1b26def1074..4e9e951598b54e840d5c0798e1186ee90919d5c8 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 
 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -2528,9 +2528,13 @@ static void stmmac_bump_dma_threshold(st
+@@ -2527,9 +2527,13 @@ static void stmmac_bump_dma_threshold(st
   * @priv: driver private structure
   * @budget: napi budget limiting this functions packet handling
   * @queue: TX queue index
@@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  {
        struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
        unsigned int bytes_compl = 0, pkts_compl = 0;
-@@ -2693,7 +2697,7 @@ static int stmmac_tx_clean(struct stmmac
+@@ -2692,7 +2696,7 @@ static int stmmac_tx_clean(struct stmmac
  
        /* We still have pending packets, let's call for a new scheduling */
        if (tx_q->dirty_tx != tx_q->cur_tx)
@@ -42,7 +42,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  
        __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
  
-@@ -5486,12 +5490,13 @@ static int stmmac_napi_poll_tx(struct na
+@@ -5485,12 +5489,13 @@ static int stmmac_napi_poll_tx(struct na
        struct stmmac_channel *ch =
                container_of(napi, struct stmmac_channel, tx_napi);
        struct stmmac_priv *priv = ch->priv_data;
@@ -57,7 +57,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
        work_done = min(work_done, budget);
  
        if (work_done < budget && napi_complete_done(napi, work_done)) {
-@@ -5502,6 +5507,10 @@ static int stmmac_napi_poll_tx(struct na
+@@ -5501,6 +5506,10 @@ static int stmmac_napi_poll_tx(struct na
                spin_unlock_irqrestore(&ch->lock, flags);
        }
  
@@ -68,7 +68,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
        return work_done;
  }
  
-@@ -5510,12 +5519,13 @@ static int stmmac_napi_poll_rxtx(struct
+@@ -5509,12 +5518,13 @@ static int stmmac_napi_poll_rxtx(struct
        struct stmmac_channel *ch =
                container_of(napi, struct stmmac_channel, rxtx_napi);
        struct stmmac_priv *priv = ch->priv_data;
@@ -83,7 +83,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
        tx_done = min(tx_done, budget);
  
        rx_done = stmmac_rx_zc(priv, budget, chan);
-@@ -5540,6 +5550,10 @@ static int stmmac_napi_poll_rxtx(struct
+@@ -5539,6 +5549,10 @@ static int stmmac_napi_poll_rxtx(struct
                spin_unlock_irqrestore(&ch->lock, flags);
        }
  
index 893a81246d8811139c3a42f0a3e7e98373bd245a..f82c8fc622b99d21a79879a5d9b9ca3f48c9e932 100644 (file)
@@ -27,15 +27,15 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  };
  
  /**
-@@ -71,6 +75,7 @@ struct phylink {
-       struct mutex state_mutex;
+@@ -72,6 +76,7 @@ struct phylink {
        struct phylink_link_state phy_state;
        struct work_struct resolve;
+       unsigned int pcs_neg_mode;
 +      unsigned int pcs_state;
  
        bool mac_link_dropped;
        bool using_mac_select_pcs;
-@@ -990,6 +995,22 @@ static void phylink_mac_pcs_an_restart(s
+@@ -992,6 +997,22 @@ static void phylink_resolve_an_pause(str
        }
  }
  
@@ -55,16 +55,17 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 +      return err;
 +}
 +
- static void phylink_major_config(struct phylink *pl, bool restart,
-                                 const struct phylink_link_state *state)
- {
-@@ -1026,11 +1047,16 @@ static void phylink_major_config(struct
+ static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+                             const struct phylink_link_state *state,
+                             bool permit_pause_to_mac)
+@@ -1094,11 +1115,17 @@ static void phylink_major_config(struct
        /* If we have a new PCS, switch to the new PCS after preparing the MAC
         * for the change.
         */
 -      if (pcs_changed)
 +      if (pcs_changed) {
 +              phylink_pcs_disable(pl->pcs);
++
                pl->pcs = pcs;
 +      }
  
@@ -73,18 +74,18 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 +      if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
 +              phylink_pcs_enable(pl->pcs);
 +
-       if (pl->pcs) {
-               err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
-                                              state->interface,
-@@ -1502,6 +1528,7 @@ struct phylink *phylink_create(struct ph
+       neg_mode = pl->cur_link_an_mode;
+       if (pl->pcs && pl->pcs->neg_mode)
+               neg_mode = pl->pcs_neg_mode;
+@@ -1586,6 +1613,7 @@ struct phylink *phylink_create(struct ph
+       pl->link_config.pause = MLO_PAUSE_AN;
        pl->link_config.speed = SPEED_UNKNOWN;
        pl->link_config.duplex = DUPLEX_UNKNOWN;
-       pl->link_config.an_enabled = true;
 +      pl->pcs_state = PCS_STATE_DOWN;
        pl->mac_ops = mac_ops;
        __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
        timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
-@@ -1903,6 +1930,8 @@ void phylink_start(struct phylink *pl)
+@@ -1987,6 +2015,8 @@ void phylink_start(struct phylink *pl)
        if (pl->netdev)
                netif_carrier_off(pl->netdev);
  
@@ -93,7 +94,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        /* Apply the link configuration to the MAC when starting. This allows
         * a fixed-link to start with the correct parameters, and also
         * ensures that we set the appropriate advertisement for Serdes links.
-@@ -1913,6 +1942,8 @@ void phylink_start(struct phylink *pl)
+@@ -1997,6 +2027,8 @@ void phylink_start(struct phylink *pl)
         */
        phylink_mac_initial_config(pl, true);
  
@@ -102,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED);
  
        if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
-@@ -1931,15 +1962,9 @@ void phylink_start(struct phylink *pl)
+@@ -2015,15 +2047,9 @@ void phylink_start(struct phylink *pl)
                        poll = true;
        }
  
@@ -120,7 +121,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        if (poll)
                mod_timer(&pl->link_poll, jiffies + HZ);
        if (pl->phydev)
-@@ -1976,6 +2001,10 @@ void phylink_stop(struct phylink *pl)
+@@ -2060,6 +2086,10 @@ void phylink_stop(struct phylink *pl)
        }
  
        phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
@@ -133,7 +134,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
 --- a/include/linux/phylink.h
 +++ b/include/linux/phylink.h
-@@ -446,6 +446,8 @@ struct phylink_pcs {
+@@ -533,6 +533,8 @@ struct phylink_pcs {
  /**
   * struct phylink_pcs_ops - MAC PCS operations structure.
   * @pcs_validate: validate the link configuration.
@@ -142,7 +143,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
   * @pcs_get_state: read the current MAC PCS link state from the hardware.
   * @pcs_config: configure the MAC PCS for the selected mode and state.
   * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
-@@ -455,6 +457,8 @@ struct phylink_pcs {
+@@ -542,6 +544,8 @@ struct phylink_pcs {
  struct phylink_pcs_ops {
        int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
                            const struct phylink_link_state *state);
@@ -150,8 +151,8 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 +      void (*pcs_disable)(struct phylink_pcs *pcs);
        void (*pcs_get_state)(struct phylink_pcs *pcs,
                              struct phylink_link_state *state);
-       int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
-@@ -485,6 +489,18 @@ int pcs_validate(struct phylink_pcs *pcs
+       int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode,
+@@ -572,6 +576,18 @@ int pcs_validate(struct phylink_pcs *pcs
                 const struct phylink_link_state *state);
  
  /**
index eb9b4b7c09ee0d785f3d41e050b91dfcb4874312..6b6369761a185e8493313fdf6b57643a027bd094 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/pcs/pcs-mtk-lynxi.c
 +++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct
+@@ -234,11 +234,19 @@ static void mtk_pcs_lynxi_link_up(struct
        }
  }
  
index 70a3a4ad5c3c5ecfb90481bbae043184924fd00c..0d2c0bcd83f26f02f04f360f32e4e41ccb6b591b 100644 (file)
@@ -48,7 +48,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  #include <linux/netdevice.h>
  #include <linux/phy.h>
  #include <linux/phy_led_triggers.h>
-@@ -644,6 +646,7 @@ struct phy_device *phy_device_create(str
+@@ -642,6 +644,7 @@ struct phy_device *phy_device_create(str
        device_initialize(&mdiodev->dev);
  
        dev->state = PHY_DOWN;
@@ -56,7 +56,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
        mutex_init(&dev->lock);
        INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
-@@ -3037,6 +3040,74 @@ static bool phy_drv_supports_irq(struct
+@@ -3035,6 +3038,74 @@ static bool phy_drv_supports_irq(struct
        return phydrv->config_intr && phydrv->handle_interrupt;
  }
  
@@ -131,7 +131,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  /**
   * fwnode_mdio_find_device - Given a fwnode, find the mdio_device
   * @fwnode: pointer to the mdio_device's fwnode
-@@ -3215,6 +3286,11 @@ static int phy_probe(struct device *dev)
+@@ -3213,6 +3284,11 @@ static int phy_probe(struct device *dev)
        /* Set the state to READY by default */
        phydev->state = PHY_READY;
  
index e2e7bd65b1edd32e0fa68a8bf9e97a28737eea03..4873c40a7766b34a39263fdcaa0f75068923ed10 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3040,11 +3040,18 @@ static bool phy_drv_supports_irq(struct
+@@ -3038,11 +3038,18 @@ static bool phy_drv_supports_irq(struct
        return phydrv->config_intr && phydrv->handle_interrupt;
  }
  
@@ -41,7 +41,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  }
  
  static int of_phy_led(struct phy_device *phydev,
-@@ -3061,12 +3068,14 @@ static int of_phy_led(struct phy_device
+@@ -3059,12 +3066,14 @@ static int of_phy_led(struct phy_device
                return -ENOMEM;
  
        cdev = &phyled->led_cdev;
index 804caf5d3565a3e879efb7412d57f38160c5736f..00bdcc54689ce6cb26960befe588a62949440b24 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3054,6 +3054,22 @@ static int phy_led_set_brightness(struct
+@@ -3052,6 +3052,22 @@ static int phy_led_set_brightness(struct
        return err;
  }
  
@@ -41,7 +41,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  static int of_phy_led(struct phy_device *phydev,
                      struct device_node *led)
  {
-@@ -3076,6 +3092,8 @@ static int of_phy_led(struct phy_device
+@@ -3074,6 +3090,8 @@ static int of_phy_led(struct phy_device
  
        if (phydev->drv->led_brightness_set)
                cdev->brightness_set_blocking = phy_led_set_brightness;
index 226c135f3c8ca6705e328f0169f71ea3f1ea69a0..3b68403690c679054fe8ac051a1b7c76b399971a 100644 (file)
@@ -53,7 +53,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3316,7 +3316,8 @@ static int phy_probe(struct device *dev)
+@@ -3314,7 +3314,8 @@ static int phy_probe(struct device *dev)
        /* Get the LEDs from the device tree, and instantiate standard
         * LEDs for them.
         */
index 5bb92bc946445545c8f6d32a2cb55f8a8e40bbc9..622bb9e94a9e31b79b11d406706e16fe903ae7cf 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3077,6 +3077,7 @@ static int of_phy_led(struct phy_device
+@@ -3075,6 +3075,7 @@ static int of_phy_led(struct phy_device
        struct led_init_data init_data = {};
        struct led_classdev *cdev;
        struct phy_led *phyled;
@@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        int err;
  
        phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL);
-@@ -3086,10 +3087,13 @@ static int of_phy_led(struct phy_device
+@@ -3084,10 +3085,13 @@ static int of_phy_led(struct phy_device
        cdev = &phyled->led_cdev;
        phyled->phydev = phydev;
  
index f7952d9f0c3318d582715cee0c1fdc56b5219167..80197e963b84832eed097acceb5324d7c462cd2d 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3070,6 +3070,15 @@ static int phy_led_blink_set(struct led_
+@@ -3068,6 +3068,15 @@ static int phy_led_blink_set(struct led_
        return err;
  }
  
@@ -38,7 +38,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  static int of_phy_led(struct phy_device *phydev,
                      struct device_node *led)
  {
-@@ -3103,7 +3112,7 @@ static int of_phy_led(struct phy_device
+@@ -3101,7 +3110,7 @@ static int of_phy_led(struct phy_device
        init_data.fwnode = of_fwnode_handle(led);
        init_data.devname_mandatory = true;
  
@@ -47,7 +47,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        if (err)
                return err;
  
-@@ -3132,6 +3141,7 @@ static int of_phy_leds(struct phy_device
+@@ -3130,6 +3139,7 @@ static int of_phy_leds(struct phy_device
                err = of_phy_led(phydev, led);
                if (err) {
                        of_node_put(led);
@@ -55,7 +55,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
                        return err;
                }
        }
-@@ -3337,6 +3347,9 @@ static int phy_remove(struct device *dev
+@@ -3335,6 +3345,9 @@ static int phy_remove(struct device *dev
  
        cancel_delayed_work_sync(&phydev->state_queue);
  
index 947db79f064f091f7dea999699bd49107f8dd191..505513a53fe31f38945583f3a445925238855419 100644 (file)
@@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3070,6 +3070,61 @@ static int phy_led_blink_set(struct led_
+@@ -3068,6 +3068,61 @@ static int phy_led_blink_set(struct led_
        return err;
  }
  
@@ -85,7 +85,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  static void phy_leds_unregister(struct phy_device *phydev)
  {
        struct phy_led *phyled;
-@@ -3107,6 +3162,19 @@ static int of_phy_led(struct phy_device
+@@ -3105,6 +3160,19 @@ static int of_phy_led(struct phy_device
                cdev->brightness_set_blocking = phy_led_set_brightness;
        if (phydev->drv->led_blink_set)
                cdev->blink_set = phy_led_blink_set;
index 1f49b3af0cc82c237626aac602d0f4639d263d6a..0182e6d1a203b07b946a68a327359ab903f29b6f 100644 (file)
@@ -28,7 +28,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -3140,6 +3140,7 @@ static int of_phy_led(struct phy_device
+@@ -3138,6 +3138,7 @@ static int of_phy_led(struct phy_device
        struct device *dev = &phydev->mdio.dev;
        struct led_init_data init_data = {};
        struct led_classdev *cdev;
@@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        struct phy_led *phyled;
        u32 index;
        int err;
-@@ -3157,6 +3158,21 @@ static int of_phy_led(struct phy_device
+@@ -3155,6 +3156,21 @@ static int of_phy_led(struct phy_device
        if (index > U8_MAX)
                return -EINVAL;
  
index 8b7f2f095577fd02ee73a145b690f7389cb26ddd..30ed515c3e43b4ba5ba8f4d8ec25b62943559b5d 100644 (file)
@@ -40,14 +40,14 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 +      phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
  }
  
- static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -134,7 +143,8 @@ static int mtk_pcs_lynxi_config(struct p
-               /* 1000base-X or 2500base-X autoneg */
-               sgm_mode = SGMII_REMOTE_FAULT_DIS;
-               use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
--                                         advertising);
-+                                         advertising) &&
-+                       !(interface == PHY_INTERFACE_MODE_2500BASEX);
-       } else {
-               /* 1000base-X or 2500base-X without autoneg */
-               sgm_mode = 0;
+ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+@@ -130,7 +139,8 @@ static int mtk_pcs_lynxi_config(struct p
+       if (neg_mode & PHYLINK_PCS_NEG_INBAND)
+               sgm_mode |= SGMII_REMOTE_FAULT_DIS;
+-      if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
++      if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
++          interface != PHY_INTERFACE_MODE_2500BASEX) {
+               if (interface == PHY_INTERFACE_MODE_SGMII)
+                       sgm_mode |= SGMII_SPEED_DUPLEX_AN;
+               bmcr = BMCR_ANENABLE;
index 27c87d5b65601641c27cc20058898d919a1f4064..bb21bb39d39866c798e068db4ca326973e779b91 100644 (file)
@@ -46,7 +46,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
        init_done:
                        /* Create mdiobus and start trying for PHY */
-@@ -2573,10 +2577,12 @@ static void sfp_check_state(struct sfp *
+@@ -2578,10 +2582,12 @@ static void sfp_check_state(struct sfp *
        mutex_lock(&sfp->st_mutex);
        state = sfp_get_state(sfp);
        changed = state ^ sfp->state;
index be28fdc803618329f83348f6a405bdfb3af72731..842fef3a9c5b3f2a9bc6525a931f11a08140702c 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4942,6 +4942,8 @@ static int mtk_probe(struct platform_dev
+@@ -4941,6 +4941,8 @@ static int mtk_probe(struct platform_dev
         * for NAPI to work
         */
        init_dummy_netdev(&eth->dummy_dev);
index 0c8810919213a73eb5cbad95041f8655db96a828..e4937a1df1be8ca5040203355ed84ef8dc430219 100644 (file)
@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -1852,6 +1852,9 @@ void phy_detach(struct phy_device *phyde
+@@ -1850,6 +1850,9 @@ void phy_detach(struct phy_device *phyde
        struct module *ndev_owner = NULL;
        struct mii_bus *bus;
  
index fe8841dd3e6c9f0c6e73976e56a27f798de173ee..a1cc109050e1df8ed24a52e1989b978a986063a4 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1563,12 +1563,28 @@ static void mtk_wake_queue(struct mtk_et
+@@ -1562,12 +1562,28 @@ static void mtk_wake_queue(struct mtk_et
        }
  }
  
@@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        bool gso = false;
        int tx_num;
  
-@@ -1590,6 +1606,18 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1589,6 +1605,18 @@ static netdev_tx_t mtk_start_xmit(struct
                return NETDEV_TX_BUSY;
        }
  
@@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        /* TSO: fill MSS info in tcp checksum field */
        if (skb_is_gso(skb)) {
                if (skb_cow_head(skb, 0)) {
-@@ -1605,8 +1633,14 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1604,8 +1632,14 @@ static netdev_tx_t mtk_start_xmit(struct
                }
        }
  
index 757d2edb2c5307f84e35892328bbfbe2d5b73765..0a49c75b00d8c1608a4a3731af330ba10496338b 100644 (file)
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        switch (speed) {
        case SPEED_2500:
        case SPEED_1000:
-@@ -3349,6 +3350,9 @@ found:
+@@ -3348,6 +3349,9 @@ found:
        if (dp->index >= MTK_QDMA_NUM_QUEUES)
                return NOTIFY_DONE;
  
index 23daa2999895fcf8b587749678b1534b85884434..4793a41d378003416ab09cf647672ab810ab0610 100644 (file)
@@ -476,9 +476,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 +}
 +
  static const struct phylink_mac_ops mtk_phylink_ops = {
-       .validate = phylink_generic_validate,
        .mac_select_pcs = mtk_mac_select_pcs,
-@@ -4617,8 +4731,21 @@ static int mtk_add_mac(struct mtk_eth *e
+       .mac_config = mtk_mac_config,
+@@ -4616,8 +4730,21 @@ static int mtk_add_mac(struct mtk_eth *e
                phy_interface_zero(mac->phylink_config.supported_interfaces);
                __set_bit(PHY_INTERFACE_MODE_INTERNAL,
                          mac->phylink_config.supported_interfaces);
@@ -500,7 +500,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        phylink = phylink_create(&mac->phylink_config,
                                 of_fwnode_handle(mac->of_node),
                                 phy_mode, &mtk_phylink_ops);
-@@ -4811,6 +4938,13 @@ static int mtk_probe(struct platform_dev
+@@ -4810,6 +4937,13 @@ static int mtk_probe(struct platform_dev
  
                if (err)
                        return err;
index bc17b3635cd9a154c54ebf85f2e5432965ec6e0f..7968095a4a985d11f4845f5579a2c099d8dbc697 100644 (file)
@@ -32,7 +32,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4886,7 +4886,10 @@ static int mtk_probe(struct platform_dev
+@@ -4885,7 +4885,10 @@ static int mtk_probe(struct platform_dev
        }
  
        if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
index 6af915da90653809b210a8ea67035d6447ce700c..8beee8f2dc1af75950b356319bf130ea04141338 100644 (file)
@@ -25,7 +25,7 @@ Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
        case PHY_INTERFACE_MODE_QUSGMII:
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -200,6 +200,7 @@ static int phylink_interface_max_speed(p
+@@ -218,6 +218,7 @@ static int phylink_interface_max_speed(p
                return SPEED_1000;
  
        case PHY_INTERFACE_MODE_2500BASEX:
index 265756ea7032632453e473fb4b74cc69ffd531c0..1a1d7a0ac789de76f7dceec835ee7198224194de 100644 (file)
@@ -32,7 +32,7 @@ Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
 
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -487,6 +487,7 @@ unsigned long phylink_get_capabilities(p
+@@ -505,6 +505,7 @@ unsigned long phylink_get_capabilities(p
                break;
  
        case PHY_INTERFACE_MODE_2500BASEX:
index b59ea02ae7a5ee9a09cdd81d509671b78c257973..26c081cffcf9274faef7ad877581b4ec7a26523d 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1239,7 +1239,7 @@ static int mtk_init_fq_dma(struct mtk_et
+@@ -1238,7 +1238,7 @@ static int mtk_init_fq_dma(struct mtk_et
                eth->scratch_ring = eth->sram_base;
        else
                eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
@@ -24,7 +24,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                                       &eth->phy_scratch_ring,
                                                       GFP_KERNEL);
        if (unlikely(!eth->scratch_ring))
-@@ -1255,16 +1255,16 @@ static int mtk_init_fq_dma(struct mtk_et
+@@ -1254,16 +1254,16 @@ static int mtk_init_fq_dma(struct mtk_et
        if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
                return -ENOMEM;
  
@@ -44,7 +44,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
                txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
                txd->txd4 = 0;
-@@ -1513,7 +1513,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1512,7 +1512,7 @@ static int mtk_tx_map(struct sk_buff *sk
        if (itxd == ring->last_free)
                return -ENOMEM;
  
@@ -53,7 +53,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        memset(itx_buf, 0, sizeof(*itx_buf));
  
        txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
-@@ -1554,7 +1554,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1553,7 +1553,7 @@ static int mtk_tx_map(struct sk_buff *sk
  
                        memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
                        txd_info.size = min_t(unsigned int, frag_size,
@@ -62,7 +62,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        txd_info.qid = queue;
                        txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
                                        !(frag_size - txd_info.size);
-@@ -1567,7 +1567,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1566,7 +1566,7 @@ static int mtk_tx_map(struct sk_buff *sk
                        mtk_tx_set_dma_desc(dev, txd, &txd_info);
  
                        tx_buf = mtk_desc_to_tx_buf(ring, txd,
@@ -71,7 +71,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        if (new_desc)
                                memset(tx_buf, 0, sizeof(*tx_buf));
                        tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-@@ -1610,7 +1610,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1609,7 +1609,7 @@ static int mtk_tx_map(struct sk_buff *sk
        } else {
                int next_idx;
  
@@ -80,7 +80,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                         ring->dma_size);
                mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
        }
-@@ -1619,7 +1619,7 @@ static int mtk_tx_map(struct sk_buff *sk
+@@ -1618,7 +1618,7 @@ static int mtk_tx_map(struct sk_buff *sk
  
  err_dma:
        do {
@@ -89,7 +89,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
                /* unmap dma */
                mtk_tx_unmap(eth, tx_buf, NULL, false);
-@@ -1644,7 +1644,7 @@ static int mtk_cal_txd_req(struct mtk_et
+@@ -1643,7 +1643,7 @@ static int mtk_cal_txd_req(struct mtk_et
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        frag = &skb_shinfo(skb)->frags[i];
                        nfrags += DIV_ROUND_UP(skb_frag_size(frag),
@@ -98,7 +98,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                }
        } else {
                nfrags += skb_shinfo(skb)->nr_frags;
-@@ -1785,7 +1785,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
+@@ -1784,7 +1784,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
  
                ring = &eth->rx_ring[i];
                idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
@@ -107,7 +107,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (rxd->rxd2 & RX_DMA_DONE) {
                        ring->calc_idx_update = true;
                        return ring;
-@@ -1953,7 +1953,7 @@ static int mtk_xdp_submit_frame(struct m
+@@ -1952,7 +1952,7 @@ static int mtk_xdp_submit_frame(struct m
        }
        htxd = txd;
  
@@ -116,7 +116,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        memset(tx_buf, 0, sizeof(*tx_buf));
        htx_buf = tx_buf;
  
-@@ -1972,7 +1972,7 @@ static int mtk_xdp_submit_frame(struct m
+@@ -1971,7 +1971,7 @@ static int mtk_xdp_submit_frame(struct m
                                goto unmap;
  
                        tx_buf = mtk_desc_to_tx_buf(ring, txd,
@@ -125,7 +125,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        memset(tx_buf, 0, sizeof(*tx_buf));
                        n_desc++;
                }
-@@ -2010,7 +2010,7 @@ static int mtk_xdp_submit_frame(struct m
+@@ -2009,7 +2009,7 @@ static int mtk_xdp_submit_frame(struct m
        } else {
                int idx;
  
@@ -134,7 +134,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
                        MT7628_TX_CTX_IDX0);
        }
-@@ -2021,7 +2021,7 @@ static int mtk_xdp_submit_frame(struct m
+@@ -2020,7 +2020,7 @@ static int mtk_xdp_submit_frame(struct m
  
  unmap:
        while (htxd != txd) {
@@ -143,7 +143,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                mtk_tx_unmap(eth, tx_buf, NULL, false);
  
                htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-@@ -2152,7 +2152,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2151,7 +2151,7 @@ static int mtk_poll_rx(struct napi_struc
                        goto rx_done;
  
                idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
@@ -152,7 +152,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                data = ring->data[idx];
  
                if (!mtk_rx_get_desc(eth, &trxd, rxd))
-@@ -2287,7 +2287,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2286,7 +2286,7 @@ static int mtk_poll_rx(struct napi_struc
                        rxdcsum = &trxd.rxd4;
                }
  
@@ -161,7 +161,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                else
                        skb_checksum_none_assert(skb);
-@@ -2411,7 +2411,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+@@ -2410,7 +2410,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
                        break;
  
                tx_buf = mtk_desc_to_tx_buf(ring, desc,
@@ -170,7 +170,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (!tx_buf->data)
                        break;
  
-@@ -2462,7 +2462,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
+@@ -2461,7 +2461,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
                }
                mtk_tx_unmap(eth, tx_buf, &bq, true);
  
@@ -179,7 +179,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                ring->last_free = desc;
                atomic_inc(&ring->free_count);
  
-@@ -2552,7 +2552,7 @@ static int mtk_napi_rx(struct napi_struc
+@@ -2551,7 +2551,7 @@ static int mtk_napi_rx(struct napi_struc
        do {
                int rx_done;
  
@@ -188,7 +188,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        reg_map->pdma.irq_status);
                rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
                rx_done_total += rx_done;
-@@ -2568,10 +2568,10 @@ static int mtk_napi_rx(struct napi_struc
+@@ -2567,10 +2567,10 @@ static int mtk_napi_rx(struct napi_struc
                        return budget;
  
        } while (mtk_r32(eth, reg_map->pdma.irq_status) &
@@ -201,7 +201,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  
        return rx_done_total;
  }
-@@ -2580,7 +2580,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+@@ -2579,7 +2579,7 @@ static int mtk_tx_alloc(struct mtk_eth *
  {
        const struct mtk_soc_data *soc = eth->soc;
        struct mtk_tx_ring *ring = &eth->tx_ring;
@@ -210,7 +210,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        struct mtk_tx_dma_v2 *txd;
        int ring_size;
        u32 ofs, val;
-@@ -2703,14 +2703,14 @@ static void mtk_tx_clean(struct mtk_eth
+@@ -2702,14 +2702,14 @@ static void mtk_tx_clean(struct mtk_eth
        }
        if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
                dma_free_coherent(eth->dma_dev,
@@ -227,7 +227,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                  ring->dma_pdma, ring->phys_pdma);
                ring->dma_pdma = NULL;
        }
-@@ -2765,15 +2765,15 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2764,15 +2764,15 @@ static int mtk_rx_alloc(struct mtk_eth *
        if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
            rx_flag != MTK_RX_FLAGS_NORMAL) {
                ring->dma = dma_alloc_coherent(eth->dma_dev,
@@ -247,7 +247,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        }
  
        if (!ring->dma)
-@@ -2784,7 +2784,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2783,7 +2783,7 @@ static int mtk_rx_alloc(struct mtk_eth *
                dma_addr_t dma_addr;
                void *data;
  
@@ -256,7 +256,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                if (ring->page_pool) {
                        data = mtk_page_pool_get_buff(ring->page_pool,
                                                      &dma_addr, GFP_KERNEL);
-@@ -2875,7 +2875,7 @@ static void mtk_rx_clean(struct mtk_eth
+@@ -2874,7 +2874,7 @@ static void mtk_rx_clean(struct mtk_eth
                        if (!ring->data[i])
                                continue;
  
@@ -265,7 +265,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        if (!rxd->rxd1)
                                continue;
  
-@@ -2892,7 +2892,7 @@ static void mtk_rx_clean(struct mtk_eth
+@@ -2891,7 +2891,7 @@ static void mtk_rx_clean(struct mtk_eth
  
        if (!in_sram && ring->dma) {
                dma_free_coherent(eth->dma_dev,
@@ -274,7 +274,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                  ring->dma, ring->phys);
                ring->dma = NULL;
        }
-@@ -3255,7 +3255,7 @@ static void mtk_dma_free(struct mtk_eth
+@@ -3254,7 +3254,7 @@ static void mtk_dma_free(struct mtk_eth
                        netdev_reset_queue(eth->netdev[i]);
        if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
                dma_free_coherent(eth->dma_dev,
@@ -283,7 +283,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                                  eth->scratch_ring, eth->phy_scratch_ring);
                eth->scratch_ring = NULL;
                eth->phy_scratch_ring = 0;
-@@ -3305,7 +3305,7 @@ static irqreturn_t mtk_handle_irq_rx(int
+@@ -3304,7 +3304,7 @@ static irqreturn_t mtk_handle_irq_rx(int
  
        eth->rx_events++;
        if (likely(napi_schedule_prep(&eth->rx_napi))) {
@@ -292,7 +292,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                __napi_schedule(&eth->rx_napi);
        }
  
-@@ -3331,9 +3331,9 @@ static irqreturn_t mtk_handle_irq(int ir
+@@ -3330,9 +3330,9 @@ static irqreturn_t mtk_handle_irq(int ir
        const struct mtk_reg_map *reg_map = eth->soc->reg_map;
  
        if (mtk_r32(eth, reg_map->pdma.irq_mask) &
@@ -304,7 +304,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                        mtk_handle_irq_rx(irq, _eth);
        }
        if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
-@@ -3351,10 +3351,10 @@ static void mtk_poll_controller(struct n
+@@ -3350,10 +3350,10 @@ static void mtk_poll_controller(struct n
        struct mtk_eth *eth = mac->hw;
  
        mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
@@ -317,7 +317,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
  }
  #endif
  
-@@ -3517,7 +3517,7 @@ static int mtk_open(struct net_device *d
+@@ -3516,7 +3516,7 @@ static int mtk_open(struct net_device *d
                napi_enable(&eth->tx_napi);
                napi_enable(&eth->rx_napi);
                mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
@@ -326,7 +326,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                refcount_set(&eth->dma_refcnt, 1);
        }
        else
-@@ -3600,7 +3600,7 @@ static int mtk_stop(struct net_device *d
+@@ -3599,7 +3599,7 @@ static int mtk_stop(struct net_device *d
        mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
  
        mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
@@ -335,7 +335,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        napi_disable(&eth->tx_napi);
        napi_disable(&eth->rx_napi);
  
-@@ -4076,9 +4076,9 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -4075,9 +4075,9 @@ static int mtk_hw_init(struct mtk_eth *e
  
        /* FE int grouping */
        mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
@@ -347,7 +347,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
  
        if (mtk_is_netsys_v3_or_greater(eth)) {
-@@ -5176,11 +5176,15 @@ static const struct mtk_soc_data mt2701_
+@@ -5175,11 +5175,15 @@ static const struct mtk_soc_data mt2701_
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
        .version = 1,
@@ -368,7 +368,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5196,11 +5200,15 @@ static const struct mtk_soc_data mt7621_
+@@ -5195,11 +5199,15 @@ static const struct mtk_soc_data mt7621_
        .offload_version = 1,
        .hash_offset = 2,
        .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
@@ -389,7 +389,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5218,11 +5226,15 @@ static const struct mtk_soc_data mt7622_
+@@ -5217,11 +5225,15 @@ static const struct mtk_soc_data mt7622_
        .hash_offset = 2,
        .has_accounting = true,
        .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
@@ -410,7 +410,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5239,11 +5251,15 @@ static const struct mtk_soc_data mt7623_
+@@ -5238,11 +5250,15 @@ static const struct mtk_soc_data mt7623_
        .hash_offset = 2,
        .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
        .disable_pll_modes = true,
@@ -431,7 +431,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5258,11 +5274,15 @@ static const struct mtk_soc_data mt7629_
+@@ -5257,11 +5273,15 @@ static const struct mtk_soc_data mt7629_
        .required_pctl = false,
        .has_accounting = true,
        .version = 1,
@@ -452,7 +452,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN,
                .dma_len_offset = 16,
        },
-@@ -5280,11 +5300,15 @@ static const struct mtk_soc_data mt7981_
+@@ -5279,11 +5299,15 @@ static const struct mtk_soc_data mt7981_
        .hash_offset = 4,
        .has_accounting = true,
        .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
@@ -473,7 +473,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
                .dma_len_offset = 8,
        },
-@@ -5302,11 +5326,15 @@ static const struct mtk_soc_data mt7986_
+@@ -5301,11 +5325,15 @@ static const struct mtk_soc_data mt7986_
        .hash_offset = 4,
        .has_accounting = true,
        .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
@@ -494,7 +494,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
                .dma_len_offset = 8,
        },
-@@ -5324,11 +5352,15 @@ static const struct mtk_soc_data mt7988_
+@@ -5323,11 +5351,15 @@ static const struct mtk_soc_data mt7988_
        .hash_offset = 4,
        .has_accounting = true,
        .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
@@ -515,7 +515,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
                .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
                .dma_len_offset = 8,
        },
-@@ -5341,11 +5373,15 @@ static const struct mtk_soc_data rt5350_
+@@ -5340,11 +5372,15 @@ static const struct mtk_soc_data rt5350_
        .required_clks = MT7628_CLKS_BITMAP,
        .required_pctl = false,
        .version = 1,
index bebd7e870a555f68c7a010ce246e2b3e1d55b2f3..c9a729fde2f6dda3ab459dffdb2828c1d3c9c14d 100644 (file)
@@ -44,7 +44,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        },
        .qdma = {
                .qtx_cfg        = 0x4400,
-@@ -1207,7 +1207,7 @@ static bool mtk_rx_get_desc(struct mtk_e
+@@ -1206,7 +1206,7 @@ static bool mtk_rx_get_desc(struct mtk_e
        rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
        rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
        rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
@@ -53,7 +53,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
                rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
        }
-@@ -2159,7 +2159,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2158,7 +2158,7 @@ static int mtk_poll_rx(struct napi_struc
                        break;
  
                /* find out which mac the packet come from. values start at 1 */
@@ -62,7 +62,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                        u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
  
                        switch (val) {
-@@ -2271,7 +2271,7 @@ static int mtk_poll_rx(struct napi_struc
+@@ -2270,7 +2270,7 @@ static int mtk_poll_rx(struct napi_struc
                skb->dev = netdev;
                bytes += skb->len;
  
@@ -71,7 +71,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                        reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
                        hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
                        if (hash != MTK_RXD5_FOE_ENTRY)
-@@ -2821,7 +2821,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+@@ -2820,7 +2820,7 @@ static int mtk_rx_alloc(struct mtk_eth *
  
                rxd->rxd3 = 0;
                rxd->rxd4 = 0;
@@ -80,7 +80,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                        rxd->rxd5 = 0;
                        rxd->rxd6 = 0;
                        rxd->rxd7 = 0;
-@@ -4022,7 +4022,7 @@ static int mtk_hw_init(struct mtk_eth *e
+@@ -4021,7 +4021,7 @@ static int mtk_hw_init(struct mtk_eth *e
        else
                mtk_hw_reset(eth);
  
@@ -89,7 +89,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                /* Set FE to PDMAv2 if necessary */
                val = mtk_r32(eth, MTK_FE_GLO_MISC);
                mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
-@@ -5306,11 +5306,11 @@ static const struct mtk_soc_data mt7981_
+@@ -5305,11 +5305,11 @@ static const struct mtk_soc_data mt7981_
                .dma_len_offset = 8,
        },
        .rx = {
@@ -105,7 +105,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        },
  };
  
-@@ -5332,11 +5332,11 @@ static const struct mtk_soc_data mt7986_
+@@ -5331,11 +5331,11 @@ static const struct mtk_soc_data mt7986_
                .dma_len_offset = 8,
        },
        .rx = {
index 15762be81d40ec2187ea7fd3e591dc7899a750db..918132e2936c43cda578ad00b63f8ed6fc05aa07 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 ---
 --- a/drivers/net/ethernet/marvell/mvneta.c
 +++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -5234,6 +5234,16 @@ static int mvneta_setup_tc(struct net_de
+@@ -5233,6 +5233,16 @@ static int mvneta_setup_tc(struct net_de
        }
  }
  
@@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  static const struct net_device_ops mvneta_netdev_ops = {
        .ndo_open            = mvneta_open,
        .ndo_stop            = mvneta_stop,
-@@ -5244,6 +5254,9 @@ static const struct net_device_ops mvnet
+@@ -5243,6 +5253,9 @@ static const struct net_device_ops mvnet
        .ndo_fix_features    = mvneta_fix_features,
        .ndo_get_stats64     = mvneta_get_stats64,
        .ndo_eth_ioctl        = mvneta_ioctl,
index 73ed55a0853883c11b2829278f1d73af501426d7..91159f2c6347deac70189398dc5b39b4c2c8fb68 100644 (file)
@@ -71,7 +71,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
                break;
 --- a/drivers/net/phy/phy_device.c
 +++ b/drivers/net/phy/phy_device.c
-@@ -1039,14 +1039,16 @@ struct phy_device *phy_find_first(struct
+@@ -1037,14 +1037,16 @@ struct phy_device *phy_find_first(struct
  }
  EXPORT_SYMBOL(phy_find_first);
  
@@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
                phydev->mii_ts->link_state(phydev->mii_ts, phydev);
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -1602,7 +1602,8 @@ bool phylink_expects_phy(struct phylink
+@@ -1687,7 +1687,8 @@ bool phylink_expects_phy(struct phylink
  }
  EXPORT_SYMBOL_GPL(phylink_expects_phy);