Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions drivers/net/phy/marvell10g.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ enum {
struct mv3310_mactype {
bool valid;
bool fixed_interface;
/* PHY copper autoneg supports multiple speeds (1G/2.5G/5G/10G) even
* though the host-side interface is fixed (rate matching). This allows
* phylink to validate and advertise all copper speeds.
*/
bool copper_multispeed;
phy_interface_t interface_10g;
};

Expand Down Expand Up @@ -405,6 +410,16 @@ static int mv3310_power_up(struct phy_device *phydev)
priv->firmware_ver < 0x00030000)
return ret;

/* Poll until SWRST reads 0 (PHY ready for a new reset) before issuing
* SWRST. Without this, the second and subsequent link-up sequences
* result in broken TX/RX. The datasheet specifies bit 15 = 1 means
* reset in progress, 0 means normal operation.
*/
if (phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
ret, !(ret & MV_V2_33X0_PORT_CTRL_SWRST),
5000, 200000, true))
phydev_warn(phydev, "SWRST timed out 200ms\n");

ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
MV_V2_33X0_PORT_CTRL_SWRST);
msleep(100);
Expand Down Expand Up @@ -947,6 +962,7 @@ static const struct mv3310_mactype mv3310_mactypes[] = {
[MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH] = {
.valid = true,
.fixed_interface = true,
.copper_multispeed = true,
.interface_10g = PHY_INTERFACE_MODE_10GBASER,
},
[MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII] = {
Expand Down Expand Up @@ -981,6 +997,7 @@ static const struct mv3310_mactype mv3340_mactypes[] = {
[MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH] = {
.valid = true,
.fixed_interface = true,
.copper_multispeed = true,
.interface_10g = PHY_INTERFACE_MODE_10GBASER,
},
[MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII] = {
Expand All @@ -999,7 +1016,7 @@ static void mv3310_fill_possible_interfaces(struct phy_device *phydev)
if (mactype->interface_10g != PHY_INTERFACE_MODE_NA)
__set_bit(priv->mactype->interface_10g, possible);

if (!mactype->fixed_interface) {
if (!mactype->fixed_interface || mactype->copper_multispeed) {
__set_bit(PHY_INTERFACE_MODE_5GBASER, possible);
__set_bit(PHY_INTERFACE_MODE_2500BASEX, possible);
__set_bit(PHY_INTERFACE_MODE_SGMII, possible);
Expand Down Expand Up @@ -1037,10 +1054,15 @@ static int mv3310_config_init(struct phy_device *phydev)

mv3310_config_init_clear_power_down(phydev);

/* Force XFI/SGMII/Auto-neg mode regardless of strap configuration */
/* Force XFI/SGMII/Auto-neg mode regardless of strap configuration.
/* Default to rate-match mode so the host serdes stays fixed at 10GBASE-R
* regardless of copper wire speed. This is correct for MACs (e.g. mvpp2) that
* configure their comphy for 10GBASE-R and cannot handle the PHY switching
* the host interface to SGMII on 1G link-up.
*/
err = phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
MV_V2_33X0_PORT_CTRL_MACTYPE_MASK,
MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER);
MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH);
if (err)
return err;

Expand Down
Loading