Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'PTP-support-for-macb-driver'



Rafal Ozieblo says:

====================
PTP support for macb driver

This patch series adds support for PTP synchronization protocol
in Cadence GEM driver based on PHC.

v2 changes:
* removed alarm's support
* removed external time stamp support
* removed PTP event interrupt handling
* removed ptp_hw_support flag
* removed all extra sanity checks
* removed unnecessary #ifdef
* fixed coding style and alligment issues
* renamed macb.c to macb_main.c

v3 changes:
* added checking NULL ptr from ptp_clock_register()
* fixed error codes return
* locals list in "upside down Christmas tree" style
* fixed some other issues from review

v4 changes:
* respin to the newest next-next (28 Jun 2017)
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b0791159 ab91f0a9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ Required properties:
	Required elements: 'pclk', 'hclk'
	Optional elements: 'tx_clk'
	Optional elements: 'rx_clk' applies to cdns,zynqmp-gem
	Optional elements: 'tsu_clk'
- clocks: Phandles to input clocks.

Optional properties for PHY child node:
+9 −1
Original line number Diff line number Diff line
@@ -29,7 +29,15 @@ config MACB
	  support for the MACB/GEM chip.

	  To compile this driver as a module, choose M here: the module
	  will be called macb.
	  will be macb.

config MACB_USE_HWSTAMP
	bool "Use IEEE 1588 hwstamp"
	depends on MACB
	default y
	imply PTP_1588_CLOCK
	---help---
	  Enable IEEE 1588 Precision Time Protocol (PTP) support for MACB.

config MACB_PCI
	tristate "Cadence PCI MACB/GEM support"
+5 −0
Original line number Diff line number Diff line
#
# Makefile for the Atmel network device drivers.
#
macb-y	:= macb_main.o

ifeq ($(CONFIG_MACB_USE_HWSTAMP),y)
macb-y	+= macb_ptp.o
endif

obj-$(CONFIG_MACB) += macb.o
obj-$(CONFIG_MACB_PCI) += macb_pci.o
+151 −7
Original line number Diff line number Diff line
@@ -11,6 +11,12 @@
#define _MACB_H

#include <linux/phy.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/net_tstamp.h>

#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) || defined(CONFIG_MACB_USE_HWSTAMP)
#define MACB_EXT_DESC
#endif

#define MACB_GREGS_NBR 16
#define MACB_GREGS_VERSION 2
@@ -86,6 +92,10 @@
#define GEM_SA3T		0x009C /* Specific3 Top */
#define GEM_SA4B		0x00A0 /* Specific4 Bottom */
#define GEM_SA4T		0x00A4 /* Specific4 Top */
#define GEM_EFTSH		0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */
#define GEM_EFRSH		0x00ec /* PTP Event Frame Received Seconds Register 47:32 */
#define GEM_PEFTSH		0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */
#define GEM_PEFRSH		0x00f4 /* PTP Peer Event Frame Received Seconds Register 47:32 */
#define GEM_OTX			0x0100 /* Octets transmitted */
#define GEM_OCTTXL		0x0100 /* Octets transmitted [31:0] */
#define GEM_OCTTXH		0x0104 /* Octets transmitted [47:32] */
@@ -155,6 +165,9 @@
#define GEM_DCFG6		0x0294 /* Design Config 6 */
#define GEM_DCFG7		0x0298 /* Design Config 7 */

#define GEM_TXBDCTRL	0x04cc /* TX Buffer Descriptor control register */
#define GEM_RXBDCTRL	0x04d0 /* RX Buffer Descriptor control register */

#define GEM_ISR(hw_q)		(0x0400 + ((hw_q) << 2))
#define GEM_TBQP(hw_q)		(0x0440 + ((hw_q) << 2))
#define GEM_TBQPH(hw_q)		(0x04C8)
@@ -191,6 +204,8 @@
#define MACB_TZQ_OFFSET		12 /* Transmit zero quantum pause frame */
#define MACB_TZQ_SIZE		1
#define MACB_SRTSM_OFFSET	15
#define MACB_OSSMODE_OFFSET 24 /* Enable One Step Synchro Mode */
#define MACB_OSSMODE_SIZE	1

