@@ -623,6 +623,7 @@ struct rtl8169_private {
623
623
int cfg9346_usage_count ;
624
624
625
625
unsigned supports_gmii :1 ;
626
+ unsigned aspm_manageable :1 ;
626
627
dma_addr_t counters_phys_addr ;
627
628
struct rtl8169_counters * counters ;
628
629
struct rtl8169_tc_offsets tc_offset ;
@@ -2746,7 +2747,8 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
2746
2747
if (tp -> mac_version < RTL_GIGA_MAC_VER_32 )
2747
2748
return ;
2748
2749
2749
- if (enable ) {
2750
+ /* Don't enable ASPM in the chip if OS can't control ASPM */
2751
+ if (enable && tp -> aspm_manageable ) {
2750
2752
/* On these chip versions ASPM can even harm
2751
2753
* bus communication of other PCI devices.
2752
2754
*/
@@ -4521,10 +4523,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
4521
4523
}
4522
4524
4523
4525
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
-
4528
4526
rtl_irq_disable (tp );
4529
4527
__napi_schedule (& tp -> napi );
4530
4528
}
@@ -4584,14 +4582,9 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
4584
4582
4585
4583
work_done = rtl_rx (dev , tp , budget );
4586
4584
4587
- if (work_done < budget && napi_complete_done (napi , work_done )) {
4585
+ if (work_done < budget && napi_complete_done (napi , work_done ))
4588
4586
rtl_irq_enable (tp );
4589
4587
4590
- rtl_unlock_config_regs (tp );
4591
- rtl_hw_aspm_clkreq_enable (tp , true);
4592
- rtl_lock_config_regs (tp );
4593
- }
4594
-
4595
4588
return work_done ;
4596
4589
}
4597
4590
@@ -5165,6 +5158,16 @@ static void rtl_init_mac_address(struct rtl8169_private *tp)
5165
5158
rtl_rar_set (tp , mac_addr );
5166
5159
}
5167
5160
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
+
5168
5171
static int rtl_init_one (struct pci_dev * pdev , const struct pci_device_id * ent )
5169
5172
{
5170
5173
struct rtl8169_private * tp ;
@@ -5234,6 +5237,19 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
5234
5237
xid );
5235
5238
tp -> mac_version = chipset ;
5236
5239
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
+
5237
5253
tp -> dash_type = rtl_check_dash (tp );
5238
5254
5239
5255
tp -> cp_cmd = RTL_R16 (tp , CPlusCmd ) & CPCMD_MASK ;
0 commit comments