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

Commit 891434b1 authored by Rayagond Kokatanur's avatar Rayagond Kokatanur Committed by David S. Miller
Browse files

stmmac: add IEEE PTPv1 and PTPv2 support.



This patch enhances the stmmac driver to support IEEE 1588-2002
PTP (Precision Time Protocol) version 1 and IEEE 1588-2008 PPT
version 2.

Precision Time Protocol(PTP),which enables precise synchronization
of clocks in measurement and control systems implemented with
technologies such as network communication,local computing,
& distributed objects.

Both PTPv1 and PTPv2 is selected at run-time using the HW capability
register.

The PTPv1 TimeStamp support can be used on chips that have the normal
descriptor structures and PTPv2 TimeStamp support can be used on chips
that have the Extended descriptors(DES4-5-6-7). All such sanity checks
are done and verified by using HW capability register.

V2: in this version the ethtool support has been included in this patch;
Koptions have been completely removed (previously added to select
PTP and PTPv2). PTPv1 and PTPv2 is now added in a single patch instead of
two patches.
get_timestamp() and get_systemtime() L/H have been combined into single APIs.

Signed-off-by: default avatarRayagond Kokatanur <rayagond@vayavyalabs.com>
Signed-off-by: default avatarGiuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cf32deec
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,4 +4,4 @@ stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
	      chain_mode.o dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o \
	      dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o \
	      mmc_core.o $(stmmac-y)
	      mmc_core.o stmmac_hwtstamp.o $(stmmac-y)
+32 −0
Original line number Diff line number Diff line
@@ -122,8 +122,40 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
	}
}

static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
{
	struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;

	if (priv->hwts_rx_en && !priv->extend_desc)
		/* NOTE: Device will overwrite des3 with timestamp value if
		 * 1588-2002 time stamping is enabled, hence reinitialize it
		 * to keep explicit chaining in the descriptor.
		 */
		p->des3 = (unsigned int)(priv->dma_rx_phy +
					 (((priv->dirty_rx) + 1) %
					 priv->dma_rx_size) *
					 sizeof(struct dma_desc));
}

static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
{
	struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;

	if (priv->hw->desc->get_tx_ls(p) && !priv->extend_desc)
		/* NOTE: Device will overwrite des3 with timestamp value if
		 * 1588-2002 time stamping is enabled, hence reinitialize it
		 * to keep explicit chaining in the descriptor.
		 */
		p->des3 = (unsigned int)(priv->dma_tx_phy +
					 (((priv->dirty_tx + 1) %
					 priv->dma_tx_size) *
					 sizeof(struct dma_desc)));
}

const struct stmmac_chain_mode_ops chain_mode_ops = {
	.init = stmmac_init_dma_chain,
	.is_jumbo_frm = stmmac_is_jumbo_frm,
	.jumbo_frm = stmmac_jumbo_frm,
	.refill_desc3 = stmmac_refill_desc3,
	.clean_desc3 = stmmac_clean_desc3,
};
+20 −2
Original line number Diff line number Diff line
@@ -339,6 +339,14 @@ struct stmmac_desc_ops {
			  struct dma_desc *p);
	void (*rx_extended_status) (void *data, struct stmmac_extra_stats *x,
				    struct dma_extended_desc *p);
	/* Set tx timestamp enable bit */
	void (*enable_tx_timestamp) (struct dma_desc *p);
	/* get tx timestamp status */
	int (*get_tx_timestamp_status) (struct dma_desc *p);
	/* get timestamp value */
	u64 (*get_timestamp) (void *desc, u32 ats);
	/* get rx timestamp status */
	int (*get_rx_timestamp_status) (void *desc, u32 ats);
};

struct stmmac_dma_ops {
@@ -398,6 +406,13 @@ struct stmmac_ops {
	void (*get_adv) (void __iomem *ioaddr, struct rgmii_adv *adv);
};

struct stmmac_hwtimestamp {
	void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
	void (*config_sub_second_increment) (void __iomem *ioaddr);
	int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec);
	int (*config_addend)(void __iomem *ioaddr, u32 addend);
};

