realtek: remove DSA internal PCS functions
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run

Now that there is a dedicated PCS driver remove the old functions
from the DSA driver and make use of the new ones.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/20129
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Markus Stockhausen 2025-09-22 11:04:05 -04:00 committed by Hauke Mehrtens
parent 6b681fd285
commit 347d546386
8 changed files with 22 additions and 253 deletions

View file

@ -26,8 +26,7 @@ extern const struct rtl838x_reg rtl931x_reg;
extern const struct dsa_switch_ops rtl83xx_switch_ops;
extern const struct dsa_switch_ops rtl930x_switch_ops;
extern const struct phylink_pcs_ops rtl83xx_pcs_ops;
extern const struct phylink_pcs_ops rtl93xx_pcs_ops;
extern struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port);
int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port)
{
@ -268,7 +267,7 @@ static int rtldsa_bus_c45_write(struct mii_bus *bus, int addr, int devad, int re
static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
{
struct device_node *dn, *phy_node, *led_node, *np, *mii_np;
struct device_node *dn, *phy_node, *pcs_node, *led_node, *np, *mii_np;
struct device *dev = priv->dev;
struct mii_bus *bus;
int ret;
@ -342,10 +341,21 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
continue;
}
/*
* TODO: phylink_pcs was completely converted to the standalone PCS driver - see
* rtpcs_create() below. Nevertheless we still make use of the old SerDes <sds>
* attribute of the phy node for the scatterd SerDes configuration functions. As
* soon as the PCS driver can completely configure the SerDes this is no longer
* needed.
*/
if (of_property_read_u32(phy_node, "sds", &priv->ports[pn].sds_num))
priv->ports[pn].sds_num = -1;
pr_debug("%s port %d has SDS %d\n", __func__, pn, priv->ports[pn].sds_num);
pcs_node = of_parse_phandle(dn, "pcs-handle", 0);
priv->pcs[pn] = rtpcs_create(priv->dev, pcs_node, pn);
if (of_get_phy_mode(dn, &interface))
interface = PHY_INTERFACE_MODE_NA;
if (interface == PHY_INTERFACE_MODE_USXGMII)
@ -1501,10 +1511,10 @@ static int rtldsa_ethernet_loaded(struct platform_device *pdev)
static int __init rtl83xx_sw_probe(struct platform_device *pdev)
{
int i, err = 0;
struct rtl838x_switch_priv *priv;
struct device *dev = &pdev->dev;
u64 bpdu_mask;
int err = 0;
pr_debug("Probing RTL838X switch device\n");
if (!pdev->dev.of_node) {
@ -1616,22 +1626,6 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
}
pr_debug("Chip version %c\n", priv->version);
for (i = 0; i <= priv->cpu_port; i++) {
switch (soc_info.family) {
case RTL8380_FAMILY_ID:
case RTL8390_FAMILY_ID:
priv->pcs[i].pcs.ops = &rtl83xx_pcs_ops;
break;
case RTL9300_FAMILY_ID:
case RTL9310_FAMILY_ID:
priv->pcs[i].pcs.ops = &rtl93xx_pcs_ops;
break;
}
priv->pcs[i].pcs.neg_mode = true;
priv->pcs[i].priv = priv;
priv->pcs[i].port = i;
}
err = rtl83xx_mdio_probe(priv);
if (err) {
/* Probing fails the 1st time because of missing ethernet driver

View file

@ -567,158 +567,13 @@ static int rtl93xx_get_sds(struct phy_device *phydev)
return sds_num;
}
static void rtldsa_83xx_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state)
{
struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
struct rtl838x_switch_priv *priv = rtpcs->priv;
int port = rtpcs->port;
u64 speed;
state->link = 0;
state->speed = SPEED_UNKNOWN;
state->duplex = DUPLEX_UNKNOWN;
state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
if (port < 0 || port > priv->cpu_port)
return;
if (!(priv->r->get_port_reg_le(priv->r->mac_link_sts) & BIT_ULL(port)))
return;
state->link = 1;
if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
state->duplex = DUPLEX_FULL;
else
state->duplex = DUPLEX_HALF;
speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
speed = (speed >> ((port % 16) << 1)) & 0x3;
switch (speed) {
case RTL_SPEED_10:
state->speed = SPEED_10;
break;
case RTL_SPEED_100:
state->speed = SPEED_100;
break;
case RTL_SPEED_1000:
state->speed = SPEED_1000;
break;
case 3:
/*
* This is ok so far but with minor inconsistencies. On RTL838x this setting is
* for either 500M or 2G. It might be that MAC_GLITE_STS register tells more. On
* RTL839x these vendor specifics are derived from MAC_LINK_500M_STS and mode 3
* is 10G. This is of interest so resolve to it. Sadly it is off by one for the
* current RTL_SPEED_10000 (=4) definition for RTL93xx.
*/
state->speed = SPEED_10000;
break;
}
if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
state->pause |= MLO_PAUSE_RX;
if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
state->pause |= MLO_PAUSE_TX;
}
static void rtldsa_93xx_pcs_get_state(struct phylink_pcs *pcs,
struct phylink_link_state *state)
{
struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
struct rtl838x_switch_priv *priv = rtpcs->priv;
int port = rtpcs->port;
u64 speed;
u64 link;
u64 media;
state->link = 0;
state->speed = SPEED_UNKNOWN;
state->duplex = DUPLEX_UNKNOWN;
state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
if (port < 0 || port > priv->cpu_port)
return;
/* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link
* state needs to be read twice in order to read a correct result.
* This would not be necessary for ports connected e.g. to RTL8218D
* PHYs.
*/
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
if (!(link & BIT_ULL(port)))
return;
state->link = 1;
if (priv->family_id == RTL9310_FAMILY_ID)
media = priv->r->get_port_reg_le(RTL931X_MAC_LINK_MEDIA_STS);
if (priv->family_id == RTL9300_FAMILY_ID)
media = sw_r32(RTL930X_MAC_LINK_MEDIA_STS);
pr_debug("%s: link state port %d: %llx, media %llx\n", __func__, port,
link & BIT_ULL(port), media);
if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
state->duplex = DUPLEX_FULL;
else
state->duplex = DUPLEX_HALF;
speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
speed = (speed >> ((port % 8) << 2)) & 0xf;
switch (speed) {
case RTL_SPEED_10:
state->speed = SPEED_10;
break;
case RTL_SPEED_100:
state->speed = SPEED_100;
break;
case RTL_SPEED_1000:
state->speed = SPEED_1000;
break;
case RTL_SPEED_10000:
state->speed = SPEED_10000;
break;
case RTL_SPEED_2500:
state->speed = SPEED_2500;
break;
case RTL_SPEED_5000:
state->speed = SPEED_5000;
break;
default:
pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf);
}
pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed);
if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
state->pause |= MLO_PAUSE_RX;
if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
state->pause |= MLO_PAUSE_TX;
}
static int rtl83xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
phy_interface_t interface,
const unsigned long *advertising,
bool permit_pause_to_mac)
{
return 0;
}
static void rtl83xx_pcs_an_restart(struct phylink_pcs *pcs)
{
/* No restart functionality existed before we migrated to pcs */
}
static struct phylink_pcs *rtl83xx_phylink_mac_select_pcs(struct dsa_switch *ds,
int port,
phy_interface_t interface)
static struct phylink_pcs *rtldsa_phylink_mac_select_pcs(struct dsa_switch *ds,
int port,
phy_interface_t interface)
{
struct rtl838x_switch_priv *priv = ds->priv;
return &priv->pcs[port].pcs;
return priv->pcs[port];
}
static void rtl83xx_config_interface(int port, phy_interface_t interface)
@ -2678,12 +2533,6 @@ static int rtldsa_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val
return mdiobus_write_nested(priv->parent_bus, addr, regnum, val);
}
const struct phylink_pcs_ops rtl83xx_pcs_ops = {
.pcs_an_restart = rtl83xx_pcs_an_restart,
.pcs_get_state = rtldsa_83xx_pcs_get_state,
.pcs_config = rtl83xx_pcs_config,
};
const struct dsa_switch_ops rtl83xx_switch_ops = {
.get_tag_protocol = rtl83xx_get_tag_protocol,
.setup = rtl83xx_setup,
@ -2695,7 +2544,7 @@ const struct dsa_switch_ops rtl83xx_switch_ops = {
.phylink_mac_config = rtl83xx_phylink_mac_config,
.phylink_mac_link_down = rtl83xx_phylink_mac_link_down,
.phylink_mac_link_up = rtl83xx_phylink_mac_link_up,
.phylink_mac_select_pcs = rtl83xx_phylink_mac_select_pcs,
.phylink_mac_select_pcs = rtldsa_phylink_mac_select_pcs,
.get_strings = rtldsa_get_strings,
.get_ethtool_stats = rtldsa_get_ethtool_stats,
@ -2741,12 +2590,6 @@ const struct dsa_switch_ops rtl83xx_switch_ops = {
.port_bridge_flags = rtl83xx_port_bridge_flags,
};
const struct phylink_pcs_ops rtl93xx_pcs_ops = {
.pcs_an_restart = rtl83xx_pcs_an_restart,
.pcs_get_state = rtldsa_93xx_pcs_get_state,
.pcs_config = rtl83xx_pcs_config,
};
const struct dsa_switch_ops rtl930x_switch_ops = {
.get_tag_protocol = rtl83xx_get_tag_protocol,
.setup = rtl93xx_setup,
@ -2758,7 +2601,7 @@ const struct dsa_switch_ops rtl930x_switch_ops = {
.phylink_mac_config = rtl93xx_phylink_mac_config,
.phylink_mac_link_down = rtl93xx_phylink_mac_link_down,
.phylink_mac_link_up = rtl93xx_phylink_mac_link_up,
.phylink_mac_select_pcs = rtl83xx_phylink_mac_select_pcs,
.phylink_mac_select_pcs = rtldsa_phylink_mac_select_pcs,
.get_strings = rtldsa_get_strings,
.get_ethtool_stats = rtldsa_get_ethtool_stats,

View file

@ -261,11 +261,6 @@ static inline int rtl838x_l2_port_new_sa_fwd(int p)
return RTL838X_L2_PORT_NEW_SA_FWD(p);
}
static inline int rtl838x_mac_link_spd_sts(int p)
{
return RTL838X_MAC_LINK_SPD_STS(p);
}
inline static int rtl838x_trk_mbr_ctr(int group)
{
return RTL838X_TRK_MBR_CTR + (group << 2);
@ -1706,11 +1701,6 @@ const struct rtl838x_reg rtl838x_reg = {
.mir_ctrl = RTL838X_MIR_CTRL,
.mir_dpm = RTL838X_MIR_DPM_CTRL,
.mir_spm = RTL838X_MIR_SPM_CTRL,
.mac_link_sts = RTL838X_MAC_LINK_STS,
.mac_link_dup_sts = RTL838X_MAC_LINK_DUP_STS,
.mac_link_spd_sts = rtl838x_mac_link_spd_sts,
.mac_rx_pause_sts = RTL838X_MAC_RX_PAUSE_STS,
.mac_tx_pause_sts = RTL838X_MAC_TX_PAUSE_STS,
.read_l2_entry_using_hash = rtl838x_read_l2_entry_using_hash,
.write_l2_entry_using_hash = rtl838x_write_l2_entry_using_hash,
.read_cam = rtl838x_read_cam,

View file

@ -123,24 +123,6 @@
#define RTL839X_MAC_LINK_STS (0x0390)
#define RTL930X_MAC_LINK_STS (0xCB10)
#define RTL931X_MAC_LINK_STS (0x0EC0)
#define RTL838X_MAC_LINK_SPD_STS(p) (0xa190 + (((p >> 4) << 2)))
#define RTL839X_MAC_LINK_SPD_STS(p) (0x03a0 + (((p >> 4) << 2)))
#define RTL930X_MAC_LINK_SPD_STS(p) (0xCB18 + (((p >> 3) << 2)))
#define RTL931X_MAC_LINK_SPD_STS (0x0ED0)
#define RTL838X_MAC_LINK_DUP_STS (0xa19c)
#define RTL839X_MAC_LINK_DUP_STS (0x03b0)
#define RTL930X_MAC_LINK_DUP_STS (0xCB28)
#define RTL931X_MAC_LINK_DUP_STS (0x0EF0)
#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0)
#define RTL839X_MAC_TX_PAUSE_STS (0x03b8)
#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C)
#define RTL931X_MAC_TX_PAUSE_STS (0x0EF8)
#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4)
#define RTL839X_MAC_RX_PAUSE_STS (0x03c0)
#define RTL930X_MAC_RX_PAUSE_STS (0xCB30)
#define RTL931X_MAC_RX_PAUSE_STS (0x0F00)
#define RTL930X_MAC_LINK_MEDIA_STS (0xCB14)
#define RTL931X_MAC_LINK_MEDIA_STS (0x0EC8)
/* MAC link state bits */
#define RTL_SPEED_10 0
@ -702,12 +684,6 @@ struct rtl838x_port {
const struct dsa_port *dp;
};
struct rtl838x_pcs {
struct phylink_pcs pcs;
struct rtl838x_switch_priv *priv;
int port;
};
struct rtl838x_vlan_info {
u64 untagged_ports;
u64 member_ports;
@ -1073,11 +1049,6 @@ struct rtl838x_reg {
int mir_ctrl;
int mir_dpm;
int mir_spm;
int mac_link_sts;
int mac_link_dup_sts;
int (*mac_link_spd_sts)(int port);
int mac_rx_pause_sts;
int mac_tx_pause_sts;
u64 (*read_l2_entry_using_hash)(u32 hash, u32 position, struct rtl838x_l2_entry *e);
void (*write_l2_entry_using_hash)(u32 hash, u32 pos, struct rtl838x_l2_entry *e);
u64 (*read_cam)(int idx, struct rtl838x_l2_entry *e);
@ -1126,7 +1097,7 @@ struct rtl838x_switch_priv {
u16 family_id;
char version;
struct rtl838x_port ports[57];
struct rtl838x_pcs pcs[57];
struct phylink_pcs *pcs[57];
struct mutex reg_mutex; /* Mutex for individual register manipulations */
struct mutex pie_mutex; /* Mutex for Packet Inspection Engine */
int link_state_irq;

View file

@ -293,11 +293,6 @@ static inline int rtl839x_l2_port_new_sa_fwd(int p)
return RTL839X_L2_PORT_NEW_SA_FWD(p);
}
static inline int rtl839x_mac_link_spd_sts(int p)
{
return RTL839X_MAC_LINK_SPD_STS(p);
}
static inline int rtl839x_trk_mbr_ctr(int group)
{
return RTL839X_TRK_MBR_CTR + (group << 3);
@ -1686,11 +1681,6 @@ const struct rtl838x_reg rtl839x_reg = {
.mir_ctrl = RTL839X_MIR_CTRL,
.mir_dpm = RTL839X_MIR_DPM_CTRL,
.mir_spm = RTL839X_MIR_SPM_CTRL,
.mac_link_sts = RTL839X_MAC_LINK_STS,
.mac_link_dup_sts = RTL839X_MAC_LINK_DUP_STS,
.mac_link_spd_sts = rtl839x_mac_link_spd_sts,
.mac_rx_pause_sts = RTL839X_MAC_RX_PAUSE_STS,
.mac_tx_pause_sts = RTL839X_MAC_TX_PAUSE_STS,
.read_l2_entry_using_hash = rtl839x_read_l2_entry_using_hash,
.write_l2_entry_using_hash = rtl839x_write_l2_entry_using_hash,
.read_cam = rtl839x_read_cam,

View file

@ -350,11 +350,6 @@ static inline int rtl930x_mac_port_ctrl(int p)
return RTL930X_MAC_L2_PORT_CTRL(p);
}
static inline int rtl930x_mac_link_spd_sts(int p)
{
return RTL930X_MAC_LINK_SPD_STS(p);
}
static u64 rtl930x_l2_hash_seed(u64 mac, u32 vid)
{
u64 v = vid;
@ -2454,11 +2449,6 @@ const struct rtl838x_reg rtl930x_reg = {
.mir_ctrl = RTL930X_MIR_CTRL,
.mir_dpm = RTL930X_MIR_DPM_CTRL,
.mir_spm = RTL930X_MIR_SPM_CTRL,
.mac_link_sts = RTL930X_MAC_LINK_STS,
.mac_link_dup_sts = RTL930X_MAC_LINK_DUP_STS,
.mac_link_spd_sts = rtl930x_mac_link_spd_sts,
.mac_rx_pause_sts = RTL930X_MAC_RX_PAUSE_STS,
.mac_tx_pause_sts = RTL930X_MAC_TX_PAUSE_STS,
.read_l2_entry_using_hash = rtl930x_read_l2_entry_using_hash,
.write_l2_entry_using_hash = rtl930x_write_l2_entry_using_hash,
.read_cam = rtl930x_read_cam,

View file

@ -265,11 +265,6 @@ static inline int rtl931x_mac_force_mode_ctrl(int p)
return RTL931X_MAC_FORCE_MODE_CTRL + (p << 2);
}
static inline int rtl931x_mac_link_spd_sts(int p)
{
return RTL931X_MAC_LINK_SPD_STS + (((p >> 3) << 2));
}
static inline int rtl931x_mac_port_ctrl(int p)
{
return RTL931X_MAC_L2_PORT_CTRL + (p << 7);
@ -1557,11 +1552,6 @@ const struct rtl838x_reg rtl931x_reg = {
.mir_ctrl = RTL931X_MIR_CTRL,
.mir_dpm = RTL931X_MIR_DPM_CTRL,
.mir_spm = RTL931X_MIR_SPM_CTRL,
.mac_link_sts = RTL931X_MAC_LINK_STS,
.mac_link_dup_sts = RTL931X_MAC_LINK_DUP_STS,
.mac_link_spd_sts = rtl931x_mac_link_spd_sts,
.mac_rx_pause_sts = RTL931X_MAC_RX_PAUSE_STS,
.mac_tx_pause_sts = RTL931X_MAC_TX_PAUSE_STS,
.read_l2_entry_using_hash = rtl931x_read_l2_entry_using_hash,
.write_l2_entry_using_hash = rtl931x_write_l2_entry_using_hash,
.read_cam = rtl931x_read_cam,

View file

@ -272,6 +272,7 @@ struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int
link->port = port;
link->sds = sds;
link->pcs.ops = ctrl->cfg->pcs_ops;
link->pcs.neg_mode = true;
ctrl->link[port] = link;