Skip to content

Commit

Permalink
net: stmmac: switch to use interrupt for hw crosstimestamping
Browse files Browse the repository at this point in the history
[ Upstream commit 76c16d3 ]

Using current implementation of polling mode, there is high chances we
will hit into timeout error when running phc2sys. Hence, update the
implementation of hardware crosstimestamping to use the MAC interrupt
service routine instead of polling for TSIS bit in the MAC Timestamp
Interrupt Status register to be set.

Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Wong Vee Khee <vee.khee.wong@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stable-dep-of: 8efbdbf ("net: stmmac: Initialize MAC_ONEUS_TIC_COUNTER register")
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
wvk86 authored and gregkh committed May 24, 2023
1 parent 46e100b commit b0a513b
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 21 deletions.
25 changes: 16 additions & 9 deletions drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ static void get_arttime(struct mii_bus *mii, int intel_adhoc_addr,
*art_time = ns;
}

static int stmmac_cross_ts_isr(struct stmmac_priv *priv)
{
return (readl(priv->ioaddr + GMAC_INT_STATUS) & GMAC_INT_TSIE);
}

static int intel_crosststamp(ktime_t *device,
struct system_counterval_t *system,
void *ctx)
Expand All @@ -313,8 +318,6 @@ static int intel_crosststamp(ktime_t *device,
u32 num_snapshot;
u32 gpio_value;
u32 acr_value;
int ret;
u32 v;
int i;

if (!boot_cpu_has(X86_FEATURE_ART))
Expand All @@ -328,6 +331,8 @@ static int intel_crosststamp(ktime_t *device,
if (priv->plat->ext_snapshot_en)
return -EBUSY;

priv->plat->int_snapshot_en = 1;

mutex_lock(&priv->aux_ts_lock);
/* Enable Internal snapshot trigger */
acr_value = readl(ptpaddr + PTP_ACR);
Expand All @@ -347,6 +352,7 @@ static int intel_crosststamp(ktime_t *device,
break;
default:
mutex_unlock(&priv->aux_ts_lock);
priv->plat->int_snapshot_en = 0;
return -EINVAL;
}
writel(acr_value, ptpaddr + PTP_ACR);
Expand All @@ -368,13 +374,12 @@ static int intel_crosststamp(ktime_t *device,
gpio_value |= GMAC_GPO1;
writel(gpio_value, ioaddr + GMAC_GPIO_STATUS);

/* Poll for time sync operation done */
ret = readl_poll_timeout(priv->ioaddr + GMAC_INT_STATUS, v,
(v & GMAC_INT_TSIE), 100, 10000);

if (ret == -ETIMEDOUT) {
pr_err("%s: Wait for time sync operation timeout\n", __func__);
return ret;
/* Time sync done Indication - Interrupt method */
if (!wait_event_interruptible_timeout(priv->tstamp_busy_wait,
stmmac_cross_ts_isr(priv),
HZ / 100)) {
priv->plat->int_snapshot_en = 0;
return -ETIMEDOUT;
}

num_snapshot = (readl(ioaddr + GMAC_TIMESTAMP_STATUS) &
Expand All @@ -392,6 +397,7 @@ static int intel_crosststamp(ktime_t *device,
}

system->cycles *= intel_priv->crossts_adj;
priv->plat->int_snapshot_en = 0;

return 0;
}
Expand Down Expand Up @@ -576,6 +582,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,

plat->has_crossts = true;
plat->crosststamp = intel_crosststamp;
plat->int_snapshot_en = 0;

/* Setup MSI vector offset specific to Intel mGbE controller */
plat->msi_mac_vec = 29;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/stmicro/stmmac/dwmac4.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@
#define GMAC_PCS_IRQ_DEFAULT (GMAC_INT_RGSMIIS | GMAC_INT_PCS_LINK | \
GMAC_INT_PCS_ANE)

#define GMAC_INT_DEFAULT_ENABLE (GMAC_INT_PMT_EN | GMAC_INT_LPI_EN)
#define GMAC_INT_DEFAULT_ENABLE (GMAC_INT_PMT_EN | GMAC_INT_LPI_EN | \
GMAC_INT_TSIE)

enum dwmac4_irq_status {
time_stamp_irq = 0x00001000,
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
static void dwmac4_core_init(struct mac_device_info *hw,
struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + GMAC_CONFIG);

Expand Down Expand Up @@ -58,6 +59,9 @@ static void dwmac4_core_init(struct mac_device_info *hw,
value |= GMAC_INT_FPE_EN;

writel(value, ioaddr + GMAC_INT_EN);

if (GMAC_INT_DEFAULT_ENABLE & GMAC_INT_TSIE)
init_waitqueue_head(&priv->tstamp_busy_wait);
}

static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/stmicro/stmmac/stmmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ struct stmmac_priv {
spinlock_t ptp_lock;
/* Protects auxiliary snapshot registers from concurrent access. */
struct mutex aux_ts_lock;
wait_queue_head_t tstamp_busy_wait;

void __iomem *mmcaddr;
void __iomem *ptpaddr;
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ static void timestamp_interrupt(struct stmmac_priv *priv)
u64 ptp_time;
int i;

if (priv->plat->int_snapshot_en) {
wake_up(&priv->tstamp_busy_wait);
return;
}

tsync_int = readl(priv->ioaddr + GMAC_INT_STATUS) & GMAC_INT_TSIE;

if (!tsync_int)
Expand Down
12 changes: 1 addition & 11 deletions drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,10 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
struct stmmac_priv *priv =
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
void __iomem *ptpaddr = priv->ptpaddr;
void __iomem *ioaddr = priv->hw->pcsr;
struct stmmac_pps_cfg *cfg;
u32 intr_value, acr_value;
int ret = -EOPNOTSUPP;
unsigned long flags;
u32 acr_value;

switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
Expand Down Expand Up @@ -213,19 +212,10 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
netdev_dbg(priv->dev, "Auxiliary Snapshot %d enabled.\n",
priv->plat->ext_snapshot_num >>
PTP_ACR_ATSEN_SHIFT);
/* Enable Timestamp Interrupt */
intr_value = readl(ioaddr + GMAC_INT_EN);
intr_value |= GMAC_INT_TSIE;
writel(intr_value, ioaddr + GMAC_INT_EN);

} else {
netdev_dbg(priv->dev, "Auxiliary Snapshot %d disabled.\n",
priv->plat->ext_snapshot_num >>
PTP_ACR_ATSEN_SHIFT);
/* Disable Timestamp Interrupt */
intr_value = readl(ioaddr + GMAC_INT_EN);
intr_value &= ~GMAC_INT_TSIE;
writel(intr_value, ioaddr + GMAC_INT_EN);
}
writel(acr_value, ptpaddr + PTP_ACR);
mutex_unlock(&priv->aux_ts_lock);
Expand Down
1 change: 1 addition & 0 deletions include/linux/stmmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ struct plat_stmmacenet_data {
bool has_crossts;
int int_snapshot_num;
int ext_snapshot_num;
bool int_snapshot_en;
bool ext_snapshot_en;
bool multi_msi_en;
int msi_mac_vec;
Expand Down

0 comments on commit b0a513b

Please sign in to comment.