]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: atlantic: extend hw_ops and TX descriptor for AQC113 PTP
authorSukhdeep Singh <sukhdeeps@marvell.com>
Wed, 10 Jun 2026 11:54:45 +0000 (17:24 +0530)
committerJakub Kicinski <kuba@kernel.org>
Mon, 15 Jun 2026 22:38:44 +0000 (15:38 -0700)
Extend the aq_hw_ops interface with new function pointers required for
PTP support on AQC113:
- enable_ptp: enable/disable PTP counter with clock selection
- hw_ring_tx_ptp_get_ts: read TX timestamp from descriptor writeback
- hw_tx_ptp_ring_init/hw_rx_ptp_ring_init: per-ring PTP initialization
- hw_get_clk_sel: query active TSG clock selection

Update existing hw_ops signatures to support AQC113 dual-clock
architecture:
- hw_gpio_pulse: add clk_sel and hightime parameters
- hw_extts_gpio_enable: add channel parameter

Add PTP-related hardware defines:
- AQ_HW_TXD_CTL_TS_EN/TS_TSG0 for TX descriptor timestamp control
- AQ2_HW_PTP_COUNTER_HZ for AQC113 TSG clock frequency
- AQ_HW_PTP_IRQS for PTP interrupt vector accounting
- PTP enable flags (L2/L4) and TSG clock selection constants

Add request_ts and clk_sel bitfields to aq_ring_buff_s for per-packet
TX timestamp request tracking.

Update hw_atl_b0.c (AQC107) implementations:
- Adapt gpio_pulse and extts_gpio_enable to new signatures
- Add TX descriptor timestamp bits for AQC113 when ANTIGUA chip
  feature is detected

Signed-off-by: Sukhdeep Singh <sukhdeeps@marvell.com>
Link: https://patch.msgid.link/20260610115448.272-10-sukhdeeps@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/aquantia/atlantic/aq_hw.h
drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c

index 57ea59026a2c150e7abf697f1f86c141a55ffb9c..0ba29b8f95ab28dab2735442abf3b57014880aba 100644 (file)
@@ -19,6 +19,9 @@
 #define AQ_HW_MAC_COUNTER_HZ   312500000ll
 #define AQ_HW_PHY_COUNTER_HZ   160000000ll
 
