Commit f3f409a9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ionic-ptp'



Shannon Nelson says:

====================
ionic: add PTP and hw clock support

This patchset adds support for accessing the DSC hardware clock and
for offloading PTP timestamping.

Tx packet timestamping happens through a separate Tx queue set up with
expanded completion descriptors that can report the timestamp.

Rx timestamping can happen either on all queues, or on a separate
timestamping queue when specific filtering is requested.  Again, the
timestamps are reported with the expanded completion descriptors.

The timestamping offload ability is advertised but not enabled until an
OS service asks for it.  At that time the driver's queues are reconfigured
to use the different completion descriptors and the private processing
queues as needed.

Reading the raw clock value comes through a new pair of values in the
device info registers in BAR0.  These high and low values are interpreted
with help from new clock mask, mult, and shift values in the device
identity information.

First we add the ability to detect new queue features, then the handling
of the new descriptor sizes.  After adding the new interface structures,
we start adding the support code, saving the advertising to the stack
for last.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c2bcb4cf afeefec6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,3 +6,4 @@ obj-$(CONFIG_IONIC) := ionic.o
ionic-y := ionic_main.o ionic_bus_pci.o ionic_devlink.o ionic_dev.o \
	   ionic_debugfs.o ionic_lif.o ionic_rx_filter.o ionic_ethtool.o \
	   ionic_txrx.o ionic_stats.o ionic_fw.o
ionic-$(CONFIG_PTP_1588_CLOCK) += ionic_phc.o
+6 −0
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@ struct ionic_lif;

#define DEVCMD_TIMEOUT  10

#define IONIC_PHC_UPDATE_NS	10000000000	    /* 10s in nanoseconds */
#define NORMAL_PPB		1000000000	    /* one billion parts per billion */
#define SCALED_PPM		(1000000ull << 16)  /* 2^16 million parts per 2^16 million */

struct ionic_vf {
	u16	 index;
	u8	 macaddr[6];
@@ -64,6 +68,8 @@ struct ionic_admin_ctx {
	union ionic_adminq_comp comp;
};

int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx, int err);
int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
int ionic_set_dma_mask(struct ionic *ionic);
+2 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ int ionic_dev_setup(struct ionic *ionic)
	idev->intr_status = bar->vaddr + IONIC_BAR0_INTR_STATUS_OFFSET;
	idev->intr_ctrl = bar->vaddr + IONIC_BAR0_INTR_CTRL_OFFSET;

	idev->hwstamp_regs = &idev->dev_info_regs->hwstamp;

	sig = ioread32(&idev->dev_info_regs->signature);
	if (sig != IONIC_DEV_INFO_SIGNATURE) {
		dev_err(dev, "Incompatible firmware signature %x", sig);
+3 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ static_assert(sizeof(struct ionic_dev_getattr_cmd) == 64);
static_assert(sizeof(struct ionic_dev_getattr_comp) == 16);
static_assert(sizeof(struct ionic_dev_setattr_cmd) == 64);
static_assert(sizeof(struct ionic_dev_setattr_comp) == 16);
static_assert(sizeof(struct ionic_lif_setphc_cmd) == 64);

/* Port commands */
static_assert(sizeof(struct ionic_port_identify_cmd) == 64);
@@ -135,6 +136,7 @@ struct ionic_devinfo {
struct ionic_dev {
	union ionic_dev_info_regs __iomem *dev_info_regs;
	union ionic_dev_cmd_regs __iomem *dev_cmd_regs;
	struct ionic_hwstamp_regs __iomem *hwstamp_regs;

	atomic_long_t last_check_time;
	unsigned long last_hb_time;
@@ -218,6 +220,7 @@ struct ionic_queue {
	unsigned int index;
	unsigned int num_descs;
	unsigned int max_sg_elems;
	u64 features;
	u64 dbell_count;
	u64 stop;
	u64 wake;
+93 −0
Original line number Diff line number Diff line
@@ -849,6 +849,98 @@ static int ionic_get_module_eeprom(struct net_device *netdev,
	return 0;
}

static int ionic_get_ts_info(struct net_device *netdev,
			     struct ethtool_ts_info *info)
{
	struct ionic_lif *lif = netdev_priv(netdev);
	struct ionic *ionic = lif->ionic;
	__le64 mask;

	if (!lif->phc || !lif->phc->ptp)
		return ethtool_op_get_ts_info(netdev, info);

	info->phc_index = ptp_clock_index(lif->phc->ptp);

	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
				SOF_TIMESTAMPING_RX_SOFTWARE |
				SOF_TIMESTAMPING_SOFTWARE |
				SOF_TIMESTAMPING_TX_HARDWARE |
				SOF_TIMESTAMPING_RX_HARDWARE |
				SOF_TIMESTAMPING_RAW_HARDWARE;

	/* tx modes */

	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
			 BIT(HWTSTAMP_TX_ON);

	mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_SYNC));
	if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_SYNC);

	mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_P2P));
	if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_P2P);

	/* rx filters */

	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
			   BIT(HWTSTAMP_FILTER_ALL);

	mask = cpu_to_le64(IONIC_PKT_CLS_NTP_ALL);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_NTP_ALL;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_SYNC);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_SYNC;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_DREQ);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_ALL);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_EVENT;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_SYNC);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_SYNC;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_DREQ);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_ALL);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_EVENT;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_SYNC);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_SYNC;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_DREQ);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_ALL);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_EVENT;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_SYNC);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_SYNC;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_DREQ);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;

	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_ALL);
	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_EVENT;

	return 0;
}

static int ionic_nway_reset(struct net_device *netdev)
{
	struct ionic_lif *lif = netdev_priv(netdev);
@@ -906,6 +998,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {
	.set_pauseparam		= ionic_set_pauseparam,
	.get_fecparam		= ionic_get_fecparam,
	.set_fecparam		= ionic_set_fecparam,
	.get_ts_info		= ionic_get_ts_info,
	.nway_reset		= ionic_nway_reset,
};

Loading