Removed because they are upstream:
   generic/backport-5.15/741-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch
   https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.15.y&id=d06977b9a4109f8738bb276125eb6a0b772bc433
Removed because they are upstream:
   generic/backport-5.15/741-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch
   https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.15.y&id=e719b52d0c56989b0f3475a03a6d64f182c85b56
Manual adapted the following patches:
   generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
   generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch
   generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
(cherry picked from commit 84d0b0b925)
		
	
		
			
				
	
	
		
			515 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			515 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From patchwork Thu Mar  9 10:57:44 2023
 | 
						|
Content-Type: text/plain; charset="utf-8"
 | 
						|
MIME-Version: 1.0
 | 
						|
Content-Transfer-Encoding: 8bit
 | 
						|
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
 | 
						|
X-Patchwork-Id: 13167235
 | 
						|
X-Patchwork-Delegate: kuba@kernel.org
 | 
						|
Return-Path: <netdev-owner@vger.kernel.org>
 | 
						|
Date: Thu, 9 Mar 2023 10:57:44 +0000
 | 
						|
From: Daniel Golle <daniel@makrotopia.org>
 | 
						|
To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org,
 | 
						|
        linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
 | 
						|
        Russell King <linux@armlinux.org.uk>,
 | 
						|
        Heiner Kallweit <hkallweit1@gmail.com>,
 | 
						|
        Lorenzo Bianconi <lorenzo@kernel.org>,
 | 
						|
        Mark Lee <Mark-MC.Lee@mediatek.com>,
 | 
						|
        John Crispin <john@phrozen.org>, Felix Fietkau <nbd@nbd.name>,
 | 
						|
        AngeloGioacchino Del Regno
 | 
						|
        <angelogioacchino.delregno@collabora.com>,
 | 
						|
        Matthias Brugger <matthias.bgg@gmail.com>,
 | 
						|
        DENG Qingfang <dqfext@gmail.com>,
 | 
						|
        Landen Chao <Landen.Chao@mediatek.com>,
 | 
						|
        Sean Wang <sean.wang@mediatek.com>,
 | 
						|
        Paolo Abeni <pabeni@redhat.com>,
 | 
						|
        Jakub Kicinski <kuba@kernel.org>,
 | 
						|
        Eric Dumazet <edumazet@google.com>,
 | 
						|
        "David S. Miller" <davem@davemloft.net>,
 | 
						|
        Vladimir Oltean <olteanv@gmail.com>,
 | 
						|
        Florian Fainelli <f.fainelli@gmail.com>,
 | 
						|
        Andrew Lunn <andrew@lunn.ch>,
 | 
						|
        Vladimir Oltean <vladimir.oltean@nxp.com>
 | 
						|
Cc: =?iso-8859-1?q?Bj=F8rn?= Mork <bjorn@mork.no>,
 | 
						|
 Frank Wunderlich <frank-w@public-files.de>,
 | 
						|
 Alexander Couzens <lynxis@fe80.eu>
 | 
						|
Subject: [PATCH net-next v13 11/16] net: dsa: mt7530: use external PCS driver
 | 
						|
Message-ID: 
 | 
						|
 <2ac2ee40d3b0e705461b50613fda6a7edfdbc4b3.1678357225.git.daniel@makrotopia.org>
 | 
						|
References: <cover.1678357225.git.daniel@makrotopia.org>
 | 
						|
MIME-Version: 1.0
 | 
						|
Content-Disposition: inline
 | 
						|
In-Reply-To: <cover.1678357225.git.daniel@makrotopia.org>
 | 
						|
Precedence: bulk
 | 
						|
List-ID: <netdev.vger.kernel.org>
 | 
						|
X-Mailing-List: netdev@vger.kernel.org
 | 
						|
X-Patchwork-Delegate: kuba@kernel.org
 | 
						|
 | 
						|
Implement regmap access wrappers, for now only to be used by the
 | 
						|
pcs-mtk driver.
 | 
						|
