summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
diff options
context:
space:
mode:
authorMadalin Bucur <madalin.bucur@freescale.com>2013-04-17 12:54:09 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-18 15:23:29 (GMT)
commit077a980e55a7ceb6040ad39474d019114bbe82cb (patch)
tree2bca729e953862fce4462483eb7a65553a2bdf93 /drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
parentac6cda36f5de41f698c7c5d3a4d1a5d8a4c7ce8b (diff)
downloadlinux-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.c41
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, &copy_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, &copy_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