Commit 8d5e12c5 authored by Milena Olech's avatar Milena Olech Committed by Tony Nguyen
Browse files

idpf: add initial PTP support



PTP feature is supported if the VIRTCHNL2_CAP_PTP is negotiated during the
capabilities recognition. Initial PTP support includes PTP initialization
and registration of the clock.

Reviewed-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Reviewed-by: default avatarVadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Reviewed-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Signed-off-by: default avatarMilena Olech <milena.olech@intel.com>
Tested-by: default avatarMina Almasry <almasrymina@google.com>
Tested-by: default avatarSamuel Salin <Samuel.salin@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 9525a12d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
config IDPF
	tristate "Intel(R) Infrastructure Data Path Function Support"
	depends on PCI_MSI
	depends on PTP_1588_CLOCK_OPTIONAL
	select DIMLIB
	select LIBETH
	help
+1 −0
Original line number Diff line number Diff line
@@ -17,3 +17,4 @@ idpf-y := \
	idpf_vf_dev.o

idpf-$(CONFIG_IDPF_SINGLEQ)	+= idpf_singleq_txrx.o
idpf-$(CONFIG_PTP_1588_CLOCK)	+= idpf_ptp.o
+3 −0
Original line number Diff line number Diff line
@@ -530,6 +530,7 @@ struct idpf_vc_xn_manager;
 * @vector_lock: Lock to protect vector distribution
 * @queue_lock: Lock to protect queue distribution
 * @vc_buf_lock: Lock to protect virtchnl buffer
 * @ptp: Storage for PTP-related data
 */
struct idpf_adapter {
	struct pci_dev *pdev;
@@ -587,6 +588,8 @@ struct idpf_adapter {
	struct mutex vector_lock;
	struct mutex queue_lock;
	struct mutex vc_buf_lock;

	struct idpf_ptp *ptp;
};

/**
+4 −0
Original line number Diff line number Diff line
@@ -168,6 +168,10 @@ static int idpf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
		goto err_free;
	}

	err = pci_enable_ptm(pdev, NULL);
	if (err)
		pci_dbg(pdev, "PCIe PTM is not supported by PCIe bus/controller\n");

	/* set up for high or low dma */
	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
	if (err) {
+90 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2024 Intel Corporation */

#include "idpf.h"
#include "idpf_ptp.h"

/**
 * idpf_ptp_create_clock - Create PTP clock device for userspace
 * @adapter: Driver specific private structure
 *
 * This function creates a new PTP clock device.
 *
 * Return: 0 on success, -errno otherwise.
 */
static int idpf_ptp_create_clock(const struct idpf_adapter *adapter)
{
	struct ptp_clock *clock;

	/* Attempt to register the clock before enabling the hardware. */
	clock = ptp_clock_register(&adapter->ptp->info,
				   &adapter->pdev->dev);
	if (IS_ERR(clock)) {
		pci_err(adapter->pdev, "PTP clock creation failed: %pe\n",
			clock);
		return PTR_ERR(clock);
	}

	adapter->ptp->clock = clock;

	return 0;
}

/**
 * idpf_ptp_init - Initialize PTP hardware clock support
 * @adapter: Driver specific private structure
 *
 * Set up the device for interacting with the PTP hardware clock for all
 * functions. Function will allocate and register a ptp_clock with the
 * PTP_1588_CLOCK infrastructure.
 *
 * Return: 0 on success, -errno otherwise.
 */
int idpf_ptp_init(struct idpf_adapter *adapter)
{
	int err;

	if (!idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_PTP)) {
		pci_dbg(adapter->pdev, "PTP capability is not detected\n");
		return -EOPNOTSUPP;
	}

	adapter->ptp = kzalloc(sizeof(*adapter->ptp), GFP_KERNEL);
	if (!adapter->ptp)
		return -ENOMEM;

	/* add a back pointer to adapter */
	adapter->ptp->adapter = adapter;

	err = idpf_ptp_create_clock(adapter);
	if (err)
		goto free_ptp;

	pci_dbg(adapter->pdev, "PTP init successful\n");

	return 0;

free_ptp:
	kfree(adapter->ptp);
	adapter->ptp = NULL;

	return err;
}

/**
 * idpf_ptp_release - Clear PTP hardware clock support
 * @adapter: Driver specific private structure
 */
void idpf_ptp_release(struct idpf_adapter *adapter)
{
	struct idpf_ptp *ptp = adapter->ptp;

	if (!ptp)
		return;

	if (ptp->clock)
		ptp_clock_unregister(ptp->clock);

	kfree(ptp);
	adapter->ptp = NULL;
}
Loading