aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorAjit Khaparde <ajit.khaparde@emulex.com>2012-03-18 02:23:11 -0400
committerDavid S. Miller <davem@davemloft.net>2012-03-19 16:52:17 -0400
commit4762f6cec4455f3bbe4ca82c100fe5d85d3c02a2 (patch)
tree51cf21b4a949b8a3292019f81447d8a9a719d7e3 /drivers/net/ethernet/emulex
parent277074777cd9c004b1ac32689772370c38fd00e2 (diff)
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>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h26
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c55
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h28
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c27
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c17
5 files changed, 136 insertions, 17 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index ab24e4600695..cabe1b892722 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -52,6 +52,10 @@
52#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */ 52#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
53#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */ 53#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
54#define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */ 54#define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */
55#define OC_SUBSYS_DEVICE_ID1 0xE602
56#define OC_SUBSYS_DEVICE_ID2 0xE642
57#define OC_SUBSYS_DEVICE_ID3 0xE612
58#define OC_SUBSYS_DEVICE_ID4 0xE652
55 59
56static inline char *nic_name(struct pci_dev *pdev) 60static inline char *nic_name(struct pci_dev *pdev)
57{ 61{
@@ -365,7 +369,6 @@ struct be_adapter {
365 bool fw_timeout; 369 bool fw_timeout;
366 u32 port_num; 370 u32 port_num;
367 bool promiscuous; 371 bool promiscuous;
368 bool wol;
369 u32 function_mode; 372 u32 function_mode;
370 u32 function_caps; 373 u32 function_caps;
371 u32 rx_fc; /* Rx flow control */ 374 u32 rx_fc; /* Rx flow control */
@@ -386,6 +389,8 @@ struct be_adapter {
386 u32 sli_family; 389 u32 sli_family;
387 u8 hba_port_num; 390 u8 hba_port_num;
388 u16 pvid; 391 u16 pvid;
392 u8 wol_cap;
393 bool wol;
389}; 394};
390 395
391#define be_physfn(adapter) (!adapter->is_virtfn) 396#define be_physfn(adapter) (!adapter->is_virtfn)
@@ -549,9 +554,28 @@ static inline bool be_error(struct be_adapter *adapter)
549 return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout; 554 return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout;
550} 555}
551 556
557static inline bool be_is_wol_excluded(struct be_adapter *adapter)
558{
559 struct pci_dev *pdev = adapter->pdev;
560
561 if (!be_physfn(adapter))
562 return true;
563
564 switch (pdev->subsystem_device) {
565 case OC_SUBSYS_DEVICE_ID1:
566 case OC_SUBSYS_DEVICE_ID2:
567 case OC_SUBSYS_DEVICE_ID3:
568 case OC_SUBSYS_DEVICE_ID4:
569 return true;
570 default:
571 return false;
572 }
573}
574
552extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, 575extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
553 u16 num_popped); 576 u16 num_popped);
554extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); 577extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
555extern void be_parse_stats(struct be_adapter *adapter); 578extern void be_parse_stats(struct be_adapter *adapter);
556extern int be_load_fw(struct be_adapter *adapter, u8 *func); 579extern int be_load_fw(struct be_adapter *adapter, u8 *func);
580extern bool be_is_wol_supported(struct be_adapter *adapter);
557#endif /* BE_H */ 581#endif /* BE_H */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 398fb5ca0fe2..d72c2b46963c 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2418,3 +2418,58 @@ err:
2418 spin_unlock_bh(&adapter->mcc_lock); 2418 spin_unlock_bh(&adapter->mcc_lock);
2419 return status; 2419 return status;
2420} 2420}
2421
2422int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
2423{
2424 struct be_mcc_wrb *wrb;
2425 struct be_cmd_req_acpi_wol_magic_config_v1 *req;
2426 int status;
2427 int payload_len = sizeof(*req);
2428 struct be_dma_mem cmd;
2429
2430 memset(&cmd, 0, sizeof(struct be_dma_mem));
2431 cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
2432 cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
2433 &cmd.dma);
2434 if (!cmd.va) {
2435 dev_err(&adapter->pdev->dev,
2436 "Memory allocation failure\n");
2437 return -ENOMEM;
2438 }
2439
2440 if (mutex_lock_interruptible(&adapter->mbox_lock))
2441 return -1;
2442
2443 wrb = wrb_from_mbox(adapter);
2444 if (!wrb) {
2445 status = -EBUSY;
2446 goto err;
2447 }
2448
2449 req = cmd.va;
2450
2451 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
2452 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
2453 payload_len, wrb, &cmd);
2454
2455 req->hdr.version = 1;
2456 req->query_options = BE_GET_WOL_CAP;
2457
2458 status = be_mbox_notify_wait(adapter);
2459 if (!status) {
2460 struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
2461 resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *) cmd.va;
2462
2463 /* the command could succeed misleadingly on old f/w
2464 * which is not aware of the V1 version. fake an error. */
2465 if (resp->hdr.response_length < payload_len) {
2466 status = -1;
2467 goto err;
2468 }
2469 adapter->wol_cap = resp->wol_settings;
2470 }
2471err:
2472 mutex_unlock(&adapter->mbox_lock);
2473 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
2474 return status;
2475}
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 687c42071411..345d49eeadc8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1206,6 +1206,33 @@ struct be_cmd_req_acpi_wol_magic_config{
1206 u8 rsvd2[2]; 1206 u8 rsvd2[2];
1207} __packed; 1207} __packed;
1208 1208
1209struct be_cmd_req_acpi_wol_magic_config_v1 {
1210 struct be_cmd_req_hdr hdr;
1211 u8 rsvd0[2];
1212 u8 query_options;
1213 u8 rsvd1[5];
1214 u32 rsvd2[288];
1215 u8 magic_mac[6];
1216 u8 rsvd3[22];
1217} __packed;
1218
1219struct be_cmd_resp_acpi_wol_magic_config_v1 {
1220 struct be_cmd_resp_hdr hdr;
1221 u8 rsvd0[2];
1222 u8 wol_settings;
1223 u8 rsvd1[5];
1224 u32 rsvd2[295];
1225} __packed;
1226
1227#define BE_GET_WOL_CAP 2
1228
1229#define BE_WOL_CAP 0x1
1230#define BE_PME_D0_CAP 0x8
1231#define BE_PME_D1_CAP 0x10
1232#define BE_PME_D2_CAP 0x20
1233#define BE_PME_D3HOT_CAP 0x40
1234#define BE_PME_D3COLD_CAP 0x80
1235
1209/********************** LoopBack test *********************/ 1236/********************** LoopBack test *********************/
1210struct be_cmd_req_loopback_test { 1237struct be_cmd_req_loopback_test {
1211 struct be_cmd_req_hdr hdr; 1238 struct be_cmd_req_hdr hdr;
@@ -1590,4 +1617,5 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
1590 bool *pmac_id_active, u32 *pmac_id, u8 *mac); 1617 bool *pmac_id_active, u32 *pmac_id, u8 *mac);
1591extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, 1618extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
1592 u8 mac_count, u32 domain); 1619 u8 mac_count, u32 domain);
1620extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
1593 1621
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 30ce17806916..c1ff73cb0e62 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -600,26 +600,16 @@ be_set_phys_id(struct net_device *netdev,
600 return 0; 600 return 0;
601} 601}
602 602
603static bool
604be_is_wol_supported(struct be_adapter *adapter)
605{
606 if (!be_physfn(adapter))
607 return false;
608 else
609 return true;
610}
611 603
612static void 604static void
613be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) 605be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
614{ 606{
615 struct be_adapter *adapter = netdev_priv(netdev); 607 struct be_adapter *adapter = netdev_priv(netdev);
616 608
617 if (be_is_wol_supported(adapter)) 609 if (be_is_wol_supported(adapter)) {
618 wol->supported = WAKE_MAGIC; 610 wol->supported |= WAKE_MAGIC;
619 611 wol->wolopts |= WAKE_MAGIC;
620 if (adapter->wol) 612 } else
621 wol->wolopts = WAKE_MAGIC;
622 else
623 wol->wolopts = 0; 613 wol->wolopts = 0;
624 memset(&wol->sopass, 0, sizeof(wol->sopass)); 614 memset(&wol->sopass, 0, sizeof(wol->sopass));
625} 615}
@@ -630,9 +620,14 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
630 struct be_adapter *adapter = netdev_priv(netdev); 620 struct be_adapter *adapter = netdev_priv(netdev);
631 621
632 if (wol->wolopts & ~WAKE_MAGIC) 622 if (wol->wolopts & ~WAKE_MAGIC)
633 return -EINVAL; 623 return -EOPNOTSUPP;
624
625 if (!be_is_wol_supported(adapter)) {
626 dev_warn(&adapter->pdev->dev, "WOL not supported\n");
627 return -EOPNOTSUPP;
628 }
634 629
635 if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter)) 630 if (wol->wolopts & WAKE_MAGIC)
636 adapter->wol = true; 631 adapter->wol = true;
637 else 632 else
638 adapter->wol = false; 633 adapter->wol = false;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index e3822788f532..050e3ebd4fb3 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3244,6 +3244,12 @@ static void __devexit be_remove(struct pci_dev *pdev)
3244 free_netdev(adapter->netdev); 3244 free_netdev(adapter->netdev);
3245} 3245}
3246 3246
3247bool be_is_wol_supported(struct be_adapter *adapter)
3248{
3249 return ((adapter->wol_cap & BE_WOL_CAP) &&
3250 !be_is_wol_excluded(adapter)) ? true : false;
3251}
3252
3247static int be_get_config(struct be_adapter *adapter) 3253static int be_get_config(struct be_adapter *adapter)
3248{ 3254{
3249 int status; 3255 int status;
@@ -3262,6 +3268,17 @@ static int be_get_config(struct be_adapter *adapter)
3262 if (status) 3268 if (status)
3263 return status; 3269 return status;
3264 3270
3271 status = be_cmd_get_acpi_wol_cap(adapter);
3272 if (status) {
3273 /* in case of a failure to get wol capabillities
3274 * check the exclusion list to determine WOL capability */
3275 if (!be_is_wol_excluded(adapter))
3276 adapter->wol_cap |= BE_WOL_CAP;
3277 }
3278
3279 if (be_is_wol_supported(adapter))
3280 adapter->wol = true;
3281
3265 return 0; 3282 return 0;
3266} 3283}
3267 3284