struct mac_link {
	int port;
	int duplex;
@@ -412,9 +427,9 @@ struct mii_regs {
struct stmmac_ring_mode_ops {
	unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
	unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
	void (*refill_desc3) (int bfsize, struct dma_desc *p);
	void (*refill_desc3) (void *priv, struct dma_desc *p);
	void (*init_desc3) (struct dma_desc *p);
	void (*clean_desc3) (struct dma_desc *p);
	void (*clean_desc3) (void *priv, struct dma_desc *p);
	int (*set_16kib_bfsize) (int mtu);
};

@@ -423,6 +438,8 @@ struct stmmac_chain_mode_ops {
		      unsigned int extend_desc);
	unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
	unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
	void (*refill_desc3) (void *priv, struct dma_desc *p);
	void (*clean_desc3) (void *priv, struct dma_desc *p);
};

struct mac_device_info {
@@ -431,6 +448,7 @@ struct mac_device_info {
	const struct stmmac_dma_ops	*dma;
	const struct stmmac_ring_mode_ops	*ring;
	const struct stmmac_chain_mode_ops	*chain;
	const struct stmmac_hwtimestamp *ptp;
	struct mii_regs mii;	/* MII register Addresses */
	struct mac_link link;
	unsigned int synopsys_uid;
+47 −0
Original line number Diff line number Diff line
@@ -378,6 +378,49 @@ static int enh_desc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
		return p->des01.erx.frame_length;
}

static void enh_desc_enable_tx_timestamp(struct dma_desc *p)
{
	p->des01.etx.time_stamp_enable = 1;
}

static int enh_desc_get_tx_timestamp_status(struct dma_desc *p)
{
	return p->des01.etx.time_stamp_status;
}

static u64 enh_desc_get_timestamp(void *desc, u32 ats)
{
	u64 ns;

	if (ats) {
		struct dma_extended_desc *p = (struct dma_extended_desc *)desc;
		ns = p->des6;
		/* convert high/sec time stamp value to nanosecond */
		ns += p->des7 * 1000000000ULL;
	} else {
		struct dma_desc *p = (struct dma_desc *)desc;
		ns = p->des2;
		ns += p->des3 * 1000000000ULL;
	}

	return ns;
}

static int enh_desc_get_rx_timestamp_status(void *desc, u32 ats)
{
	if (ats) {
		struct dma_extended_desc *p = (struct dma_extended_desc *)desc;
		return p->basic.des01.erx.ipc_csum_error;
	} else {
		struct dma_desc *p = (struct dma_desc *)desc;
		if ((p->des2 == 0xffffffff) && (p->des3 == 0xffffffff))
			/* timestamp is corrupted, hence don't store it */
			return 0;
		else
			return 1;
	}
}

const struct stmmac_desc_ops enh_desc_ops = {
	.tx_status = enh_desc_get_tx_status,
	.rx_status = enh_desc_get_rx_status,
@@ -395,4 +438,8 @@ const struct stmmac_desc_ops enh_desc_ops = {
	.set_rx_owner = enh_desc_set_rx_owner,
	.get_rx_frame_len = enh_desc_get_rx_frame_len,
	.rx_extended_status = enh_desc_get_ext_status,
	.enable_tx_timestamp = enh_desc_enable_tx_timestamp,
	.get_tx_timestamp_status = enh_desc_get_tx_timestamp_status,
	.get_timestamp = enh_desc_get_timestamp,
	.get_rx_timestamp_status = enh_desc_get_rx_timestamp_status,
};
+37 −0
Original line number Diff line number Diff line
@@ -219,6 +219,39 @@ static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
		return p->des01.rx.frame_length;
}

static void ndesc_enable_tx_timestamp(struct dma_desc *p)
{
	p->des01.tx.time_stamp_enable = 1;
}

static int ndesc_get_tx_timestamp_status(struct dma_desc *p)
{
	return p->des01.tx.time_stamp_status;
}

static u64 ndesc_get_timestamp(void *desc, u32 ats)
{
	struct dma_desc *p = (struct dma_desc *)desc;
	u64 ns;

	ns = p->des2;
	/* convert high/sec time stamp value to nanosecond */
	ns += p->des3 * 1000000000ULL;

	return ns;
}

static int ndesc_get_rx_timestamp_status(void *desc, u32 ats)
{
	struct dma_desc *p = (struct dma_desc *)desc;

	if ((p->des2 == 0xffffffff) && (p->des3 == 0xffffffff))
		/* timestamp is corrupted, hence don't store it */
		return 0;
	else
		return 1;
}

const struct stmmac_desc_ops ndesc_ops = {
	.tx_status = ndesc_get_tx_status,
	.rx_status = ndesc_get_rx_status,
@@ -235,4 +268,8 @@ const struct stmmac_desc_ops ndesc_ops = {
	.set_tx_owner = ndesc_set_tx_owner,
	.set_rx_owner = ndesc_set_rx_owner,
	.get_rx_frame_len = ndesc_get_rx_frame_len,
	.enable_tx_timestamp = ndesc_enable_tx_timestamp,
	.get_tx_timestamp_status = ndesc_get_tx_timestamp_status,
	.get_timestamp = ndesc_get_timestamp,
	.get_rx_timestamp_status = ndesc_get_rx_timestamp_status,
};
Loading