summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2016-11-10 17:09:45 -0600
committerDavid S. Miller <davem@davemloft.net>2016-11-13 00:56:26 -0500
commitaba9777ae3ddea356874d46431183efaff0b3b1a (patch)
treece7ff886ad7d345799e4e58a644ce47ef480edf8 /drivers
parent5ffc0335d5118bad9f98ea952e74eaf38334dd7f (diff)
downloadlinux-aba9777ae3ddea356874d46431183efaff0b3b1a.tar.bz2
amd-xgbe: Add a workaround for Tx timestamp issue
Update the reading of the Tx timestamp to account for a hardware issue on how the fields and interrupt are cleared. The "seconds" portion of the timestamp should be read first, followed by the "nanoseconds" portion. Reading the "nanoseconds" portion should clear the timestamp data and the interrupt. Because of an issue with the hardware this order is reversed and reading the "seconds" portion actually clears the timestamp. The code currently follows this workaround, but to guard against future versions where this is fixed add a field to the version data to indicate if the workaround is required or not. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c13
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-platform.c1
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h1
3 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index e3862bbf2f76..81d47807c3cc 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1360,14 +1360,21 @@ static u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata)
static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
{
- unsigned int tx_snr;
+ unsigned int tx_snr, tx_ssr;
u64 nsec;
- tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+ if (pdata->vdata->tx_tstamp_workaround) {
+ tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+ tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
+ } else {
+ tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
+ tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+ }
+
if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
return 0;
- nsec = XGMAC_IOREAD(pdata, MAC_TXSSR);
+ nsec = tx_ssr;
nsec *= NSEC_PER_SEC;
nsec += tx_snr;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-platform.c b/drivers/net/ethernet/amd/xgbe/xgbe-platform.c
index 0edbcd523f8f..7a701de5eed3 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-platform.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-platform.c
@@ -581,6 +581,7 @@ static const struct xgbe_version_data xgbe_v1 = {
.xpcs_access = XGBE_XPCS_ACCESS_V1,
.tx_max_fifo_size = 81920,
.rx_max_fifo_size = 81920,
+ .tx_tstamp_workaround = 1,
};
#ifdef CONFIG_ACPI
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 0779247057fb..8523779329f8 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -805,6 +805,7 @@ struct xgbe_version_data {
unsigned int mmc_64bit;
unsigned int tx_max_fifo_size;
unsigned int rx_max_fifo_size;
+ unsigned int tx_tstamp_workaround;
};
struct xgbe_prv_data {