/* Bitfields in NCFGR */
#define MACB_SPD_OFFSET		0 /* Speed */
@@ -269,6 +284,10 @@
#define GEM_RXBS_SIZE		8
#define GEM_DDRP_OFFSET		24 /* disc_when_no_ahb */
#define GEM_DDRP_SIZE		1
#define GEM_RXEXT_OFFSET	28 /* RX extended Buffer Descriptor mode */
#define GEM_RXEXT_SIZE		1
#define GEM_TXEXT_OFFSET	29 /* TX extended Buffer Descriptor mode */
#define GEM_TXEXT_SIZE		1
#define GEM_ADDR64_OFFSET	30 /* Address bus width - 64b or 32b */
#define GEM_ADDR64_SIZE		1

@@ -425,6 +444,11 @@
#define GEM_TX_PKT_BUFF_OFFSET			21
#define GEM_TX_PKT_BUFF_SIZE			1


/* Bitfields in DCFG5. */
#define GEM_TSU_OFFSET				8
#define GEM_TSU_SIZE				1

/* Bitfields in DCFG6. */
#define GEM_PBUF_LSO_OFFSET			27
#define GEM_PBUF_LSO_SIZE			1
@@ -439,6 +463,52 @@
#define GEM_NSINCR_OFFSET			0
#define GEM_NSINCR_SIZE				8

/* Bitfields in TSH */
#define GEM_TSH_OFFSET				0 /* TSU timer value (s). MSB [47:32] of seconds timer count */
#define GEM_TSH_SIZE				16

/* Bitfields in TSL */
#define GEM_TSL_OFFSET				0 /* TSU timer value (s). LSB [31:0] of seconds timer count */
#define GEM_TSL_SIZE				32

/* Bitfields in TN */
#define GEM_TN_OFFSET				0 /* TSU timer value (ns) */
#define GEM_TN_SIZE					30

/* Bitfields in TXBDCTRL */
#define GEM_TXTSMODE_OFFSET			4 /* TX Descriptor Timestamp Insertion mode */
#define GEM_TXTSMODE_SIZE			2

/* Bitfields in RXBDCTRL */
#define GEM_RXTSMODE_OFFSET			4 /* RX Descriptor Timestamp Insertion mode */
#define GEM_RXTSMODE_SIZE			2

/* Transmit DMA buffer descriptor Word 1 */
#define GEM_DMA_TXVALID_OFFSET		23 /* timestamp has been captured in the Buffer Descriptor */
#define GEM_DMA_TXVALID_SIZE		1

/* Receive DMA buffer descriptor Word 0 */
#define GEM_DMA_RXVALID_OFFSET		2 /* indicates a valid timestamp in the Buffer Descriptor */
#define GEM_DMA_RXVALID_SIZE		1

/* DMA buffer descriptor Word 2 (32 bit addressing) or Word 4 (64 bit addressing) */
#define GEM_DMA_SECL_OFFSET			30 /* Timestamp seconds[1:0]  */
#define GEM_DMA_SECL_SIZE			2
#define GEM_DMA_NSEC_OFFSET			0 /* Timestamp nanosecs [29:0] */
#define GEM_DMA_NSEC_SIZE			30

/* DMA buffer descriptor Word 3 (32 bit addressing) or Word 5 (64 bit addressing) */

/* New hardware supports 12 bit precision of timestamp in DMA buffer descriptor.
 * Old hardware supports only 6 bit precision but it is enough for PTP.
 * Less accuracy is used always instead of checking hardware version.
 */
#define GEM_DMA_SECH_OFFSET			0 /* Timestamp seconds[5:2] */
#define GEM_DMA_SECH_SIZE			4
#define GEM_DMA_SEC_WIDTH			(GEM_DMA_SECH_SIZE + GEM_DMA_SECL_SIZE)
#define GEM_DMA_SEC_TOP				(1 << GEM_DMA_SEC_WIDTH)
#define GEM_DMA_SEC_MASK			(GEM_DMA_SEC_TOP - 1)