Make use of external PCS driver and drop the reduntant implementation
 | 
						|
in mt7530.c.
 | 
						|
As a nice side effect the SGMII registers can now also more easily be
 | 
						|
inspected for debugging via /sys/kernel/debug/regmap.
 | 
						|
 | 
						|
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
 | 
						|
Tested-by: Bjørn Mork <bjorn@mork.no>
 | 
						|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
						|
Tested-by: Frank Wunderlich <frank-w@public-files.de>
 | 
						|
---
 | 
						|
 drivers/net/dsa/Kconfig  |   1 +
 | 
						|
 drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
 | 
						|
 drivers/net/dsa/mt7530.h |  47 +------
 | 
						|
 3 files changed, 71 insertions(+), 254 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/net/dsa/Kconfig
 | 
						|
+++ b/drivers/net/dsa/Kconfig
 | 
						|
@@ -37,6 +37,7 @@ config NET_DSA_MT7530
 | 
						|
 	tristate "MediaTek MT753x and MT7621 Ethernet switch support"
 | 
						|
 	select NET_DSA_TAG_MTK
 | 
						|
 	select MEDIATEK_GE_PHY
 | 
						|
+	select PCS_MTK_LYNXI
 | 
						|
 	help
 | 
						|
 	  This enables support for the MediaTek MT7530, MT7531, and MT7621
 | 
						|
 	  Ethernet switch chips.
 | 
						|
--- a/drivers/net/dsa/mt7530.c
 | 
						|
+++ b/drivers/net/dsa/mt7530.c
 | 
						|
@@ -14,6 +14,7 @@
 | 
						|
 #include <linux/of_mdio.h>
 | 
						|
 #include <linux/of_net.h>
 | 
						|
 #include <linux/of_platform.h>
 | 
						|
+#include <linux/pcs/pcs-mtk-lynxi.h>
 | 
						|
 #include <linux/phylink.h>
 | 
						|
 #include <linux/regmap.h>
 | 
						|
 #include <linux/regulator/consumer.h>
 | 
						|
@@ -2831,128 +2832,11 @@ static int mt7531_rgmii_setup(struct mt7
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
 | 
						|
-			       phy_interface_t interface, int speed, int duplex)
 | 
						|
-{
 | 
						|
-	struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
 | 
						|
-	int port = pcs_to_mt753x_pcs(pcs)->port;
 | 
						|
-	unsigned int val;
 | 
						|
-
 | 
						|
-	/* For adjusting speed and duplex of SGMII force mode. */
 | 
						|
-	if (interface != PHY_INTERFACE_MODE_SGMII ||
 | 
						|
-	    phylink_autoneg_inband(mode))
 | 
						|
-		return;
 | 
						|
-
 | 
						|
-	/* SGMII force mode setting */
 | 
						|
-	val = mt7530_read(priv, MT7531_SGMII_MODE(port));
 | 
						|
-	val &= ~MT7531_SGMII_IF_MODE_MASK;
 | 
						|
-
 | 
						|
-	switch (speed) {
 | 
						|
-	case SPEED_10:
 | 
						|
-		val |= MT7531_SGMII_FORCE_SPEED_10;
 | 
						|
-		break;
 | 
						|
-	case SPEED_100:
 | 
						|
-		val |= MT7531_SGMII_FORCE_SPEED_100;
 | 
						|
-		break;
 | 
						|
-	case SPEED_1000:
 | 
						|
-		val |= MT7531_SGMII_FORCE_SPEED_1000;
 | 
						|
-		break;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	/* MT7531 SGMII 1G force mode can only work in full duplex mode,
 | 
						|
-	 * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
 | 
						|
-	 *
 | 
						|
-	 * The speed check is unnecessary as the MAC capabilities apply
 | 
						|
-	 * this restriction. --rmk
 | 
						|
-	 */
 | 
						|
-	if ((speed == SPEED_10 || speed == SPEED_100) &&
 | 
						|
-	    duplex != DUPLEX_FULL)
 | 
						|
-		val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
 | 
						|
-
 | 
						|
-	mt7530_write(priv, MT7531_SGMII_MODE(port), val);
 | 
						|
-}
 | 
						|
-
 | 
						|
 static bool mt753x_is_mac_port(u32 port)
 | 
						|
 {
 | 
						|
 	return (port == 5 || port == 6);
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
 | 
						|
-					 phy_interface_t interface)
 | 
						|
-{
 | 
						|
-	u32 val;
 | 
						|
-
 | 
						|
-	if (!mt753x_is_mac_port(port))
 | 
						|
-		return -EINVAL;
 | 
						|
-
 | 
						|
-	mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
 | 
						|
-		   MT7531_SGMII_PHYA_PWD);
 | 
						|
-
 | 
						|
-	val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
 | 
						|
-	val &= ~MT7531_RG_TPHY_SPEED_MASK;
 | 
						|
-	/* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
 | 
						|
-	 * encoding.
 | 
						|
-	 */
 | 
						|
-	val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
 | 
						|
-		MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
 | 
						|
-	mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
 | 
						|
-
 | 
						|
-	mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
 | 
						|
-
 | 
						|
-	/* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
 | 
						|
-	 * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
 | 
						|
-	 */
 | 
						|
-	mt7530_rmw(priv, MT7531_SGMII_MODE(port),
 | 
						|
-		   MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
 | 
						|
-		   MT7531_SGMII_FORCE_SPEED_1000);
 | 
						|
-
 | 
						|
-	mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
-static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
 | 
						|
-				      phy_interface_t interface)
 | 
						|
