diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-29 11:33:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-29 11:33:01 -0700 |
commit | bd6c11bc43c496cddfc6cf603b5d45365606dbd5 (patch) | |
tree | 36318fa68f784d397111991177d65bd6325189c4 /drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c | |
parent | 68cf01760bc0891074e813b9bb06d2696cac1c01 (diff) | |
parent | c873512ef3a39cc1a605b7a5ff2ad0a33d619aa8 (diff) |
Merge tag 'net-next-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Paolo Abeni:
"Core:
- Increase size limits for to-be-sent skb frag allocations. This
allows tun, tap devices and packet sockets to better cope with
large writes operations
- Store netdevs in an xarray, to simplify iterating over netdevs
- Refactor nexthop selection for multipath routes
- Improve sched class lifetime handling
- Add backup nexthop ID support for bridge
- Implement drop reasons support in openvswitch
- Several data races annotations and fixes
- Constify the sk parameter of routing functions
- Prepend kernel version to netconsole message
Protocols:
- Implement support for TCP probing the peer being under memory
pressure
- Remove hard coded limitation on IPv6 specific info placement inside
the socket struct
- Get rid of sysctl_tcp_adv_win_scale and use an auto-estimated per
socket scaling factor
- Scaling-up the IPv6 expired route GC via a separated list of
expiring routes
- In-kernel support for the TLS alert protocol
- Better support for UDP reuseport with connected sockets
- Add NEXT-C-SID support for SRv6 End.X behavior, reducing the SR
header size
- Get rid of additional ancillary per MPTCP connection struct socket
- Implement support for BPF-based MPTCP packet schedulers
- Format MPTCP subtests selftests results in TAP
- Several new SMC 2.1 features including unique experimental options,
max connections per lgr negotiation, max links per lgr negotiation
BPF:
- Multi-buffer support in AF_XDP
- Add multi uprobe BPF links for attaching multiple uprobes and usdt
probes, which is significantly faster and saves extra fds
- Implement an fd-based tc BPF attach API (TCX) and BPF link support
on top of it
- Add SO_REUSEPORT support for TC bpf_sk_assign
- Support new instructions from cpu v4 to simplify the generated code
and feature completeness, for x86, arm64, riscv64
- Support defragmenting IPv(4|6) packets in BPF
- Teach verifier actual bounds of bpf_get_smp_processor_id() and fix
perf+libbpf issue related to custom section handling
- Introduce bpf map element count and enable it for all program types
- Add a BPF hook in sys_socket() to change the protocol ID from
IPPROTO_TCP to IPPROTO_MPTCP to cover migration for legacy
- Introduce bpf_me_mcache_free_rcu() and fix OOM under stress
- Add uprobe support for the bpf_get_func_ip helper
- Check skb ownership against full socket
- Support for up to 12 arguments in BPF trampoline
- Extend link_info for kprobe_multi and perf_event links
Netfilter:
- Speed-up process exit by aborting ruleset validation if a fatal
signal is pending
- Allow NLA_POLICY_MASK to be used with BE16/BE32 types
Driver API:
- Page pool optimizations, to improve data locality and cache usage
- Introduce ndo_hwtstamp_get() and ndo_hwtstamp_set() to avoid the
need for raw ioctl() handling in drivers
- Simplify genetlink dump operations (doit/dumpit) providing them the
common information already populated in struct genl_info
- Extend and use the yaml devlink specs to [re]generate the split ops
- Introduce devlink selective dumps, to allow SF filtering SF based
on handle and other attributes
- Add yaml netlink spec for netlink-raw families, allow route, link
and address related queries via the ynl tool
- Remove phylink legacy mode support
- Support offload LED blinking to phy
- Add devlink port function attributes for IPsec
New hardware / drivers:
- Ethernet:
- Broadcom ASP 2.0 (72165) ethernet controller
- MediaTek MT7988 SoC
- Texas Instruments AM654 SoC
- Texas Instruments IEP driver
- Atheros qca8081 phy
- Marvell 88Q2110 phy
- NXP TJA1120 phy
- WiFi:
- MediaTek mt7981 support
- Can:
- Kvaser SmartFusion2 PCI Express devices
- Allwinner T113 controllers
- Texas Instruments tcan4552/4553 chips
- Bluetooth:
- Intel Gale Peak
- Qualcomm WCN3988 and WCN7850
- NXP AW693 and IW624
- Mediatek MT2925
Drivers:
- Ethernet NICs:
- nVidia/Mellanox:
- mlx5:
- support UDP encapsulation in packet offload mode
- IPsec packet offload support in eswitch mode
- improve aRFS observability by adding new set of counters
- extends MACsec offload support to cover RoCE traffic
- dynamic completion EQs
- mlx4:
- convert to use auxiliary bus instead of custom interface
logic
- Intel
- ice:
- implement switchdev bridge offload, even for LAG
interfaces
- implement SRIOV support for LAG interfaces
- igc:
- add support for multiple in-flight TX timestamps
- Broadcom:
- bnxt:
- use the unified RX page pool buffers for XDP and non-XDP
- use the NAPI skb allocation cache
- OcteonTX2:
- support Round Robin scheduling HTB offload
- TC flower offload support for SPI field
- Freescale:
- add XDP_TX feature support
- AMD:
- ionic: add support for PCI FLR event
- sfc:
- basic conntrack offload
- introduce eth, ipv4 and ipv6 pedit offloads
- ST Microelectronics:
- stmmac: maximze PTP timestamping resolution
- Virtual NICs:
- Microsoft vNIC:
- batch ringing RX queue doorbell on receiving packets
- add page pool for RX buffers
- Virtio vNIC:
- add per queue interrupt coalescing support
- Google vNIC:
- add queue-page-list mode support
- Ethernet high-speed switches:
- nVidia/Mellanox (mlxsw):
- add port range matching tc-flower offload
- permit enslavement to netdevices with uppers
- Ethernet embedded switches:
- Marvell (mv88e6xxx):
- convert to phylink_pcs
- Renesas:
- r8A779fx: add speed change support
- rzn1: enables vlan support
- Ethernet PHYs:
- convert mv88e6xxx to phylink_pcs
- WiFi:
- Qualcomm Wi-Fi 7 (ath12k):
- extremely High Throughput (EHT) PHY support
- RealTek (rtl8xxxu):
- enable AP mode for: RTL8192FU, RTL8710BU (RTL8188GU),
RTL8192EU and RTL8723BU
- RealTek (rtw89):
- Introduce Time Averaged SAR (TAS) support
- Connector:
- support for event filtering"
* tag 'net-next-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1806 commits)
net: ethernet: mtk_wed: minor change in wed_{tx,rx}info_show
net: ethernet: mtk_wed: add some more info in wed_txinfo_show handler
net: stmmac: clarify difference between "interface" and "phy_interface"
r8152: add vendor/device ID pair for D-Link DUB-E250
devlink: move devlink_notify_register/unregister() to dev.c
devlink: move small_ops definition into netlink.c
devlink: move tracepoint definitions into core.c
devlink: push linecard related code into separate file
devlink: push rate related code into separate file
devlink: push trap related code into separate file
devlink: use tracepoint_enabled() helper
devlink: push region related code into separate file
devlink: push param related code into separate file
devlink: push resource related code into separate file
devlink: push dpipe related code into separate file
devlink: move and rename devlink_dpipe_send_and_alloc_skb() helper
devlink: push shared buffer related code into separate file
devlink: push port related code into separate file
devlink: push object register/unregister notifications into separate helpers
inet: fix IP_TRANSPARENT error handling
...
Diffstat (limited to 'drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c')
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c | 177 |
1 files changed, 144 insertions, 33 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c index 896b2f9bac34..3a72b0793d4a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c @@ -10,6 +10,65 @@ #include "otx2_common.h" #include "otx2_ptp.h" +static bool is_tstmp_atomic_update_supported(struct otx2_ptp *ptp) +{ + struct ptp_get_cap_rsp *rsp; + struct msg_req *req; + int err; + + if (!ptp->nic) + return false; + + mutex_lock(&ptp->nic->mbox.lock); + req = otx2_mbox_alloc_msg_ptp_get_cap(&ptp->nic->mbox); + if (!req) { + mutex_unlock(&ptp->nic->mbox.lock); + return false; + } + + err = otx2_sync_mbox_msg(&ptp->nic->mbox); + if (err) { + mutex_unlock(&ptp->nic->mbox.lock); + return false; + } + rsp = (struct ptp_get_cap_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, + &req->hdr); + mutex_unlock(&ptp->nic->mbox.lock); + + if (IS_ERR(rsp)) + return false; + + if (rsp->cap & PTP_CAP_HW_ATOMIC_UPDATE) + return true; + + return false; +} + +static int otx2_ptp_hw_adjtime(struct ptp_clock_info *ptp_info, s64 delta) +{ + struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, + ptp_info); + struct otx2_nic *pfvf = ptp->nic; + struct ptp_req *req; + int rc; + + if (!ptp->nic) + return -ENODEV; + + mutex_lock(&pfvf->mbox.lock); + req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); + if (!req) { + mutex_unlock(&pfvf->mbox.lock); + return -ENOMEM; + } + req->op = PTP_OP_ADJTIME; + req->delta = delta; + rc = otx2_sync_mbox_msg(&ptp->nic->mbox); + mutex_unlock(&pfvf->mbox.lock); + + return rc; +} + static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp) { struct ptp_req *req; @@ -37,6 +96,49 @@ static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp) return rsp->clk; } +static int otx2_ptp_hw_gettime(struct ptp_clock_info *ptp_info, + struct timespec64 *ts) +{ + struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, + ptp_info); + u64 tstamp; + + tstamp = otx2_ptp_get_clock(ptp); + + *ts = ns_to_timespec64(tstamp); + return 0; +} + +static int otx2_ptp_hw_settime(struct ptp_clock_info *ptp_info, + const struct timespec64 *ts) +{ + struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, + ptp_info); + struct otx2_nic *pfvf = ptp->nic; + struct ptp_req *req; + u64 nsec; + int rc; + + if (!ptp->nic) + return -ENODEV; + + nsec = timespec64_to_ns(ts); + + mutex_lock(&pfvf->mbox.lock); + req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); + if (!req) { + mutex_unlock(&pfvf->mbox.lock); + return -ENOMEM; + } + + req->op = PTP_OP_SET_CLOCK; + req->clk = nsec; + rc = otx2_sync_mbox_msg(&ptp->nic->mbox); + mutex_unlock(&pfvf->mbox.lock); + + return rc; +} + static int otx2_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) { struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, @@ -124,16 +226,7 @@ static u64 ptp_tstmp_read(struct otx2_ptp *ptp) return rsp->clk; } -static void otx2_get_ptpclock(struct otx2_ptp *ptp, u64 *tstamp) -{ - struct otx2_nic *pfvf = ptp->nic; - - mutex_lock(&pfvf->mbox.lock); - *tstamp = timecounter_read(&ptp->time_counter); - mutex_unlock(&pfvf->mbox.lock); -} - -static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) +static int otx2_ptp_tc_adjtime(struct ptp_clock_info *ptp_info, s64 delta) { struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, ptp_info); @@ -146,32 +239,33 @@ static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) return 0; } -static int otx2_ptp_gettime(struct ptp_clock_info *ptp_info, - struct timespec64 *ts) +static int otx2_ptp_tc_gettime(struct ptp_clock_info *ptp_info, + struct timespec64 *ts) { struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, ptp_info); u64 tstamp; - otx2_get_ptpclock(ptp, &tstamp); + mutex_lock(&ptp->nic->mbox.lock); + tstamp = timecounter_read(&ptp->time_counter); + mutex_unlock(&ptp->nic->mbox.lock); *ts = ns_to_timespec64(tstamp); return 0; } -static int otx2_ptp_settime(struct ptp_clock_info *ptp_info, - const struct timespec64 *ts) +static int otx2_ptp_tc_settime(struct ptp_clock_info *ptp_info, + const struct timespec64 *ts) { struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, ptp_info); - struct otx2_nic *pfvf = ptp->nic; u64 nsec; nsec = timespec64_to_ns(ts); - mutex_lock(&pfvf->mbox.lock); + mutex_lock(&ptp->nic->mbox.lock); timecounter_init(&ptp->time_counter, &ptp->cycle_counter, nsec); - mutex_unlock(&pfvf->mbox.lock); + mutex_unlock(&ptp->nic->mbox.lock); return 0; } @@ -190,6 +284,12 @@ static int otx2_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin, return 0; } +static u64 otx2_ptp_hw_tstamp2time(const struct timecounter *time_counter, u64 tstamp) +{ + /* On HW which supports atomic updates, timecounter is not initialized */ + return tstamp; +} + static void otx2_ptp_extts_check(struct work_struct *work) { struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, @@ -204,7 +304,7 @@ static void otx2_ptp_extts_check(struct work_struct *work) if (tstmp != ptp->last_extts) { event.type = PTP_CLOCK_EXTTS; event.index = 0; - event.timestamp = timecounter_cyc2time(&ptp->time_counter, tstmp); + event.timestamp = ptp->ptp_tstamp2nsec(&ptp->time_counter, tstmp); ptp_clock_event(ptp->ptp_clock, &event); new_thresh = tstmp % 500000000; if (ptp->thresh != new_thresh) { @@ -229,7 +329,7 @@ static void otx2_sync_tstamp(struct work_struct *work) tstamp = otx2_ptp_get_clock(ptp); mutex_unlock(&pfvf->mbox.lock); - ptp->tstamp = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); + ptp->tstamp = ptp->ptp_tstamp2nsec(&ptp->time_counter, tstamp); ptp->base_ns = tstamp % NSEC_PER_SEC; schedule_delayed_work(&ptp->synctstamp_work, msecs_to_jiffies(250)); @@ -302,15 +402,6 @@ int otx2_ptp_init(struct otx2_nic *pfvf) ptp_ptr->nic = pfvf; - cc = &ptp_ptr->cycle_counter; - cc->read = ptp_cc_read; - cc->mask = CYCLECOUNTER_MASK(64); - cc->mult = 1; - cc->shift = 0; - - timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter, - ktime_to_ns(ktime_get_real())); - snprintf(ptp_ptr->extts_config.name, sizeof(ptp_ptr->extts_config.name), "TSTAMP"); ptp_ptr->extts_config.index = 0; ptp_ptr->extts_config.func = PTP_PF_NONE; @@ -324,13 +415,33 @@ int otx2_ptp_init(struct otx2_nic *pfvf) .pps = 0, .pin_config = &ptp_ptr->extts_config, .adjfine = otx2_ptp_adjfine, - .adjtime = otx2_ptp_adjtime, - .gettime64 = otx2_ptp_gettime, - .settime64 = otx2_ptp_settime, .enable = otx2_ptp_enable, .verify = otx2_ptp_verify_pin, }; + /* Check whether hardware supports atomic updates to timestamp */ + if (is_tstmp_atomic_update_supported(ptp_ptr)) { + ptp_ptr->ptp_info.adjtime = otx2_ptp_hw_adjtime; + ptp_ptr->ptp_info.gettime64 = otx2_ptp_hw_gettime; + ptp_ptr->ptp_info.settime64 = otx2_ptp_hw_settime; + + ptp_ptr->ptp_tstamp2nsec = otx2_ptp_hw_tstamp2time; + } else { + ptp_ptr->ptp_info.adjtime = otx2_ptp_tc_adjtime; + ptp_ptr->ptp_info.gettime64 = otx2_ptp_tc_gettime; + ptp_ptr->ptp_info.settime64 = otx2_ptp_tc_settime; + + cc = &ptp_ptr->cycle_counter; + cc->read = ptp_cc_read; + cc->mask = CYCLECOUNTER_MASK(64); + cc->mult = 1; + cc->shift = 0; + ptp_ptr->ptp_tstamp2nsec = timecounter_cyc2time; + + timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter, + ktime_to_ns(ktime_get_real())); + } + INIT_DELAYED_WORK(&ptp_ptr->extts_work, otx2_ptp_extts_check); ptp_ptr->ptp_clock = ptp_clock_register(&ptp_ptr->ptp_info, pfvf->dev); @@ -387,7 +498,7 @@ int otx2_ptp_tstamp2time(struct otx2_nic *pfvf, u64 tstamp, u64 *tsns) if (!pfvf->ptp) return -ENODEV; - *tsns = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); + *tsns = pfvf->ptp->ptp_tstamp2nsec(&pfvf->ptp->time_counter, tstamp); return 0; } |