/* Bitfields in ADJ */
#define GEM_ADDSUB_OFFSET			31
#define GEM_ADDSUB_SIZE				1
@@ -514,6 +584,8 @@
#define queue_readl(queue, reg)		(queue)->bp->macb_reg_readl((queue)->bp, (queue)->reg)
#define queue_writel(queue, reg, value)	(queue)->bp->macb_reg_writel((queue)->bp, (queue)->reg, (value))

#define PTP_TS_BUFFER_SIZE		128 /* must be power of 2 */

/* Conditional GEM/MACB macros.  These perform the operation to the correct
 * register dependent on whether the device is a GEM or a MACB.  For registers
 * and bitfields that are common across both devices, use macb_{read,write}l
@@ -546,16 +618,26 @@ struct macb_dma_desc {
	u32	ctrl;
};

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
enum macb_hw_dma_cap {
	HW_DMA_CAP_32B,
	HW_DMA_CAP_64B,
};
#ifdef MACB_EXT_DESC
#define HW_DMA_CAP_32B		0
#define HW_DMA_CAP_64B		(1 << 0)
#define HW_DMA_CAP_PTP		(1 << 1)
#define HW_DMA_CAP_64B_PTP	(HW_DMA_CAP_64B | HW_DMA_CAP_PTP)

struct macb_dma_desc_64 {
	u32 addrh;
	u32 resvd;
};

struct macb_dma_desc_ptp {
	u32	ts_1;
	u32	ts_2;
};

struct gem_tx_ts {
	struct sk_buff *skb;
	struct macb_dma_desc_ptp desc_ptp;
};
#endif

/* DMA descriptor bitfields */
@@ -871,6 +953,11 @@ struct macb_config {
	int	jumbo_max_len;
};

struct tsu_incr {
	u32 sub_ns;
	u32 ns;
};

struct macb_queue {
	struct macb		*bp;
	int			irq;
@@ -887,6 +974,12 @@ struct macb_queue {
	struct macb_tx_skb	*tx_skb;
	dma_addr_t		tx_ring_dma;
	struct work_struct	tx_error_task;

#ifdef CONFIG_MACB_USE_HWSTAMP
	struct work_struct	tx_ts_task;
	unsigned int		tx_ts_head, tx_ts_tail;
	struct gem_tx_ts	tx_timestamps[PTP_TS_BUFFER_SIZE];
#endif
};

struct macb {
@@ -955,11 +1048,62 @@ struct macb {
	u32			wol;

	struct macb_ptp_info	*ptp_info;	/* macb-ptp interface */
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	enum macb_hw_dma_cap hw_dma_cap;
#ifdef MACB_EXT_DESC
	uint8_t hw_dma_cap;
#endif
	spinlock_t tsu_clk_lock; /* gem tsu clock locking */
	unsigned int tsu_rate;
	struct ptp_clock *ptp_clock;
	struct ptp_clock_info ptp_clock_info;
	struct tsu_incr tsu_incr;
	struct hwtstamp_config tstamp_config;
};

#ifdef CONFIG_MACB_USE_HWSTAMP
#define GEM_TSEC_SIZE  (GEM_TSH_SIZE + GEM_TSL_SIZE)
#define TSU_SEC_MAX_VAL (((u64)1 << GEM_TSEC_SIZE) - 1)
#define TSU_NSEC_MAX_VAL ((1 << GEM_TN_SIZE) - 1)

enum macb_bd_control {
	TSTAMP_DISABLED,
	TSTAMP_FRAME_PTP_EVENT_ONLY,
	TSTAMP_ALL_PTP_FRAMES,
	TSTAMP_ALL_FRAMES,
};

void gem_ptp_init(struct net_device *ndev);
void gem_ptp_remove(struct net_device *ndev);
int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb, struct macb_dma_desc *des);
void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);
static inline int gem_ptp_do_txstamp(struct macb_queue *queue, struct sk_buff *skb, struct macb_dma_desc *desc)
{
	if (queue->bp->tstamp_config.tx_type == TSTAMP_DISABLED)
		return -ENOTSUPP;

	return gem_ptp_txstamp(queue, skb, desc);
}

