mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
401a6ccfaf
Backport lots upstream changes, many of them fixes, for the mt7530 DSA driver. Some of them may or may not find they way into Linux 6.1 stable, some certainly won't because they are fixes for backported commits which aren't even present in Linux 6.1 upstream. Apart from adding new patches, also remove mutated patch 723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch which should never have been added for Linux 6.1 -- it was applied already upstream but coincidentally would fuzzy-apply in the wrong place as well (for MT7530 instead of MT7531). While that didn't really hurt anyone it is just unneeded. The other deleted patch 795-mt7530-register-OF-node-for-internal-MDIO-bus.patch has been replaced by an equivalent commit with a more complete patch description by upstream maintainer Arınç Ünal. The remaining differences compared to the upstream driver are: * C22/C45 MDIO ops aren't split Upstream did that, backporting it would require making changes to *all* DSA drivers * 'slave' -> 'user', 'master' -> 'conduit' language change in DSA * support for selecting preferred CPU port on MT7531 Also this would require too many DSA framework changes potentially affecting other devices. If we ever really use Linux 6.1 in a release (I hope not) we can still reconsider to make the effort to backport that. In addition to some minor bug fixes and style improvements the switch should now behave more conformant when it comes to link-local frames, and we will again be able to cleanly pick patches from upstream. MAINTAIERS NOTE: Three patches are already part of Linux stable and should be removed with the next minor kernel version bump: 789-STABLE-01-net-dsa-mt7530-prevent-possible-incorrect-XTAL-frequ.patch 789-STABLE-02-net-dsa-mt7530-fix-link-local-frames-that-ingress-vl.patch 789-STABLE-03-net-dsa-mt7530-fix-handling-of-all-link-local-frames.patch Signed-off-by: Daniel Golle <daniel@makrotopia.org>
228 lines
7.2 KiB
Diff
228 lines
7.2 KiB
Diff
From b0d590a5cdd95ed863717b279751d6166083889f Mon Sep 17 00:00:00 2001
|
||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||
Date: Mon, 22 Jan 2024 08:35:54 +0300
|
||
Subject: [PATCH 25/48] net: dsa: mt7530: store port 5 SGMII capability of
|
||
MT7531
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Introduce the p5_sgmii field to store the information for whether port 5
|
||
has got SGMII or not. Instead of reading the MT7531_TOP_SIG_SR register
|
||
multiple times, the register will be read once and the value will be
|
||
stored on the p5_sgmii field. This saves unnecessary reads of the
|
||
register.
|
||
|
||
Move the comment about MT7531AE and MT7531BE to mt7531_setup(), where the
|
||
switch is identified.
|
||
|
||
Get rid of mt7531_dual_sgmii_supported() now that priv->p5_sgmii stores the
|
||
information. Address the code where mt7531_dual_sgmii_supported() is used.
|
||
|
||
Get rid of mt7531_is_rgmii_port() which just prints the opposite of
|
||
priv->p5_sgmii.
|
||
|
||
Instead of calling mt7531_pll_setup() then returning, do not call it if
|
||
port 5 is SGMII.
|
||
|
||
Remove P5_INTF_SEL_GMAC5_SGMII. The p5_interface_select enum is supposed to
|
||
represent the mode that port 5 is being used in, not the hardware
|
||
information of port 5. Set p5_intf_sel to P5_INTF_SEL_GMAC5 instead, if
|
||
port 5 is not dsa_is_unused_port().
|
||
|
||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||
Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-3-042401f2b279@arinc9.com
|
||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||
---
|
||
drivers/net/dsa/mt7530-mdio.c | 7 ++---
|
||
drivers/net/dsa/mt7530.c | 48 ++++++++++++-----------------------
|
||
drivers/net/dsa/mt7530.h | 6 +++--
|
||
3 files changed, 22 insertions(+), 39 deletions(-)
|
||
|
||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||
@@ -81,17 +81,14 @@ static const struct regmap_bus mt7530_re
|
||
};
|
||
|
||
static int
|
||
-mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
|
||
+mt7531_create_sgmii(struct mt7530_priv *priv)
|
||
{
|
||
struct regmap_config *mt7531_pcs_config[2] = {};
|
||
struct phylink_pcs *pcs;
|
||
struct regmap *regmap;
|
||
int i, ret = 0;
|
||
|
||
- /* MT7531AE has two SGMII units for port 5 and port 6
|
||
- * MT7531BE has only one SGMII unit for port 6
|
||
- */
|
||
- for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
|
||
+ for (i = priv->p5_sgmii ? 0 : 1; i < 2; i++) {
|
||
mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||
sizeof(struct regmap_config),
|
||
GFP_KERNEL);
|
||
--- a/drivers/net/dsa/mt7530.c
|
||
+++ b/drivers/net/dsa/mt7530.c
|
||
@@ -473,15 +473,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
|
||
return 0;
|
||
}
|
||
|
||
-static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv)
|
||
-{
|
||
- u32 val;
|
||
-
|
||
- val = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||
-
|
||
- return (val & PAD_DUAL_SGMII_EN) != 0;
|
||
-}
|
||
-
|
||
static int
|
||
mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||
{
|
||
@@ -496,9 +487,6 @@ mt7531_pll_setup(struct mt7530_priv *pri
|
||
u32 xtal;
|
||
u32 val;
|
||
|
||
- if (mt7531_dual_sgmii_supported(priv))
|
||
- return;
|
||
-
|
||
val = mt7530_read(priv, MT7531_CREV);
|
||
top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||
hwstrap = mt7530_read(priv, MT7531_HWTRAP);
|
||
@@ -913,8 +901,6 @@ static const char *p5_intf_modes(unsigne
|
||
return "PHY P4";
|
||
case P5_INTF_SEL_GMAC5:
|
||
return "GMAC5";
|
||
- case P5_INTF_SEL_GMAC5_SGMII:
|
||
- return "GMAC5_SGMII";
|
||
default:
|
||
return "unknown";
|
||
}
|
||
@@ -2515,6 +2501,12 @@ mt7531_setup(struct dsa_switch *ds)
|
||
return -ENODEV;
|
||
}
|
||
|
||
+ /* MT7531AE has got two SGMII units. One for port 5, one for port 6.
|
||
+ * MT7531BE has got only one SGMII unit which is for port 6.
|
||
+ */
|
||
+ val = mt7530_read(priv, MT7531_TOP_SIG_SR);
|
||
+ priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
|
||
+
|
||
/* all MACs must be forced link-down before sw reset */
|
||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||
mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
|
||
@@ -2524,21 +2516,18 @@ mt7531_setup(struct dsa_switch *ds)
|
||
SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
|
||
SYS_CTRL_REG_RST);
|
||
|
||
- mt7531_pll_setup(priv);
|
||
-
|
||
- if (mt7531_dual_sgmii_supported(priv)) {
|
||
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII;
|
||
-
|
||
+ if (!priv->p5_sgmii) {
|
||
+ mt7531_pll_setup(priv);
|
||
+ } else {
|
||
/* Let ds->slave_mii_bus be able to access external phy. */
|
||
mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK,
|
||
MT7531_EXT_P_MDC_11);
|
||
mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK,
|
||
MT7531_EXT_P_MDIO_12);
|
||
- } else {
|
||
- priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||
}
|
||
- dev_dbg(ds->dev, "P5 support %s interface\n",
|
||
- p5_intf_modes(priv->p5_intf_sel));
|
||
+
|
||
+ if (!dsa_is_unused_port(ds, 5))
|
||
+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5;
|
||
|
||
mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
|
||
MT7531_GPIO0_INTERRUPT);
|
||
@@ -2598,11 +2587,6 @@ static void mt7530_mac_port_get_caps(str
|
||
}
|
||
}
|
||
|
||
-static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
|
||
-{
|
||
- return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
|
||
-}
|
||
-
|
||
static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||
struct phylink_config *config)
|
||
{
|
||
@@ -2615,7 +2599,7 @@ static void mt7531_mac_port_get_caps(str
|
||
break;
|
||
|
||
case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
|
||
- if (mt7531_is_rgmii_port(priv, port)) {
|
||
+ if (!priv->p5_sgmii) {
|
||
phy_interface_set_rgmii(config->supported_interfaces);
|
||
break;
|
||
}
|
||
@@ -2682,7 +2666,7 @@ static int mt7531_rgmii_setup(struct mt7
|
||
{
|
||
u32 val;
|
||
|
||
- if (!mt7531_is_rgmii_port(priv, port)) {
|
||
+ if (priv->p5_sgmii) {
|
||
dev_err(priv->dev, "RGMII mode is not available for port %d\n",
|
||
port);
|
||
return -EINVAL;
|
||
@@ -2925,7 +2909,7 @@ mt7531_cpu_port_config(struct dsa_switch
|
||
|
||
switch (port) {
|
||
case 5:
|
||
- if (mt7531_is_rgmii_port(priv, port))
|
||
+ if (!priv->p5_sgmii)
|
||
interface = PHY_INTERFACE_MODE_RGMII;
|
||
else
|
||
interface = PHY_INTERFACE_MODE_2500BASEX;
|
||
@@ -3083,7 +3067,7 @@ mt753x_setup(struct dsa_switch *ds)
|
||
mt7530_free_irq_common(priv);
|
||
|
||
if (priv->create_sgmii) {
|
||
- ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
|
||
+ ret = priv->create_sgmii(priv);
|
||
if (ret && priv->irq)
|
||
mt7530_free_irq(priv);
|
||
}
|
||
--- a/drivers/net/dsa/mt7530.h
|
||
+++ b/drivers/net/dsa/mt7530.h
|
||
@@ -707,7 +707,6 @@ enum p5_interface_select {
|
||
P5_INTF_SEL_PHY_P0,
|
||
P5_INTF_SEL_PHY_P4,
|
||
P5_INTF_SEL_GMAC5,
|
||
- P5_INTF_SEL_GMAC5_SGMII,
|
||
};
|
||
|
||
struct mt7530_priv;
|
||
@@ -769,6 +768,8 @@ struct mt753x_info {
|
||
* registers
|
||
* @p6_interface Holding the current port 6 interface
|
||
* @p5_intf_sel: Holding the current port 5 interface select
|
||
+ * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
|
||
+ * has got SGMII
|
||
* @irq: IRQ number of the switch
|
||
* @irq_domain: IRQ domain of the switch irq_chip
|
||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||
@@ -790,6 +791,7 @@ struct mt7530_priv {
|
||
phy_interface_t p6_interface;
|
||
phy_interface_t p5_interface;
|
||
enum p5_interface_select p5_intf_sel;
|
||
+ bool p5_sgmii;
|
||
u8 mirror_rx;
|
||
u8 mirror_tx;
|
||
struct mt7530_port ports[MT7530_NUM_PORTS];
|
||
@@ -799,7 +801,7 @@ struct mt7530_priv {
|
||
int irq;
|
||
struct irq_domain *irq_domain;
|
||
u32 irq_enable;
|
||
- int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
|
||
+ int (*create_sgmii)(struct mt7530_priv *priv);
|
||
u8 active_cpu_ports;
|
||
};
|
||
|