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
@@ -90,7 +90,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
@@ -316,7 +316,7 @@ static inline long rgmii_clock(int speed
 	}
 }
 
-#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"
@@ -402,10 +402,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
@@ -480,7 +480,7 @@ struct dsa_switch {
 	/*
 	 * User mii_bus and devices for the individual ports.
 	 */
-	u32			phys_mii_mask;
+	u64			phys_mii_mask;
 	struct mii_bus		*user_mii_bus;
 
 	/* Ageing Time limits in msecs */
@@ -616,24 +616,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/user.c
+++ b/net/dsa/user.c
@@ -320,7 +320,7 @@ static int dsa_user_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_user_phy_write(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_write(ds, addr, reg, val);
 
 	return 0;
--- a/drivers/net/phy/mdio_bus_provider.c
+++ b/drivers/net/phy/mdio_bus_provider.c
@@ -209,7 +209,7 @@ static int mdiobus_scan_bus_c22(struct m
 	int i;
 
 	for (i = 0; i < PHY_MAX_ADDR; i++) {
-		if ((bus->phy_mask & BIT(i)) == 0) {
+		if ((bus->phy_mask & BIT_ULL(i)) == 0) {
 			struct phy_device *phydev;
 
 			phydev = mdiobus_scan_c22(bus, i);
@@ -225,7 +225,7 @@ static int mdiobus_scan_bus_c45(struct m
 	int i;
 
 	for (i = 0; i < PHY_MAX_ADDR; i++) {
-		if ((bus->phy_mask & BIT(i)) == 0) {
+		if ((bus->phy_mask & BIT_ULL(i)) == 0) {
 			struct phy_device *phydev;
 
 			/* Don't scan C45 if we already have a C22 device */