static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc)
{
	if (bp->tstamp_config.rx_filter == TSTAMP_DISABLED)
		return;

	gem_ptp_rxstamp(bp, skb, desc);
}
int gem_get_hwtst(struct net_device *dev, struct ifreq *rq);
int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd);
#else
static inline void gem_ptp_init(struct net_device *ndev) { }
static inline void gem_ptp_remove(struct net_device *ndev) { }

static inline int gem_ptp_do_txstamp(struct macb_queue *queue, struct sk_buff *skb, struct macb_dma_desc *desc)
{
	return -1;
}

static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }
#endif

static inline bool macb_is_gem(struct macb *bp)
{
	return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
+170 −33
Original line number Diff line number Diff line
@@ -79,33 +79,84 @@
#define MACB_HALT_TIMEOUT	1230

/* DMA buffer descriptor might be different size
 * depends on hardware configuration.
 * depends on hardware configuration:
 *
 * 1. dma address width 32 bits:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *
 * 2. dma address width 64 bits:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *    word 3: upper 32 bit address of Data Buffer
 *    word 4: unused
 *
 * 3. dma address width 32 bits with hardware timestamping:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *    word 3: timestamp word 1
 *    word 4: timestamp word 2
 *
 * 4. dma address width 64 bits with hardware timestamping:
 *    word 1: 32 bit address of Data Buffer
 *    word 2: control
 *    word 3: upper 32 bit address of Data Buffer
 *    word 4: unused
 *    word 5: timestamp word 1
 *    word 6: timestamp word 2
 */
static unsigned int macb_dma_desc_get_size(struct macb *bp)
{
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	if (bp->hw_dma_cap == HW_DMA_CAP_64B)
		return sizeof(struct macb_dma_desc) + sizeof(struct macb_dma_desc_64);
#ifdef MACB_EXT_DESC
	unsigned int desc_size;

	switch (bp->hw_dma_cap) {
	case HW_DMA_CAP_64B:
		desc_size = sizeof(struct macb_dma_desc)
			+ sizeof(struct macb_dma_desc_64);
		break;
	case HW_DMA_CAP_PTP:
		desc_size = sizeof(struct macb_dma_desc)
			+ sizeof(struct macb_dma_desc_ptp);
		break;
	case HW_DMA_CAP_64B_PTP:
		desc_size = sizeof(struct macb_dma_desc)
			+ sizeof(struct macb_dma_desc_64)
			+ sizeof(struct macb_dma_desc_ptp);
		break;
	default:
		desc_size = sizeof(struct macb_dma_desc);
	}
	return desc_size;
#endif
	return sizeof(struct macb_dma_desc);
}

static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int idx)
static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int desc_idx)
{
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	/* Dma buffer descriptor is 4 words length (instead of 2 words)
	 * for 64b GEM.
	 */
	if (bp->hw_dma_cap == HW_DMA_CAP_64B)
		idx <<= 1;
#ifdef MACB_EXT_DESC
	switch (bp->hw_dma_cap) {
	case HW_DMA_CAP_64B:
	case HW_DMA_CAP_PTP:
		desc_idx <<= 1;
		break;
	case HW_DMA_CAP_64B_PTP:
		desc_idx *= 3;
		break;
	default:
		break;
	}
	return desc_idx;
#endif
	return idx;
	return desc_idx;
}

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
static struct macb_dma_desc_64 *macb_64b_desc(struct macb *bp, struct macb_dma_desc *desc)
{
	if (bp->hw_dma_cap & HW_DMA_CAP_64B)
		return (struct macb_dma_desc_64 *)((void *)desc + sizeof(struct macb_dma_desc));
	return NULL;
}
#endif

