Skip to content

Commit 53dfb3e

Browse files
plappermaulhauke
authored andcommitted
realtek: phy: reorganize package handling
With kernel 6.18 the package shared structure will be hidden from the phy drivers. Workaround that in advance by providing a shared private structure that covers all information that is needed for normal operation. For further simplification provide a new join() function that takes care of a consistent initialization. Signed-off-by: Markus Stockhausen <[email protected]> Link: openwrt/openwrt#21204 Signed-off-by: Hauke Mehrtens <[email protected]>
1 parent f79a2a5 commit 53dfb3e

File tree

1 file changed

+45
-20
lines changed

1 file changed

+45
-20
lines changed

target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,51 @@ extern struct rtl83xx_soc_info soc_info;
5353
#define RTL821X_MEDIA_PAGE_FIBRE 3
5454
#define RTL821X_MEDIA_PAGE_INTERNAL 8
5555

56+
#define RTL821X_JOIN_FIRST 0
57+
#define RTL821X_JOIN_LAST 1
58+
#define RTL821X_JOIN_OTHER 2
59+
5660
static const struct firmware rtl838x_8380_fw;
5761
static const struct firmware rtl838x_8214fc_fw;
5862
static const struct firmware rtl838x_8218b_fw;
5963

64+
struct rtl821x_shared_priv {
65+
int base_addr;
66+
int ports;
67+
};
68+
69+
/* TODO: for kernel 6.18 drop this function and use it from phy_package library instead */
70+
static void *phy_package_get_priv(struct phy_device *phydev)
71+
{
72+
return phydev->shared->priv;
73+
}
74+
75+
static int rtl821x_package_join(struct phy_device *phydev, int ports)
76+
{
77+
struct rtl821x_shared_priv *shared_priv;
78+
int base_addr = phydev->mdio.addr & ~(ports - 1);
79+
80+
devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr,
81+
sizeof(struct rtl821x_shared_priv));
82+
83+
shared_priv = phy_package_get_priv(phydev);
84+
shared_priv->base_addr = base_addr;
85+
shared_priv->ports++;
86+
87+
if (shared_priv->ports == 1)
88+
return RTL821X_JOIN_FIRST;
89+
90+
if (shared_priv->ports == ports)
91+
return RTL821X_JOIN_LAST;
92+
93+
return RTL821X_JOIN_OTHER;
94+
}
95+
6096
static inline struct phy_device *get_package_phy(struct phy_device *phydev, int port)
6197
{
62-
return mdiobus_get_phy(phydev->mdio.bus, phydev->shared->base_addr + port);
98+
struct rtl821x_shared_priv *shared_priv = phy_package_get_priv(phydev);
99+
100+
return mdiobus_get_phy(phydev->mdio.bus, shared_priv->base_addr + port);
63101
}
64102

65103
static inline struct phy_device *get_base_phy(struct phy_device *phydev)
@@ -839,11 +877,9 @@ static const struct sfp_upstream_ops rtl8214fc_sfp_ops = {
839877

840878
static int rtl8214fc_phy_probe(struct phy_device *phydev)
841879
{
842-
int base_addr = phydev->mdio.addr & ~3;
843880
int ret = 0;
844881

845-
devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
846-
if (phydev->mdio.addr == base_addr + 3) {
882+
if (rtl821x_package_join(phydev, 4) == RTL821X_JOIN_LAST) {
847883
if (soc_info.family == RTL8380_FAMILY_ID)
848884
ret = rtl8380_configure_rtl8214fc(get_base_phy(phydev));
849885
if (ret)
@@ -855,21 +891,15 @@ static int rtl8214fc_phy_probe(struct phy_device *phydev)
855891

856892
static int rtl8214c_phy_probe(struct phy_device *phydev)
857893
{
858-
int base_addr = phydev->mdio.addr & ~3;
859-
860-
devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
861-
if (phydev->mdio.addr == base_addr + 3)
894+
if (rtl821x_package_join(phydev, 4) == RTL821X_JOIN_LAST)
862895
return rtl8380_configure_rtl8214c(get_base_phy(phydev));
863896

864897
return 0;
865898
}
866899

867900
static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
868901
{
869-
int base_addr = phydev->mdio.addr & ~7;
870-
871-
devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
872-
if (phydev->mdio.addr == base_addr + 7) {
902+
if (rtl821x_package_join(phydev, 8) == RTL821X_JOIN_LAST) {
873903
if (soc_info.family == RTL8380_FAMILY_ID)
874904
return rtl8380_configure_ext_rtl8218b(get_base_phy(phydev));
875905
}
@@ -879,25 +909,20 @@ static int rtl8218b_ext_phy_probe(struct phy_device *phydev)
879909

880910
static int rtl8218b_int_phy_probe(struct phy_device *phydev)
881911
{
882-
int base_addr = phydev->mdio.addr & ~7;
883-
884912
if (soc_info.family != RTL8380_FAMILY_ID)
885913
return -ENODEV;
886-
if (base_addr >= 24)
914+
if (phydev->mdio.addr >= 24)
887915
return -ENODEV;
888916

889-
devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
890-
if (phydev->mdio.addr == base_addr + 7)
917+
if (rtl821x_package_join(phydev, 8) == RTL821X_JOIN_LAST)
891918
return rtl8380_configure_int_rtl8218b(get_base_phy(phydev));
892919

893920
return 0;
894921
}
895922

896923
static int rtl8218x_phy_probe(struct phy_device *phydev)
897924
{
898-
int base_addr = phydev->mdio.addr & ~7;
899-
900-
devm_phy_package_join(&phydev->mdio.dev, phydev, base_addr, 0);
925+
rtl821x_package_join(phydev, 8);
901926

902927
return 0;
903928
}

0 commit comments

Comments
 (0)