-{
 | 
						|
-	if (!mt753x_is_mac_port(port))
 | 
						|
-		return -EINVAL;
 | 
						|
-
 | 
						|
-	mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
 | 
						|
-		   MT7531_SGMII_PHYA_PWD);
 | 
						|
-
 | 
						|
-	mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
 | 
						|
-		   MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
 | 
						|
-
 | 
						|
-	mt7530_set(priv, MT7531_SGMII_MODE(port),
 | 
						|
-		   MT7531_SGMII_REMOTE_FAULT_DIS |
 | 
						|
-		   MT7531_SGMII_SPEED_DUPLEX_AN);
 | 
						|
-
 | 
						|
-	mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
 | 
						|
-		   MT7531_SGMII_TX_CONFIG_MASK, 1);
 | 
						|
-
 | 
						|
-	mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
 | 
						|
-
 | 
						|
-	mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
 | 
						|
-
 | 
						|
-	mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
-static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
 | 
						|
-{
 | 
						|
-	struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
 | 
						|
-	int port = pcs_to_mt753x_pcs(pcs)->port;
 | 
						|
-	u32 val;
 | 
						|
-
 | 
						|
-	/* Only restart AN when AN is enabled */
 | 
						|
-	val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
 | 
						|
-	if (val & MT7531_SGMII_AN_ENABLE) {
 | 
						|
-		val |= MT7531_SGMII_AN_RESTART;
 | 
						|
-		mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
 | 
						|
-	}
 | 
						|
-}
 | 
						|
-
 | 
						|
 static int
 | 
						|
 mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 | 
						|
 		  phy_interface_t interface)
 | 
						|
@@ -2975,11 +2859,11 @@ mt7531_mac_config(struct dsa_switch *ds,
 | 
						|
 		phydev = dp->slave->phydev;
 | 
						|
 		return mt7531_rgmii_setup(priv, port, interface, phydev);
 | 
						|
 	case PHY_INTERFACE_MODE_SGMII:
 | 
						|
-		return mt7531_sgmii_setup_mode_an(priv, port, interface);
 | 
						|
 	case PHY_INTERFACE_MODE_NA:
 | 
						|
 	case PHY_INTERFACE_MODE_1000BASEX:
 | 
						|
 	case PHY_INTERFACE_MODE_2500BASEX:
 | 
						|
-		return mt7531_sgmii_setup_mode_force(priv, port, interface);
 | 
						|
+		/* handled in SGMII PCS driver */
 | 
						|
+		return 0;
 | 
						|
 	default:
 | 
						|
 		return -EINVAL;
 | 
						|
 	}
 | 
						|
