diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-15 15:04:25 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-15 15:04:25 -0700 |
commit | 9a76aba02a37718242d7cdc294f0a3901928aa57 (patch) | |
tree | 2040d038f85d2120f21af83b0793efd5af1864e3 /drivers/net/dsa/mv88e6xxx/ptp.c | |
parent | 0a957467c5fd46142bc9c52758ffc552d4c5e2f7 (diff) | |
parent | 26a1ccc6c117be8e33e0410fce8c5298b0015b99 (diff) | |
download | linux-9a76aba02a37718242d7cdc294f0a3901928aa57.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
"Highlights:
- Gustavo A. R. Silva keeps working on the implicit switch fallthru
changes.
- Support 802.11ax High-Efficiency wireless in cfg80211 et al, From
Luca Coelho.
- Re-enable ASPM in r8169, from Kai-Heng Feng.
- Add virtual XFRM interfaces, which avoids all of the limitations of
existing IPSEC tunnels. From Steffen Klassert.
- Convert GRO over to use a hash table, so that when we have many
flows active we don't traverse a long list during accumluation.
- Many new self tests for routing, TC, tunnels, etc. Too many
contributors to mention them all, but I'm really happy to keep
seeing this stuff.
- Hardware timestamping support for dpaa_eth/fsl-fman from Yangbo Lu.
- Lots of cleanups and fixes in L2TP code from Guillaume Nault.
- Add IPSEC offload support to netdevsim, from Shannon Nelson.
- Add support for slotting with non-uniform distribution to netem
packet scheduler, from Yousuk Seung.
- Add UDP GSO support to mlx5e, from Boris Pismenny.
- Support offloading of Team LAG in NFP, from John Hurley.
- Allow to configure TX queue selection based upon RX queue, from
Amritha Nambiar.
- Support ethtool ring size configuration in aquantia, from Anton
Mikaev.
- Support DSCP and flowlabel per-transport in SCTP, from Xin Long.
- Support list based batching and stack traversal of SKBs, this is
very exciting work. From Edward Cree.
- Busyloop optimizations in vhost_net, from Toshiaki Makita.
- Introduce the ETF qdisc, which allows time based transmissions. IGB
can offload this in hardware. From Vinicius Costa Gomes.
- Add parameter support to devlink, from Moshe Shemesh.
- Several multiplication and division optimizations for BPF JIT in
nfp driver, from Jiong Wang.
- Lots of prepatory work to make more of the packet scheduler layer
lockless, when possible, from Vlad Buslov.
- Add ACK filter and NAT awareness to sch_cake packet scheduler, from
Toke Høiland-Jørgensen.
- Support regions and region snapshots in devlink, from Alex Vesker.
- Allow to attach XDP programs to both HW and SW at the same time on
a given device, with initial support in nfp. From Jakub Kicinski.
- Add TLS RX offload and support in mlx5, from Ilya Lesokhin.
- Use PHYLIB in r8169 driver, from Heiner Kallweit.
- All sorts of changes to support Spectrum 2 in mlxsw driver, from
Ido Schimmel.
- PTP support in mv88e6xxx DSA driver, from Andrew Lunn.
- Make TCP_USER_TIMEOUT socket option more accurate, from Jon
Maxwell.
- Support for templates in packet scheduler classifier, from Jiri
Pirko.
- IPV6 support in RDS, from Ka-Cheong Poon.
- Native tproxy support in nf_tables, from Máté Eckl.
- Maintain IP fragment queue in an rbtree, but optimize properly for
in-order frags. From Peter Oskolkov.
- Improvde handling of ACKs on hole repairs, from Yuchung Cheng"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1996 commits)
bpf: test: fix spelling mistake "REUSEEPORT" -> "REUSEPORT"
hv/netvsc: Fix NULL dereference at single queue mode fallback
net: filter: mark expected switch fall-through
xen-netfront: fix warn message as irq device name has '/'
cxgb4: Add new T5 PCI device ids 0x50af and 0x50b0
net: dsa: mv88e6xxx: missing unlock on error path
rds: fix building with IPV6=m
inet/connection_sock: prefer _THIS_IP_ to current_text_addr
net: dsa: mv88e6xxx: bitwise vs logical bug
net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd()
ieee802154: hwsim: using right kind of iteration
net: hns3: Add vlan filter setting by ethtool command -K
net: hns3: Set tx ring' tc info when netdev is up
net: hns3: Remove tx ring BD len register in hns3_enet
net: hns3: Fix desc num set to default when setting channel
net: hns3: Fix for phy link issue when using marvell phy driver
net: hns3: Fix for information of phydev lost problem when down/up
net: hns3: Fix for command format parsing error in hclge_is_all_function_id_zero
net: hns3: Add support for serdes loopback selftest
bnxt_en: take coredump_record structure off stack
...
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/ptp.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/ptp.c | 101 |
1 files changed, 84 insertions, 17 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c index bd85e2c390e1..4b336d8d4c67 100644 --- a/drivers/net/dsa/mv88e6xxx/ptp.c +++ b/drivers/net/dsa/mv88e6xxx/ptp.c @@ -16,6 +16,7 @@ #include "chip.h" #include "global2.h" +#include "hwtstamp.h" #include "ptp.h" /* Raw timestamps are in units of 8-ns clock periods. */ @@ -50,7 +51,7 @@ static int mv88e6xxx_tai_write(struct mv88e6xxx_chip *chip, int addr, u16 data) } /* TODO: places where this are called should be using pinctrl */ -static int mv88e6xxx_set_gpio_func(struct mv88e6xxx_chip *chip, int pin, +static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin, int func, int input) { int err; @@ -65,7 +66,7 @@ static int mv88e6xxx_set_gpio_func(struct mv88e6xxx_chip *chip, int pin, return chip->info->ops->gpio_ops->set_pctl(chip, pin, func); } -static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) +static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) { struct mv88e6xxx_chip *chip = cc_to_chip(cc); u16 phc_time[2]; @@ -79,13 +80,27 @@ static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) return ((u32)phc_time[1] << 16) | phc_time[0]; } -/* mv88e6xxx_config_eventcap - configure TAI event capture +static u64 mv88e6165_ptp_clock_read(const struct cyclecounter *cc) +{ + struct mv88e6xxx_chip *chip = cc_to_chip(cc); + u16 phc_time[2]; + int err; + + err = mv88e6xxx_tai_read(chip, MV88E6XXX_PTP_GC_TIME_LO, phc_time, + ARRAY_SIZE(phc_time)); + if (err) + return 0; + else + return ((u32)phc_time[1] << 16) | phc_time[0]; +} + +/* mv88e6352_config_eventcap - configure TAI event capture * @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external) * @rising: zero for falling-edge trigger, else rising-edge trigger * * This will also reset the capture sequence counter. */ -static int mv88e6xxx_config_eventcap(struct mv88e6xxx_chip *chip, int event, +static int mv88e6352_config_eventcap(struct mv88e6xxx_chip *chip, int event, int rising) { u16 global_config; @@ -118,7 +133,7 @@ static int mv88e6xxx_config_eventcap(struct mv88e6xxx_chip *chip, int event, return err; } -static void mv88e6xxx_tai_event_work(struct work_struct *ugly) +static void mv88e6352_tai_event_work(struct work_struct *ugly) { struct delayed_work *dw = to_delayed_work(ugly); struct mv88e6xxx_chip *chip = dw_tai_event_to_chip(dw); @@ -232,7 +247,7 @@ static int mv88e6xxx_ptp_settime(struct ptp_clock_info *ptp, return 0; } -static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip, +static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip *chip, struct ptp_clock_request *rq, int on) { int rising = (rq->extts.flags & PTP_RISING_EDGE); @@ -250,18 +265,18 @@ static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip, if (on) { func = MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ; - err = mv88e6xxx_set_gpio_func(chip, pin, func, true); + err = mv88e6352_set_gpio_func(chip, pin, func, true); if (err) goto out; schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL); - err = mv88e6xxx_config_eventcap(chip, PTP_CLOCK_EXTTS, rising); + err = mv88e6352_config_eventcap(chip, PTP_CLOCK_EXTTS, rising); } else { func = MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO; - err = mv88e6xxx_set_gpio_func(chip, pin, func, true); + err = mv88e6352_set_gpio_func(chip, pin, func, true); cancel_delayed_work_sync(&chip->tai_event_work); } @@ -272,20 +287,20 @@ out: return err; } -static int mv88e6xxx_ptp_enable(struct ptp_clock_info *ptp, +static int mv88e6352_ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *rq, int on) { struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); switch (rq->type) { case PTP_CLK_REQ_EXTTS: - return mv88e6xxx_ptp_enable_extts(chip, rq, on); + return mv88e6352_ptp_enable_extts(chip, rq, on); default: return -EOPNOTSUPP; } } -static int mv88e6xxx_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, +static int mv88e6352_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan) { switch (func) { @@ -299,6 +314,55 @@ static int mv88e6xxx_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, return 0; } +const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { + .clock_read = mv88e6352_ptp_clock_read, + .ptp_enable = mv88e6352_ptp_enable, + .ptp_verify = mv88e6352_ptp_verify, + .event_work = mv88e6352_tai_event_work, + .port_enable = mv88e6352_hwtstamp_port_enable, + .port_disable = mv88e6352_hwtstamp_port_disable, + .n_ext_ts = 1, + .arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS, + .arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS, + .dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS, + .rx_filters = (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | + (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | + (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) | + (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), +}; + +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) +{ + struct mv88e6xxx_chip *chip = cc_to_chip(cc); + + if (chip->info->ops->ptp_ops->clock_read) + return chip->info->ops->ptp_ops->clock_read(cc); + + return 0; +} + /* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3 * seconds; this task forces periodic reads so that we don't miss any. */ @@ -317,6 +381,7 @@ static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip) { + const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; int i; /* Set up the cycle counter */ @@ -330,14 +395,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip) ktime_to_ns(ktime_get_real())); INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check); - INIT_DELAYED_WORK(&chip->tai_event_work, mv88e6xxx_tai_event_work); + if (ptp_ops->event_work) + INIT_DELAYED_WORK(&chip->tai_event_work, ptp_ops->event_work); chip->ptp_clock_info.owner = THIS_MODULE; snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name), dev_name(chip->dev)); chip->ptp_clock_info.max_adj = 1000000; - chip->ptp_clock_info.n_ext_ts = 1; + chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts; chip->ptp_clock_info.n_per_out = 0; chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip); chip->ptp_clock_info.pps = 0; @@ -355,8 +421,8 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip) chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime; chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime; chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime; - chip->ptp_clock_info.enable = mv88e6xxx_ptp_enable; - chip->ptp_clock_info.verify = mv88e6xxx_ptp_verify; + chip->ptp_clock_info.enable = ptp_ops->ptp_enable; + chip->ptp_clock_info.verify = ptp_ops->ptp_verify; chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work; chip->ptp_clock = ptp_clock_register(&chip->ptp_clock_info, chip->dev); @@ -373,7 +439,8 @@ void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip) { if (chip->ptp_clock) { cancel_delayed_work_sync(&chip->overflow_work); - cancel_delayed_work_sync(&chip->tai_event_work); + if (chip->info->ops->ptp_ops->event_work) + cancel_delayed_work_sync(&chip->tai_event_work); ptp_clock_unregister(chip->ptp_clock); chip->ptp_clock = NULL; |