From: <sukhdeeps@marvell.com>
To: <netdev@vger.kernel.org>
Cc: <andrew+netdev@lunn.ch>, <davem@davemloft.net>,
<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
<linux-kernel@vger.kernel.org>, <horms@kernel.org>,
<vadim.fedorenko@linux.dev>,
Sukhdeep Singh <sukhdeeps@marvell.com>
Subject: [PATCH net-next v5 11/12] net: atlantic: add AQC113 TX timestamp polling and PTP TX classification
Date: Wed, 10 Jun 2026 17:24:47 +0530 [thread overview]
Message-ID: <20260610115448.272-12-sukhdeeps@marvell.com> (raw)
In-Reply-To: <20260610115448.272-1-sukhdeeps@marvell.com>
From: Sukhdeep Singh <sukhdeeps@marvell.com>
aq_ring.h / aq_ring.c:
- Add ptp_ts_deadline field to aq_ring_s to track TX timestamp timeout.
- In aq_ring_tx_clean(): when hw_ring_tx_ptp_get_ts() returns 0 (HW not
yet written back the timestamp), clear buff->is_mapped and buff->pa
before breaking to prevent double dma_unmap on retry. When
ptp_ts_deadline expires, dequeue and drop the head of skb_ring to keep
it in lockstep with buff_ring, then clear request_ts and free the skb
via dev_kfree_skb_any() to unblock the ring.
aq_main.c:
- Add IPv6 PTP packet detection in aq_ndev_start_xmit() using
ipv6_hdr()->nexthdr for ETH_P_IPV6 frames, steering them through
aq_ptp_xmit() alongside the existing IPv4 path.
- Use PTP_EV_PORT/PTP_GEN_PORT constants instead of magic numbers 319/320.
- Remove duplicate aq_reapply_rxnfc_all_rules() and
aq_filters_vlans_update()
calls from aq_ndev_open() - now covered by aq_nic_start(), which also
ensures filters are restored correctly after PM resume.
aq_nic.c:
- Move aq_reapply_rxnfc_all_rules() and aq_filters_vlans_update() into
aq_nic_start() after hardware init, replacing the duplicate calls that
were removed from aq_ndev_open().
Signed-off-by: Sukhdeep Singh <sukhdeeps@marvell.com>
---
.../net/ethernet/aquantia/atlantic/aq_main.c | 30 ++++++++++---------
.../net/ethernet/aquantia/atlantic/aq_nic.c | 8 +++++
.../net/ethernet/aquantia/atlantic/aq_ptp.c | 12 ++++++++
.../net/ethernet/aquantia/atlantic/aq_ptp.h | 2 ++
.../net/ethernet/aquantia/atlantic/aq_ring.c | 26 +++++++++++++++-
.../net/ethernet/aquantia/atlantic/aq_ring.h | 1 +
6 files changed, 64 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
index 4ef4fe64b8ac..1da14786fe5c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
@@ -19,8 +19,10 @@
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/udp.h>
#include <net/pkt_cls.h>
+#include <linux/ptp_classify.h>
#include <net/pkt_sched.h>
#include <linux/filter.h>
@@ -68,14 +70,6 @@ int aq_ndev_open(struct net_device *ndev)
if (err < 0)
goto err_exit;
- err = aq_reapply_rxnfc_all_rules(aq_nic);
- if (err < 0)
- goto err_exit;
-
- err = aq_filters_vlans_update(aq_nic);
- if (err < 0)
- goto err_exit;
-
err = aq_nic_start(aq_nic);
if (err < 0) {
aq_nic_stop(aq_nic);
@@ -113,12 +107,20 @@ static netdev_tx_t aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *nd
* and hardware PTP design of the chip. Otherwise ptp stream
* will fail to sync
*/
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) ||
- unlikely((ip_hdr(skb)->version == 4) &&
- (ip_hdr(skb)->protocol == IPPROTO_UDP) &&
- ((udp_hdr(skb)->dest == htons(319)) ||
- (udp_hdr(skb)->dest == htons(320)))) ||
- unlikely(eth_hdr(skb)->h_proto == htons(ETH_P_1588)))
+ if (unlikely(skb->protocol == htons(ETH_P_IP) &&
+ ip_hdr(skb)->protocol == IPPROTO_UDP &&
+ (udp_hdr(skb)->dest == htons(PTP_EV_PORT) ||
+ udp_hdr(skb)->dest == htons(PTP_GEN_PORT))))
+ return aq_ptp_xmit(aq_nic, skb);
+
+ /* PTP over IPv6 does not use extension headers */
+ if (unlikely(skb->protocol == htons(ETH_P_IPV6) &&
+ ipv6_hdr(skb)->nexthdr == IPPROTO_UDP &&
+ (udp_hdr(skb)->dest == htons(PTP_EV_PORT) ||
+ udp_hdr(skb)->dest == htons(PTP_GEN_PORT))))
+ return aq_ptp_xmit(aq_nic, skb);
+
+ if (unlikely(eth_hdr(skb)->h_proto == htons(ETH_P_1588)))
return aq_ptp_xmit(aq_nic, skb);
}
#endif
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index ef9447810071..09c90c969fb1 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -496,6 +496,14 @@ int aq_nic_start(struct aq_nic_s *self)
goto err_exit;
}
+ err = aq_reapply_rxnfc_all_rules(self);
+ if (err < 0)
+ goto err_exit;
+
+ err = aq_filters_vlans_update(self);
+ if (err < 0)
+ goto err_exit;
+
err = aq_ptp_ring_start(self);
if (err < 0)
goto err_exit;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
index 7486a28d7ff8..16592e11b82c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
@@ -268,6 +268,18 @@ static void aq_ptp_tx_timeout_check(struct aq_ptp_s *aq_ptp)
}
}
+void aq_ptp_tx_skb_drop_head(struct aq_nic_s *aq_nic)
+{
+ struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
+ struct sk_buff *skb;
+
+ if (!aq_ptp)
+ return;
+ skb = aq_ptp_skb_get(&aq_ptp->skb_ring);
+ if (skb)
+ dev_kfree_skb_any(skb);
+}
+
/* aq_ptp_adjfine
* @ptp: the ptp clock structure
* @ppb: parts per billion adjustment from base
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
index 5e643ec7cc06..1658ef788de8 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
@@ -53,6 +53,7 @@ void aq_ptp_service_task(struct aq_nic_s *aq_nic);
void aq_ptp_tm_offset_set(struct aq_nic_s *aq_nic, unsigned int mbps);
void aq_ptp_clock_init(struct aq_nic_s *aq_nic);
+void aq_ptp_tx_skb_drop_head(struct aq_nic_s *aq_nic);
/* Traffic processing functions */
int aq_ptp_xmit(struct aq_nic_s *aq_nic, struct sk_buff *skb);
@@ -123,6 +124,7 @@ static inline void aq_ptp_service_task(struct aq_nic_s *aq_nic) {}
static inline void aq_ptp_tm_offset_set(struct aq_nic_s *aq_nic,
unsigned int mbps) {}
static inline void aq_ptp_clock_init(struct aq_nic_s *aq_nic) {}
+static inline void aq_ptp_tx_skb_drop_head(struct aq_nic_s *aq_nic) {}
static inline int aq_ptp_xmit(struct aq_nic_s *aq_nic, struct sk_buff *skb)
{
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index e270327e47fd..8ff07de2bd52 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -311,6 +311,30 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
if (likely(!buff->is_eop))
goto out;
+ if (unlikely(buff->request_ts) &&
+ self->aq_nic->aq_hw_ops->hw_ring_tx_ptp_get_ts) {
+ u64 ts = self->aq_nic->aq_hw_ops->hw_ring_tx_ptp_get_ts(self);
+
+ if (!ts) {
+ if (time_after(jiffies,
+ self->ptp_ts_deadline)) {
+ /* Timeout: drain skb_ring head to
+ * keep in sync with buff_ring
+ */
+ aq_ptp_tx_skb_drop_head(self->aq_nic);
+ buff->request_ts = 0;
+ dev_kfree_skb_any(buff->skb);
+ buff->skb = NULL;
+ goto out;
+ } else {
+ buff->is_mapped = 0;
+ buff->pa = 0U;
+ break;
+ }
+ }
+
+ aq_ptp_tx_hwtstamp(self->aq_nic, ts);
+ }
if (buff->skb) {
u64_stats_update_begin(&self->stats.tx.syncp);
++self->stats.tx.packets;
@@ -570,7 +594,7 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
self->hw_head);
if (unlikely(!is_rsc_completed) ||
- frag_cnt > MAX_SKB_FRAGS) {
+ frag_cnt > MAX_SKB_FRAGS) {
err = 0;
goto err_exit;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
index e578fe04d22c..a70b880ada67 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
@@ -154,6 +154,7 @@ struct aq_ring_s {
struct bpf_prog *xdp_prog;
enum atl_ring_type ring_type;
struct xdp_rxq_info xdp_rxq;
+ unsigned long ptp_ts_deadline;
};
struct aq_ring_param_s {
--
2.43.0
next prev parent reply other threads:[~2026-06-10 11:56 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-10 11:54 [PATCH net-next v5 0/12] net: atlantic: add PTP support for AQC113 (Antigua) sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 1/12] net: atlantic: correct L3L4 filter flow_type masking and IPv6 handling sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 2/12] net: atlantic: move active_ipv4/ipv6 bitmap updates after HW write sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 3/12] net: atlantic: decouple aq_set_data_fl3l4() from driver internals sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 4/12] net: atlantic: add AQC113 hardware register definitions and accessors sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 5/12] net: atlantic: add AQC113 filter data structures, firmware query and register dump sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 6/12] net: atlantic: fix AQC113 HW init: ART, L2 filter slot, MAC address sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 7/12] net: atlantic: implement AQC113 L2/L3/L4 RX filter ops sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 8/12] net: atlantic: add AQC113 PTP traffic class and TX path setup sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 9/12] net: atlantic: extend hw_ops and TX descriptor for AQC113 PTP sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 10/12] net: atlantic: add AQC113 PTP hardware ops in hw_atl2 sukhdeeps
2026-06-10 11:54 ` sukhdeeps [this message]
2026-06-10 11:54 ` [PATCH net-next v5 12/12] net: atlantic: add AQC113 PTP support in aq_ptp and driver core sukhdeeps
2026-06-15 22:50 ` [PATCH net-next v5 0/12] net: atlantic: add PTP support for AQC113 (Antigua) patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260610115448.272-12-sukhdeeps@marvell.com \
--to=sukhdeeps@marvell.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vadim.fedorenko@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.