summaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa/mv88e6xxx/port.c
diff options
context:
space:
mode:
authorVivien Didelot2016-11-04 03:23:32 +0100
committerDavid S. Miller2016-11-04 19:40:00 +0100
commit08ef7f1022e85539d5e3ce925e1fab60b205ae39 (patch)
tree595503dd04399944d12515518754cfc423613f0d /drivers/net/dsa/mv88e6xxx/port.c
parentnet: dsa: mv88e6xxx: add port 802.1Q mode setter (diff)
downloadkernel-qcow2-linux-08ef7f1022e85539d5e3ce925e1fab60b205ae39.tar.gz
kernel-qcow2-linux-08ef7f1022e85539d5e3ce925e1fab60b205ae39.tar.xz
kernel-qcow2-linux-08ef7f1022e85539d5e3ce925e1fab60b205ae39.zip
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: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/port.c')
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 53d17e63b04a..09e25f975b25 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -30,6 +30,47 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
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 */
static const char * const mv88e6xxx_port_state_names[] = {