mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-26 22:24:09 +08:00
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>
This commit is contained in:
parent
48cb5e03d5
commit
e2294a8bf5
@ -274,6 +274,7 @@ struct mv88e6xxx_chip {
|
||||
struct ptp_pin_desc pin_config[MV88E6XXX_MAX_GPIO];
|
||||
u16 trig_config;
|
||||
u16 evcap_config;
|
||||
u16 enable_count;
|
||||
|
||||
/* Per-port timestamping resources. */
|
||||
struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
|
||||
@ -499,6 +500,8 @@ struct mv88e6xxx_ptp_ops {
|
||||
void (*event_work)(struct work_struct *ugly);
|
||||
int (*port_enable)(struct mv88e6xxx_chip *chip, int port);
|
||||
int (*port_disable)(struct mv88e6xxx_chip *chip, int port);
|
||||
int (*global_enable)(struct mv88e6xxx_chip *chip);
|
||||
int (*global_disable)(struct mv88e6xxx_chip *chip);
|
||||
int n_ext_ts;
|
||||
int arr0_sts_reg;
|
||||
int arr1_sts_reg;
|
||||
|
@ -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
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/* Global PTP registers */
|
||||
/* Global 6352 PTP registers */
|
||||
/* Offset 0x00: PTP EtherType */
|
||||
#define MV88E6XXX_PTP_ETHERTYPE 0x00
|
||||
|
||||
@ -34,6 +34,12 @@
|
||||
/* Offset 0x02: Timestamp Arrival Capture Pointers */
|
||||
#define MV88E6XXX_PTP_TS_ARRIVAL_PTR 0x02
|
||||
|
||||
/* Offset 0x05: PTP Global Configuration */
|
||||
#define MV88E6165_PTP_CFG 0x05
|
||||
#define MV88E6165_PTP_CFG_TSPEC_MASK 0xf000
|
||||
#define MV88E6165_PTP_CFG_DISABLE_TS_OVERWRITE BIT(1)
|
||||
#define MV88E6165_PTP_CFG_DISABLE_PTP BIT(0)
|
||||
|
||||
/* Offset 0x07: PTP Global Configuration */
|
||||
#define MV88E6341_PTP_CFG 0x07
|
||||
#define MV88E6341_PTP_CFG_UPDATE 0x8000
|
||||
@ -46,7 +52,7 @@
|
||||
/* Offset 0x08: PTP Interrupt Status */
|
||||
#define MV88E6XXX_PTP_IRQ_STATUS 0x08
|
||||
|
||||
/* Per-Port PTP Registers */
|
||||
/* Per-Port 6352 PTP Registers */
|
||||
/* Offset 0x00: PTP Configuration 0 */
|
||||
#define MV88E6XXX_PORT_PTP_CFG0 0x00
|
||||
#define MV88E6XXX_PORT_PTP_CFG0_TSPEC_SHIFT 12
|
||||
@ -125,6 +131,8 @@ int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip);
|
||||
void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip);
|
||||
int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port);
|
||||
int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port);
|
||||
int mv88e6165_global_enable(struct mv88e6xxx_chip *chip);
|
||||
int mv88e6165_global_disable(struct mv88e6xxx_chip *chip);
|
||||
|
||||
#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
|
||||
|
||||
|
@ -339,6 +339,18 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
|
||||
|
||||
const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
|
||||
.clock_read = mv88e6165_ptp_clock_read,
|
||||
.global_enable = mv88e6165_global_enable,
|
||||
.global_disable = mv88e6165_global_disable,
|
||||
.arr0_sts_reg = MV88E6165_PORT_PTP_ARR0_STS,
|
||||
.arr1_sts_reg = MV88E6165_PORT_PTP_ARR1_STS,
|
||||
.dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS,
|
||||
.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
|
||||
};
|
||||
|
||||
static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
|
||||
|
@ -81,6 +81,7 @@
|
||||
/* Offset 0x00: Ether Type */
|
||||
#define MV88E6XXX_PTP_GC_ETYPE 0x00
|
||||
|
||||
/* 6165 Global Control Registers */
|
||||
/* Offset 0x01: Message ID */
|
||||
#define MV88E6XXX_PTP_GC_MESSAGE_ID 0x01
|
||||
|
||||
@ -105,6 +106,40 @@
|
||||
#define MV88E6XXX_PTP_GC_TIME_LO 0x09
|
||||
#define MV88E6XXX_PTP_GC_TIME_HI 0x0A
|
||||
|
||||
/* 6165 Per Port Registers */
|
||||
/* Offset 0: Arrival Time 0 Status */
|
||||
#define MV88E6165_PORT_PTP_ARR0_STS 0x00
|
||||
|
||||
/* Offset 0x01/0x02: PTP Arrival 0 Time */
|
||||
#define MV88E6165_PORT_PTP_ARR0_TIME_LO 0x01
|
||||
#define MV88E6165_PORT_PTP_ARR0_TIME_HI 0x02
|
||||
|
||||
/* Offset 0x03: PTP Arrival 0 Sequence ID */
|
||||
#define MV88E6165_PORT_PTP_ARR0_SEQID 0x03
|
||||
|
||||
/* Offset 0x04: PTP Arrival 1 Status */
|
||||
#define MV88E6165_PORT_PTP_ARR1_STS 0x04
|
||||
|
||||
/* Offset 0x05/0x6E: PTP Arrival 1 Time */
|
||||
#define MV88E6165_PORT_PTP_ARR1_TIME_LO 0x05
|
||||
#define MV88E6165_PORT_PTP_ARR1_TIME_HI 0x06
|
||||
|
||||
/* Offset 0x07: PTP Arrival 1 Sequence ID */
|
||||
#define MV88E6165_PORT_PTP_ARR1_SEQID 0x07
|
||||
|
||||
/* Offset 0x08: PTP Departure Status */
|
||||
#define MV88E6165_PORT_PTP_DEP_STS 0x08
|
||||
|
||||
/* Offset 0x09/0x0a: PTP Deperture Time */
|
||||
#define MV88E6165_PORT_PTP_DEP_TIME_LO 0x09
|
||||
#define MV88E6165_PORT_PTP_DEP_TIME_HI 0x0a
|
||||
|
||||
/* Offset 0x0b: PTP Departure Sequence ID */
|
||||
#define MV88E6165_PORT_PTP_DEP_SEQID 0x0b
|
||||
|
||||
/* Offset 0x0d: Port Status */
|
||||
#define MV88E6164_PORT_STATUS 0x0d
|
||||
|
||||
#ifdef CONFIG_NET_DSA_MV88E6XXX_PTP
|
||||
|
||||
long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp);
|
||||
|
Loading…
Reference in New Issue
Block a user