Skip to content

Commit 2b314aa

Browse files
committed
iavf: add initial framework for registering PTP clock
JIRA: https://issues.redhat.com/browse/RHEL-83568 commit d734223 Author: Jacob Keller <jacob.e.keller@intel.com> Date: Wed Nov 6 12:37:23 2024 -0500 iavf: add initial framework for registering PTP clock Add the iavf_ptp.c file and fill it in with a skeleton framework to allow registering the PTP clock device. Add implementation of helper functions to check if a PTP capability is supported and handle change in PTP capabilities. Enabling virtual clock would be possible, though it would probably perform poorly due to the lack of direct time access. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Sai Krishna <saikrishnag@marvell.com> Reviewed-by: Simon Horman <horms@kernel.org> Co-developed-by: Ahmed Zaki <ahmed.zaki@intel.com> Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Co-developed-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com> Signed-off-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
1 parent c565b6e commit 2b314aa

File tree

7 files changed

+155
-0
lines changed

7 files changed

+155
-0
lines changed

drivers/net/ethernet/intel/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ config I40EVF
264264
tristate "Intel(R) Ethernet Adaptive Virtual Function support"
265265
select IAVF
266266
depends on PCI_MSI
267+
depends on PTP_1588_CLOCK_OPTIONAL
267268
help
268269
This driver supports virtual functions for Intel XL710,
269270
X710, X722, XXV710, and all devices advertising support for

drivers/net/ethernet/intel/iavf/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ obj-$(CONFIG_IAVF) += iavf.o
1313

1414
iavf-y := iavf_main.o iavf_ethtool.o iavf_virtchnl.o iavf_fdir.o \
1515
iavf_adv_rss.o iavf_txrx.o iavf_common.o iavf_adminq.o
16+
17+
iavf-$(CONFIG_PTP_1588_CLOCK) += iavf_ptp.o

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/net/intel/libie/rx.h>
55

66
#include "iavf.h"
7+
#include "iavf_ptp.h"
78
#include "iavf_prototype.h"
89
/* All iavf tracepoints are defined by the include below, which must
910
* be included exactly once across the whole kernel with
@@ -2871,6 +2872,9 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
28712872
if (QOS_ALLOWED(adapter))
28722873
adapter->aq_required |= IAVF_FLAG_AQ_GET_QOS_CAPS;
28732874

2875+
/* Setup initial PTP configuration */
2876+
iavf_ptp_init(adapter);
2877+
28742878
iavf_schedule_finish_config(adapter);
28752879
return;
28762880

@@ -5645,6 +5649,8 @@ static void iavf_remove(struct pci_dev *pdev)
56455649
msleep(50);
56465650
}
56475651

5652+
iavf_ptp_release(adapter);
5653+
56485654
iavf_misc_irq_disable(adapter);
56495655
/* Shut down all the garbage mashers on the detention level */
56505656
cancel_work_sync(&adapter->reset_task);
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright(c) 2024 Intel Corporation. */
3+
4+
#include "iavf.h"
5+
#include "iavf_ptp.h"
6+
7+
/**
8+
* iavf_ptp_cap_supported - Check if a PTP capability is supported
9+
* @adapter: private adapter structure
10+
* @cap: the capability bitmask to check
11+
*
12+
* Return: true if every capability set in cap is also set in the enabled
13+
* capabilities reported by the PF, false otherwise.
14+
*/
15+
bool iavf_ptp_cap_supported(const struct iavf_adapter *adapter, u32 cap)
16+
{
17+
if (!IAVF_PTP_ALLOWED(adapter))
18+
return false;
19+
20+
/* Only return true if every bit in cap is set in hw_caps.caps */
21+
return (adapter->ptp.hw_caps.caps & cap) == cap;
22+
}
23+
24+
/**
25+
* iavf_ptp_register_clock - Register a new PTP for userspace
26+
* @adapter: private adapter structure
27+
*
28+
* Allocate and register a new PTP clock device if necessary.
29+
*
30+
* Return: 0 if success, error otherwise.
31+
*/
32+
static int iavf_ptp_register_clock(struct iavf_adapter *adapter)
33+
{
34+
struct ptp_clock_info *ptp_info = &adapter->ptp.info;
35+
struct device *dev = &adapter->pdev->dev;
36+
struct ptp_clock *clock;
37+
38+
snprintf(ptp_info->name, sizeof(ptp_info->name), "%s-%s-clk",
39+
KBUILD_MODNAME, dev_name(dev));
40+
ptp_info->owner = THIS_MODULE;
41+
42+
clock = ptp_clock_register(ptp_info, dev);
43+
if (IS_ERR(clock))
44+
return PTR_ERR(clock);
45+
46+
adapter->ptp.clock = clock;
47+
48+
dev_dbg(&adapter->pdev->dev, "PTP clock %s registered\n",
49+
adapter->ptp.info.name);
50+
51+
return 0;
52+
}
53+
54+
/**
55+
* iavf_ptp_init - Initialize PTP support if capability was negotiated
56+
* @adapter: private adapter structure
57+
*
58+
* Initialize PTP functionality, based on the capabilities that the PF has
59+
* enabled for this VF.
60+
*/
61+
void iavf_ptp_init(struct iavf_adapter *adapter)
62+
{
63+
int err;
64+
65+
if (!iavf_ptp_cap_supported(adapter, VIRTCHNL_1588_PTP_CAP_READ_PHC)) {
66+
pci_notice(adapter->pdev,
67+
"Device does not have PTP clock support\n");
68+
return;
69+
}
70+
71+
err = iavf_ptp_register_clock(adapter);
72+
if (err) {
73+
pci_err(adapter->pdev,
74+
"Failed to register PTP clock device (%p)\n",
75+
ERR_PTR(err));
76+
return;
77+
}
78+
79+
for (int i = 0; i < adapter->num_active_queues; i++) {
80+
struct iavf_ring *rx_ring = &adapter->rx_rings[i];
81+
82+
rx_ring->ptp = &adapter->ptp;
83+
}
84+
}
85+
86+
/**
87+
* iavf_ptp_release - Disable PTP support
88+
* @adapter: private adapter structure
89+
*
90+
* Release all PTP resources that were previously initialized.
91+
*/
92+
void iavf_ptp_release(struct iavf_adapter *adapter)
93+
{
94+
if (!adapter->ptp.clock)
95+
return;
96+
97+
pci_dbg(adapter->pdev, "removing PTP clock %s\n",
98+
adapter->ptp.info.name);
99+
ptp_clock_unregister(adapter->ptp.clock);
100+
adapter->ptp.clock = NULL;
101+
}
102+
103+
/**
104+
* iavf_ptp_process_caps - Handle change in PTP capabilities
105+
* @adapter: private adapter structure
106+
*
107+
* Handle any state changes necessary due to change in PTP capabilities, such
108+
* as after a device reset or change in configuration from the PF.
109+
*/
110+
void iavf_ptp_process_caps(struct iavf_adapter *adapter)
111+
{
112+
bool phc = iavf_ptp_cap_supported(adapter, VIRTCHNL_1588_PTP_CAP_READ_PHC);
113+
114+
/* Check if the device gained or lost necessary access to support the
115+
* PTP hardware clock. If so, driver must respond appropriately by
116+
* creating or destroying the PTP clock device.
117+
*/
118+
if (adapter->ptp.clock && !phc)
119+
iavf_ptp_release(adapter);
120+
else if (!adapter->ptp.clock && phc)
121+
iavf_ptp_init(adapter);
122+
}

