Commit b7052ba7 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-dsa-mv88e6xxx-augment-phylink-support-for-10G'



Russell King says:

====================
net: dsa: mv88e6xxx: augment phylink support for 10G

This series adds phylink 10G support for the 88E6390 series switches,
as suggested by Andrew Lunn.

The first patch cleans up the code to use generic definitions for the
registers in a similar way to what was done with the initial conversion
of 1G serdes support.

The second patch adds the necessary bits 10GBASE mode to the
pcs_get_state() method.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bf2320a6 7019bba4
Loading
Loading
Loading
Loading
+47 −8
Original line number Diff line number Diff line
@@ -534,21 +534,21 @@ static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
	int err;

	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
				    MV88E6390_PCS_CONTROL_1, &val);
				    MV88E6390_10G_CTRL1, &val);

	if (err)
		return err;

	if (up)
		new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
				  MV88E6390_PCS_CONTROL_1_LOOPBACK |
				  MV88E6390_PCS_CONTROL_1_PDOWN);
		new_val = val & ~(MDIO_CTRL1_RESET |
				  MDIO_PCS_CTRL1_LOOPBACK |
				  MDIO_CTRL1_LPOWER);
	else
		new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN;
		new_val = val | MDIO_CTRL1_LPOWER;

	if (val != new_val)
		err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
					     MV88E6390_PCS_CONTROL_1, new_val);
					     MV88E6390_10G_CTRL1, new_val);

	return err;
}
@@ -748,8 +748,8 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
				      MV88E6390_SGMII_BMCR, bmcr);
}

int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
				   u8 lane, struct phylink_link_state *state)
static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
	int port, u8 lane, struct phylink_link_state *state)
{
	u16 lpa, status;
	int err;
@@ -771,6 +771,45 @@ int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
	return mv88e6xxx_serdes_pcs_get_state(chip, status, lpa, state);
}

static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
	int port, u8 lane, struct phylink_link_state *state)
{
	u16 status;
	int err;

	err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
				    MV88E6390_10G_STAT1, &status);
	if (err)
		return err;

	state->link = !!(status & MDIO_STAT1_LSTATUS);
	if (state->link) {
		state->speed = SPEED_10000;
		state->duplex = DUPLEX_FULL;
	}

	return 0;
}

int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
				   u8 lane, struct phylink_link_state *state)
{
	switch (state->interface) {
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_1000BASEX:
	case PHY_INTERFACE_MODE_2500BASEX:
		return mv88e6390_serdes_pcs_get_state_sgmii(chip, port, lane,
							    state);
	case PHY_INTERFACE_MODE_XAUI:
	case PHY_INTERFACE_MODE_RXAUI:
		return mv88e6390_serdes_pcs_get_state_10g(chip, port, lane,
							  state);

	default:
		return -EOPNOTSUPP;
	}
}

int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
				    u8 lane)
{
+2 −5
Original line number Diff line number Diff line
@@ -40,11 +40,8 @@
#define MV88E6390_PORT10_LANE3		0x17

/* 10GBASE-R and 10GBASE-X4/X2 */
#define MV88E6390_PCS_CONTROL_1		0x1000
#define MV88E6390_PCS_CONTROL_1_RESET		BIT(15)
#define MV88E6390_PCS_CONTROL_1_LOOPBACK	BIT(14)
#define MV88E6390_PCS_CONTROL_1_SPEED		BIT(13)
#define MV88E6390_PCS_CONTROL_1_PDOWN		BIT(11)
#define MV88E6390_10G_CTRL1		(0x1000 + MDIO_CTRL1)
#define MV88E6390_10G_STAT1		(0x1000 + MDIO_STAT1)

/* 1000BASE-X and SGMII */
#define MV88E6390_SGMII_BMCR		(0x2000 + MII_BMCR)