be2net: enable WOL by default if h/w supports it
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
277074777c
Коммит
4762f6cec4
|
@ -52,6 +52,10 @@
|
|||
#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
|
||||
#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
|
||||
#define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */
|
||||
#define OC_SUBSYS_DEVICE_ID1 0xE602
|
||||
#define OC_SUBSYS_DEVICE_ID2 0xE642
|
||||
#define OC_SUBSYS_DEVICE_ID3 0xE612
|
||||
#define OC_SUBSYS_DEVICE_ID4 0xE652
|
||||
|
||||
static inline char *nic_name(struct pci_dev *pdev)
|
||||
{
|
||||
|
@ -365,7 +369,6 @@ struct be_adapter {
|
|||
bool fw_timeout;
|
||||
u32 port_num;
|
||||
bool promiscuous;
|
||||
bool wol;
|
||||
u32 function_mode;
|
||||
u32 function_caps;
|
||||
u32 rx_fc; /* Rx flow control */
|
||||
|
@ -386,6 +389,8 @@ struct be_adapter {
|
|||
u32 sli_family;
|
||||
u8 hba_port_num;
|
||||
u16 pvid;
|
||||
u8 wol_cap;
|
||||
bool wol;
|
||||
};
|
||||
|
||||
#define be_physfn(adapter) (!adapter->is_virtfn)
|
||||
|
@ -549,9 +554,28 @@ static inline bool be_error(struct be_adapter *adapter)
|
|||
return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout;
|
||||
}
|
||||
|
||||
static inline bool be_is_wol_excluded(struct be_adapter *adapter)
|
||||
{
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
|
||||
if (!be_physfn(adapter))
|
||||
return true;
|
||||
|
||||
switch (pdev->subsystem_device) {
|
||||
case OC_SUBSYS_DEVICE_ID1:
|
||||
case OC_SUBSYS_DEVICE_ID2:
|
||||
case OC_SUBSYS_DEVICE_ID3:
|
||||
case OC_SUBSYS_DEVICE_ID4:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
|
||||
u16 num_popped);
|
||||
extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
|
||||
extern void be_parse_stats(struct be_adapter *adapter);
|
||||
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
|
||||
extern bool be_is_wol_supported(struct be_adapter *adapter);
|
||||
#endif /* BE_H */
|
||||
|
|
|
@ -2418,3 +2418,58 @@ err:
|
|||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
|
||||
{
|
||||
struct be_mcc_wrb *wrb;
|
||||
struct be_cmd_req_acpi_wol_magic_config_v1 *req;
|
||||
int status;
|
||||
int payload_len = sizeof(*req);
|
||||
struct be_dma_mem cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(struct be_dma_mem));
|
||||
cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
|
||||
cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
|
||||
&cmd.dma);
|
||||
if (!cmd.va) {
|
||||
dev_err(&adapter->pdev->dev,
|
||||
"Memory allocation failure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (mutex_lock_interruptible(&adapter->mbox_lock))
|
||||
return -1;
|
||||
|
||||
wrb = wrb_from_mbox(adapter);
|
||||
if (!wrb) {
|
||||
status = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
req = cmd.va;
|
||||
|
||||
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
|
||||
OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
|
||||
payload_len, wrb, &cmd);
|
||||
|
||||
req->hdr.version = 1;
|
||||
req->query_options = BE_GET_WOL_CAP;
|
||||
|
||||
status = be_mbox_notify_wait(adapter);
|
||||
if (!status) {
|
||||
struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
|
||||
resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *) cmd.va;
|
||||
|
||||
/* the command could succeed misleadingly on old f/w
|
||||
* which is not aware of the V1 version. fake an error. */
|
||||
if (resp->hdr.response_length < payload_len) {
|
||||
status = -1;
|
||||
goto err;
|
||||
}
|
||||
adapter->wol_cap = resp->wol_settings;
|
||||
}
|
||||
err:
|
||||
mutex_unlock(&adapter->mbox_lock);
|
||||
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -1206,6 +1206,33 @@ struct be_cmd_req_acpi_wol_magic_config{
|
|||
u8 rsvd2[2];
|
||||
} __packed;
|
||||
|
||||
struct be_cmd_req_acpi_wol_magic_config_v1 {
|
||||
struct be_cmd_req_hdr hdr;
|
||||
u8 rsvd0[2];
|
||||
u8 query_options;
|
||||
u8 rsvd1[5];
|
||||
u32 rsvd2[288];
|
||||
u8 magic_mac[6];
|
||||
u8 rsvd3[22];
|
||||
} __packed;
|
||||
|
||||
struct be_cmd_resp_acpi_wol_magic_config_v1 {
|
||||
struct be_cmd_resp_hdr hdr;
|
||||
u8 rsvd0[2];
|
||||
u8 wol_settings;
|
||||
u8 rsvd1[5];
|
||||
u32 rsvd2[295];
|
||||
} __packed;
|
||||
|
||||
#define BE_GET_WOL_CAP 2
|
||||
|
||||
#define BE_WOL_CAP 0x1
|
||||
#define BE_PME_D0_CAP 0x8
|
||||
#define BE_PME_D1_CAP 0x10
|
||||
#define BE_PME_D2_CAP 0x20
|
||||
#define BE_PME_D3HOT_CAP 0x40
|
||||
#define BE_PME_D3COLD_CAP 0x80
|
||||
|
||||
/********************** LoopBack test *********************/
|
||||
struct be_cmd_req_loopback_test {
|
||||
struct be_cmd_req_hdr hdr;
|
||||
|
@ -1590,4 +1617,5 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
|
|||
bool *pmac_id_active, u32 *pmac_id, u8 *mac);
|
||||
extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
|
||||
u8 mac_count, u32 domain);
|
||||
extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
|
||||
|
||||
|
|
|
@ -600,26 +600,16 @@ be_set_phys_id(struct net_device *netdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
be_is_wol_supported(struct be_adapter *adapter)
|
||||
{
|
||||
if (!be_physfn(adapter))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (be_is_wol_supported(adapter))
|
||||
wol->supported = WAKE_MAGIC;
|
||||
|
||||
if (adapter->wol)
|
||||
wol->wolopts = WAKE_MAGIC;
|
||||
else
|
||||
if (be_is_wol_supported(adapter)) {
|
||||
wol->supported |= WAKE_MAGIC;
|
||||
wol->wolopts |= WAKE_MAGIC;
|
||||
} else
|
||||
wol->wolopts = 0;
|
||||
memset(&wol->sopass, 0, sizeof(wol->sopass));
|
||||
}
|
||||
|
@ -630,9 +620,14 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
|
|||
struct be_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if (wol->wolopts & ~WAKE_MAGIC)
|
||||
return -EINVAL;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter))
|
||||
if (!be_is_wol_supported(adapter)) {
|
||||
dev_warn(&adapter->pdev->dev, "WOL not supported\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (wol->wolopts & WAKE_MAGIC)
|
||||
adapter->wol = true;
|
||||
else
|
||||
adapter->wol = false;
|
||||
|
|
|
@ -3244,6 +3244,12 @@ static void __devexit be_remove(struct pci_dev *pdev)
|
|||
free_netdev(adapter->netdev);
|
||||
}
|
||||
|
||||
bool be_is_wol_supported(struct be_adapter *adapter)
|
||||
{
|
||||
return ((adapter->wol_cap & BE_WOL_CAP) &&
|
||||
!be_is_wol_excluded(adapter)) ? true : false;
|
||||
}
|
||||
|
||||
static int be_get_config(struct be_adapter *adapter)
|
||||
{
|
||||
int status;
|
||||
|
@ -3262,6 +3268,17 @@ static int be_get_config(struct be_adapter *adapter)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
status = be_cmd_get_acpi_wol_cap(adapter);
|
||||
if (status) {
|
||||
/* in case of a failure to get wol capabillities
|
||||
* check the exclusion list to determine WOL capability */
|
||||
if (!be_is_wol_excluded(adapter))
|
||||
adapter->wol_cap |= BE_WOL_CAP;
|
||||
}
|
||||
|
||||
if (be_is_wol_supported(adapter))
|
||||
adapter->wol = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче