Skip to content

Commit 602d959

Browse files
committed
Merge branch 'intel-wired-lan-driver-updates-2024-05-28-e1000e-i40e-ice'
Jacob Keller says: ==================== Intel Wired LAN Driver Updates 2024-05-28 (e1000e, i40e, ice) [part] This series includes a variety of fixes that have been accumulating on the Intel Wired LAN dev-queue. Hui Wang provides a fix for suspend/resume on e1000e due to failure to correctly setup the SMBUS in enable_ulp(). Thinh Tran provides a fix for EEH I/O suspend/resume on i40e to ensure that I/O operations can continue after a resume. To avoid duplicate code, the common logic is factored out of i40e_suspend and i40e_resume. Paul Greenwalt provides a fix to correctly map the 200G PHY types to link speeds in the ice driver. Dave Ertman provides a fix correcting devlink parameter unregistration in the event that the driver loads in safe mode and some of the parameters were not registered. ==================== Link: https://lore.kernel.org/r/20240528-net-2024-05-28-intel-net-fixes-v1-0-dc8593d2bbc6@intel.com Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 278d65c + a51c9b1 commit 602d959

File tree

5 files changed

+195
-144
lines changed

5 files changed

+195
-144
lines changed

drivers/net/ethernet/intel/e1000e/ich8lan.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,28 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
12251225
}
12261226

12271227
release:
1228+
/* Switching PHY interface always returns MDI error
1229+
* so disable retry mechanism to avoid wasting time
1230+
*/
1231+
e1000e_disable_phy_retry(hw);
1232+
1233+
/* Force SMBus mode in PHY */
1234+
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
1235+
if (ret_val) {
1236+
e1000e_enable_phy_retry(hw);
1237+
hw->phy.ops.release(hw);
1238+
goto out;
1239+
}
1240+
phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
1241+
e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
1242+
1243+
e1000e_enable_phy_retry(hw);
1244+
1245+
/* Force SMBus mode in MAC */
1246+
mac_reg = er32(CTRL_EXT);
1247+
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
1248+
ew32(CTRL_EXT, mac_reg);
1249+
12281250
hw->phy.ops.release(hw);
12291251
out:
12301252
if (ret_val)

drivers/net/ethernet/intel/e1000e/netdev.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6623,7 +6623,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
66236623
struct e1000_hw *hw = &adapter->hw;
66246624
u32 ctrl, ctrl_ext, rctl, status, wufc;
66256625
int retval = 0;
6626-
u16 smb_ctrl;
66276626

66286627
/* Runtime suspend should only enable wakeup for link changes */
66296628
if (runtime)
@@ -6697,23 +6696,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
66976696
if (retval)
66986697
return retval;
66996698
}
6700-
6701-
/* Force SMBUS to allow WOL */
6702-
/* Switching PHY interface always returns MDI error
6703-
* so disable retry mechanism to avoid wasting time
6704-
*/
6705-
e1000e_disable_phy_retry(hw);
6706-
6707-
e1e_rphy(hw, CV_SMB_CTRL, &smb_ctrl);
6708-
smb_ctrl |= CV_SMB_CTRL_FORCE_SMBUS;
6709-
e1e_wphy(hw, CV_SMB_CTRL, smb_ctrl);
6710-
6711-
e1000e_enable_phy_retry(hw);
6712-
6713-
/* Force SMBus mode in MAC */
6714-
ctrl_ext = er32(CTRL_EXT);
6715-
ctrl_ext |= E1000_CTRL_EXT_FORCE_SMBUS;
6716-
ew32(CTRL_EXT, ctrl_ext);
67176699
}
67186700

