diff options
author | Andrew Lunn | 2018-07-18 22:38:25 +0200 |
---|---|---|
committer | David S. Miller | 2018-07-19 00:05:38 +0200 |
commit | e2294a8bf52b8bf1bab52b4165ffdceec4a143e0 (patch) | |
tree | ed566e3d41e9ae6358e3087083d391394d7db607 /drivers/net/dsa/mv88e6xxx/hwtstamp.c | |
parent | net: dsa: mv88e6xxx: Abstract supported PTP filters (diff) | |
download | kernel-qcow2-linux-e2294a8bf52b8bf1bab52b4165ffdceec4a143e0.tar.gz kernel-qcow2-linux-e2294a8bf52b8bf1bab52b4165ffdceec4a143e0.tar.xz kernel-qcow2-linux-e2294a8bf52b8bf1bab52b4165ffdceec4a143e0.zip |
net: dsa: mv88e6xxx: Add hwtimestamp support for the 6165
The 6165 family supports a more restricted version of hardware time
stamps. Only L2 PTP is supported. All ports have to use the same
EtherType, and transport spec configuration. PTP can only be
enabled/disabled globally, not per port.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/hwtstamp.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/hwtstamp.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/hwtstamp.c b/drivers/net/dsa/mv88e6xxx/hwtstamp.c index 0307704e0063..01e60a8c97fb 100644 --- a/drivers/net/dsa/mv88e6xxx/hwtstamp.c +++ b/drivers/net/dsa/mv88e6xxx/hwtstamp.c @@ -51,6 +51,15 @@ static int mv88e6xxx_ptp_write(struct mv88e6xxx_chip *chip, int addr, return chip->info->ops->avb_ops->ptp_write(chip, addr, data); } +static int mv88e6xxx_ptp_read(struct mv88e6xxx_chip *chip, int addr, + u16 *data) +{ + if (!chip->info->ops->avb_ops->ptp_read) + return -EOPNOTSUPP; + + return chip->info->ops->avb_ops->ptp_read(chip, addr, data, 1); +} + /* TX_TSTAMP_TIMEOUT: This limits the time spent polling for a TX * timestamp. When working properly, hardware will produce a timestamp * within 1ms. Software may enounter delays due to MDIO contention, so @@ -144,11 +153,17 @@ static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port, mutex_lock(&chip->reg_lock); if (tstamp_enable) { + chip->enable_count += 1; + if (chip->enable_count == 1 && ptp_ops->global_enable) + ptp_ops->global_enable(chip); if (ptp_ops->port_enable) ptp_ops->port_enable(chip, port); } else { if (ptp_ops->port_disable) ptp_ops->port_disable(chip, port); + chip->enable_count -= 1; + if (chip->enable_count == 0 && ptp_ops->global_disable) + ptp_ops->global_disable(chip); } mutex_unlock(&chip->reg_lock); @@ -516,6 +531,33 @@ bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port, return true; } +int mv88e6165_global_disable(struct mv88e6xxx_chip *chip) +{ + u16 val; + int err; + + err = mv88e6xxx_ptp_read(chip, MV88E6165_PTP_CFG, &val); + if (err) + return err; + val |= MV88E6165_PTP_CFG_DISABLE_PTP; + + return mv88e6xxx_ptp_write(chip, MV88E6165_PTP_CFG, val); +} + +int mv88e6165_global_enable(struct mv88e6xxx_chip *chip) +{ + u16 val; + int err; + + err = mv88e6xxx_ptp_read(chip, MV88E6165_PTP_CFG, &val); + if (err) + return err; + + val &= ~(MV88E6165_PTP_CFG_DISABLE_PTP | MV88E6165_PTP_CFG_TSPEC_MASK); + + return mv88e6xxx_ptp_write(chip, MV88E6165_PTP_CFG, val); +} + int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port) { return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0, @@ -546,6 +588,7 @@ static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port) int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip) { + const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; int err; int i; @@ -556,6 +599,13 @@ int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip) return err; } + /* Disable PTP globally */ + if (ptp_ops->global_disable) { + err = ptp_ops->global_disable(chip); + if (err) + return err; + } + /* MV88E6XXX_PTP_MSG_TYPE is a mask of PTP message types to * timestamp. This affects all ports that have timestamping enabled, * but the timestamp config is per-port; thus we configure all events |