diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-28 01:05:08 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-28 01:05:08 +0300 |
commit | 5ca26d6039a6b42341f7f5cc8d10d30ca1561a7b (patch) | |
tree | 58ade31b75cea2f1a32b1dd0d3576017f1dd2a88 /drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | |
parent | 982818426a0ffaf93b0621826ed39a84be3d7d62 (diff) | |
parent | 580f98cc33a260bb8c6a39ae2921b29586b84fdf (diff) | |
download | linux-5ca26d6039a6b42341f7f5cc8d10d30ca1561a7b.tar.xz |
Merge tag 'net-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
"Including fixes from wireless and netfilter.
The notable fixes here are the EEE fix which restores boot for many
embedded platforms (real and QEMU); WiFi warning suppression and the
ICE Kconfig cleanup.
Current release - regressions:
- phy: multiple fixes for EEE rework
- wifi: wext: warn about usage only once
- wifi: ath11k: allow system suspend to survive ath11k
Current release - new code bugs:
- mlx5: Fix memory leak in IPsec RoCE creation
- ibmvnic: assign XPS map to correct queue index
Previous releases - regressions:
- netfilter: ip6t_rpfilter: Fix regression with VRF interfaces
- netfilter: ctnetlink: make event listener tracking global
- nf_tables: allow to fetch set elements when table has an owner
- mlx5:
- fix skb leak while fifo resync and push
- fix possible ptp queue fifo use-after-free
Previous releases - always broken:
- sched: fix action bind logic
- ptp: vclock: use mutex to fix "sleep on atomic" bug if driver also
uses a mutex
- netfilter: conntrack: fix rmmod double-free race
- netfilter: xt_length: use skb len to match in length_mt6, avoid
issues with BIG TCP
Misc:
- ice: remove unnecessary CONFIG_ICE_GNSS
- mlx5e: remove hairpin write debugfs files
- sched: act_api: move TCA_EXT_WARN_MSG to the correct hierarchy"
* tag 'net-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (53 commits)
tcp: tcp_check_req() can be called from process context
net: phy: c45: fix network interface initialization failures on xtensa, arm:cubieboard
xen-netback: remove unused variables pending_idx and index
net/sched: act_api: move TCA_EXT_WARN_MSG to the correct hierarchy
net: dsa: ocelot_ext: remove unnecessary phylink.h include
net: mscc: ocelot: fix duplicate driver name error
net: dsa: felix: fix internal MDIO controller resource length
net: dsa: seville: ignore mscc-miim read errors from Lynx PCS
net/sched: act_sample: fix action bind logic
net/sched: act_mpls: fix action bind logic
net/sched: act_pedit: fix action bind logic
wifi: wext: warn about usage only once
wifi: mt76: usb: fix use-after-free in mt76u_free_rx_queue
qede: avoid uninitialized entries in coal_entry array
nfc: fix memory leak of se_io context in nfc_genl_se_io
ice: remove unnecessary CONFIG_ICE_GNSS
net/sched: cls_api: Move call to tcf_exts_miss_cookie_base_destroy()
ibmvnic: Assign XPS map to correct queue index
docs: net: fix inaccuracies in msg_zerocopy.rst
tools: net: add __pycache__ to gitignore
...
Diffstat (limited to 'drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c')
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c index ef10aef3cda0..7045fedfd73a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c @@ -10,6 +10,7 @@ #include <net/tso.h> #include <linux/bpf.h> #include <linux/bpf_trace.h> +#include <net/ip6_checksum.h> #include "otx2_reg.h" #include "otx2_common.h" @@ -699,7 +700,7 @@ static void otx2_sqe_add_ext(struct otx2_nic *pfvf, struct otx2_snd_queue *sq, static void otx2_sqe_add_mem(struct otx2_snd_queue *sq, int *offset, int alg, u64 iova, int ptp_offset, - u64 base_ns, int udp_csum) + u64 base_ns, bool udp_csum_crt) { struct nix_sqe_mem_s *mem; @@ -711,7 +712,7 @@ static void otx2_sqe_add_mem(struct otx2_snd_queue *sq, int *offset, if (ptp_offset) { mem->start_offset = ptp_offset; - mem->udp_csum_crt = udp_csum; + mem->udp_csum_crt = !!udp_csum_crt; mem->base_ns = base_ns; mem->step_type = 1; } @@ -986,10 +987,11 @@ static bool otx2_validate_network_transport(struct sk_buff *skb) return false; } -static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, int *udp_csum) +static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, bool *udp_csum_crt) { struct ethhdr *eth = (struct ethhdr *)(skb->data); u16 nix_offload_hlen = 0, inner_vhlen = 0; + bool udp_hdr_present = false, is_sync; u8 *data = skb->data, *msgtype; __be16 proto = eth->h_proto; int network_depth = 0; @@ -1029,45 +1031,81 @@ static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, int *udp_csum) if (!otx2_validate_network_transport(skb)) return false; - *udp_csum = 1; *offset = nix_offload_hlen + skb_transport_offset(skb) + sizeof(struct udphdr); + udp_hdr_present = true; + } msgtype = data + *offset; - /* Check PTP messageId is SYNC or not */ - return (*msgtype & 0xf) == 0; + is_sync = !(*msgtype & 0xf); + if (is_sync) + *udp_csum_crt = udp_hdr_present; + else + *offset = 0; + + return is_sync; } static void otx2_set_txtstamp(struct otx2_nic *pfvf, struct sk_buff *skb, struct otx2_snd_queue *sq, int *offset) { + struct ethhdr *eth = (struct ethhdr *)(skb->data); struct ptpv2_tstamp *origin_tstamp; - int ptp_offset = 0, udp_csum = 0; + bool udp_csum_crt = false; + unsigned int udphoff; struct timespec64 ts; + int ptp_offset = 0; + __wsum skb_csum; u64 iova; if (unlikely(!skb_shinfo(skb)->gso_size && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { - if (unlikely(pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC)) { - if (otx2_ptp_is_sync(skb, &ptp_offset, &udp_csum)) { - origin_tstamp = (struct ptpv2_tstamp *) - ((u8 *)skb->data + ptp_offset + - PTP_SYNC_SEC_OFFSET); - ts = ns_to_timespec64(pfvf->ptp->tstamp); - origin_tstamp->seconds_msb = htons((ts.tv_sec >> 32) & 0xffff); - origin_tstamp->seconds_lsb = htonl(ts.tv_sec & 0xffffffff); - origin_tstamp->nanoseconds = htonl(ts.tv_nsec); - /* Point to correction field in PTP packet */ - ptp_offset += 8; + if (unlikely(pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC && + otx2_ptp_is_sync(skb, &ptp_offset, &udp_csum_crt))) { + origin_tstamp = (struct ptpv2_tstamp *) + ((u8 *)skb->data + ptp_offset + + PTP_SYNC_SEC_OFFSET); + ts = ns_to_timespec64(pfvf->ptp->tstamp); + origin_tstamp->seconds_msb = htons((ts.tv_sec >> 32) & 0xffff); + origin_tstamp->seconds_lsb = htonl(ts.tv_sec & 0xffffffff); + origin_tstamp->nanoseconds = htonl(ts.tv_nsec); + /* Point to correction field in PTP packet */ + ptp_offset += 8; + + /* When user disables hw checksum, stack calculates the csum, + * but it does not cover ptp timestamp which is added later. + * Recalculate the checksum manually considering the timestamp. + */ + if (udp_csum_crt) { + struct udphdr *uh = udp_hdr(skb); + + if (skb->ip_summed != CHECKSUM_PARTIAL && uh->check != 0) { + udphoff = skb_transport_offset(skb); + uh->check = 0; + skb_csum = skb_checksum(skb, udphoff, skb->len - udphoff, + 0); + if (ntohs(eth->h_proto) == ETH_P_IPV6) + uh->check = csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + skb->len - udphoff, + ipv6_hdr(skb)->nexthdr, + skb_csum); + else + uh->check = csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, + skb->len - udphoff, + IPPROTO_UDP, + skb_csum); + } } } else { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; } iova = sq->timestamps->iova + (sq->head * sizeof(u64)); otx2_sqe_add_mem(sq, offset, NIX_SENDMEMALG_E_SETTSTMP, iova, - ptp_offset, pfvf->ptp->base_ns, udp_csum); + ptp_offset, pfvf->ptp->base_ns, udp_csum_crt); } else { skb_tx_timestamp(skb); } |