67196701
/* Ensure that the appropriate bits are set in LPI_CTRL

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 141 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -11171,6 +11171,8 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit,
1117111171
ret = i40e_reset(pf);
1117211172
if (!ret)
1117311173
i40e_rebuild(pf, reinit, lock_acquired);
11174+
else
11175+
dev_err(&pf->pdev->dev, "%s: i40e_reset() FAILED", __func__);
1117411176
}
1117511177

1117611178
/**
@@ -16334,6 +16336,139 @@ static void i40e_remove(struct pci_dev *pdev)
1633416336
pci_disable_device(pdev);
1633516337
}
1633616338

16339+
/**
16340+
* i40e_enable_mc_magic_wake - enable multicast magic packet wake up
16341+
* using the mac_address_write admin q function
16342+
* @pf: pointer to i40e_pf struct
16343+
**/
16344+
static void i40e_enable_mc_magic_wake(struct i40e_pf *pf)
16345+
{
16346+
struct i40e_vsi *main_vsi = i40e_pf_get_main_vsi(pf);
16347+
struct i40e_hw *hw = &pf->hw;
16348+
u8 mac_addr[6];
16349+
u16 flags = 0;
16350+
int ret;
16351+
16352+
/* Get current MAC address in case it's an LAA */
16353+
if (main_vsi && main_vsi->netdev) {
16354+
ether_addr_copy(mac_addr, main_vsi->netdev->dev_addr);
16355+
} else {
16356+
dev_err(&pf->pdev->dev,
16357+
"Failed to retrieve MAC address; using default\n");
16358+
ether_addr_copy(mac_addr, hw->mac.addr);
16359+
}
16360+
16361+
/* The FW expects the mac address write cmd to first be called with
16362+
* one of these flags before calling it again with the multicast
16363+
* enable flags.
16364+
*/
16365+
flags = I40E_AQC_WRITE_TYPE_LAA_WOL;
16366+
16367+
if (hw->func_caps.flex10_enable && hw->partition_id != 1)
16368+
flags = I40E_AQC_WRITE_TYPE_LAA_ONLY;
16369+
16370+
ret = i40e_aq_mac_address_write(hw, flags, mac_addr, NULL);
16371+
if (ret) {
16372+
dev_err(&pf->pdev->dev,
16373+
"Failed to update MAC address registers; cannot enable Multicast Magic packet wake up");
16374+
return;
16375+
}
16376+
16377+
flags = I40E_AQC_MC_MAG_EN
16378+
| I40E_AQC_WOL_PRESERVE_ON_PFR
16379+
| I40E_AQC_WRITE_TYPE_UPDATE_MC_MAG;
16380+
ret = i40e_aq_mac_address_write(hw, flags, mac_addr, NULL);
16381+
if (ret)
16382+
dev_err(&pf->pdev->dev,
16383+
"Failed to enable Multicast Magic Packet wake up\n");
16384+
}
16385+
16386+
/**
16387+
* i40e_io_suspend - suspend all IO operations
16388+
* @pf: pointer to i40e_pf struct
16389+
*
16390+
**/
16391+
static int i40e_io_suspend(struct i40e_pf *pf)
16392+
{
16393+
struct i40e_hw *hw = &pf->hw;
16394+
16395+
set_bit(__I40E_DOWN, pf->state);
16396+
16397+
/* Ensure service task will not be running */
16398+
del_timer_sync(&pf->service_timer);
16399+
cancel_work_sync(&pf->service_task);
16400+
16401+
/* Client close must be called explicitly here because the timer
16402+
* has been stopped.
16403+
*/
16404+
i40e_notify_client_of_netdev_close(pf, false);
16405+
16406+
if (test_bit(I40E_HW_CAP_WOL_MC_MAGIC_PKT_WAKE, pf->hw.caps) &&
16407+
pf->wol_en)
16408+
i40e_enable_mc_magic_wake(pf);
16409+
16410+
/* Since we're going to destroy queues during the
16411+
* i40e_clear_interrupt_scheme() we should hold the RTNL lock for this
16412+
* whole section
16413+
*/
16414+
rtnl_lock();
16415+
16416+
i40e_prep_for_reset(pf);
16417+
16418+
wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
16419+
wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));
16420+
16421+
/* Clear the interrupt scheme and release our IRQs so that the system
16422+
* can safely hibernate even when there are a large number of CPUs.
16423+
* Otherwise hibernation might fail when mapping all the vectors back
16424+
* to CPU0.
16425+
*/
16426+
i40e_clear_interrupt_scheme(pf);
16427+
16428+
rtnl_unlock();
16429+
16430+
return 0;
16431+
}
16432+
16433+
/**
16434+
* i40e_io_resume - resume IO operations
16435+
* @pf: pointer to i40e_pf struct
16436+
*
16437+
**/
16438+
static int i40e_io_resume(struct i40e_pf *pf)
16439+
{
16440+
struct device *dev = &pf->pdev->dev;
16441+
int err;
16442+
16443+
/* We need to hold the RTNL lock prior to restoring interrupt schemes,
16444+
* since we're going to be restoring queues
16445+
*/
16446+
rtnl_lock();
16447+
16448+
/* We cleared the interrupt scheme when we suspended, so we need to
16449+
* restore it now to resume device functionality.
16450+
*/
16451+
err = i40e_restore_interrupt_scheme(pf);
16452+
if (err) {
16453+
dev_err(dev, "Cannot restore interrupt scheme: %d\n",
16454+
err);
16455+
}
16456+
16457+
clear_bit(__I40E_DOWN, pf->state);
16458+
i40e_reset_and_rebuild(pf, false, true);
16459+
16460+
rtnl_unlock();
16461+
16462+
/* Clear suspended state last after everything is recovered */
16463+
clear_bit(__I40E_SUSPENDED, pf->state);
16464+
16465+
/* Restart the service task */
16466+
mod_timer(&pf->service_timer,
16467+
round_jiffies(jiffies + pf->service_timer_period));
16468+
16469+
return 0;
16470+
}
16471+
1633716472
/**
1633816473
* i40e_pci_error_detected - warning that something funky happened in PCI land
1633916474
* @pdev: PCI device information struct
@@ -16358,7 +16493,7 @@ static pci_ers_result_t i40e_pci_error_detected(struct pci_dev *pdev,
1635816493

1635916494
/* shutdown all operations */
1636016495
if (!test_bit(__I40E_SUSPENDED, pf->state))
16361-
i40e_prep_for_reset(pf);
16496+
i40e_io_suspend(pf);
1636216497