@@ -621,7 +672,7 @@ static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	struct macb_dma_desc_64 *desc_64;

	if (bp->hw_dma_cap == HW_DMA_CAP_64B) {
	if (bp->hw_dma_cap & HW_DMA_CAP_64B) {
		desc_64 = macb_64b_desc(bp, desc);
		desc_64->addrh = upper_32_bits(addr);
	}
@@ -635,7 +686,7 @@ static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	struct macb_dma_desc_64 *desc_64;

	if (bp->hw_dma_cap == HW_DMA_CAP_64B) {
	if (bp->hw_dma_cap & HW_DMA_CAP_64B) {
		desc_64 = macb_64b_desc(bp, desc);
		addr = ((u64)(desc_64->addrh) << 32);
	}
@@ -734,7 +785,7 @@ static void macb_tx_error_task(struct work_struct *work)
	/* Reinitialize the TX desc queue */
	queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	if (bp->hw_dma_cap == HW_DMA_CAP_64B)
	if (bp->hw_dma_cap & HW_DMA_CAP_64B)
		queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma));
#endif
	/* Make TX ring reflect state of hardware */
@@ -796,6 +847,12 @@ static void macb_tx_interrupt(struct macb_queue *queue)

			/* First, update TX stats if needed */
			if (skb) {
				if (gem_ptp_do_txstamp(queue, skb, desc) == 0) {
					/* skb now belongs to timestamp buffer
					 * and will be removed later
					 */
					tx_skb->skb = NULL;
				}
				netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
					    macb_tx_ring_wrap(bp, tail),
					    skb->data);
@@ -962,6 +1019,8 @@ static int gem_rx(struct macb *bp, int budget)
		bp->dev->stats.rx_packets++;
		bp->dev->stats.rx_bytes += skb->len;

		gem_ptp_do_rxstamp(bp, skb, desc);

#if defined(DEBUG) && defined(VERBOSE_DEBUG)
		netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
			    skb->len, skb->csum);
@@ -1283,7 +1342,6 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
			if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
				queue_writel(queue, ISR, MACB_BIT(HRESP));
		}

		status = queue_readl(queue, ISR);
	}

@@ -1613,7 +1671,6 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)

	/* Make newly initialized descriptor visible to hardware */
	wmb();

	skb_tx_timestamp(skb);

	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
@@ -1942,8 +1999,12 @@ static void macb_configure_dma(struct macb *bp)
			dmacfg &= ~GEM_BIT(TXCOEN);

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
		if (bp->hw_dma_cap == HW_DMA_CAP_64B)
		if (bp->hw_dma_cap & HW_DMA_CAP_64B)
			dmacfg |= GEM_BIT(ADDR64);
#endif
#ifdef CONFIG_MACB_USE_HWSTAMP
		if (bp->hw_dma_cap & HW_DMA_CAP_PTP)
			dmacfg |= GEM_BIT(RXEXT) | GEM_BIT(TXEXT);
#endif
		netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
			   dmacfg);
@@ -1992,13 +2053,13 @@ static void macb_init_hw(struct macb *bp)
	/* Initialize TX and RX buffers */
	macb_writel(bp, RBQP, lower_32_bits(bp->rx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	if (bp->hw_dma_cap == HW_DMA_CAP_64B)
	if (bp->hw_dma_cap & HW_DMA_CAP_64B)
		macb_writel(bp, RBQPH, upper_32_bits(bp->rx_ring_dma));
#endif
	for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
		queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
		if (bp->hw_dma_cap == HW_DMA_CAP_64B)
		if (bp->hw_dma_cap & HW_DMA_CAP_64B)
			queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma));
#endif

@@ -2467,6 +2528,70 @@ static int macb_set_ringparam(struct net_device *netdev,
	return 0;
}

#ifdef CONFIG_MACB_USE_HWSTAMP
static unsigned int gem_get_tsu_rate(struct macb *bp)
{
	struct clk *tsu_clk;
	unsigned int tsu_rate;

	tsu_clk = devm_clk_get(&bp->pdev->dev, "tsu_clk");
	if (!IS_ERR(tsu_clk))
		tsu_rate = clk_get_rate(tsu_clk);
	/* try pclk instead */
	else if (!IS_ERR(bp->pclk)) {
		tsu_clk = bp->pclk;
		tsu_rate = clk_get_rate(tsu_clk);
	} else
		return -ENOTSUPP;
	return tsu_rate;
}

static s32 gem_get_ptp_max_adj(void)
{
	return 64000000;
}

