Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

e1000e Refactor of Runtime Power Management

Fix issues with:
RuntimePM causing the device to repeatedly flip between suspend and resume
with the interface administratively downed.
Having RuntimePM enabled interfering with the functionality of Energy
Efficient Ethernet.

Added checks to disallow functions that should not be executed if the
device is currently runtime suspended

Make runtime_idle callback to use same deterministic behavior as the igb
driver.

Signed-off-by: Dave Ertman <davidx.m.ertman@intel.com>
Acked-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

David Ertman and committed by
Jeff Kirsher
63eb48f1 28002099

+54 -40
-1
drivers/net/ethernet/intel/e1000e/e1000.h
··· 326 326 struct work_struct update_phy_task; 327 327 struct work_struct print_hang_task; 328 328 329 - bool idle_check; 330 329 int phy_hang_count; 331 330 332 331 u16 tx_ring_count;
+54 -39
drivers/net/ethernet/intel/e1000e/netdev.c
··· 3327 3327 struct e1000_hw *hw = &adapter->hw; 3328 3328 u32 rctl; 3329 3329 3330 + if (pm_runtime_suspended(netdev->dev.parent)) 3331 + return; 3332 + 3330 3333 /* Check for Promiscuous and All Multicast modes */ 3331 3334 rctl = er32(RCTL); 3332 3335 ··· 4320 4317 adapter->tx_hang_recheck = false; 4321 4318 netif_start_queue(netdev); 4322 4319 4323 - adapter->idle_check = true; 4324 4320 hw->mac.get_link_status = true; 4325 4321 pm_runtime_put(&pdev->dev); 4326 4322 ··· 4371 4369 if (!test_bit(__E1000_DOWN, &adapter->state)) { 4372 4370 e1000e_down(adapter, true); 4373 4371 e1000_free_irq(adapter); 4372 + 4373 + /* Link status message must follow this format */ 4374 + pr_info("%s NIC Link is Down\n", adapter->netdev->name); 4374 4375 } 4375 4376 4376 4377 napi_disable(&adapter->napi); ··· 5683 5678 adapter->max_frame_size = max_frame; 5684 5679 e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); 5685 5680 netdev->mtu = new_mtu; 5681 + 5682 + pm_runtime_get_sync(netdev->dev.parent); 5683 + 5686 5684 if (netif_running(netdev)) 5687 5685 e1000e_down(adapter, true); 5688 5686 ··· 5712 5704 e1000e_up(adapter); 5713 5705 else 5714 5706 e1000e_reset(adapter); 5707 + 5708 + pm_runtime_put_sync(netdev->dev.parent); 5715 5709 5716 5710 clear_bit(__E1000_RESETTING, &adapter->state); 5717 5711 ··· 5989 5979 ew32(CTRL_EXT, ctrl_ext); 5990 5980 } 5991 5981 5982 + if (!runtime) 5983 + e1000e_power_up_phy(adapter); 5984 + 5992 5985 if (adapter->flags & FLAG_IS_ICH) 5993 5986 e1000_suspend_workarounds_ich8lan(&adapter->hw); 5994 5987 ··· 6121 6108 } 6122 6109 6123 6110 #ifdef CONFIG_PM 6124 - static bool e1000e_pm_ready(struct e1000_adapter *adapter) 6125 - { 6126 - return !!adapter->tx_ring->buffer_info; 6127 - } 6128 - 6129 6111 static int __e1000_resume(struct pci_dev *pdev) 6130 6112 { 6131 6113 struct net_device *netdev = pci_get_drvdata(pdev); ··· 6174 6166 e1000e_reset(adapter); 6175 6167 6176 6168 e1000_init_manageability_pt(adapter); 6177 - 6178 - if (netif_running(netdev)) 6179 - e1000e_up(adapter); 6180 - 6181 - netif_device_attach(netdev); 6182 6169 6183 6170 /* If the controller has AMT, do not set DRV_LOAD until the interface 6184 6171 * is up. For all other cases, let the f/w know that the h/w is now ··· 6229 6226 #endif /* CONFIG_PM_SLEEP */ 6230 6227 6231 6228 #ifdef CONFIG_PM_RUNTIME 6232 - static int e1000_runtime_suspend(struct device *dev) 6229 + static int e1000e_pm_runtime_idle(struct device *dev) 6233 6230 { 6234 6231 struct pci_dev *pdev = to_pci_dev(dev); 6235 6232 struct net_device *netdev = pci_get_drvdata(pdev); 6236 6233 struct e1000_adapter *adapter = netdev_priv(netdev); 6237 6234 6238 - if (!e1000e_pm_ready(adapter)) 6239 - return 0; 6240 - 6241 - return __e1000_shutdown(pdev, true); 6242 - } 6243 - 6244 - static int e1000_idle(struct device *dev) 6245 - { 6246 - struct pci_dev *pdev = to_pci_dev(dev); 6247 - struct net_device *netdev = pci_get_drvdata(pdev); 6248 - struct e1000_adapter *adapter = netdev_priv(netdev); 6249 - 6250 - if (!e1000e_pm_ready(adapter)) 6251 - return 0; 6252 - 6253 - if (adapter->idle_check) { 6254 - adapter->idle_check = false; 6255 - if (!e1000e_has_link(adapter)) 6256 - pm_schedule_suspend(dev, MSEC_PER_SEC); 6257 - } 6235 + if (!e1000e_has_link(adapter)) 6236 + pm_schedule_suspend(dev, 5 * MSEC_PER_SEC); 6258 6237 6259 6238 return -EBUSY; 6260 6239 } 6261 6240 6262 - static int e1000_runtime_resume(struct device *dev) 6241 + static int e1000e_pm_runtime_resume(struct device *dev) 6242 + { 6243 + struct pci_dev *pdev = to_pci_dev(dev); 6244 + struct net_device *netdev = pci_get_drvdata(pdev); 6245 + struct e1000_adapter *adapter = netdev_priv(netdev); 6246 + int rc; 6247 + 6248 + rc = __e1000_resume(pdev); 6249 + if (rc) 6250 + return rc; 6251 + 6252 + if (netdev->flags & IFF_UP) 6253 + rc = e1000e_up(adapter); 6254 + 6255 + return rc; 6256 + } 6257 + 6258 + static int e1000e_pm_runtime_suspend(struct device *dev) 6263 6259 { 6264 6260 struct pci_dev *pdev = to_pci_dev(dev); 6265 6261 struct net_device *netdev = pci_get_drvdata(pdev); 6266 6262 struct e1000_adapter *adapter = netdev_priv(netdev); 6267 6263 6268 - if (!e1000e_pm_ready(adapter)) 6269 - return 0; 6264 + if (netdev->flags & IFF_UP) { 6265 + int count = E1000_CHECK_RESET_COUNT; 6270 6266 6271 - adapter->idle_check = !dev->power.runtime_auto; 6272 - return __e1000_resume(pdev); 6267 + while (test_bit(__E1000_RESETTING, &adapter->state) && count--) 6268 + usleep_range(10000, 20000); 6269 + 6270 + WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); 6271 + 6272 + /* Down the device without resetting the hardware */ 6273 + e1000e_down(adapter, false); 6274 + } 6275 + 6276 + if (__e1000_shutdown(pdev, true)) { 6277 + e1000e_pm_runtime_resume(dev); 6278 + return -EBUSY; 6279 + } 6280 + 6281 + return 0; 6273 6282 } 6274 6283 #endif /* CONFIG_PM_RUNTIME */ 6275 6284 #endif /* CONFIG_PM */ ··· 7066 7051 .thaw = e1000e_pm_thaw, 7067 7052 .poweroff = e1000e_pm_suspend, 7068 7053 .restore = e1000e_pm_resume, 7069 - SET_RUNTIME_PM_OPS(e1000_runtime_suspend, e1000_runtime_resume, 7070 - e1000_idle) 7054 + SET_RUNTIME_PM_OPS(e1000e_pm_runtime_suspend, e1000e_pm_runtime_resume, 7055 + e1000e_pm_runtime_idle) 7071 7056 }; 7072 7057 7073 7058 /* PCI Device API Driver */