Skip to content

Commit bb7bbb6

Browse files
elkablodavem330
authored andcommitted
net: marvell: mvpp2: Fix wrong SerDes reconfiguration order
Commit bfe301e ("net: mvpp2: convert to use mac_prepare()/mac_finish()") introduced a bug wherein it leaves the MAC RESET register asserted after mac_finish(), due to wrong order of function calls. Before it was: .mac_config() mvpp22_mode_reconfigure() assert reset mvpp2_xlg_config() deassert reset Now it is: .mac_prepare() .mac_config() mvpp2_xlg_config() deassert reset .mac_finish() mvpp2_xlg_config() assert reset Obviously this is wrong. This bug is triggered when phylink tries to change the PHY interface mode from a GMAC mode (sgmii, 1000base-x, 2500base-x) to XLG mode (10gbase-r, xaui). The XLG mode does not work since reset is left asserted. Only after ifconfig down && ifconfig up is called will the XLG mode work. Move the call to mvpp22_mode_reconfigure() to .mac_prepare() implementation. Since some of the subsequent functions need to know whether the interface is being changed, we unfortunately also need to pass around the new interface mode before setting port->phy_interface. Fixes: bfe301e ("net: mvpp2: convert to use mac_prepare()/mac_finish()") Signed-off-by: Marek Behún <[email protected]> Signed-off-by: Russell King (Oracle) <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7a16685 commit bb7bbb6

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,15 +1605,15 @@ static void mvpp22_gop_fca_set_periodic_timer(struct mvpp2_port *port)
16051605
mvpp22_gop_fca_enable_periodic(port, true);
16061606
}
16071607

1608-
static int mvpp22_gop_init(struct mvpp2_port *port)
1608+
static int mvpp22_gop_init(struct mvpp2_port *port, phy_interface_t interface)
16091609
{
16101610
struct mvpp2 *priv = port->priv;
16111611
u32 val;
16121612

16131613
if (!priv->sysctrl_base)
16141614
return 0;
16151615

1616-
switch (port->phy_interface) {
1616+
switch (interface) {
16171617
case PHY_INTERFACE_MODE_RGMII:
16181618
case PHY_INTERFACE_MODE_RGMII_ID:
16191619
case PHY_INTERFACE_MODE_RGMII_RXID:
@@ -1743,15 +1743,15 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
17431743
* lanes by the physical layer. This is why configurations like
17441744
* "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid.
17451745
*/
1746-
static int mvpp22_comphy_init(struct mvpp2_port *port)
1746+
static int mvpp22_comphy_init(struct mvpp2_port *port,
1747+
phy_interface_t interface)
17471748
{
17481749
int ret;
17491750

17501751
if (!port->comphy)
17511752
return 0;
17521753

1753-
ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET,
1754-
port->phy_interface);
1754+
ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET, interface);
17551755
if (ret)
17561756
return ret;
17571757

@@ -2172,7 +2172,8 @@ static void mvpp22_pcs_reset_assert(struct mvpp2_port *port)
21722172
writel(val & ~MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0);
21732173
}
21742174

2175-
static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port)
2175+
static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port,
2176+
phy_interface_t interface)
21762177
{
21772178
struct mvpp2 *priv = port->priv;
21782179
void __iomem *mpcs, *xpcs;
@@ -2184,7 +2185,7 @@ static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port)
21842185
mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
21852186
xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
21862187

2187-
switch (port->phy_interface) {
2188+
switch (interface) {
21882189
case PHY_INTERFACE_MODE_10GBASER:
21892190
val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
21902191
val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX |
@@ -4529,7 +4530,8 @@ static int mvpp2_poll(struct napi_struct *napi, int budget)
45294530
return rx_done;
45304531
}
45314532

4532-
static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
4533+
static void mvpp22_mode_reconfigure(struct mvpp2_port *port,
4534+
phy_interface_t interface)
45334535
{
45344536
u32 ctrl3;
45354537

@@ -4540,26 +4542,26 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
45404542
mvpp22_pcs_reset_assert(port);
45414543

45424544
/* comphy reconfiguration */
4543-
mvpp22_comphy_init(port);
4545+
mvpp22_comphy_init(port, interface);
45444546

45454547
/* gop reconfiguration */
4546-
mvpp22_gop_init(port);
4548+
mvpp22_gop_init(port, interface);
45474549

4548-
mvpp22_pcs_reset_deassert(port);
4550+
mvpp22_pcs_reset_deassert(port, interface);
45494551

45504552
if (mvpp2_port_supports_xlg(port)) {
45514553
ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG);
45524554
ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK;
45534555

4554-
if (mvpp2_is_xlg(port->phy_interface))
4556+
if (mvpp2_is_xlg(interface))
45554557
ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_10G;
45564558
else
45574559
ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_GMAC;
45584560

45594561
writel(ctrl3, port->base + MVPP22_XLG_CTRL3_REG);
45604562
}
45614563

4562-
if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(port->phy_interface))
4564+
if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(interface))
45634565
mvpp2_xlg_max_rx_size_set(port);
45644566
else
45654567
mvpp2_gmac_max_rx_size_set(port);
@@ -4579,7 +4581,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
45794581
mvpp2_interrupts_enable(port);
45804582

45814583
if (port->priv->hw_version >= MVPP22)
4582-
mvpp22_mode_reconfigure(port);
4584+
mvpp22_mode_reconfigure(port, port->phy_interface);
45834585

45844586
if (port->phylink) {
45854587
phylink_start(port->phylink);
@@ -6444,6 +6446,9 @@ static int mvpp2__mac_prepare(struct phylink_config *config, unsigned int mode,
64446446
mvpp22_gop_mask_irq(port);
64456447

64466448
phy_power_off(port->comphy);
6449+
6450+
/* Reconfigure the serdes lanes */
6451+
mvpp22_mode_reconfigure(port, interface);
64476452
}
64486453
}
64496454

@@ -6498,9 +6503,6 @@ static int mvpp2_mac_finish(struct phylink_config *config, unsigned int mode,
64986503
port->phy_interface != interface) {
64996504
port->phy_interface = interface;
65006505

6501-
/* Reconfigure the serdes lanes */
6502-
mvpp22_mode_reconfigure(port);
6503-
65046506
/* Unmask interrupts */
65056507
mvpp22_gop_unmask_irq(port);
65066508
}
@@ -6961,7 +6963,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
69616963
* driver does this, we can remove this code.
69626964
*/
69636965
if (port->comphy) {
6964-
err = mvpp22_comphy_init(port);
6966+
err = mvpp22_comphy_init(port, port->phy_interface);
69656967
if (err == 0)
69666968
phy_power_off(port->comphy);
69676969
}

0 commit comments

Comments
 (0)