drivers/net/ethernet/intel/iavf/iavf_ptp.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,18 @@
66

77
#include "iavf_types.h"
88

9+
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
10+
void iavf_ptp_init(struct iavf_adapter *adapter);
11+
void iavf_ptp_release(struct iavf_adapter *adapter);
12+
void iavf_ptp_process_caps(struct iavf_adapter *adapter);
13+
bool iavf_ptp_cap_supported(const struct iavf_adapter *adapter, u32 cap);
14+
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
15+
static inline void iavf_ptp_init(struct iavf_adapter *adapter) { }
16+
static inline void iavf_ptp_release(struct iavf_adapter *adapter) { }
17+
static inline void iavf_ptp_process_caps(struct iavf_adapter *adapter) { }
18+
static inline bool iavf_ptp_cap_supported(struct iavf_adapter *adapter, u32 cap)
19+
{
20+
return false;
21+
}
22+
#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
923
#endif /* _IAVF_PTP_H_ */

drivers/net/ethernet/intel/iavf/iavf_txrx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ struct iavf_ring {
278278
* for this ring.
279279
*/
280280

281+
struct iavf_ptp *ptp;
282+
281283
u32 rx_buf_len;
282284
struct net_shaper q_shaper;
283285
bool q_shaper_update;

drivers/net/ethernet/intel/iavf/iavf_virtchnl.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/net/intel/libie/rx.h>
55

66
#include "iavf.h"
7+
#include "iavf_ptp.h"
78
#include "iavf_prototype.h"
89

910
/**
@@ -359,6 +360,7 @@ void iavf_configure_queues(struct iavf_adapter *adapter)
359360
int pairs = adapter->num_active_queues;
360361
struct virtchnl_queue_pair_info *vqpi;
361362
u32 i, max_frame;
363+
u8 rx_flags = 0;
362364
size_t len;
363365

364366
max_frame = LIBIE_MAX_RX_FRM_LEN(adapter->rx_rings->pp->p.offset);
@@ -376,6 +378,9 @@ void iavf_configure_queues(struct iavf_adapter *adapter)
376378
if (!vqci)
377379
return;
378380

381+
if (iavf_ptp_cap_supported(adapter, VIRTCHNL_1588_PTP_CAP_RX_TSTAMP))
382+
rx_flags |= VIRTCHNL_PTP_RX_TSTAMP;
383+
379384
vqci->vsi_id = adapter->vsi_res->vsi_id;
380385
vqci->num_queue_pairs = pairs;
381386
vqpi = vqci->qpair;
@@ -398,6 +403,7 @@ void iavf_configure_queues(struct iavf_adapter *adapter)
398403
if (CRC_OFFLOAD_ALLOWED(adapter))
399404
vqpi->rxq.crc_disable = !!(adapter->netdev->features &
400405
NETIF_F_RXFCS);
406+
vqpi->rxq.flags = rx_flags;
401407
vqpi++;
402408
}
403409

@@ -2608,6 +2614,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
26082614

26092615
adapter->ptp.hw_caps = *(struct virtchnl_ptp_caps *)msg;
26102616

2617+
/* process any state change needed due to new capabilities */
2618+
iavf_ptp_process_caps(adapter);
26112619
break;
26122620
case VIRTCHNL_OP_ENABLE_QUEUES:
26132621
/* enable transmits */

0 commit comments

Comments
 (0)