@@ -3004,11 +2888,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
 | 
						|
 
 | 
						|
 	switch (interface) {
 | 
						|
 	case PHY_INTERFACE_MODE_TRGMII:
 | 
						|
+		return &priv->pcs[port].pcs;
 | 
						|
 	case PHY_INTERFACE_MODE_SGMII:
 | 
						|
 	case PHY_INTERFACE_MODE_1000BASEX:
 | 
						|
 	case PHY_INTERFACE_MODE_2500BASEX:
 | 
						|
-		return &priv->pcs[port].pcs;
 | 
						|
-
 | 
						|
+		return priv->ports[port].sgmii_pcs;
 | 
						|
 	default:
 | 
						|
 		return NULL;
 | 
						|
 	}
 | 
						|
@@ -3249,86 +3133,6 @@ static void mt7530_pcs_get_state(struct
 | 
						|
 		state->pause |= MLO_PAUSE_TX;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int
 | 
						|
-mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
 | 
						|
-			      struct phylink_link_state *state)
 | 
						|
-{
 | 
						|
-	u32 status, val;
 | 
						|
-	u16 config_reg;
 | 
						|
-
 | 
						|
-	status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
 | 
						|
-	state->link = !!(status & MT7531_SGMII_LINK_STATUS);
 | 
						|
-	state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
 | 
						|
-	if (state->interface == PHY_INTERFACE_MODE_SGMII &&
 | 
						|
-	    (status & MT7531_SGMII_AN_ENABLE)) {
 | 
						|
-		val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
 | 
						|
-		config_reg = val >> 16;
 | 
						|
-
 | 
						|
-		switch (config_reg & LPA_SGMII_SPD_MASK) {
 | 
						|
-		case LPA_SGMII_1000:
 | 
						|
-			state->speed = SPEED_1000;
 | 
						|
-			break;
 | 
						|
-		case LPA_SGMII_100:
 | 
						|
-			state->speed = SPEED_100;
 | 
						|
-			break;
 | 
						|
-		case LPA_SGMII_10:
 | 
						|
-			state->speed = SPEED_10;
 | 
						|
-			break;
 | 
						|
-		default:
 | 
						|
-			dev_err(priv->dev, "invalid sgmii PHY speed\n");
 | 
						|
-			state->link = false;
 | 
						|
-			return -EINVAL;
 | 
						|
-		}
 | 
						|
-
 | 
						|
-		if (config_reg & LPA_SGMII_FULL_DUPLEX)
 | 
						|
-			state->duplex = DUPLEX_FULL;
 | 
						|
-		else
 | 
						|
-			state->duplex = DUPLEX_HALF;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
-static void
 | 
						|
-mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
 | 
						|
-				  struct phylink_link_state *state)
 | 
						|
-{
 | 
						|
-	unsigned int val;
 | 
						|
-
 | 
						|
-	val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
 | 
						|
-	state->link = !!(val & MT7531_SGMII_LINK_STATUS);
 | 
						|
-	if (!state->link)
 | 
						|
-		return;
 | 
						|
-
 | 
						|
-	state->an_complete = state->link;
 | 
						|
-
 | 
						|
-	if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
 | 
						|
-		state->speed = SPEED_2500;
 | 
						|
-	else
 | 
						|
-		state->speed = SPEED_1000;
 | 
						|
-
 | 
						|
-	state->duplex = DUPLEX_FULL;
 | 
						|
-	state->pause = MLO_PAUSE_NONE;
 | 
						|
-}
 | 
						|
-
 | 
						|
-static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
 | 
						|
-				 struct phylink_link_state *state)
 | 
						|
