Files
openwrt/target/linux/realtek/patches-6.6/700-dsa-mdio-increase-max-ports-for-rtl839x-rtl931x.patch
Markus Stockhausen 9716f89df6 realtek: enhance & harmonize dsa/phy max port patches
DSA silently drops internal phy access to ports >= 32 in dsa_user_phy_read()
and dsa_user_phy_write(). The code shows:

static int dsa_user_phy_read(struct mii_bus *bus, int addr, int reg)
{
	struct dsa_switch *ds = bus->priv;

	if (ds->phys_mii_mask & (1 << addr))
		return ds->ops->phy_read(ds, addr, reg);

	return 0xffff;
}

With ds->phys_mii_mask being a 32 bit variable the reason is clear. So do
not only increase the max values but also adapt the needed bitmasks in
the dsa and phy code. This fixes the dsa_user_ports() and dsa_cpu_ports()
too.

While we are here combine the old separated patches because dsa, mdio and
phy are tigthly coupled.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18846
Signed-off-by: Robert Marko <robimarko@gmail.com>
2025-05-31 12:28:14 +02:00

133 lines
3.9 KiB
Diff

From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 26 Nov 2020 12:02:21 +0100
Subject: realtek dsa/phy: Increase max ports for RTL839X/RTL931X
Linux standard can only support up to 32 devices per mdio bus and up to
12 ports per DSA switch. This is not enough for the large RTL839X and
RTL931X devices. Increase the max values accordingly. Additionally take
care about the functions that work on bit masks.
Submitted-by: Bert Vermeulen <bert@biot.com>
Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
Submitted-by: Sander Vanheule <sander@svanheule.net>
Submitted-by: Bjørn Mork <bjorn@mork.no>
Submitted-by: John Crispin <john@phrozen.org>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/fwnode_mdio.c | 2 +-
include/linux/phy.h | 6 +++---
include/linux/platform_data/dsa.h | 2 +-
include/net/dsa.h | 14 +++++++-------
net/dsa/slave.c | 4 ++--
5 files changed, 14 insertions(+), 14 deletions(-)
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -87,7 +87,7 @@ int fwnode_mdiobus_phy_device_register(s
}
if (fwnode_property_read_bool(child, "broken-turn-around"))
- mdio->phy_ignore_ta_mask |= 1 << addr;
+ mdio->phy_ignore_ta_mask |= BIT_ULL(addr);
fwnode_property_read_u32(child, "reset-assert-us",
&phy->mdio.reset_assert_delay);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -294,7 +294,7 @@ static inline const char *phy_modes(phy_
#define PHY_INIT_TIMEOUT 100000
#define PHY_FORCE_TIMEOUT 10
-#define PHY_MAX_ADDR 32
+#define PHY_MAX_ADDR 64
/* Used when trying to connect to a specific phy (mii bus id:phy device id) */
#define PHY_ID_FMT "%s:%02x"
@@ -414,10 +414,10 @@ struct mii_bus {
struct mdio_device *mdio_map[PHY_MAX_ADDR];
/** @phy_mask: PHY addresses to be ignored when probing */
- u32 phy_mask;
+ u64 phy_mask;
/** @phy_ignore_ta_mask: PHY addresses to ignore the TA/read failure */
- u32 phy_ignore_ta_mask;
+ u64 phy_ignore_ta_mask;
/**
* @irq: An array of interrupts, each PHY's interrupt at the index
--- a/include/linux/platform_data/dsa.h
+++ b/include/linux/platform_data/dsa.h
@@ -6,7 +6,7 @@ struct device;
struct net_device;
#define DSA_MAX_SWITCHES 4
-#define DSA_MAX_PORTS 12
+#define DSA_MAX_PORTS 54
#define DSA_RTABLE_NONE -1
struct dsa_chip_data {
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -465,7 +465,7 @@ struct dsa_switch {
/*
* Slave mii_bus and devices for the individual ports.
*/
- u32 phys_mii_mask;
+ u64 phys_mii_mask;
struct mii_bus *slave_mii_bus;
/* Ageing Time limits in msecs */
@@ -597,24 +597,24 @@ static inline bool dsa_is_user_port(stru
dsa_switch_for_each_port_continue_reverse((_dp), (_ds)) \
if (dsa_port_is_cpu((_dp)))
-static inline u32 dsa_user_ports(struct dsa_switch *ds)
+static inline u64 dsa_user_ports(struct dsa_switch *ds)
{
struct dsa_port *dp;
- u32 mask = 0;
+ u64 mask = 0;
dsa_switch_for_each_user_port(dp, ds)
- mask |= BIT(dp->index);
+ mask |= BIT_ULL(dp->index);
return mask;
}
-static inline u32 dsa_cpu_ports(struct dsa_switch *ds)
+static inline u64 dsa_cpu_ports(struct dsa_switch *ds)
{
struct dsa_port *cpu_dp;
- u32 mask = 0;
+ u64 mask = 0;
dsa_switch_for_each_cpu_port(cpu_dp, ds)
- mask |= BIT(cpu_dp->index);
+ mask |= BIT_ULL(cpu_dp->index);
return mask;
}
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -320,7 +320,7 @@ static int dsa_slave_phy_read(struct mii
{
struct dsa_switch *ds = bus->priv;
- if (ds->phys_mii_mask & (1 << addr))
+ if (ds->phys_mii_mask & BIT_ULL(addr))
return ds->ops->phy_read(ds, addr, reg);
return 0xffff;
@@ -330,7 +330,7 @@ static int dsa_slave_phy_write(struct mi
{
struct dsa_switch *ds = bus->priv;
- if (ds->phys_mii_mask & (1 << addr))
+ if (ds->phys_mii_mask & BIT_ULL(addr))
return ds->ops->phy_write(ds, addr, reg, val);
return 0;