aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cadence/macb_main.c
diff options
context:
space:
mode:
authorRafal Ozieblo <rafalo@cadence.com>2017-06-29 02:14:16 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-30 13:11:42 -0400
commitab91f0a9b5f4b9b5b341fdc0ed457121e69c20e1 (patch)
tree5bcc4aab1d4509c2fbe87e37859c3005edcf658b /drivers/net/ethernet/cadence/macb_main.c
parentb83f1527d098c04424832b0a59d75046e26bfff1 (diff)
net: macb: Add hardware PTP support
This patch is based on original Harini's patch and Andrei's patch, implemented in a separate file to ease the review/maintanance and integration with other platforms. This driver supports GEM-GXL: - Register ptp clock framework - Initialize PTP related registers - HW time stamp on the PTP Ethernet packets are received using the SO_TIMESTAMPING API. Time stamps are obtained from the dma buffer descriptors - add macb_ptp to compilation chain Signed-off-by: Rafal Ozieblo <rafalo@cadence.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cadence/macb_main.c')
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c90
1 files changed, 84 insertions, 6 deletions
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 2d43a7619f58..41e5711544fc 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -847,6 +847,12 @@ static void macb_tx_interrupt(struct macb_queue *queue)
847 847
848 /* First, update TX stats if needed */ 848 /* First, update TX stats if needed */
849 if (skb) { 849 if (skb) {
850 if (gem_ptp_do_txstamp(queue, skb, desc) == 0) {
851 /* skb now belongs to timestamp buffer
852 * and will be removed later
853 */
854 tx_skb->skb = NULL;
855 }
850 netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n", 856 netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
851 macb_tx_ring_wrap(bp, tail), 857 macb_tx_ring_wrap(bp, tail),
852 skb->data); 858 skb->data);
@@ -1013,6 +1019,8 @@ static int gem_rx(struct macb *bp, int budget)
1013 bp->dev->stats.rx_packets++; 1019 bp->dev->stats.rx_packets++;
1014 bp->dev->stats.rx_bytes += skb->len; 1020 bp->dev->stats.rx_bytes += skb->len;
1015 1021
1022 gem_ptp_do_rxstamp(bp, skb, desc);
1023
1016#if defined(DEBUG) && defined(VERBOSE_DEBUG) 1024#if defined(DEBUG) && defined(VERBOSE_DEBUG)
1017 netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n", 1025 netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
1018 skb->len, skb->csum); 1026 skb->len, skb->csum);
@@ -1334,7 +1342,6 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
1334 if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1342 if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
1335 queue_writel(queue, ISR, MACB_BIT(HRESP)); 1343 queue_writel(queue, ISR, MACB_BIT(HRESP));
1336 } 1344 }
1337
1338 status = queue_readl(queue, ISR); 1345 status = queue_readl(queue, ISR);
1339 } 1346 }
1340 1347
@@ -1664,7 +1671,6 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
1664 1671
1665 /* Make newly initialized descriptor visible to hardware */ 1672 /* Make newly initialized descriptor visible to hardware */
1666 wmb(); 1673 wmb();
1667
1668 skb_tx_timestamp(skb); 1674 skb_tx_timestamp(skb);
1669 1675
1670 macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); 1676 macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
@@ -2522,6 +2528,70 @@ static int macb_set_ringparam(struct net_device *netdev,
2522 return 0; 2528 return 0;
2523} 2529}
2524 2530
2531#ifdef CONFIG_MACB_USE_HWSTAMP
2532static unsigned int gem_get_tsu_rate(struct macb *bp)
2533{
2534 struct clk *tsu_clk;
2535 unsigned int tsu_rate;
2536
2537 tsu_clk = devm_clk_get(&bp->pdev->dev, "tsu_clk");
2538 if (!IS_ERR(tsu_clk))
2539 tsu_rate = clk_get_rate(tsu_clk);
2540 /* try pclk instead */
2541 else if (!IS_ERR(bp->pclk)) {
2542 tsu_clk = bp->pclk;
2543 tsu_rate = clk_get_rate(tsu_clk);
2544 } else
2545 return -ENOTSUPP;
2546 return tsu_rate;
2547}
2548
2549static s32 gem_get_ptp_max_adj(void)
2550{
2551 return 64000000;
2552}
2553
2554static int gem_get_ts_info(struct net_device *dev,
2555 struct ethtool_ts_info *info)
2556{
2557 struct macb *bp = netdev_priv(dev);
2558
2559 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) {
2560 ethtool_op_get_ts_info(dev, info);
2561 return 0;
2562 }
2563
2564 info->so_timestamping =
2565 SOF_TIMESTAMPING_TX_SOFTWARE |
2566 SOF_TIMESTAMPING_RX_SOFTWARE |
2567 SOF_TIMESTAMPING_SOFTWARE |
2568 SOF_TIMESTAMPING_TX_HARDWARE |
2569 SOF_TIMESTAMPING_RX_HARDWARE |
2570 SOF_TIMESTAMPING_RAW_HARDWARE;
2571 info->tx_types =
2572 (1 << HWTSTAMP_TX_ONESTEP_SYNC) |
2573 (1 << HWTSTAMP_TX_OFF) |
2574 (1 << HWTSTAMP_TX_ON);
2575 info->rx_filters =
2576 (1 << HWTSTAMP_FILTER_NONE) |
2577 (1 << HWTSTAMP_FILTER_ALL);
2578
2579 info->phc_index = bp->ptp_clock ? ptp_clock_index(bp->ptp_clock) : -1;
2580
2581 return 0;
2582}
2583
2584static struct macb_ptp_info gem_ptp_info = {
2585 .ptp_init = gem_ptp_init,
2586 .ptp_remove = gem_ptp_remove,
2587 .get_ptp_max_adj = gem_get_ptp_max_adj,
2588 .get_tsu_rate = gem_get_tsu_rate,
2589 .get_ts_info = gem_get_ts_info,
2590 .get_hwtst = gem_get_hwtst,
2591 .set_hwtst = gem_set_hwtst,
2592};
2593#endif
2594
2525static int macb_get_ts_info(struct net_device *netdev, 2595static int macb_get_ts_info(struct net_device *netdev,
2526 struct ethtool_ts_info *info) 2596 struct ethtool_ts_info *info)
2527{ 2597{
@@ -2655,12 +2725,16 @@ static void macb_configure_caps(struct macb *bp,
2655 dcfg = gem_readl(bp, DCFG2); 2725 dcfg = gem_readl(bp, DCFG2);
2656 if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0) 2726 if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
2657 bp->caps |= MACB_CAPS_FIFO_MODE; 2727 bp->caps |= MACB_CAPS_FIFO_MODE;
2658 if (IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) && gem_has_ptp(bp)) { 2728#ifdef CONFIG_MACB_USE_HWSTAMP
2729 if (gem_has_ptp(bp)) {
2659 if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5))) 2730 if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))
2660 pr_err("GEM doesn't support hardware ptp.\n"); 2731 pr_err("GEM doesn't support hardware ptp.\n");
2661 else 2732 else {
2662 bp->hw_dma_cap |= HW_DMA_CAP_PTP; 2733 bp->hw_dma_cap |= HW_DMA_CAP_PTP;
2734 bp->ptp_info = &gem_ptp_info;
2735 }
2663 } 2736 }
2737#endif
2664 } 2738 }
2665 2739
2666 dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps); 2740 dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps);
@@ -3266,7 +3340,9 @@ static const struct macb_config np4_config = {
3266}; 3340};
3267 3341
3268static const struct macb_config zynqmp_config = { 3342static const struct macb_config zynqmp_config = {
3269 .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO, 3343 .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
3344 MACB_CAPS_JUMBO |
3345 MACB_CAPS_GEM_HAS_PTP,
3270 .dma_burst_length = 16, 3346 .dma_burst_length = 16,
3271 .clk_init = macb_clk_init, 3347 .clk_init = macb_clk_init,
3272 .init = macb_init, 3348 .init = macb_init,
@@ -3300,7 +3376,9 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids);
3300#endif /* CONFIG_OF */ 3376#endif /* CONFIG_OF */
3301 3377
3302static const struct macb_config default_gem_config = { 3378static const struct macb_config default_gem_config = {
3303 .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO, 3379 .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
3380 MACB_CAPS_JUMBO |
3381 MACB_CAPS_GEM_HAS_PTP,
3304 .dma_burst_length = 16, 3382 .dma_burst_length = 16,
3305 .clk_init = macb_clk_init, 3383 .clk_init = macb_clk_init,
3306 .init = macb_init, 3384 .init = macb_init,