1636316498
/* Request a slot reset */
1636416499
return PCI_ERS_RESULT_NEED_RESET;
@@ -16380,7 +16515,8 @@ static pci_ers_result_t i40e_pci_error_slot_reset(struct pci_dev *pdev)
1638016515
u32 reg;
1638116516

1638216517
dev_dbg(&pdev->dev, "%s\n", __func__);
16383-
if (pci_enable_device_mem(pdev)) {
16518+
/* enable I/O and memory of the device */
16519+
if (pci_enable_device(pdev)) {
1638416520
dev_info(&pdev->dev,
1638516521
"Cannot re-enable PCI device after reset.\n");
1638616522
result = PCI_ERS_RESULT_DISCONNECT;
@@ -16443,54 +16579,7 @@ static void i40e_pci_error_resume(struct pci_dev *pdev)
1644316579
if (test_bit(__I40E_SUSPENDED, pf->state))
1644416580
return;
1644516581

16446-
i40e_handle_reset_warning(pf, false);
16447-
}
16448-
16449-
/**
16450-
* i40e_enable_mc_magic_wake - enable multicast magic packet wake up
16451-
* using the mac_address_write admin q function
16452-
* @pf: pointer to i40e_pf struct
16453-
**/
16454-
static void i40e_enable_mc_magic_wake(struct i40e_pf *pf)
16455-
{
16456-
struct i40e_vsi *main_vsi = i40e_pf_get_main_vsi(pf);
16457-
struct i40e_hw *hw = &pf->hw;
16458-
u8 mac_addr[6];
16459-
u16 flags = 0;
16460-
int ret;
16461-
16462-
/* Get current MAC address in case it's an LAA */
16463-
if (main_vsi && main_vsi->netdev) {
16464-
ether_addr_copy(mac_addr, main_vsi->netdev->dev_addr);
16465-
} else {
16466-
dev_err(&pf->pdev->dev,
16467-
"Failed to retrieve MAC address; using default\n");
16468-
ether_addr_copy(mac_addr, hw->mac.addr);
16469-
}
16470-
16471-
/* The FW expects the mac address write cmd to first be called with
16472-
* one of these flags before calling it again with the multicast
16473-
* enable flags.
16474-
*/
16475-
flags = I40E_AQC_WRITE_TYPE_LAA_WOL;
16476-
16477-
if (hw->func_caps.flex10_enable && hw->partition_id != 1)
16478-
flags = I40E_AQC_WRITE_TYPE_LAA_ONLY;
16479-
16480-
ret = i40e_aq_mac_address_write(hw, flags, mac_addr, NULL);
16481-
if (ret) {
16482-
dev_err(&pf->pdev->dev,
16483-
"Failed to update MAC address registers; cannot enable Multicast Magic packet wake up");
16484-
return;
16485-
}
16486-
16487-
flags = I40E_AQC_MC_MAG_EN
16488-
| I40E_AQC_WOL_PRESERVE_ON_PFR
16489-
| I40E_AQC_WRITE_TYPE_UPDATE_MC_MAG;
16490-
ret = i40e_aq_mac_address_write(hw, flags, mac_addr, NULL);
16491-
if (ret)
16492-
dev_err(&pf->pdev->dev,
16493-
"Failed to enable Multicast Magic Packet wake up\n");
16582+
i40e_io_resume(pf);
1649416583
}
1649516584

1649616585
/**
@@ -16552,48 +16641,11 @@ static void i40e_shutdown(struct pci_dev *pdev)
1655216641
static int i40e_suspend(struct device *dev)
1655316642
{
1655416643
struct i40e_pf *pf = dev_get_drvdata(dev);
16555-
struct i40e_hw *hw = &pf->hw;
1655616644

1655716645
/* If we're already suspended, then there is nothing to do */
1655816646
if (test_and_set_bit(__I40E_SUSPENDED, pf->state))
1655916647
return 0;
16560-
16561-
set_bit(__I40E_DOWN, pf->state);
16562-
16563-
/* Ensure service task will not be running */
16564-
del_timer_sync(&pf->service_timer);
16565-
cancel_work_sync(&pf->service_task);
16566-
16567-
/* Client close must be called explicitly here because the timer
16568-
* has been stopped.
16569-
*/
16570-
i40e_notify_client_of_netdev_close(pf, false);
16571-
16572-
if (test_bit(I40E_HW_CAP_WOL_MC_MAGIC_PKT_WAKE, pf->hw.caps) &&
16573-
pf->wol_en)
16574-
i40e_enable_mc_magic_wake(pf);
16575-
16576-
/* Since we're going to destroy queues during the
16577-
* i40e_clear_interrupt_scheme() we should hold the RTNL lock for this
16578-
* whole section
16579-
*/
16580-
rtnl_lock();
16581-
16582-
i40e_prep_for_reset(pf);
16583-
16584-
wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
16585-
wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));
16586-
16587-
/* Clear the interrupt scheme and release our IRQs so that the system
16588-
* can safely hibernate even when there are a large number of CPUs.
16589-
* Otherwise hibernation might fail when mapping all the vectors back
16590-
* to CPU0.
16591-
*/
16592-
i40e_clear_interrupt_scheme(pf);
16593-
16594-
rtnl_unlock();
16595-
16596-
return 0;
16648+
return i40e_io_suspend(pf);
1659716649
}
1659816650

