r8126: Fix PCIe completion timeouts

During PTP operation, abnormal interrupt handling could stall internal
transactions, leading to delayed BAR register reads and PCIe completion
timeout errors.

This patch adjusts the PTP interrupt mechanism to
eliminate the stall and reduce latency.

Bug 4755448

Change-Id: Id7fa3fbcac33ba89b3635d86a15932ac95f7e4bd
Signed-off-by: Revanth Kumar Uppala <ruppala@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3446115
Reviewed-by: Brad Griffis <bgriffis@nvidia.com>
Reviewed-by: Shobek Attupurath <sattupurath@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Revanth Kumar Uppala
2025-09-04 06:46:16 +00:00
committed by Amulya Yarlagadda
parent 11f63191e9
commit 08707b030b
4 changed files with 53 additions and 44 deletions

View File

@@ -1584,6 +1584,7 @@ enum RTL8126_registers {
PTP_Time_SHIFTER_S_8125 = 0x6856,
PPS_RISE_TIME_NS_8125 = 0x68A0,
PPS_RISE_TIME_S_8125 = 0x68A4,
PTP_DUMMY_REG = 0XC070,
PTP_EGRESS_TIME_BASE_NS_8125 = 0XCF20,
PTP_EGRESS_TIME_BASE_S_8125 = 0XCF24,
PTP_CTL = 0xE400,
@@ -2760,6 +2761,7 @@ struct rtl8126_private {
u16 MacMcuPageSize;
u64 hw_mcu_patch_code_ver;
u64 bin_mcu_patch_code_ver;
u8 hw_has_mac_mcu_patch_code;
u8 HwSuppTcamVer;

View File

@@ -1021,6 +1021,7 @@ static int proc_get_driver_variable(struct seq_file *m, void *v)
seq_printf(m, "HwIcVerUnknown\t0x%x\n", tp->HwIcVerUnknown);
seq_printf(m, "NotWrRamCodeToMicroP\t0x%x\n", tp->NotWrRamCodeToMicroP);
seq_printf(m, "NotWrMcuPatchCode\t0x%x\n", tp->NotWrMcuPatchCode);
seq_printf(m, "hw_has_mac_mcu_patch_code\t0x%x\n", tp->hw_has_mac_mcu_patch_code);
seq_printf(m, "HwHasWrRamCodeToMicroP\t0x%x\n", tp->HwHasWrRamCodeToMicroP);
seq_printf(m, "sw_ram_code_ver\t0x%x\n", tp->sw_ram_code_ver);
seq_printf(m, "hw_ram_code_ver\t0x%x\n", tp->hw_ram_code_ver);
@@ -1745,6 +1746,7 @@ static int proc_get_driver_variable(char *page, char **start,
"HwIcVerUnknown\t0x%x\n"
"NotWrRamCodeToMicroP\t0x%x\n"
"NotWrMcuPatchCode\t0x%x\n"
"hw_has_mac_mcu_patch_code\t0x%x\n"
"HwHasWrRamCodeToMicroP\t0x%x\n"
"sw_ram_code_ver\t0x%x\n"
"hw_ram_code_ver\t0x%x\n"
@@ -1872,6 +1874,7 @@ static int proc_get_driver_variable(char *page, char **start,
tp->HwIcVerUnknown,
tp->NotWrRamCodeToMicroP,
tp->NotWrMcuPatchCode,
tp->hw_has_mac_mcu_patch_code,
tp->HwHasWrRamCodeToMicroP,
tp->sw_ram_code_ver,
tp->hw_ram_code_ver,
@@ -2969,9 +2972,11 @@ static ssize_t testmode_show(struct device *dev,
struct net_device *netdev = to_net_dev(dev);
struct rtl8126_private *tp = netdev_priv(netdev);
sprintf(buf, "%u\n", tp->testmode);
return strlen(buf);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,103)
return sprintf(buf, "%u\n", tp->testmode);
#else
return sysfs_emit(buf, "%u\n", tp->testmode);
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,4,103) */
}
static ssize_t testmode_store(struct device *dev,
@@ -4057,8 +4062,7 @@ static bool
rtl8126_vec_2_tx_q_num(
struct rtl8126_private *tp,
u32 messageId,
u32 *qnum
)
u32 *qnum)
{
u32 whichQ = 0xffffffff;
bool rc = false;
@@ -4109,8 +4113,7 @@ static bool
rtl8126_vec_2_rx_q_num(
struct rtl8126_private *tp,
u32 messageId,
u32 *qnum
)
u32 *qnum)
{
u32 whichQ = 0xffffffff;
bool rc = false;
@@ -6957,6 +6960,9 @@ rtl8126_wait_phy_ups_resume(struct net_device *dev, u16 PhyState)
static void
rtl8126_set_mcu_d3_stack(struct rtl8126_private *tp)
{
if (!tp->hw_has_mac_mcu_patch_code)
return;
switch (tp->mcfg) {
case CFG_METHOD_2:
rtl8126_mac_ocp_write(tp, 0xD018, 0xD116);
@@ -7216,8 +7222,8 @@ rtl8126_set_mac_mcu_8126a_2(struct net_device *dev)
rtl8126_mac_ocp_write(tp, 0xFC26, 0x8000);
//rtl8126_mac_ocp_write(tp, 0xFC28, 0x00FE);
//rtl8126_mac_ocp_write(tp, 0xFC2A, 0x4A14);
rtl8126_mac_ocp_write(tp, 0xFC28, 0x00FE);
rtl8126_mac_ocp_write(tp, 0xFC2A, 0x4A14);
rtl8126_mac_ocp_write(tp, 0xFC2C, 0x2360);
rtl8126_mac_ocp_write(tp, 0xFC2E, 0x14A4);
rtl8126_mac_ocp_write(tp, 0xFC30, 0x415E);
@@ -7225,7 +7231,7 @@ rtl8126_set_mac_mcu_8126a_2(struct net_device *dev)
rtl8126_mac_ocp_write(tp, 0xFC34, 0x4280);
rtl8126_mac_ocp_write(tp, 0xFC36, 0x234A);
rtl8126_mac_ocp_write(tp, 0xFC48, 0x00FC);
rtl8126_mac_ocp_write(tp, 0xFC48, 0x00FF);
}
static void
@@ -7281,8 +7287,8 @@ rtl8126_set_mac_mcu_8126a_3(struct net_device *dev)
rtl8126_mac_ocp_write(tp, 0xFC26, 0x8000);
//rtl8126_mac_ocp_write(tp, 0xFC28, 0x00FE);
//rtl8126_mac_ocp_write(tp, 0xFC2A, 0x55DE);
rtl8126_mac_ocp_write(tp, 0xFC28, 0x00FE);
rtl8126_mac_ocp_write(tp, 0xFC2A, 0x55DE);
rtl8126_mac_ocp_write(tp, 0xFC2C, 0x14A4);
rtl8126_mac_ocp_write(tp, 0xFC2E, 0x4176);
rtl8126_mac_ocp_write(tp, 0xFC30, 0x41FC);
@@ -7292,7 +7298,7 @@ rtl8126_set_mac_mcu_8126a_3(struct net_device *dev)
//rtl8126_mac_ocp_write(tp, 0xFC38, 0x2382);
rtl8126_mac_ocp_write(tp, 0xFC3A, 0x234A);
rtl8126_mac_ocp_write(tp, 0xFC48, 0x023C);
rtl8126_mac_ocp_write(tp, 0xFC48, 0x023F);
}
static void
@@ -7300,6 +7306,8 @@ rtl8126_hw_mac_mcu_config(struct net_device *dev)
{
struct rtl8126_private *tp = netdev_priv(dev);
tp->hw_has_mac_mcu_patch_code = FALSE;
if (tp->NotWrMcuPatchCode == TRUE)
return;
@@ -7315,7 +7323,11 @@ rtl8126_hw_mac_mcu_config(struct net_device *dev)
case CFG_METHOD_3:
rtl8126_set_mac_mcu_8126a_3(dev);
break;
default:
return;
}
tp->hw_has_mac_mcu_patch_code = TRUE;
}
#endif
@@ -7351,6 +7363,8 @@ static void rtl8126_apply_firmware(struct rtl8126_private *tp)
tp->sw_ram_code_ver = tp->hw_ram_code_ver;
tp->HwHasWrRamCodeToMicroP = TRUE;
tp->hw_has_mac_mcu_patch_code = TRUE;
r8126_spin_unlock(&tp->phy_lock, flags);
}
}
@@ -16374,10 +16388,6 @@ static void rtl8126_shutdown(struct pci_dev *pdev)
tp->wol_enabled = WOL_DISABLED;
rtl8126_close(dev);
if (netif_running(dev))
netif_device_detach(dev);
rtl8126_disable_msi(pdev, tp);
rtnl_unlock();

View File

@@ -558,8 +558,6 @@ static void rtl8126_ptp_tx_hwtstamp(struct rtl8126_private *tp)
struct skb_shared_hwtstamps shhwtstamps = { 0 };
struct timespec64 ts64;
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_INSR, TX_TX_INTR);
rtl8126_ptp_egresstime(tp, &ts64);
/* Upper 32 bits contain s, lower 32 bits contain ns. */
@@ -590,31 +588,28 @@ static void rtl8126_ptp_tx_work(struct work_struct *work)
if (!tp->ptp_tx_skb)
return;
rtnl_lock();
if (rtl8126_mac_ocp_read(tp, PTP_DUMMY_REG) & TX_TS_INTR) {
tx_intr = true;
rtl8126_mac_ocp_write(tp, PTP_DUMMY_REG, TX_TS_INTR);
} else
tx_intr = false;
rtnl_unlock();
if (time_is_before_jiffies(tp->ptp_tx_start +
RTL8126_PTP_TX_TIMEOUT)) {
dev_kfree_skb_any(tp->ptp_tx_skb);
tp->ptp_tx_skb = NULL;
clear_bit_unlock(__RTL8126_PTP_TX_IN_PROGRESS, &tp->state);
tp->tx_hwtstamp_timeouts++;
/* Clear the tx valid bit in TSYNCTXCTL register to enable
* interrupt
*/
r8126_spin_lock(&tp->phy_lock, flags);
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_INSR, TX_TX_INTR);
r8126_spin_unlock(&tp->phy_lock, flags);
return;
}
r8126_spin_lock(&tp->phy_lock, flags);
if (rtl8126_mdio_direct_read_phy_ocp(tp, PTP_INSR) & TX_TX_INTR) {
tx_intr = true;
if (tx_intr) {
r8126_spin_lock(&tp->phy_lock, flags);
rtl8126_ptp_tx_hwtstamp(tp);
r8126_spin_unlock(&tp->phy_lock, flags);
} else {
tx_intr = false;
}
r8126_spin_unlock(&tp->phy_lock, flags);
if (!tx_intr) {
/* reschedule to check later */
schedule_work(&tp->ptp_tx_work);
}
@@ -624,26 +619,28 @@ static int rtl8126_hwtstamp_enable(struct rtl8126_private *tp, bool enable)
{
unsigned long flags;
ASSERT_RTNL();
r8126_spin_lock(&tp->phy_lock, flags);
/* trx timestamp interrupt disable */
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_INER, RX_TS_INTR | TX_TS_INTR);
//clear ptp isr
rtl8126_mac_ocp_write(tp, PTP_DUMMY_REG, 0xffff);
if (enable) {
//trx timestamp interrupt enable
rtl8126_set_eth_phy_ocp_bit(tp, PTP_INER, BIT_2 | BIT_3);
//tx timestamp interrupt enable
rtl8126_set_eth_phy_ocp_bit(tp, PTP_INER, TX_TS_INTR);
//set isr clear mode
rtl8126_set_eth_phy_ocp_bit(tp, PTP_GEN_CFG, BIT_0);
//clear ptp isr
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_INSR, 0xFFFF);
//set isr clear mode to read clear
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_GEN_CFG, BIT_0);
//enable ptp
rtl8126_ptp_enable_config(tp);
//rtl8126_set_local_time(tp);
} else {
/* trx timestamp interrupt disable */
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_INER, BIT_2 | BIT_3);
/* disable ptp */
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_SYNCE_CTL, BIT_0);
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_CTL, BIT_0);

View File

@@ -94,7 +94,7 @@ enum PTP_INSR_TYPE {
EVENT_CAP_INTR = (1 << 0),
TRIG_GEN_INTR = (1 << 1),
RX_TS_INTR = (1 << 2),
TX_TX_INTR = (1 << 3),
TX_TS_INTR = (1 << 3),
};
enum PTP_TRX_TS_STA_REG {