Skip to content

Commit 45f13df

Browse files
sbasavapatnadavem330
authored andcommitted
be2net: Enable Wake-On-LAN from shutdown for Skyhawk
Skyhawk does support wake-up from ACPI shutdown state - S5, provided the platform supports it (like Auxiliary power source etc). The changes listed below are done to fix this. 1) There's no need to defer the HW configuration of WOL to be_suspend(). Remove this in be_suspend() and move it to be_set_wol() ethtool function so it is configured directly in the context of ethtool. This automatically takes care of the shutdown case. 2) The driver incorrectly uses WOL_CAP field in the FW response to get_acpi_wol_cap() command, to determine if WOL is enabled. Instead the driver must rely on the macaddr field in the response to infer WOL state. 3) In be_get_config() during init, if we find that WOL is enabled in FW, call pci_enable_wake() to enable pmcsr.pme_en bit. This is needed to support persistent WOL configuration provided by the FW in some platforms. 4) Remove code in be_set_wol() that writes to PCICFG_PM_CONTROL_OFFSET to set pme_en bit; pci_enable_wake() sets that. Fixes: 028991e ("Enabling Wake-on-LAN is not supported in S5 state") Signed-off-by: Sriharsha Basavapatna <[email protected]> Signed-off-by: Sathya Perla <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b9263cb commit 45f13df

File tree

4 files changed

+39
-47
lines changed

4 files changed

+39
-47
lines changed

drivers/net/ethernet/emulex/benet/be_cmds.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4023,7 +4023,10 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
40234023
resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *)cmd.va;
40244024

40254025
adapter->wol_cap = resp->wol_settings;
4026-
if (adapter->wol_cap & BE_WOL_CAP)
4026+
4027+
/* Non-zero macaddr indicates WOL is enabled */
4028+
if (adapter->wol_cap & BE_WOL_CAP &&
4029+
!is_zero_ether_addr(resp->magic_mac))
40274030
adapter->wol_en = true;
40284031
}
40294032
err:

drivers/net/ethernet/emulex/benet/be_cmds.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,9 @@ struct be_cmd_resp_acpi_wol_magic_config_v1 {
15561556
u8 rsvd0[2];
15571557
u8 wol_settings;
15581558
u8 rsvd1[5];
1559-
u32 rsvd2[295];
1559+
u32 rsvd2[288];
1560+
u8 magic_mac[6];
1561+
u8 rsvd3[22];
15601562
} __packed;
15611563

15621564
#define BE_GET_WOL_CAP 2

drivers/net/ethernet/emulex/benet/be_ethtool.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,11 @@ static void be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
793793
static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
794794
{
795795
struct be_adapter *adapter = netdev_priv(netdev);
796+
struct device *dev = &adapter->pdev->dev;
797+
struct be_dma_mem cmd;
798+
u8 mac[ETH_ALEN];
799+
bool enable;
800+
int status;
796801

797802
if (wol->wolopts & ~WAKE_MAGIC)
798803
return -EOPNOTSUPP;
@@ -802,12 +807,32 @@ static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
802807
return -EOPNOTSUPP;
803808
}
804809

805-
if (wol->wolopts & WAKE_MAGIC)
806-
adapter->wol_en = true;
807-
else
808-
adapter->wol_en = false;
810+
cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
811+
cmd.va = dma_zalloc_coherent(dev, cmd.size, &cmd.dma, GFP_KERNEL);
812+
if (!cmd.va)
813+
return -ENOMEM;
809814

810-
return 0;
815+
eth_zero_addr(mac);
816+
817+
enable = wol->wolopts & WAKE_MAGIC;
818+
if (enable)
819+
ether_addr_copy(mac, adapter->netdev->dev_addr);
820+
821+
status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
822+
if (status) {
823+
dev_err(dev, "Could not set Wake-on-lan mac address\n");
824+
status = be_cmd_status(status);
825+
goto err;
826+
}
827+
828+
pci_enable_wake(adapter->pdev, PCI_D3hot, enable);
829+
pci_enable_wake(adapter->pdev, PCI_D3cold, enable);
830+
831+
adapter->wol_en = enable ? true : false;
832+
833+
err:
834+
dma_free_coherent(dev, cmd.size, cmd.va, cmd.dma);
835+
return status;
811836
}
812837

813838
static int be_test_ddr_dma(struct be_adapter *adapter)

drivers/net/ethernet/emulex/benet/be_main.c

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3636,40 +3636,6 @@ static int be_open(struct net_device *netdev)
36363636
return -EIO;
36373637
}
36383638

3639-
static int be_setup_wol(struct be_adapter *adapter, bool enable)
3640-
{
3641-
struct device *dev = &adapter->pdev->dev;
3642-
struct be_dma_mem cmd;
3643-
u8 mac[ETH_ALEN];
3644-
int status;
3645-
3646-
eth_zero_addr(mac);
3647-
3648-
cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
3649-
cmd.va = dma_zalloc_coherent(dev, cmd.size, &cmd.dma, GFP_KERNEL);
3650-
if (!cmd.va)
3651-
return -ENOMEM;
3652-
3653-
if (enable) {
3654-
status = pci_write_config_dword(adapter->pdev,
3655-
PCICFG_PM_CONTROL_OFFSET,
3656-
PCICFG_PM_CONTROL_MASK);
3657-
if (status) {
3658-
dev_err(dev, "Could not enable Wake-on-lan\n");
3659-
goto err;
3660-
}
3661-
} else {
3662-
ether_addr_copy(mac, adapter->netdev->dev_addr);
3663-
}
3664-
3665-
status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
3666-
pci_enable_wake(adapter->pdev, PCI_D3hot, enable);
3667-
pci_enable_wake(adapter->pdev, PCI_D3cold, enable);
3668-
err:
3669-
dma_free_coherent(dev, cmd.size, cmd.va, cmd.dma);
3670-
return status;
3671-
}
3672-
36733639
static void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
36743640
{
36753641
u32 addr;
@@ -4294,6 +4260,8 @@ static int be_get_config(struct be_adapter *adapter)
42944260
}
42954261

42964262
be_cmd_get_acpi_wol_cap(adapter);
4263+
pci_enable_wake(adapter->pdev, PCI_D3hot, adapter->wol_en);
4264+
pci_enable_wake(adapter->pdev, PCI_D3cold, adapter->wol_en);
42974265

42984266
be_cmd_query_port_name(adapter);
42994267

@@ -5463,9 +5431,6 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
54635431
{
54645432
struct be_adapter *adapter = pci_get_drvdata(pdev);
54655433

5466-
if (adapter->wol_en)
5467-
be_setup_wol(adapter, true);
5468-
54695434
be_intr_set(adapter, false);
54705435
be_cancel_err_detection(adapter);
54715436

@@ -5494,9 +5459,6 @@ static int be_pci_resume(struct pci_dev *pdev)
54945459

54955460
be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
54965461

5497-
if (adapter->wol_en)
5498-
be_setup_wol(adapter, false);
5499-
55005462
return 0;
55015463
}
55025464

0 commit comments

Comments
 (0)