+#define AQ_HW_TXD_CTL_TS_EN       0x40000000U
+#define AQ_HW_TXD_CTL_TS_TSG0     0x80000000U
+
 enum aq_tc_mode {
        AQ_TC_MODE_INVALID = -1,
        AQ_TC_MODE_8TCS,
@@ -38,6 +41,8 @@ enum aq_tc_mode {
 
 #define AQ_FRAC_PER_NS 0x100000000LL
 
+#define AQ2_HW_PTP_COUNTER_HZ   156250000ll
+
 /* Used for rate to Mbps conversion */
 #define AQ_MBPS_DIVISOR         125000 /* 1000000 / 8 */
 
@@ -109,6 +114,7 @@ struct aq_stats_s {
 #define AQ_HW_IRQ_MSIX    3U
 
 #define AQ_HW_SERVICE_IRQS   1U
+#define AQ_HW_PTP_IRQS       1U
 
 #define AQ_HW_POWER_STATE_D0   0U
 #define AQ_HW_POWER_STATE_D3   3U
@@ -157,6 +163,15 @@ enum aq_priv_flags {
        AQ_HW_LOOPBACK_PHYEXT_SYS,
 };
 
+enum {
+       AQ_HW_PTP_DISABLE = 0,
+       AQ_HW_PTP_L2_ENABLE = BIT(1),
+       AQ_HW_PTP_L4_ENABLE = BIT(2),
+};
+
+#define ATL_TSG_CLOCK_SEL_0 0
+#define ATL_TSG_CLOCK_SEL_1 1
+
 #define AQ_HW_LOOPBACK_MASK    (BIT(AQ_HW_LOOPBACK_DMA_SYS) |\
                                 BIT(AQ_HW_LOOPBACK_PKT_SYS) |\
                                 BIT(AQ_HW_LOOPBACK_DMA_NET) |\
@@ -198,6 +213,7 @@ struct aq_hw_s {
        u32 rpc_tid;
        struct hw_atl_utils_fw_rpc rpc;
        s64 ptp_clk_offset;
+       s8 clk_select;
        u16 phy_id;
        void *priv;
 };
@@ -323,11 +339,15 @@ struct aq_hw_ops {
 
        int (*hw_ts_to_sys_clock)(struct aq_hw_s *self, u64 ts, u64 *time);
 
-       int (*hw_gpio_pulse)(struct aq_hw_s *self, u32 index, u64 start,
-                            u32 period);
+       int (*hw_gpio_pulse)(struct aq_hw_s *self, u32 index,
+                            u32 clk_sel, u64 start,
+                            u32 period, u32 hightime);
 
        int (*hw_extts_gpio_enable)(struct aq_hw_s *self, u32 index,
-                                   u32 enable);
+                                   u32 channel, int enable);
+
+       void (*enable_ptp)(struct aq_hw_s *self, unsigned int param,
+                          int enable);
 
        int (*hw_get_sync_ts)(struct aq_hw_s *self, u64 *ts);
 
@@ -337,6 +357,14 @@ struct aq_hw_ops {
        int (*extract_hwts)(struct aq_hw_s *self, u8 *p, unsigned int len,
                            u64 *timestamp);
 
+       u64 (*hw_ring_tx_ptp_get_ts)(struct aq_ring_s *ring);
+
+       int (*hw_tx_ptp_ring_init)(struct aq_hw_s *self,
+                                  struct aq_ring_s *aq_ring);
+       int (*hw_rx_ptp_ring_init)(struct aq_hw_s *self,
+                                  struct aq_ring_s *aq_ring);
+       u32 (*hw_get_clk_sel)(struct aq_hw_s *self);
+
        int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc);
 
        int (*hw_set_loopback)(struct aq_hw_s *self, u32 mode, bool enable);
index 9df8918216f6f7fff428679758973586e935a478..7486a28d7ff8f7f9ebab3809e18dd4711a0ad89c 100644 (file)
@@ -380,7 +380,7 @@ static int aq_ptp_hw_pin_conf(struct aq_nic_s *aq_nic, u32 pin_index, u64 start,
         */
        mutex_lock(&aq_nic->fwreq_mutex);
        aq_nic->aq_hw_ops->hw_gpio_pulse(aq_nic->aq_hw, pin_index,
-                                        start, (u32)period);
+                                        0, start, (u32)period, 0);
        mutex_unlock(&aq_nic->fwreq_mutex);
 
        return 0;
@@ -454,7 +454,7 @@ static void aq_ptp_extts_pin_ctrl(struct aq_ptp_s *aq_ptp)
 
        if (aq_nic->aq_hw_ops->hw_extts_gpio_enable)
                aq_nic->aq_hw_ops->hw_extts_gpio_enable(aq_nic->aq_hw, 0,
-                                                       enable);
+                                                       0, enable);
 }
 
 static int aq_ptp_extts_pin_configure(struct ptp_clock_info *ptp,
index d627ace850ff54201b760a079416e4d690e73184..e578fe04d22c9c5d07138ea444e6aa60fec8441c 100644 (file)
@@ -85,7 +85,9 @@ struct __packed aq_ring_buff_s {
                        u32 is_error:1;
                        u32 is_vlan:1;
                        u32 is_lro:1;
-                       u32 rsvd3:3;
+                       u32 request_ts:1;
+                       u32 clk_sel:1;
+                       u32 rsvd3:1;
                        u16 eop_index;
                        u16 rsvd4;
                };
index c7895bfb2ecf819f4e08121b1d986531a1a77b25..6c25ad264b19d5645d2c1a8d652d0a88a604bbf2 100644 (file)
@@ -736,6 +736,15 @@ int hw_atl_b0_hw_ring_tx_xmit(struct aq_hw_s *self, struct aq_ring_s *ring,
                                txd->ctl |= HW_ATL_B0_TXD_CTL_CMD_WB;
                                is_gso = false;
                                is_vlan = false;
+
+                               if (ATL_HW_IS_CHIP_FEATURE(self, ANTIGUA) &&
+                                   unlikely(buff->request_ts)) {
+                                       txd->ctl |= AQ_HW_TXD_CTL_TS_EN;
+                                       if (buff->clk_sel != ATL_TSG_CLOCK_SEL_1)
+                                               txd->ctl |= AQ_HW_TXD_CTL_TS_TSG0;
+                                       /* The only DD+TS is required */
+                                       txd->ctl &= ~HW_ATL_B0_TXD_CTL_CMD_WB;
+                               }
                        }
                }
                ring->sw_tail = aq_ring_next_dx(ring, ring->sw_tail);
@@ -1323,8 +1332,8 @@ static int hw_atl_b0_adj_clock_freq(struct aq_hw_s *self, s32 ppb)
        return self->aq_fw_ops->send_fw_request(self, &fwreq, size);
 }
 
-static int hw_atl_b0_gpio_pulse(struct aq_hw_s *self, u32 index,
-                               u64 start, u32 period)
+static int hw_atl_b0_gpio_pulse(struct aq_hw_s *self, u32 index, u32 clk_sel,
+                               u64 start, u32 period, u32 hightime)
 {
        struct hw_fw_request_iface fwreq;
        size_t size;
@@ -1342,7 +1351,7 @@ static int hw_atl_b0_gpio_pulse(struct aq_hw_s *self, u32 index,
 }
 
 static int hw_atl_b0_extts_gpio_enable(struct aq_hw_s *self, u32 index,
-                                      u32 enable)
+                                      u32 channel, int enable)
 {
        /* Enable/disable Sync1588 GPIO Timestamping */
        aq_phy_write_reg(self, MDIO_MMD_PCS, 0xc611, enable ? 0x71 : 0);