diff options
author | Chris Packham <judge.packham@gmail.com> | 2016-08-26 17:30:26 +1200 |
---|---|---|
committer | Joe Hershberger <joe.hershberger@ni.com> | 2016-10-13 12:25:18 -0500 |
commit | b755abecd45d6c5e1589ec4b17b6189a9dcbdac0 (patch) | |
tree | 3def43abd544932b8472b6ad124c72f2ab6f4460 /drivers | |
parent | 65d4d00abc9166c0f837e9ca08b2d4453241e68c (diff) |
net: mv88e61xx: Add support for fixed links
On some boards these switches are wired directly into a SERDES
interface on another Ethernet MAC. Add the ability to specify
these kinds of boards using CONFIG_MV88E61XX_FIXED_PORTS which defines
a bit mask of these fixed ports.
Signed-off-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/phy/mv88e61xx.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c index 7385848c718..a2fd1686fc3 100644 --- a/drivers/net/phy/mv88e61xx.c +++ b/drivers/net/phy/mv88e61xx.c @@ -103,8 +103,16 @@ #define PORT_REG_STATUS_CMODE_1000BASE_X 0x9 #define PORT_REG_STATUS_CMODE_SGMII 0xa +#define PORT_REG_PHYS_CTRL_PCS_AN_EN BIT(10) +#define PORT_REG_PHYS_CTRL_PCS_AN_RST BIT(9) +#define PORT_REG_PHYS_CTRL_FC_VALUE BIT(7) +#define PORT_REG_PHYS_CTRL_FC_FORCE BIT(6) #define PORT_REG_PHYS_CTRL_LINK_VALUE BIT(5) #define PORT_REG_PHYS_CTRL_LINK_FORCE BIT(4) +#define PORT_REG_PHYS_CTRL_DUPLEX_VALUE BIT(3) +#define PORT_REG_PHYS_CTRL_DUPLEX_FORCE BIT(2) +#define PORT_REG_PHYS_CTRL_SPD1000 BIT(1) +#define PORT_REG_PHYS_CTRL_SPD_MASK (BIT(1) | BIT(0)) #define PORT_REG_CTRL_PSTATE_SHIFT 0 #define PORT_REG_CTRL_PSTATE_WIDTH 2 @@ -166,6 +174,14 @@ #error Define CONFIG_MV88E61XX_CPU_PORT to the port the CPU is attached to #endif +/* + * These are ports without PHYs that may be wired directly + * to other serdes interfaces + */ +#ifndef CONFIG_MV88E61XX_FIXED_PORTS +#define CONFIG_MV88E61XX_FIXED_PORTS 0 +#endif + /* ID register values for different switch models */ #define PORT_SWITCH_ID_6096 0x0980 #define PORT_SWITCH_ID_6097 0x0990 @@ -793,6 +809,27 @@ static int mv88e61xx_phy_setup(struct phy_device *phydev, u8 phy) return 0; } +static int mv88e61xx_fixed_port_setup(struct phy_device *phydev, u8 port) +{ + int val; + + val = mv88e61xx_port_read(phydev, port, PORT_REG_PHYS_CTRL); + if (val < 0) + return val; + + val &= ~(PORT_REG_PHYS_CTRL_SPD_MASK | + PORT_REG_PHYS_CTRL_FC_VALUE); + val |= PORT_REG_PHYS_CTRL_PCS_AN_EN | + PORT_REG_PHYS_CTRL_PCS_AN_RST | + PORT_REG_PHYS_CTRL_FC_FORCE | + PORT_REG_PHYS_CTRL_DUPLEX_VALUE | + PORT_REG_PHYS_CTRL_DUPLEX_FORCE | + PORT_REG_PHYS_CTRL_SPD1000; + + return mv88e61xx_port_write(phydev, port, PORT_REG_PHYS_CTRL, + val); +} + static int mv88e61xx_phy_config_port(struct phy_device *phydev, u8 phy) { int val; @@ -911,6 +948,12 @@ static int mv88e61xx_phy_config(struct phy_device *phydev) /* Return success if any PHY succeeds */ ret = 0; + } else if ((1 << i) & CONFIG_MV88E61XX_FIXED_PORTS) { + res = mv88e61xx_fixed_port_setup(phydev, i); + if (res < 0) { + printf("Error configuring port %i\n", i); + continue; + } } } |