Re: [RFC PATCH 2/3] net: macb: Add support for 1588 for Zynq Ultrascale+ MPSoC
From: Harini Katakam
Date: Mon Sep 21 2015 - 13:49:40 EST
On Fri, Sep 11, 2015 at 1:27 PM, Harini Katakam
<harini.katakam@xxxxxxxxxx> wrote:
> Cadence GEM in Zynq Ultrascale+ MPSoC supports 1588 and provides a
> 102 bit time counter with 48 bits for seconds, 30 bits for nsecs and
> 24 bits for sub-nsecs. The timestamp is made available to the SW through
> registers as well as (more precisely) through upper two words in
> an extended BD.
>
> This patch does the following:
> - Adds MACB_CAPS_TSU in zynqmp_config.
> - Registers to ptp clock framework (after checking for timestamp support in
> IP and capability in config).
> - TX BD and RX BD control registers are written to populate timestamp in
> extended BD words.
> - Timer initialization is done by writing time of day to the timer counter.
> - ns increment register is programmed as NS_PER_SEC/TSU_CLK.
> For a 24 bit subns precision, the subns increment equals
> remainder of (NS_PER_SEC/TSU_CLK) * (2^24).
> TSU (Time stamp unit) clock is obtained by the driver from devicetree.
> - HW time stamp capabilities are advertised via ethtool and macb ioctl is
> updated accordingly.
> - For all PTP event frames, nanoseconds and the lower 5 bits of seconds are
> obtained from the BD. This offers a precise timestamp. The upper bits
> (which dont vary between consecutive packets) are obtained from the
> TX/RX PTP event/PEER registers. The timestamp obtained thus is updated
> in skb for upper layers to access.
> - The drivers register functions with ptp to perform time and frequency
> adjustment.
> - Time adjustment is done by writing to the 1558_ADJUST register.
> The controller will read the delta in this register and update the timer
> counter register. Alternatively, for large time offset adjustments,
> the driver reads the secs and nsecs counter values, adds/subtracts the
> delta and updates the timer counter. In order to be as precise as possible,
> nsecs counter is read again if secs has incremented during the counter read.
> - Frequency adjustment is not directly supported by this IP.
> addend is the initial value ns increment and similarly addendesub.
> The ppb (parts per billion) provided is used as
> ns_incr = addend +/- (ppb/rate).
> Similarly the remainder of the above is used to populate subns increment.
> In case the ppb requested is negative AND subns adjustment greater than
> the addendsub, ns_incr is reduced by 1 and subns_incr is adjusted in
> positive accordingly.
>
> Signed-off-by: Harini Katakam <harinik@xxxxxxxxxx>:
> ---
> drivers/net/ethernet/cadence/macb.c | 372 ++++++++++++++++++++++++++++++++++-
> drivers/net/ethernet/cadence/macb.h | 64 ++++++
> 2 files changed, 428 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
> index bb2932c..b531008 100644
> --- a/drivers/net/ethernet/cadence/macb.c
> +++ b/drivers/net/ethernet/cadence/macb.c
> @@ -30,6 +30,8 @@
> #include <linux/of_device.h>
> #include <linux/of_mdio.h>
> #include <linux/of_net.h>
> +#include <linux/net_tstamp.h>
> +#include <linux/ptp_clock_kernel.h>
>
> #include "macb.h"
>
> @@ -56,6 +58,9 @@
>
> #define GEM_MTU_MIN_SIZE 68
>
> +#define GEM_TX_PTPHDR_OFFSET 42
> +#define GEM_RX_PTPHDR_OFFSET 28
> +
> /*
> * Graceful stop timeouts in us. We should allow up to
> * 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)
> @@ -165,6 +170,9 @@ static void macb_set_hwaddr(struct macb *bp)
> top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4)));
> macb_or_gem_writel(bp, SA1T, top);
>
> + gem_writel(bp, RXPTPUNI, bottom);
> + gem_writel(bp, TXPTPUNI, bottom);
> +
> /* Clear unused address register sets */
> macb_or_gem_writel(bp, SA2B, 0);
> macb_or_gem_writel(bp, SA2T, 0);
> @@ -653,6 +661,40 @@ static void macb_tx_error_task(struct work_struct *work)
> spin_unlock_irqrestore(&bp->lock, flags);
> }
>
> +static inline void macb_handle_txtstamp(struct macb *bp, struct sk_buff *skb,
> + struct macb_dma_desc *desc)
> +{
> + u32 ts_s, ts_ns;
> + u8 msg_type;
> +
> + skb_copy_from_linear_data_offset(skb, GEM_TX_PTPHDR_OFFSET,
> + &msg_type, 1);
> +
> + /* Bit[32:6] of TS secs from register
> + * Bit[5:0] of TS secs from BD
> + * TS nano secs is available in BD
> + */
> + if (msg_type & 0x2) {
> + /* PTP Peer Event Frame packets */
> + ts_s = (gem_readl(bp, 1588PEERTXSEC) & GEM_SEC_MASK) |
> + ((desc->tsl >> GEM_TSL_SEC_RS) |
> + (desc->tsh << GEM_TSH_SEC_LS));
> + ts_ns = desc->tsl & GEM_TSL_NSEC_MASK;
> + } else {
> + /* PTP Event Frame packets */
> + ts_s = (gem_readl(bp, 1588TXSEC) & GEM_SEC_MASK) |
> + ((desc->tsl >> GEM_TSL_SEC_RS) |
> + (desc->tsh << GEM_TSH_SEC_LS));
> + ts_ns = desc->tsl & GEM_TSL_NSEC_MASK;
> + }
> +
> + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
> +
> + memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
> + shhwtstamps->hwtstamp = ns_to_ktime((ts_s * NS_PER_SEC) + ts_ns);
> + skb_tstamp_tx(skb, skb_hwtstamps(skb));
> +}
> +
> static void macb_tx_interrupt(struct macb_queue *queue)
> {
> unsigned int tail;
> @@ -703,6 +745,10 @@ static void macb_tx_interrupt(struct macb_queue *queue)
> bp->stats.tx_bytes += skb->len;
> }
>
> +#ifdef CONFIG_MACB_EXT_BD
> + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
> + macb_handle_txtstamp(bp, skb, desc);
> +#endif
> /* Now we can safely release resources */
> macb_tx_unmap(bp, tx_skb);
>
> @@ -796,6 +842,39 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
> */
> }
>
> +static inline void macb_handle_rxtstamp(struct macb *bp, struct sk_buff *skb,
> + struct macb_dma_desc *desc)
> +{
> + u8 msg_type;
> + u32 ts_ns, ts_s;
> +
> + skb_copy_from_linear_data_offset(skb, GEM_RX_PTPHDR_OFFSET,
> + &msg_type, 1);
> +
> + /* Bit[32:6] of TS secs from register
> + * Bit[5:0] of TS secs from BD
> + * TS nano secs is available in BD
> + */
> + if (msg_type & 0x2) {
> + /* PTP Peer Event Frame packets */
> + ts_s = (gem_readl(bp, 1588PEERRXSEC) & GEM_SEC_MASK) |
> + ((desc->tsl >> GEM_TSL_SEC_RS) |
> + (desc->tsh << GEM_TSH_SEC_LS));
> + ts_ns = desc->tsl & GEM_TSL_NSEC_MASK;
> + } else {
> + /* PTP Event Frame packets */
> + ts_s = (gem_readl(bp, 1588RXSEC) & GEM_SEC_MASK) |
> + ((desc->tsl >> GEM_TSL_SEC_RS) |
> + (desc->tsh << GEM_TSH_SEC_LS));
> + ts_ns = desc->tsl & GEM_TSL_NSEC_MASK;
> + }
> +
> + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
> +
> + memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
> + shhwtstamps->hwtstamp = ns_to_ktime((ts_s * NS_PER_SEC) + ts_ns);
> +}
> +
> static int gem_rx(struct macb *bp, int budget)
> {
> unsigned int len;
> @@ -847,6 +926,12 @@ static int gem_rx(struct macb *bp, int budget)
> bp->rx_buffer_size, DMA_FROM_DEVICE);
>
> skb->protocol = eth_type_trans(skb, bp->dev);
> +
> +#ifdef CONFIG_MACB_EXT_BD
> + if (addr & GEM_RX_TS_MASK)
> + macb_handle_rxtstamp(bp, skb, desc);
> +#endif
> +
> skb_checksum_none_assert(skb);
> if (bp->dev->features & NETIF_F_RXCSUM &&
> !(bp->dev->flags & IFF_PROMISC) &&
> @@ -1636,6 +1721,193 @@ static u32 macb_dbw(struct macb *bp)
> }
> }
>
> +static inline void macb_ptp_read(struct macb *bp, struct timespec *ts)
> +{
> + ts->tv_sec = gem_readl(bp, 1588S);
> + ts->tv_nsec = gem_readl(bp, 1588NS);
> +
> + if (ts->tv_sec < gem_readl(bp, 1588S))
> + ts->tv_nsec = gem_readl(bp, 1588NS);
> +}
> +
> +static inline void macb_ptp_write(struct macb *bp, const struct timespec *ts)
> +{
> + gem_writel(bp, 1588S, ts->tv_sec);
> + gem_writel(bp, 1588NS, ts->tv_nsec);
> +}
> +
> +static int macb_ptp_enable(struct ptp_clock_info *ptp,
> + struct ptp_clock_request *rq, int on)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +static void macb_ptp_close(struct macb *bp)
> +{
> + /* Clear the time counters */
> + gem_writel(bp, 1588NS, 0);
> + gem_writel(bp, 1588S, 0);
> + gem_writel(bp, 1588ADJ, 0);
> + gem_writel(bp, 1588INCR, 0);
> +
> + ptp_clock_unregister(bp->ptp_clock);
> +}
> +
> +static int macb_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
> +{
> + struct macb *bp = container_of(ptp, struct macb, ptp_caps);
> +
> + macb_ptp_read(bp, ts);
> +
> + return 0;
> +}
> +
> +static int macb_ptp_settime(struct ptp_clock_info *ptp,
> + const struct timespec *ts)
> +{
> + struct macb *bp = container_of(ptp, struct macb, ptp_caps);
> +
> + macb_ptp_write(bp, ts);
> +
> + return 0;
> +}
> +
> +static int macb_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
> +{
> + struct macb *bp = container_of(ptp, struct macb, ptp_caps);
> + struct timespec now, then = ns_to_timespec(delta);
> + u32 adj, sign = 0;
> +
> + if (delta < 0) {
> + delta = -delta;
> + sign = 1;
> + }
> +
> + if (delta > 0x3FFFFFFF) {
> + macb_ptp_read(bp, &now);
> +
> + if (sign)
> + now = timespec_sub(now, then);
> + else
> + now = timespec_add(now, then);
> +
> + macb_ptp_write(bp, (const struct timespec *)&now);
> + } else {
> + adj = delta;
> + if (sign)
> + adj |= GEM_BIT(ADDSUB);
> +
> + gem_writel(bp, 1588ADJ, adj);
> + }
> +
> + return 0;
> +}
> +
> +static int macb_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
> +{
> + struct macb *bp = container_of(ptp, struct macb, ptp_caps);
> + unsigned long rate = bp->tsu_clk;
> + u64 adjsub;
> + u32 addend, diff;
> + u32 diffsub, addendsub;
> + bool neg_adj = false;
> + u32 subnsreg, rem;
> +
> + if (ppb < 0) {
> + neg_adj = true;
> + ppb = -ppb;
> + }
> +
> + addend = bp->ns_incr;
> + addendsub = bp->subns_incr;
> +
> + diff = div_u64_rem(ppb, rate, &rem);
> + addend = neg_adj ? addend - diff : addend + diff;
> +
> + if (rem) {
> + adjsub = rem;
> + /* Multiple by 2^24 as subns field is 24 bits */
> + adjsub = adjsub << 24;
> +
> + diffsub = div_u64(adjsub, rate);
> + } else {
> + diffsub = 0;
> + }
> +
> + if (neg_adj && (diffsub > addendsub)) {
> + addend -= 1;
> + rem = (NS_PER_SEC - rem);
> + neg_adj = false;
> +
> + adjsub = rem;
> + adjsub = adjsub << 24;
> + diffsub = div_u64(adjsub, rate);
> + }
> +
> + addendsub = neg_adj ? addendsub - diffsub : addendsub + diffsub;
> + /* RegBit[15:0] = Subns[23:8]; RegBit[31:24] = Subns[7:0] */
> + subnsreg = ((addendsub & GEM_SUBNSINCL_MASK) << GEM_SUBNSINCL_SHFT) |
> + ((addendsub & GEM_SUBNSINCH_MASK) >> GEM_SUBNSINCH_SHFT);
> +
> + gem_writel(bp, 1588INCRSUBNS, subnsreg);
> + gem_writel(bp, 1588INCR, GEM_BF(NSINCR, addend));
> +
> + return 0;
> +}
> +
> +static void macb_ptp_init(struct macb *bp)
> +{
> + struct timespec now;
> + unsigned long rate;
> + u32 subnsreg, rem = 0;
> + u64 adj;
> +
> + bp->ptp_caps.owner = THIS_MODULE;
> + bp->ptp_caps.max_adj = 250000000;
> + bp->ptp_caps.n_alarm = 0;
> + bp->ptp_caps.n_ext_ts = 0;
> + bp->ptp_caps.n_per_out = 0;
> + bp->ptp_caps.pps = 0;
> + bp->ptp_caps.adjtime = macb_ptp_adjtime;
> + bp->ptp_caps.gettime = macb_ptp_gettime;
> + bp->ptp_caps.settime = macb_ptp_settime;
> + bp->ptp_caps.enable = macb_ptp_enable;
> + bp->ptp_caps.adjfreq = macb_ptp_adjfreq;
> +
> + rate = bp->tsu_clk;
> +
> + getnstimeofday(&now);
> + gem_writel(bp, 1588SMSB, 0);
> + macb_ptp_write(bp, (const struct timespec *)&now);
> +
> + bp->ns_incr = div_u64_rem(NS_PER_SEC, rate, &rem);
> + if (rem) {
> + adj = rem;
> + /* Multiply by 2^24 as subns register is 24 bits */
> + adj = adj << 24;
> +
> + bp->subns_incr = div_u64(adj, rate);
> + } else {
> + bp->subns_incr = 0;
> + }
> +
> + /* RegBit[15:0] = Subns[23:8]; RegBit[31:24] = Subns[7:0] */
> + subnsreg = ((bp->subns_incr & GEM_SUBNSINCL_MASK)
> + << GEM_SUBNSINCL_SHFT) |
> + ((bp->subns_incr & GEM_SUBNSINCH_MASK)
> + >> GEM_SUBNSINCH_SHFT);
> + gem_writel(bp, 1588INCRSUBNS, subnsreg);
> + gem_writel(bp, 1588INCR, bp->ns_incr);
> + gem_writel(bp, 1588ADJ, 0);
> +
> + bp->ptp_clock = ptp_clock_register(&bp->ptp_caps, &bp->pdev->dev);
> + if (IS_ERR(bp->ptp_clock)) {
> + bp->ptp_clock = NULL;
> + netdev_err(bp->dev, "ptp_clock_register failed\n");
> + }
> + bp->phc_index = ptp_clock_index(bp->ptp_clock);
> +}
> +
> /*
> * Configure the receive DMA engine
> * - use the correct receive buffer size
> @@ -1686,6 +1958,7 @@ static void macb_init_hw(struct macb *bp)
> macb_set_hwaddr(bp);
>
> config = macb_mdc_clk_div(bp);
> + config |= macb_readl(bp, NCFGR) & (3 << 21);
> config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */
> config |= MACB_BIT(PAE); /* PAuse Enable */
> config |= MACB_BIT(DRFCS); /* Discard Rx FCS */
> @@ -1709,6 +1982,18 @@ static void macb_init_hw(struct macb *bp)
> if (bp->caps & MACB_CAPS_JUMBO)
> bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK;
>
> + gem_writel(bp, TXBDCNTRL,
> + (gem_readl(bp, TXBDCNTRL) & ~(GEM_TXBDCNTRL_MODE_ALL)) |
> + GEM_TXBDCNTRL_MODE_PTP_EVNT);
> + gem_writel(bp, RXBDCNTRL,
> + (gem_readl(bp, RXBDCNTRL) & ~(GEM_RXBDCNTRL_MODE_ALL)) |
> + GEM_RXBDCNTRL_MODE_PTP_EVNT);
> +
> + if ((gem_readl(bp, DCFG5) & GEM_BIT(TSU)) &&
> + (bp->caps & MACB_CAPS_TSU)) {
> + macb_ptp_init(bp);
> + }
> +
> macb_configure_dma(bp);
>
> /* Initialize TX and RX buffers */
> @@ -1724,7 +2009,8 @@ static void macb_init_hw(struct macb *bp)
> }
>
> /* Enable TX and RX */
> - macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
> + macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE) |
> + MACB_BIT(PTPUNI));
> }
>
> /*
> @@ -1903,6 +2189,7 @@ static int macb_close(struct net_device *dev)
>
> spin_lock_irqsave(&bp->lock, flags);
> macb_reset_hw(bp);
> + macb_ptp_close(bp);
> netif_carrier_off(dev);
> spin_unlock_irqrestore(&bp->lock, flags);
>
> @@ -2130,6 +2417,23 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
> }
> }
>
> +static int macb_get_ts_info(struct net_device *dev,
> + struct ethtool_ts_info *info)
> +{
> + struct macb *bp = netdev_priv(dev);
> +
> + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
> + SOF_TIMESTAMPING_RX_HARDWARE |
> + SOF_TIMESTAMPING_RAW_HARDWARE;
> + info->phc_index = bp->phc_index;
> + info->tx_types = (1 << HWTSTAMP_TX_OFF) |
> + (1 << HWTSTAMP_TX_ON);
> + info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
> + (1 << HWTSTAMP_FILTER_ALL);
> +
> + return 0;
> +}
> +
> static const struct ethtool_ops macb_ethtool_ops = {
> .get_settings = macb_get_settings,
> .set_settings = macb_set_settings,
> @@ -2145,24 +2449,74 @@ static const struct ethtool_ops gem_ethtool_ops = {
> .get_regs_len = macb_get_regs_len,
> .get_regs = macb_get_regs,
> .get_link = ethtool_op_get_link,
> - .get_ts_info = ethtool_op_get_ts_info,
> + .get_ts_info = macb_get_ts_info,
> .get_ethtool_stats = gem_get_ethtool_stats,
> .get_strings = gem_get_ethtool_strings,
> .get_sset_count = gem_get_sset_count,
> };
>
> +static int macb_hwtstamp_ioctl(struct net_device *dev,
> + struct ifreq *ifr, int cmd)
> +{
> + struct hwtstamp_config config;
> +
> + if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
> + return -EFAULT;
> +
> + /* reserved for future extensions */
> + if (config.flags)
> + return -EINVAL;
> +
> + if ((config.tx_type != HWTSTAMP_TX_OFF) &&
> + (config.tx_type != HWTSTAMP_TX_ON))
> + return -ERANGE;
> +
> + switch (config.rx_filter) {
> + case HWTSTAMP_FILTER_NONE:
> + break;
> + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
> + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
> + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
> + case HWTSTAMP_FILTER_ALL:
> + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
> + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
> + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
> + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
> + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
> + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
> + case HWTSTAMP_FILTER_PTP_V2_EVENT:
> + case HWTSTAMP_FILTER_PTP_V2_SYNC:
> + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
> + config.rx_filter = HWTSTAMP_FILTER_ALL;
> + break;
> + default:
> + return -ERANGE;
> + }
> +
> + config.tx_type = HWTSTAMP_TX_ON;
> +
> + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
> + -EFAULT : 0;
> +}
> +
> static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
> {
> struct macb *bp = netdev_priv(dev);
> struct phy_device *phydev = bp->phy_dev;
>
> - if (!netif_running(dev))
> - return -EINVAL;
> + switch (cmd) {
> + case SIOCSHWTSTAMP:
> + return macb_hwtstamp_ioctl(dev, rq, cmd);
>
> - if (!phydev)
> - return -ENODEV;
> + default:
> + if (!netif_running(dev))
> + return -EINVAL;
> +
> + if (!phydev)
> + return -ENODEV;
>
> - return phy_mii_ioctl(phydev, rq, cmd);
> + return phy_mii_ioctl(phydev, rq, cmd);
> + }
> }
>
> static int macb_set_features(struct net_device *netdev,
> @@ -2778,7 +3132,7 @@ static const struct macb_config emac_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_TSU,
> .dma_burst_length = 16,
> .clk_init = macb_clk_init,
> .init = macb_init,
> @@ -2885,6 +3239,8 @@ static int macb_probe(struct platform_device *pdev)
> if (macb_config)
> bp->jumbo_max_len = macb_config->jumbo_max_len;
>
> + of_property_read_u32(pdev->dev.of_node, "tsu-clk", &bp->tsu_clk);
> +
> spin_lock_init(&bp->lock);
>
> /* setup capabilities */
> diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
> index 58c9870..16edad4 100644
> --- a/drivers/net/ethernet/cadence/macb.h
> +++ b/drivers/net/ethernet/cadence/macb.h
> @@ -82,6 +82,8 @@
> #define GEM_SA3T 0x009C /* Specific3 Top */
> #define GEM_SA4B 0x00A0 /* Specific4 Bottom */
> #define GEM_SA4T 0x00A4 /* Specific4 Top */
> +#define GEM_RXPTPUNI 0x00D4 /* PTP RX Unicast address */
> +#define GEM_TXPTPUNI 0x00D8 /* PTP TX Unicast address */
> #define GEM_OTX 0x0100 /* Octets transmitted */
> #define GEM_OCTTXL 0x0100 /* Octets transmitted [31:0] */
> #define GEM_OCTTXH 0x0104 /* Octets transmitted [47:32] */
> @@ -129,6 +131,20 @@
> #define GEM_RXIPCCNT 0x01a8 /* IP header Checksum Error Counter */
> #define GEM_RXTCPCCNT 0x01ac /* TCP Checksum Error Counter */
> #define GEM_RXUDPCCNT 0x01b0 /* UDP Checksum Error Counter */
> +#define GEM_1588INCRSUBNS 0x01BC /* 1588 timer sub nsec increment */
> +#define GEM_1588SMSB 0x01C0 /* 1588 timer seconds register[47:32] */
> +#define GEM_1588S 0x01D0 /* 1588 timer seconds register[31:0] */
> +#define GEM_1588NS 0x01D4 /* 1588 timer nano seconds register */
> +#define GEM_1588ADJ 0x01D8 /* 1588 timer adjust register */
> +#define GEM_1588INCR 0x01DC /* 1588 timer increment register */
> +#define GEM_1588TXSEC 0x01E0 /* PTP event TX timestamp secs */
> +#define GEM_1588TXNSEC 0x01E4 /* PTP event TX timestamp nsecs */
> +#define GEM_1588RXSEC 0x01E8 /* PTP event RX timestamp secs */
> +#define GEM_1588RXNSEC 0x01EC /* PTP event RX timestamp nsecs */
> +#define GEM_1588PEERTXSEC 0x01F0 /* PTP peer event TX timestamp secs */
> +#define GEM_1588PEERTXNSEC 0x01F4 /* PTP peer event TX timestamp nsecs */
> +#define GEM_1588PEERRXSEC 0x01F8 /* PTP peer event RX timestamp secs */
> +#define GEM_1588PEERRXNSEC 0x01FC /* PTP peer event RX timestamp nsecs */
> #define GEM_DCFG1 0x0280 /* Design Config 1 */
> #define GEM_DCFG2 0x0284 /* Design Config 2 */
> #define GEM_DCFG3 0x0288 /* Design Config 3 */
> @@ -136,6 +152,8 @@
> #define GEM_DCFG5 0x0290 /* Design Config 5 */
> #define GEM_DCFG6 0x0294 /* Design Config 6 */
> #define GEM_DCFG7 0x0298 /* Design Config 7 */
> +#define GEM_TXBDCNTRL 0x04CC /* TX descriptor control */
> +#define GEM_RXBDCNTRL 0x04D0 /* RX descriptor control */
>
> #define GEM_ISR(hw_q) (0x0400 + ((hw_q) << 2))
> #define GEM_TBQP(hw_q) (0x0440 + ((hw_q) << 2))
> @@ -171,6 +189,8 @@
> #define MACB_NCR_TPF_SIZE 1
> #define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */
> #define MACB_TZQ_SIZE 1
> +#define MACB_PTPUNI_OFFSET 20
> +#define MACB_PTPUNI_SIZE 1
>
> /* Bitfields in NCFGR */
> #define MACB_SPD_OFFSET 0 /* Speed */
> @@ -374,6 +394,34 @@
> #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 1588INCRSUBNS */
> +#define GEM_SUBNSINCL_SHFT 24
> +#define GEM_SUBNSINCL_MASK 0xFF
> +#define GEM_SUBNSINCH_SHFT 8
> +#define GEM_SUBNSINCH_MASK 0xFFFF00
> +
> +/* Bitfields in 1588INCRNS */
> +#define GEM_NSINCR_OFFSET 0
> +#define GEM_NSINCR_SIZE 8
> +
> +/* Bitfields in 1588ADJ */
> +#define GEM_ADDSUB_OFFSET 31
> +#define GEM_ADDSUB_SIZE 1
> +
> +/* Bitfields in TXBDCNTRL */
> +#define GEM_TXBDCNTRL_MODE_ALL 0x00000030
> +#define GEM_TXBDCNTRL_MODE_PTP_EVNT 0x00000010
> +#define GEM_TXBDCNTRL_MODE_PTP_ALL 0x00000020
> +
> +/* Bitfields in RXBDCNTRL */
> +#define GEM_RXBDCNTRL_MODE_ALL 0x00000030
> +#define GEM_RXBDCNTRL_MODE_PTP_EVNT 0x00000010
> +#define GEM_RXBDCNTRL_MODE_PTP_ALL 0x00000020
> +
> /* Constants for CLK */
> #define MACB_CLK_DIV8 0
> #define MACB_CLK_DIV16 1
> @@ -404,6 +452,8 @@
> #define MACB_CAPS_SG_DISABLED 0x40000000
> #define MACB_CAPS_MACB_IS_GEM 0x80000000
> #define MACB_CAPS_JUMBO 0x00000010
> +#define MACB_CAPS_TSU 0x00000020
> +#define NS_PER_SEC 1000000000ULL
>
> /* Bit manipulation macros */
> #define MACB_BIT(name) \
> @@ -550,6 +600,11 @@ struct macb_dma_desc {
> #define GEM_TX_FRMLEN_OFFSET 0
> #define GEM_TX_FRMLEN_SIZE 14
>
> +#define GEM_SEC_MASK 0xFFFFFFC0
> +#define GEM_TSL_SEC_RS 30
> +#define GEM_TSH_SEC_LS 2
> +#define GEM_TSL_NSEC_MASK 0x3FFFFFFF
> +
> /* Buffer descriptor constants */
> #define GEM_RX_CSUM_NONE 0
> #define GEM_RX_CSUM_IP_ONLY 1
> @@ -559,6 +614,8 @@ struct macb_dma_desc {
> /* limit RX checksum offload to TCP and UDP packets */
> #define GEM_RX_CSUM_CHECKED_MASK 2
>
> +#define GEM_RX_TS_MASK 0x4
> +
> /* struct macb_tx_skb - data about an skb which is being transmitted
> * @skb: skb currently being transmitted, only set for the last buffer
> * of the frame
> @@ -843,6 +900,13 @@ struct macb {
>
> unsigned int rx_frm_len_mask;
> unsigned int jumbo_max_len;
> + unsigned int tsu_clk;
> + struct ptp_clock *ptp_clock;
> + struct ptp_clock_info ptp_caps;
> + int rx_hwtstamp_filter;
> + int phc_index;
> + unsigned int ns_incr;
> + unsigned int subns_incr;
> };
>
> static inline bool macb_is_gem(struct macb *bp)
> --
> 1.7.9.5
>
Ping
Thanks.
Regards,
Hairni
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/