mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2026-03-07 12:59:30 -05:00
realtek: dsa: rtl931x: configure phy ability source
The MAC can get PHY abilities, link status, etc. via different ways. In RTL931x, the corresponding register needs to be setup properly. By default, all ports use out-of-band MDIO polling to retrieve that information. Thus, PHY-backed ports usually work with the default setting. For SFP ports, there is no MDIO polling available. Instead, the SerDes ability bus needs to be used to retrieve the link information. So far, the bootloader (e.g. U-boot) had to properly initialize that setting. Instead of relying on that, do that properly during MAC setup. Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com> Link: https://github.com/openwrt/openwrt/pull/21351 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
committed by
Hauke Mehrtens
parent
e782341848
commit
e581929341
@@ -614,6 +614,10 @@ static int rtl93xx_setup(struct dsa_switch *ds)
|
||||
}
|
||||
priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port));
|
||||
|
||||
/* Configure how MAC gets PHY ability for each port */
|
||||
if (priv->family_id == RTL9310_FAMILY_ID)
|
||||
rtldsa_931x_config_phy_ability_source(priv);
|
||||
|
||||
if (priv->family_id == RTL9300_FAMILY_ID)
|
||||
rtl930x_print_matrix();
|
||||
else if (priv->family_id == RTL9310_FAMILY_ID)
|
||||
|
||||
@@ -182,6 +182,7 @@ void rtl930x_print_matrix(void);
|
||||
/* RTL931x-specific */
|
||||
irqreturn_t rtl931x_switch_irq(int irq, void *dev_id);
|
||||
void rtl931x_print_matrix(void);
|
||||
void rtldsa_931x_config_phy_ability_source(struct rtl838x_switch_priv *priv);
|
||||
|
||||
int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info);
|
||||
int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port);
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
#define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2, 1)
|
||||
#define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0, 0)
|
||||
|
||||
#define RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL 0x0cac
|
||||
#define RTLDSA_931X_PHY_ABLTY_OUTBAND_MDIO 0x0
|
||||
#define RTLDSA_931X_PHY_ABLTY_INBAND_SDS_POLL 0x1
|
||||
#define RTLDSA_931X_PHY_ABLTY_SDS_ABLTY_BUS 0x2
|
||||
|
||||
/* Definition of the RTL931X-specific template field IDs as used in the PIE */
|
||||
enum template_field_id {
|
||||
TEMPLATE_FIELD_SPM0 = 1,
|
||||
@@ -1764,6 +1769,30 @@ static void rtldsa_931x_qos_init(struct rtl838x_switch_priv *priv)
|
||||
rtldsa_931x_qos_set_scheduling_queue_weights(priv);
|
||||
}
|
||||
|
||||
void rtldsa_931x_config_phy_ability_source(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
u32 phy_ablty_sel[4] = {0};
|
||||
|
||||
for (int port = 0; port < priv->cpu_port; port++) {
|
||||
u32 val = RTLDSA_931X_PHY_ABLTY_OUTBAND_MDIO;
|
||||
|
||||
/* port driven by SerDes */
|
||||
if (!priv->ports[port].phy && priv->pcs[port])
|
||||
val = RTLDSA_931X_PHY_ABLTY_SDS_ABLTY_BUS;
|
||||
|
||||
phy_ablty_sel[port / 16] |= (val & 0x3) << ((port % 16) * 2);
|
||||
}
|
||||
|
||||
pr_debug("%s: phy_ablty_sel [0] %x [1] %x [2] %x [3] %x\n", __func__,
|
||||
phy_ablty_sel[0], phy_ablty_sel[1], phy_ablty_sel[2],
|
||||
phy_ablty_sel[3]);
|
||||
|
||||
sw_w32(phy_ablty_sel[0], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL);
|
||||
sw_w32(phy_ablty_sel[1], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL + 0x4);
|
||||
sw_w32(phy_ablty_sel[2], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL + 0x8);
|
||||
sw_w32(phy_ablty_sel[3], RTLDSA_931X_SMI_PHY_ABLTY_GET_SEL + 0xc);
|
||||
}
|
||||
|
||||
const struct rtl838x_reg rtl931x_reg = {
|
||||
.mask_port_reg_be = rtl839x_mask_port_reg_be,
|
||||
.set_port_reg_be = rtl839x_set_port_reg_be,
|
||||
|
||||
Reference in New Issue
Block a user