-{
 | 
						|
-	struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
 | 
						|
-	int port = pcs_to_mt753x_pcs(pcs)->port;
 | 
						|
-
 | 
						|
-	if (state->interface == PHY_INTERFACE_MODE_SGMII) {
 | 
						|
-		mt7531_sgmii_pcs_get_state_an(priv, port, state);
 | 
						|
-		return;
 | 
						|
-	} else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
 | 
						|
-		   (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
 | 
						|
-		mt7531_sgmii_pcs_get_state_inband(priv, port, state);
 | 
						|
-		return;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	state->link = false;
 | 
						|
-}
 | 
						|
-
 | 
						|
 static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 | 
						|
 			     phy_interface_t interface,
 | 
						|
 			     const unsigned long *advertising,
 | 
						|
@@ -3348,18 +3152,57 @@ static const struct phylink_pcs_ops mt75
 | 
						|
 	.pcs_an_restart = mt7530_pcs_an_restart,
 | 
						|
 };
 | 
						|
 
 | 
						|
-static const struct phylink_pcs_ops mt7531_pcs_ops = {
 | 
						|
-	.pcs_validate = mt753x_pcs_validate,
 | 
						|
-	.pcs_get_state = mt7531_pcs_get_state,
 | 
						|
-	.pcs_config = mt753x_pcs_config,
 | 
						|
-	.pcs_an_restart = mt7531_pcs_an_restart,
 | 
						|
-	.pcs_link_up = mt7531_pcs_link_up,
 | 
						|
+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
 | 
						|
+{
 | 
						|
+	struct mt7530_priv *priv = context;
 | 
						|
+
 | 
						|
+	*val = mt7530_read(priv, reg);
 | 
						|
+	return 0;
 | 
						|
+};
 | 
						|
+
 | 
						|
+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
 | 
						|
+{
 | 
						|
+	struct mt7530_priv *priv = context;
 | 
						|
+
 | 
						|
+	mt7530_write(priv, reg, val);
 | 
						|
+	return 0;
 | 
						|
+};
 | 
						|
+
 | 
						|
+static int mt7530_regmap_update_bits(void *context, unsigned int reg,
 | 
						|
+				     unsigned int mask, unsigned int val)
 | 
						|
+{
 | 
						|
+	struct mt7530_priv *priv = context;
 | 
						|
+
 | 
						|
+	mt7530_rmw(priv, reg, mask, val);
 | 
						|
+	return 0;
 | 
						|
+};
 | 
						|
+
 | 
						|
+static const struct regmap_bus mt7531_regmap_bus = {
 | 
						|
+	.reg_write = mt7530_regmap_write,
 | 
						|
+	.reg_read = mt7530_regmap_read,
 | 
						|
+	.reg_update_bits = mt7530_regmap_update_bits,
 | 
						|
+};
 | 
						|
+
 | 
						|
+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
 | 
						|
+	{				\
 | 
						|
+		.name = _name,		\
 | 
						|
+		.reg_bits = 16,		\
 | 
						|
+		.val_bits = 32,		\
 | 
						|
+		.reg_stride = 4,	\
 | 
						|
+		.reg_base = _reg_base,	\
 | 
						|
+		.max_register = 0x17c,	\
 | 
						|
+	}
 | 
						|
+
 | 
						|
+static const struct regmap_config mt7531_pcs_config[] = {
 | 
						|
+	MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
 | 
						|
+	MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
 | 
						|
 };
 | 
						|
 
 | 
						|
 static int
 | 
						|
 mt753x_setup(struct dsa_switch *ds)
 | 
						|
 {
 | 
						|
 	struct mt7530_priv *priv = ds->priv;
 | 
						|
+	struct regmap *regmap;
 | 
						|
 	int i, ret;
 | 
						|
 
 | 
						|
 	/* Initialise the PCS devices */
 | 
						|
@@ -3367,8 +3210,6 @@ mt753x_setup(struct dsa_switch *ds)
 | 
						|
 		priv->pcs[i].pcs.ops = priv->info->pcs_ops;
 | 
						|
 		priv->pcs[i].priv = priv;
 | 
						|
 		priv->pcs[i].port = i;
 | 
						|
-		if (mt753x_is_mac_port(i))
 | 
						|
-			priv->pcs[i].pcs.poll = 1;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	ret = priv->info->sw_setup(ds);
 | 
						|
@@ -3383,6 +3224,16 @@ mt753x_setup(struct dsa_switch *ds)
 | 
						|
 	if (ret && priv->irq)
 | 
						|
 		mt7530_free_irq_common(priv);
 | 
						|
 
 | 
						|
+	if (priv->id == ID_MT7531)
 | 
						|
+		for (i = 0; i < 2; i++) {
 | 
						|
+			regmap = devm_regmap_init(ds->dev,
 | 
						|
+						  &mt7531_regmap_bus, priv,
 | 
						|
+						  &mt7531_pcs_config[i]);
 | 
						|
+			priv->ports[5 + i].sgmii_pcs =
 | 
						|
+				mtk_pcs_lynxi_create(ds->dev, regmap,
 | 
						|
+						     MT7531_PHYA_CTRL_SIGNAL3, 0);
 | 
						|
+		}
 | 
						|
+
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -3475,7 +3326,7 @@ static const struct mt753x_info mt753x_t
 | 
						|
 	},
 | 
						|
 	[ID_MT7531] = {
 | 
						|
 		.id = ID_MT7531,
 | 
						|
-		.pcs_ops = &mt7531_pcs_ops,
 | 
						|
+		.pcs_ops = &mt7530_pcs_ops,
 | 
						|
 		.sw_setup = mt7531_setup,
 | 
						|
 		.phy_read = mt7531_ind_phy_read,
 | 
						|
 		.phy_write = mt7531_ind_phy_write,
 | 
						|
@@ -3583,7 +3434,7 @@ static void
 | 
						|
 mt7530_remove(struct mdio_device *mdiodev)
 | 
						|
 {
 | 
						|
 	struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
 | 
						|
-	int ret = 0;
 | 
						|
+	int ret = 0, i;
 | 
						|
 
 | 
						|
 	if (!priv)
 | 
						|
 		return;
 | 
						|
@@ -3602,6 +3453,10 @@ mt7530_remove(struct mdio_device *mdiode
 | 
						|
 		mt7530_free_irq(priv);
 | 
						|
 
 | 
						|
 	dsa_unregister_switch(priv->ds);
 | 
						|
+
 | 
						|
+	for (i = 0; i < 2; ++i)
 | 
						|
+		mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
 | 
						|
+
 | 
						|
 	mutex_destroy(&priv->reg_mutex);
 | 
						|
 
 | 
						|
 	dev_set_drvdata(&mdiodev->dev, NULL);
 | 
						|
--- a/drivers/net/dsa/mt7530.h
 | 
						|
+++ b/drivers/net/dsa/mt7530.h
 | 
						|
@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm {
 | 
						|
 					 CCR_TX_OCT_CNT_BAD)
 | 
						|
 
 | 
						|
 /* MT7531 SGMII register group */
 | 
						|
-#define MT7531_SGMII_REG_BASE		0x5000
 | 
						|
-#define MT7531_SGMII_REG(p, r)		(MT7531_SGMII_REG_BASE + \
 | 
						|
-					((p) - 5) * 0x1000 + (r))
 | 
						|
-
 | 
						|
-/* Register forSGMII PCS_CONTROL_1 */
 | 
						|
-#define MT7531_PCS_CONTROL_1(p)		MT7531_SGMII_REG(p, 0x00)
 | 
						|
-#define  MT7531_SGMII_LINK_STATUS	BIT(18)
 | 
						|
-#define  MT7531_SGMII_AN_ENABLE		BIT(12)
 | 
						|
-#define  MT7531_SGMII_AN_RESTART	BIT(9)
 | 
						|
-#define  MT7531_SGMII_AN_COMPLETE	BIT(21)
 | 
						|
-
 | 
						|
-/* Register for SGMII PCS_SPPED_ABILITY */
 | 
						|
-#define MT7531_PCS_SPEED_ABILITY(p)	MT7531_SGMII_REG(p, 0x08)
 | 
						|
-#define  MT7531_SGMII_TX_CONFIG_MASK	GENMASK(15, 0)
 | 
						|
-#define  MT7531_SGMII_TX_CONFIG		BIT(0)
 | 
						|
-
 | 
						|
-/* Register for SGMII_MODE */
 | 
						|
-#define MT7531_SGMII_MODE(p)		MT7531_SGMII_REG(p, 0x20)
 | 
						|
-#define  MT7531_SGMII_REMOTE_FAULT_DIS	BIT(8)
 | 
						|
-#define  MT7531_SGMII_IF_MODE_MASK	GENMASK(5, 1)
 | 
						|
-#define  MT7531_SGMII_FORCE_DUPLEX	BIT(4)
 | 
						|
-#define  MT7531_SGMII_FORCE_SPEED_MASK	GENMASK(3, 2)
 | 
						|
-#define  MT7531_SGMII_FORCE_SPEED_1000	BIT(3)
 | 
						|
-#define  MT7531_SGMII_FORCE_SPEED_100	BIT(2)
 | 
						|
-#define  MT7531_SGMII_FORCE_SPEED_10	0
 | 
						|
-#define  MT7531_SGMII_SPEED_DUPLEX_AN	BIT(1)
 | 
						|
-
 | 
						|
-enum mt7531_sgmii_force_duplex {
 | 
						|
-	MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
 | 
						|
-	MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
 | 
						|
-};
 | 
						|
-
 | 
						|
-/* Fields of QPHY_PWR_STATE_CTRL */
 | 
						|
-#define MT7531_QPHY_PWR_STATE_CTRL(p)	MT7531_SGMII_REG(p, 0xe8)
 | 
						|
-#define  MT7531_SGMII_PHYA_PWD		BIT(4)
 | 
						|
-
 | 
						|
-/* Values of SGMII SPEED */
 | 
						|
-#define MT7531_PHYA_CTRL_SIGNAL3(p)	MT7531_SGMII_REG(p, 0x128)
 | 
						|
-#define  MT7531_RG_TPHY_SPEED_MASK	(BIT(2) | BIT(3))
 | 
						|
-#define  MT7531_RG_TPHY_SPEED_1_25G	0x0
 | 
						|
-#define  MT7531_RG_TPHY_SPEED_3_125G	BIT(2)
 | 
						|
+#define MT7531_SGMII_REG_BASE(p)	(0x5000 + ((p) - 5) * 0x1000)
 | 
						|
+#define MT7531_PHYA_CTRL_SIGNAL3	0x128
 | 
						|
 
 | 
						|
 /* Register for system reset */
 | 
						|
 #define MT7530_SYS_CTRL			0x7000
 | 
						|
@@ -741,13 +702,13 @@ struct mt7530_fdb {
 | 
						|
  * @pm:		The matrix used to show all connections with the port.
 | 
						|
  * @pvid:	The VLAN specified is to be considered a PVID at ingress.  Any
 | 
						|
  *		untagged frames will be assigned to the related VLAN.
 | 
						|
- * @vlan_filtering: The flags indicating whether the port that can recognize
 | 
						|
- *		    VLAN-tagged frames.
 | 
						|
+ * @sgmii_pcs:	Pointer to PCS instance for SerDes ports
 | 
						|
  */
 | 
						|
 struct mt7530_port {
 | 
						|
 	bool enable;
 | 
						|
 	u32 pm;
 | 
						|
 	u16 pvid;
 | 
						|
+	struct phylink_pcs *sgmii_pcs;
 | 
						|
 };
 | 
						|
 
 | 
						|
 /* Port 5 interface select definitions */
 |