diff options
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/chip.h')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.h | 135 |
1 files changed, 131 insertions, 4 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 3dba6e90adcf..80490f66bc06 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -15,7 +15,10 @@ #include <linux/if_vlan.h> #include <linux/irq.h> #include <linux/gpio/consumer.h> +#include <linux/kthread.h> #include <linux/phy.h> +#include <linux/ptp_clock_kernel.h> +#include <linux/timecounter.h> #include <net/dsa.h> #ifndef UINT64_MAX @@ -39,6 +42,8 @@ #define MV88E6XXX_MAX_PVT_SWITCHES 32 #define MV88E6XXX_MAX_PVT_PORTS 16 +#define MV88E6XXX_MAX_GPIO 16 + enum mv88e6xxx_egress_mode { MV88E6XXX_EGRESS_MODE_UNMODIFIED, MV88E6XXX_EGRESS_MODE_UNTAGGED, @@ -105,6 +110,8 @@ struct mv88e6xxx_info { const char *name; unsigned int num_databases; unsigned int num_ports; + unsigned int num_internal_phys; + unsigned int num_gpio; unsigned int max_vid; unsigned int port_base_addr; unsigned int global1_addr; @@ -126,6 +133,9 @@ struct mv88e6xxx_info { */ u8 atu_move_port_mask; const struct mv88e6xxx_ops *ops; + + /* Supports PTP */ + bool ptp_support; }; struct mv88e6xxx_atu_entry { @@ -146,6 +156,8 @@ struct mv88e6xxx_vtu_entry { struct mv88e6xxx_bus_ops; struct mv88e6xxx_irq_ops; +struct mv88e6xxx_gpio_ops; +struct mv88e6xxx_avb_ops; struct mv88e6xxx_irq { u16 masked; @@ -154,6 +166,41 @@ struct mv88e6xxx_irq { unsigned int nirqs; }; +/* state flags for mv88e6xxx_port_hwtstamp::state */ +enum { + MV88E6XXX_HWTSTAMP_ENABLED, + MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, +}; + +struct mv88e6xxx_port_hwtstamp { + /* Port index */ + int port_id; + + /* Timestamping state */ + unsigned long state; + + /* Resources for receive timestamping */ + struct sk_buff_head rx_queue; + struct sk_buff_head rx_queue2; + + /* Resources for transmit timestamping */ + unsigned long tx_tstamp_start; + struct sk_buff *tx_skb; + u16 tx_seq_id; + + /* Current timestamp configuration */ + struct hwtstamp_config tstamp_config; +}; + +struct mv88e6xxx_port { + u64 serdes_stats[2]; + u64 atu_member_violation; + u64 atu_miss_violation; + u64 atu_full_violation; + u64 vtu_member_violation; + u64 vtu_miss_violation; +}; + struct mv88e6xxx_chip { const struct mv88e6xxx_info *info; @@ -207,8 +254,34 @@ struct mv88e6xxx_chip { int irq; int device_irq; int watchdog_irq; + int atu_prob_irq; int vtu_prob_irq; + struct kthread_worker *kworker; + struct kthread_delayed_work irq_poll_work; + + /* GPIO resources */ + u8 gpio_data[2]; + + /* This cyclecounter abstracts the switch PTP time. + * reg_lock must be held for any operation that read()s. + */ + struct cyclecounter tstamp_cc; + struct timecounter tstamp_tc; + struct delayed_work overflow_work; + + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_clock_info; + struct delayed_work tai_event_work; + struct ptp_pin_desc pin_config[MV88E6XXX_MAX_GPIO]; + u16 trig_config; + u16 evcap_config; + + /* Per-port timestamping resources. */ + struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS]; + + /* Array of port structures. */ + struct mv88e6xxx_port ports[DSA_MAX_PORTS]; }; struct mv88e6xxx_bus_ops { @@ -327,9 +400,9 @@ struct mv88e6xxx_ops { /* Return the number of strings describing statistics */ int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip); - void (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data); - void (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port, - uint64_t *data); + int (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data); + int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port, + uint64_t *data); int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port); int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port); const struct mv88e6xxx_irq_ops *watchdog_ops; @@ -339,11 +412,24 @@ struct mv88e6xxx_ops { /* Power on/off a SERDES interface */ int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on); + /* Statistics from the SERDES interface */ + int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); + int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, + uint8_t *data); + int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, + uint64_t *data); + /* VLAN Translation Unit operations */ int (*vtu_getnext)(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry); int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip, struct mv88e6xxx_vtu_entry *entry); + + /* GPIO operations */ + const struct mv88e6xxx_gpio_ops *gpio_ops; + + /* Interface to the AVB/PTP registers */ + const struct mv88e6xxx_avb_ops *avb_ops; }; struct mv88e6xxx_irq_ops { @@ -355,13 +441,49 @@ struct mv88e6xxx_irq_ops { void (*irq_free)(struct mv88e6xxx_chip *chip); }; +struct mv88e6xxx_gpio_ops { + /* Get/set data on GPIO pin */ + int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin); + int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin, + int value); + + /* get/set GPIO direction */ + int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin); + int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin, + bool input); + + /* get/set GPIO pin control */ + int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin, + int *func); + int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin, + int func); +}; + +struct mv88e6xxx_avb_ops { + /* Access port-scoped Precision Time Protocol registers */ + int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr, + u16 *data, int len); + int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr, + u16 data); + + /* Access global Precision Time Protocol registers */ + int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data, + int len); + int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data); + + /* Access global Time Application Interface registers */ + int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data, + int len); + int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data); +}; + #define STATS_TYPE_PORT BIT(0) #define STATS_TYPE_BANK0 BIT(1) #define STATS_TYPE_BANK1 BIT(2) struct mv88e6xxx_hw_stat { char string[ETH_GSTRING_LEN]; - int sizeof_stat; + size_t size; int reg; int type; }; @@ -386,6 +508,11 @@ static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip) return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0); } +static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip) +{ + return chip->info->num_gpio; +} + int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, |