diff options
author | Madalin Bucur <madalin.bucur@freescale.com> | 2013-04-17 12:54:09 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-04-18 15:23:29 (GMT) |
commit | 077a980e55a7ceb6040ad39474d019114bbe82cb (patch) | |
tree | 2bca729e953862fce4462483eb7a65553a2bdf93 /drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c | |
parent | ac6cda36f5de41f698c7c5d3a4d1a5d8a4c7ce8b (diff) | |
download | linux-fsl-qoriq-077a980e55a7ceb6040ad39474d019114bbe82cb.tar.xz |
dpaa_eth: Add support for hardware timestamping
Add Linux conforming support for hardware timestamping.
Minor fixes and comments about the FSL_DPA_1588 code.
Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
Change-Id: I6f9cd77cbe157219cb77e87bb8cfd72bee037261
Reviewed-on: http://git.am.freescale.net:8181/1469
Reviewed-by: Radulescu Ruxandra Ioana-B05472 <ruxandra.radulescu@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c')
-rw-r--r-- | drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c index 9aec590..b50ccab 100644 --- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c @@ -249,6 +249,16 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, */ sgt = phys_to_virt(addr + dpa_fd_offset(fd)); +#ifdef CONFIG_FSL_DPA_TS + if (unlikely(priv->ts_tx_en && + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct skb_shared_hwtstamps shhwtstamps; + + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh); + skb_tstamp_tx(skb, &shhwtstamps); + } +#endif /* CONFIG_FSL_DPA_TS */ + /* sgt[0] is from lowmem, was dma_map_single()-ed */ dma_unmap_single(dpa_bp->dev, sgt[0].addr, sgt[0].length, dma_dir); @@ -269,7 +279,19 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, /* Free separately the pages that we allocated on Tx */ free_page((unsigned long)phys_to_virt(addr)); -} + } +#ifdef CONFIG_FSL_DPA_TS + else { + /* get the timestamp for non-SG frames */ + if (unlikely(priv->ts_tx_en && + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct skb_shared_hwtstamps shhwtstamps; + + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh); + skb_tstamp_tx(skb, &shhwtstamps); + } + } +#endif /* CONFIG_FSL_DPA_TS */ return skb; } @@ -295,6 +317,7 @@ static void __hot contig_fd_to_skb(const struct dpa_priv_s *priv, vaddr = phys_to_virt(addr); + /* do we need the timestamp for bad frames? */ #ifdef CONFIG_FSL_DPA_1588 if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl) dpa_ptp_store_rxstamp(priv->net_dev, skb, fd); @@ -304,6 +327,11 @@ static void __hot contig_fd_to_skb(const struct dpa_priv_s *priv, parse_results = (const t_FmPrsResult *)(vaddr + DPA_RX_PRIV_DATA_SIZE); _dpa_process_parse_results(parse_results, fd, skb, use_gro, ©_size); +#ifdef CONFIG_FSL_DPA_TS + if (priv->ts_rx_en) + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr); +#endif /* CONFIG_FSL_DPA_TS */ + tailptr = skb_put(skb, copy_size); /* Copy (at least) the headers in the linear portion */ @@ -364,6 +392,11 @@ static void __hot sg_fd_to_skb(const struct dpa_priv_s *priv, /* Inspect the parse results before anything else. */ _dpa_process_parse_results(parse_results, fd, skb, use_gro, ©_size); +#ifdef CONFIG_FSL_DPA_TS + if (priv->ts_rx_en) + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr); +#endif /* CONFIG_FSL_DPA_TS */ + /* * Iterate through the SGT entries and add the data buffers as * skb fragments @@ -708,6 +741,12 @@ int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl) fd.cmd |= FM_FD_CMD_UPD; #endif +#ifdef CONFIG_FSL_DPA_TS + if (unlikely(priv->ts_tx_en && + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) + fd.cmd |= FM_FD_CMD_UPD; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; +#endif /* CONFIG_FSL_DPA_TS */ /* * MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure |