diff --git a/drivers/net/ethernet/realtek/r8126/r8126.h b/drivers/net/ethernet/realtek/r8126/r8126.h index 83b851ee..ef028d11 100644 --- a/drivers/net/ethernet/realtek/r8126/r8126.h +++ b/drivers/net/ethernet/realtek/r8126/r8126.h @@ -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; diff --git a/drivers/net/ethernet/realtek/r8126/r8126_n.c b/drivers/net/ethernet/realtek/r8126/r8126_n.c index 2bd5e53a..5458c468 100644 --- a/drivers/net/ethernet/realtek/r8126/r8126_n.c +++ b/drivers/net/ethernet/realtek/r8126/r8126_n.c @@ -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(); diff --git a/drivers/net/ethernet/realtek/r8126/r8126_ptp.c b/drivers/net/ethernet/realtek/r8126/r8126_ptp.c index b453c88e..17b62b7d 100644 --- a/drivers/net/ethernet/realtek/r8126/r8126_ptp.c +++ b/drivers/net/ethernet/realtek/r8126/r8126_ptp.c @@ -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); diff --git a/drivers/net/ethernet/realtek/r8126/r8126_ptp.h b/drivers/net/ethernet/realtek/r8126/r8126_ptp.h index 62366dd6..d9fb256e 100644 --- a/drivers/net/ethernet/realtek/r8126/r8126_ptp.h +++ b/drivers/net/ethernet/realtek/r8126/r8126_ptp.h @@ -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 {