@@ -623,6 +623,7 @@ struct rtl8169_private {
623623 int cfg9346_usage_count ;
624624
625625 unsigned supports_gmii :1 ;
626+ unsigned aspm_manageable :1 ;
626627 dma_addr_t counters_phys_addr ;
627628 struct rtl8169_counters * counters ;
628629 struct rtl8169_tc_offsets tc_offset ;
@@ -2746,7 +2747,8 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
27462747 if (tp -> mac_version < RTL_GIGA_MAC_VER_32 )
27472748 return ;
27482749
2749- if (enable ) {
2750+ /* Don't enable ASPM in the chip if OS can't control ASPM */
2751+ if (enable && tp -> aspm_manageable ) {
27502752 /* On these chip versions ASPM can even harm
27512753 * bus communication of other PCI devices.
27522754 */
@@ -4521,10 +4523,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
45214523 }
45224524
45234525 if (napi_schedule_prep (& tp -> napi )) {
4524- rtl_unlock_config_regs (tp );
4525- rtl_hw_aspm_clkreq_enable (tp , false);
4526- rtl_lock_config_regs (tp );
4527-
45284526 rtl_irq_disable (tp );
45294527 __napi_schedule (& tp -> napi );
45304528 }
@@ -4584,14 +4582,9 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
45844582
45854583 work_done = rtl_rx (dev , tp , budget );
45864584
4587- if (work_done < budget && napi_complete_done (napi , work_done )) {
4585+ if (work_done < budget && napi_complete_done (napi , work_done ))
45884586 rtl_irq_enable (tp );
45894587
4590- rtl_unlock_config_regs (tp );
4591- rtl_hw_aspm_clkreq_enable (tp , true);
4592- rtl_lock_config_regs (tp );
4593- }
4594-
45954588 return work_done ;
45964589}
45974590
@@ -5165,6 +5158,16 @@ static void rtl_init_mac_address(struct rtl8169_private *tp)
51655158 rtl_rar_set (tp , mac_addr );
51665159}
51675160
5161+ /* register is set if system vendor successfully tested ASPM 1.2 */
5162+ static bool rtl_aspm_is_safe (struct rtl8169_private * tp )
5163+ {
5164+ if (tp -> mac_version >= RTL_GIGA_MAC_VER_61 &&
5165+ r8168_mac_ocp_read (tp , 0xc0b2 ) & 0xf )
5166+ return true;
5167+
5168+ return false;
5169+ }
5170+
51685171static int rtl_init_one (struct pci_dev * pdev , const struct pci_device_id * ent )
51695172{
51705173 struct rtl8169_private * tp ;
@@ -5234,6 +5237,19 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
52345237 xid );
52355238 tp -> mac_version = chipset ;
52365239
5240+ /* Disable ASPM L1 as that cause random device stop working
5241+ * problems as well as full system hangs for some PCIe devices users.
5242+ * Chips from RTL8168h partially have issues with L1.2, but seem
5243+ * to work fine with L1 and L1.1.
5244+ */
5245+ if (rtl_aspm_is_safe (tp ))
5246+ rc = 0 ;
5247+ else if (tp -> mac_version >= RTL_GIGA_MAC_VER_46 )
5248+ rc = pci_disable_link_state (pdev , PCIE_LINK_STATE_L1_2 );
5249+ else
5250+ rc = pci_disable_link_state (pdev , PCIE_LINK_STATE_L1 );
5251+ tp -> aspm_manageable = !rc ;
5252+
52375253 tp -> dash_type = rtl_check_dash (tp );
52385254
52395255 tp -> cp_cmd = RTL_R16 (tp , CPlusCmd ) & CPCMD_MASK ;
0 commit comments