static int gem_get_ts_info(struct net_device *dev,
			   struct ethtool_ts_info *info)
{
	struct macb *bp = netdev_priv(dev);

	if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) {
		ethtool_op_get_ts_info(dev, info);
		return 0;
	}

	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;
	info->tx_types =
		(1 << HWTSTAMP_TX_ONESTEP_SYNC) |
		(1 << HWTSTAMP_TX_OFF) |
		(1 << HWTSTAMP_TX_ON);
	info->rx_filters =
		(1 << HWTSTAMP_FILTER_NONE) |
		(1 << HWTSTAMP_FILTER_ALL);

	info->phc_index = bp->ptp_clock ? ptp_clock_index(bp->ptp_clock) : -1;

	return 0;
}

static struct macb_ptp_info gem_ptp_info = {
	.ptp_init	 = gem_ptp_init,
	.ptp_remove	 = gem_ptp_remove,
	.get_ptp_max_adj = gem_get_ptp_max_adj,
	.get_tsu_rate	 = gem_get_tsu_rate,
	.get_ts_info	 = gem_get_ts_info,
	.get_hwtst	 = gem_get_hwtst,
	.set_hwtst	 = gem_set_hwtst,
};
#endif

static int macb_get_ts_info(struct net_device *netdev,
			    struct ethtool_ts_info *info)
{
@@ -2600,6 +2725,16 @@ static void macb_configure_caps(struct macb *bp,
		dcfg = gem_readl(bp, DCFG2);
		if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
			bp->caps |= MACB_CAPS_FIFO_MODE;
#ifdef CONFIG_MACB_USE_HWSTAMP
		if (gem_has_ptp(bp)) {
			if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))
				pr_err("GEM doesn't support hardware ptp.\n");
			else {
				bp->hw_dma_cap |= HW_DMA_CAP_PTP;
				bp->ptp_info = &gem_ptp_info;
			}
		}
#endif
	}

	dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps);
@@ -2737,7 +2872,7 @@ static int macb_init(struct platform_device *pdev)
			queue->IMR  = GEM_IMR(hw_q - 1);
			queue->TBQP = GEM_TBQP(hw_q - 1);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
			if (bp->hw_dma_cap == HW_DMA_CAP_64B)
			if (bp->hw_dma_cap & HW_DMA_CAP_64B)
				queue->TBQPH = GEM_TBQPH(hw_q - 1);
#endif
		} else {
@@ -2748,7 +2883,7 @@ static int macb_init(struct platform_device *pdev)
			queue->IMR  = MACB_IMR;
			queue->TBQP = MACB_TBQP;
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
			if (bp->hw_dma_cap == HW_DMA_CAP_64B)
			if (bp->hw_dma_cap & HW_DMA_CAP_64B)
				queue->TBQPH = MACB_TBQPH;
#endif
		}
@@ -3205,7 +3340,9 @@ static const struct macb_config np4_config = {
};

static const struct macb_config zynqmp_config = {
	.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO,
	.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
			MACB_CAPS_JUMBO |
			MACB_CAPS_GEM_HAS_PTP,
	.dma_burst_length = 16,
	.clk_init = macb_clk_init,
	.init = macb_init,
@@ -3239,7 +3376,9 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif /* CONFIG_OF */

static const struct macb_config default_gem_config = {
	.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO,
	.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
			MACB_CAPS_JUMBO |
			MACB_CAPS_GEM_HAS_PTP,
	.dma_burst_length = 16,
	.clk_init = macb_clk_init,
	.init = macb_init,
@@ -3328,19 +3467,17 @@ static int macb_probe(struct platform_device *pdev)
		bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
	device_init_wakeup(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) {
		dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
		bp->hw_dma_cap = HW_DMA_CAP_64B;
	} else
		bp->hw_dma_cap = HW_DMA_CAP_32B;
#endif

	spin_lock_init(&bp->lock);

	/* setup capabilities */
	macb_configure_caps(bp, macb_config);

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) {
		dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
		bp->hw_dma_cap |= HW_DMA_CAP_64B;
	}
#endif
	platform_set_drvdata(pdev, dev);

	dev->irq = platform_get_irq(pdev, 0);
Loading