Commit 08ef7f10 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

net: dsa: mv88e6xxx: add port link setter

Most of the chips will have a port register control bits to force the
port's link up, down, or let normal link detection occurs.

Implement such operation to use it later when setting duplex, etc.
Signed-off-by: default avatarVivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 385a0995
...@@ -3160,42 +3160,49 @@ static const struct mv88e6xxx_ops mv88e6085_ops = { ...@@ -3160,42 +3160,49 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.set_switch_mac = mv88e6xxx_g1_set_switch_mac, .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
.phy_read = mv88e6xxx_phy_ppu_read, .phy_read = mv88e6xxx_phy_ppu_read,
.phy_write = mv88e6xxx_phy_ppu_write, .phy_write = mv88e6xxx_phy_ppu_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6095_ops = { static const struct mv88e6xxx_ops mv88e6095_ops = {
.set_switch_mac = mv88e6xxx_g1_set_switch_mac, .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
.phy_read = mv88e6xxx_phy_ppu_read, .phy_read = mv88e6xxx_phy_ppu_read,
.phy_write = mv88e6xxx_phy_ppu_write, .phy_write = mv88e6xxx_phy_ppu_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6123_ops = { static const struct mv88e6xxx_ops mv88e6123_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_read, .phy_read = mv88e6xxx_read,
.phy_write = mv88e6xxx_write, .phy_write = mv88e6xxx_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6131_ops = { static const struct mv88e6xxx_ops mv88e6131_ops = {
.set_switch_mac = mv88e6xxx_g1_set_switch_mac, .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
.phy_read = mv88e6xxx_phy_ppu_read, .phy_read = mv88e6xxx_phy_ppu_read,
.phy_write = mv88e6xxx_phy_ppu_write, .phy_write = mv88e6xxx_phy_ppu_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6161_ops = { static const struct mv88e6xxx_ops mv88e6161_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_read, .phy_read = mv88e6xxx_read,
.phy_write = mv88e6xxx_write, .phy_write = mv88e6xxx_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6165_ops = { static const struct mv88e6xxx_ops mv88e6165_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_read, .phy_read = mv88e6xxx_read,
.phy_write = mv88e6xxx_write, .phy_write = mv88e6xxx_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6171_ops = { static const struct mv88e6xxx_ops mv88e6171_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6172_ops = { static const struct mv88e6xxx_ops mv88e6172_ops = {
...@@ -3204,12 +3211,14 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { ...@@ -3204,12 +3211,14 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6175_ops = { static const struct mv88e6xxx_ops mv88e6175_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6176_ops = { static const struct mv88e6xxx_ops mv88e6176_ops = {
...@@ -3218,12 +3227,14 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { ...@@ -3218,12 +3227,14 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6185_ops = { static const struct mv88e6xxx_ops mv88e6185_ops = {
.set_switch_mac = mv88e6xxx_g1_set_switch_mac, .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
.phy_read = mv88e6xxx_phy_ppu_read, .phy_read = mv88e6xxx_phy_ppu_read,
.phy_write = mv88e6xxx_phy_ppu_write, .phy_write = mv88e6xxx_phy_ppu_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6240_ops = { static const struct mv88e6xxx_ops mv88e6240_ops = {
...@@ -3232,6 +3243,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { ...@@ -3232,6 +3243,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6320_ops = { static const struct mv88e6xxx_ops mv88e6320_ops = {
...@@ -3240,6 +3252,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { ...@@ -3240,6 +3252,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6321_ops = { static const struct mv88e6xxx_ops mv88e6321_ops = {
...@@ -3248,18 +3261,21 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { ...@@ -3248,18 +3261,21 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6350_ops = { static const struct mv88e6xxx_ops mv88e6350_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6351_ops = { static const struct mv88e6xxx_ops mv88e6351_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_ops mv88e6352_ops = { static const struct mv88e6xxx_ops mv88e6352_ops = {
...@@ -3268,6 +3284,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { ...@@ -3268,6 +3284,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.set_switch_mac = mv88e6xxx_g2_set_switch_mac, .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
.phy_read = mv88e6xxx_g2_smi_phy_read, .phy_read = mv88e6xxx_g2_smi_phy_read,
.phy_write = mv88e6xxx_g2_smi_phy_write, .phy_write = mv88e6xxx_g2_smi_phy_write,
.port_set_link = mv88e6xxx_port_set_link,
}; };
static const struct mv88e6xxx_info mv88e6xxx_table[] = { static const struct mv88e6xxx_info mv88e6xxx_table[] = {
......
...@@ -727,6 +727,16 @@ struct mv88e6xxx_ops { ...@@ -727,6 +727,16 @@ struct mv88e6xxx_ops {
u16 *val); u16 *val);
int (*phy_write)(struct mv88e6xxx_chip *chip, int addr, int reg, int (*phy_write)(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 val); u16 val);
#define LINK_FORCED_DOWN 0
#define LINK_FORCED_UP 1
#define LINK_UNFORCED -2
/* Port's MAC link state
* Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
* or LINK_UNFORCED for normal link detection.
*/
int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
}; };
enum stat_type { enum stat_type {
......
...@@ -30,6 +30,47 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, ...@@ -30,6 +30,47 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
return mv88e6xxx_write(chip, addr, reg, val); return mv88e6xxx_write(chip, addr, reg, val);
} }
/* Offset 0x01: MAC (or PCS or Physical) Control Register
*
* Link, Duplex and Flow Control have one force bit, one value bit.
*/
int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
{
u16 reg;
int err;
err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
if (err)
return err;
reg &= ~(PORT_PCS_CTRL_FORCE_LINK | PORT_PCS_CTRL_LINK_UP);
switch (link) {
case LINK_FORCED_DOWN:
reg |= PORT_PCS_CTRL_FORCE_LINK;
break;
case LINK_FORCED_UP:
reg |= PORT_PCS_CTRL_FORCE_LINK | PORT_PCS_CTRL_LINK_UP;
break;
case LINK_UNFORCED:
/* normal link detection */
break;
default:
return -EINVAL;
}
err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
if (err)
return err;
netdev_dbg(chip->ds->ports[port].netdev, "%s link %s\n",
reg & PORT_PCS_CTRL_FORCE_LINK ? "Force" : "Unforce",
reg & PORT_PCS_CTRL_LINK_UP ? "up" : "down");
return 0;
}
/* Offset 0x04: Port Control Register */ /* Offset 0x04: Port Control Register */
static const char * const mv88e6xxx_port_state_names[] = { static const char * const mv88e6xxx_port_state_names[] = {
......
...@@ -21,6 +21,8 @@ int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, ...@@ -21,6 +21,8 @@ int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
u16 val); u16 val);
int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link);
int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state); int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map); int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment