mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-30 14:34:51 +08:00
net: stmmac: switch to use interrupt for hw crosstimestamping
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>
This commit is contained in:
parent
11052589cf
commit
76c16d3e19
@ -298,6 +298,11 @@ static void get_arttime(struct mii_bus *mii, int intel_adhoc_addr,
|
|||||||
*art_time = ns;
|
*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,
|
static int intel_crosststamp(ktime_t *device,
|
||||||
struct system_counterval_t *system,
|
struct system_counterval_t *system,
|
||||||
void *ctx)
|
void *ctx)
|
||||||
@ -313,8 +318,6 @@ static int intel_crosststamp(ktime_t *device,
|
|||||||
u32 num_snapshot;
|
u32 num_snapshot;
|
||||||
u32 gpio_value;
|
u32 gpio_value;
|
||||||
u32 acr_value;
|
u32 acr_value;
|
||||||
int ret;
|
|
||||||
u32 v;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!boot_cpu_has(X86_FEATURE_ART))
|
if (!boot_cpu_has(X86_FEATURE_ART))
|
||||||
@ -328,6 +331,8 @@ static int intel_crosststamp(ktime_t *device,
|
|||||||
if (priv->plat->ext_snapshot_en)
|
if (priv->plat->ext_snapshot_en)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
priv->plat->int_snapshot_en = 1;
|
||||||
|
|
||||||
mutex_lock(&priv->aux_ts_lock);
|
mutex_lock(&priv->aux_ts_lock);
|
||||||
/* Enable Internal snapshot trigger */
|
/* Enable Internal snapshot trigger */
|
||||||
acr_value = readl(ptpaddr + PTP_ACR);
|
acr_value = readl(ptpaddr + PTP_ACR);
|
||||||
@ -347,6 +352,7 @@ static int intel_crosststamp(ktime_t *device,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mutex_unlock(&priv->aux_ts_lock);
|
mutex_unlock(&priv->aux_ts_lock);
|
||||||
|
priv->plat->int_snapshot_en = 0;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
writel(acr_value, ptpaddr + PTP_ACR);
|
writel(acr_value, ptpaddr + PTP_ACR);
|
||||||
@ -368,13 +374,12 @@ static int intel_crosststamp(ktime_t *device,
|
|||||||
gpio_value |= GMAC_GPO1;
|
gpio_value |= GMAC_GPO1;
|
||||||
writel(gpio_value, ioaddr + GMAC_GPIO_STATUS);
|
writel(gpio_value, ioaddr + GMAC_GPIO_STATUS);
|
||||||
|
|
||||||
/* Poll for time sync operation done */
|
/* Time sync done Indication - Interrupt method */
|
||||||
ret = readl_poll_timeout(priv->ioaddr + GMAC_INT_STATUS, v,
|
if (!wait_event_interruptible_timeout(priv->tstamp_busy_wait,
|
||||||
(v & GMAC_INT_TSIE), 100, 10000);
|
stmmac_cross_ts_isr(priv),
|
||||||
|
HZ / 100)) {
|
||||||
if (ret == -ETIMEDOUT) {
|
priv->plat->int_snapshot_en = 0;
|
||||||
pr_err("%s: Wait for time sync operation timeout\n", __func__);
|
return -ETIMEDOUT;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
num_snapshot = (readl(ioaddr + GMAC_TIMESTAMP_STATUS) &
|
num_snapshot = (readl(ioaddr + GMAC_TIMESTAMP_STATUS) &
|
||||||
@ -392,6 +397,7 @@ static int intel_crosststamp(ktime_t *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
system->cycles *= intel_priv->crossts_adj;
|
system->cycles *= intel_priv->crossts_adj;
|
||||||
|
priv->plat->int_snapshot_en = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -576,6 +582,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
|
|||||||
|
|
||||||
plat->has_crossts = true;
|
plat->has_crossts = true;
|
||||||
plat->crosststamp = intel_crosststamp;
|
plat->crosststamp = intel_crosststamp;
|
||||||
|
plat->int_snapshot_en = 0;
|
||||||
|
|
||||||
/* Setup MSI vector offset specific to Intel mGbE controller */
|
/* Setup MSI vector offset specific to Intel mGbE controller */
|
||||||
plat->msi_mac_vec = 29;
|
plat->msi_mac_vec = 29;
|
||||||
|
@ -150,7 +150,8 @@
|
|||||||
#define GMAC_PCS_IRQ_DEFAULT (GMAC_INT_RGSMIIS | GMAC_INT_PCS_LINK | \
|
#define GMAC_PCS_IRQ_DEFAULT (GMAC_INT_RGSMIIS | GMAC_INT_PCS_LINK | \
|
||||||
GMAC_INT_PCS_ANE)
|
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 {
|
enum dwmac4_irq_status {
|
||||||
time_stamp_irq = 0x00001000,
|
time_stamp_irq = 0x00001000,
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
static void dwmac4_core_init(struct mac_device_info *hw,
|
static void dwmac4_core_init(struct mac_device_info *hw,
|
||||||
struct net_device *dev)
|
struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
struct stmmac_priv *priv = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = hw->pcsr;
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
u32 value = readl(ioaddr + GMAC_CONFIG);
|
u32 value = readl(ioaddr + GMAC_CONFIG);
|
||||||
|
|
||||||
@ -58,6 +59,9 @@ static void dwmac4_core_init(struct mac_device_info *hw,
|
|||||||
value |= GMAC_INT_FPE_EN;
|
value |= GMAC_INT_FPE_EN;
|
||||||
|
|
||||||
writel(value, ioaddr + GMAC_INT_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,
|
static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
|
||||||
|
@ -266,6 +266,7 @@ struct stmmac_priv {
|
|||||||
rwlock_t ptp_lock;
|
rwlock_t ptp_lock;
|
||||||
/* Protects auxiliary snapshot registers from concurrent access. */
|
/* Protects auxiliary snapshot registers from concurrent access. */
|
||||||
struct mutex aux_ts_lock;
|
struct mutex aux_ts_lock;
|
||||||
|
wait_queue_head_t tstamp_busy_wait;
|
||||||
|
|
||||||
void __iomem *mmcaddr;
|
void __iomem *mmcaddr;
|
||||||
void __iomem *ptpaddr;
|
void __iomem *ptpaddr;
|
||||||
|
@ -179,6 +179,11 @@ static void timestamp_interrupt(struct stmmac_priv *priv)
|
|||||||
u64 ptp_time;
|
u64 ptp_time;
|
||||||
int i;
|
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;
|
tsync_int = readl(priv->ioaddr + GMAC_INT_STATUS) & GMAC_INT_TSIE;
|
||||||
|
|
||||||
if (!tsync_int)
|
if (!tsync_int)
|
||||||
|
@ -175,11 +175,10 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
|
|||||||
struct stmmac_priv *priv =
|
struct stmmac_priv *priv =
|
||||||
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
|
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
|
||||||
void __iomem *ptpaddr = priv->ptpaddr;
|
void __iomem *ptpaddr = priv->ptpaddr;
|
||||||
void __iomem *ioaddr = priv->hw->pcsr;
|
|
||||||
struct stmmac_pps_cfg *cfg;
|
struct stmmac_pps_cfg *cfg;
|
||||||
u32 intr_value, acr_value;
|
|
||||||
int ret = -EOPNOTSUPP;
|
int ret = -EOPNOTSUPP;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
u32 acr_value;
|
||||||
|
|
||||||
switch (rq->type) {
|
switch (rq->type) {
|
||||||
case PTP_CLK_REQ_PEROUT:
|
case PTP_CLK_REQ_PEROUT:
|
||||||
@ -213,19 +212,10 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
|
|||||||
netdev_dbg(priv->dev, "Auxiliary Snapshot %d enabled.\n",
|
netdev_dbg(priv->dev, "Auxiliary Snapshot %d enabled.\n",
|
||||||
priv->plat->ext_snapshot_num >>
|
priv->plat->ext_snapshot_num >>
|
||||||
PTP_ACR_ATSEN_SHIFT);
|
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 {
|
} else {
|
||||||
netdev_dbg(priv->dev, "Auxiliary Snapshot %d disabled.\n",
|
netdev_dbg(priv->dev, "Auxiliary Snapshot %d disabled.\n",
|
||||||
priv->plat->ext_snapshot_num >>
|
priv->plat->ext_snapshot_num >>
|
||||||
PTP_ACR_ATSEN_SHIFT);
|
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);
|
writel(acr_value, ptpaddr + PTP_ACR);
|
||||||
mutex_unlock(&priv->aux_ts_lock);
|
mutex_unlock(&priv->aux_ts_lock);
|
||||||
|
@ -260,6 +260,7 @@ struct plat_stmmacenet_data {
|
|||||||
bool has_crossts;
|
bool has_crossts;
|
||||||
int int_snapshot_num;
|
int int_snapshot_num;
|
||||||
int ext_snapshot_num;
|
int ext_snapshot_num;
|
||||||
|
bool int_snapshot_en;
|
||||||
bool ext_snapshot_en;
|
bool ext_snapshot_en;
|
||||||
bool multi_msi_en;
|
bool multi_msi_en;
|
||||||
int msi_mac_vec;
|
int msi_mac_vec;
|
||||||
|
Loading…
Reference in New Issue
Block a user