1659916651
/**
@@ -16603,39 +16655,11 @@ static int i40e_suspend(struct device *dev)
1660316655
static int i40e_resume(struct device *dev)
1660416656
{
1660516657
struct i40e_pf *pf = dev_get_drvdata(dev);
16606-
int err;
1660716658

1660816659
/* If we're not suspended, then there is nothing to do */
1660916660
if (!test_bit(__I40E_SUSPENDED, pf->state))
1661016661
return 0;
16611-
16612-
/* We need to hold the RTNL lock prior to restoring interrupt schemes,
16613-
* since we're going to be restoring queues
16614-
*/
16615-
rtnl_lock();
16616-
16617-
/* We cleared the interrupt scheme when we suspended, so we need to
16618-
* restore it now to resume device functionality.
16619-
*/
16620-
err = i40e_restore_interrupt_scheme(pf);
16621-
if (err) {
16622-
dev_err(dev, "Cannot restore interrupt scheme: %d\n",
16623-
err);
16624-
}
16625-
16626-
clear_bit(__I40E_DOWN, pf->state);
16627-
i40e_reset_and_rebuild(pf, false, true);
16628-
16629-
rtnl_unlock();
16630-
16631-
/* Clear suspended state last after everything is recovered */
16632-
clear_bit(__I40E_SUSPENDED, pf->state);
16633-
16634-
/* Restart the service task */
16635-
mod_timer(&pf->service_timer,
16636-
round_jiffies(jiffies + pf->service_timer_period));
16637-
16638-
return 0;
16662+
return i40e_io_resume(pf);
1663916663
}
1664016664

1664116665
static const struct pci_error_handlers i40e_err_handler = {

0 commit comments

Comments
 (0)