aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/benet/be.h1
-rw-r--r--drivers/net/benet/be_cmds.c36
-rw-r--r--drivers/net/benet/be_cmds.h11
-rw-r--r--drivers/net/benet/be_ethtool.c32
-rw-r--r--drivers/net/benet/be_hw.h4
-rw-r--r--drivers/net/benet/be_main.c44
6 files changed, 128 insertions, 0 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 12247480a1f8..e71cc5949413 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -269,6 +269,7 @@ struct be_adapter {
269 bool link_up; 269 bool link_up;
270 u32 port_num; 270 u32 port_num;
271 bool promiscuous; 271 bool promiscuous;
272 bool wol;
272 u32 cap; 273 u32 cap;
273 u32 rx_fc; /* Rx flow control */ 274 u32 rx_fc; /* Rx flow control */
274 u32 tx_fc; /* Tx flow control */ 275 u32 tx_fc; /* Tx flow control */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 5ec61de3b97f..bee7b822d120 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1442,3 +1442,39 @@ err:
1442 spin_unlock_bh(&adapter->mcc_lock); 1442 spin_unlock_bh(&adapter->mcc_lock);
1443 return status; 1443 return status;
1444} 1444}
1445
1446extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
1447 struct be_dma_mem *nonemb_cmd)
1448{
1449 struct be_mcc_wrb *wrb;
1450 struct be_cmd_req_acpi_wol_magic_config *req;
1451 struct be_sge *sge;
1452 int status;
1453
1454 spin_lock_bh(&adapter->mcc_lock);
1455
1456 wrb = wrb_from_mccq(adapter);
1457 if (!wrb) {
1458 status = -EBUSY;
1459 goto err;
1460 }
1461 req = nonemb_cmd->va;
1462 sge = nonembedded_sgl(wrb);
1463
1464 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
1465 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG);
1466
1467 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
1468 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req));
1469 memcpy(req->magic_mac, mac, ETH_ALEN);
1470
1471 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1472 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1473 sge->len = cpu_to_le32(nonemb_cmd->size);
1474
1475 status = be_mcc_notify_wait(adapter);
1476
1477err:
1478 spin_unlock_bh(&adapter->mcc_lock);
1479 return status;
1480}
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 8ec6528cb054..e8512a144f5e 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -150,6 +150,7 @@ struct be_mcc_mailbox {
150#define OPCODE_ETH_RX_CREATE 8 150#define OPCODE_ETH_RX_CREATE 8
151#define OPCODE_ETH_TX_DESTROY 9 151#define OPCODE_ETH_TX_DESTROY 9
152#define OPCODE_ETH_RX_DESTROY 10 152#define OPCODE_ETH_RX_DESTROY 10
153#define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG 12
153 154
154struct be_cmd_req_hdr { 155struct be_cmd_req_hdr {
155 u8 opcode; /* dword 0 */ 156 u8 opcode; /* dword 0 */
@@ -788,6 +789,14 @@ struct be_cmd_write_flashrom {
788 struct flashrom_params params; 789 struct flashrom_params params;
789}; 790};
790 791
792/************************ WOL *******************************/
793struct be_cmd_req_acpi_wol_magic_config{
794 struct be_cmd_req_hdr hdr;
795 u32 rsvd0[145];
796 u8 magic_mac[6];
797 u8 rsvd2[2];
798} __packed;
799
791extern int be_pci_fnum_get(struct be_adapter *adapter); 800extern int be_pci_fnum_get(struct be_adapter *adapter);
792extern int be_cmd_POST(struct be_adapter *adapter); 801extern int be_cmd_POST(struct be_adapter *adapter);
793extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, 802extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -851,5 +860,7 @@ extern int be_cmd_write_flashrom(struct be_adapter *adapter,
851 struct be_dma_mem *cmd, u32 flash_oper, 860 struct be_dma_mem *cmd, u32 flash_oper,
852 u32 flash_opcode, u32 buf_size); 861 u32 flash_opcode, u32 buf_size);
853extern int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc); 862extern int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc);
863extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
864 struct be_dma_mem *nonemb_cmd);
854extern int be_cmd_fw_init(struct be_adapter *adapter); 865extern int be_cmd_fw_init(struct be_adapter *adapter);
855extern int be_cmd_fw_clean(struct be_adapter *adapter); 866extern int be_cmd_fw_clean(struct be_adapter *adapter);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 329560f9e543..83a2fc703995 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -411,6 +411,36 @@ be_phys_id(struct net_device *netdev, u32 data)
411 return status; 411 return status;
412} 412}
413 413
414static void
415be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
416{
417 struct be_adapter *adapter = netdev_priv(netdev);
418
419 wol->supported = WAKE_MAGIC;
420 if (adapter->wol)
421 wol->wolopts = WAKE_MAGIC;
422 else
423 wol->wolopts = 0;
424 memset(&wol->sopass, 0, sizeof(wol->sopass));
425 return;
426}
427
428static int
429be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
430{
431 struct be_adapter *adapter = netdev_priv(netdev);
432
433 if (wol->wolopts & ~WAKE_MAGIC)
434 return -EINVAL;
435
436 if (wol->wolopts & WAKE_MAGIC)
437 adapter->wol = true;
438 else
439 adapter->wol = false;
440
441 return 0;
442}
443
414static int 444static int
415be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) 445be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
416{ 446{
@@ -428,6 +458,8 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
428const struct ethtool_ops be_ethtool_ops = { 458const struct ethtool_ops be_ethtool_ops = {
429 .get_settings = be_get_settings, 459 .get_settings = be_get_settings,
430 .get_drvinfo = be_get_drvinfo, 460 .get_drvinfo = be_get_drvinfo,
461 .get_wol = be_get_wol,
462 .set_wol = be_set_wol,
431 .get_link = ethtool_op_get_link, 463 .get_link = ethtool_op_get_link,
432 .get_coalesce = be_get_coalesce, 464 .get_coalesce = be_get_coalesce,
433 .set_coalesce = be_set_coalesce, 465 .set_coalesce = be_set_coalesce,
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index f53d5ca2da9e..e2b3beffd49d 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -52,6 +52,10 @@
52 */ 52 */
53#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */ 53#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */
54 54
55/********* Power managment (WOL) **********/
56#define PCICFG_PM_CONTROL_OFFSET 0x44
57#define PCICFG_PM_CONTROL_MASK 0x108 /* bits 3 & 8 */
58
55/********* ISR0 Register offset **********/ 59/********* ISR0 Register offset **********/
56#define CEV_ISR0_OFFSET 0xC18 60#define CEV_ISR0_OFFSET 0xC18
57#define CEV_ISR_SIZE 4 61#define CEV_ISR_SIZE 4
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index f24ac4b5ce8f..84f686f41b53 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1659,6 +1659,44 @@ ret_sts:
1659 return status; 1659 return status;
1660} 1660}
1661 1661
1662static int be_setup_wol(struct be_adapter *adapter, bool enable)
1663{
1664 struct be_dma_mem cmd;
1665 int status = 0;
1666 u8 mac[ETH_ALEN];
1667
1668 memset(mac, 0, ETH_ALEN);
1669
1670 cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
1671 cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
1672 if (cmd.va == NULL)
1673 return -1;
1674 memset(cmd.va, 0, cmd.size);
1675
1676 if (enable) {
1677 status = pci_write_config_dword(adapter->pdev,
1678 PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK);
1679 if (status) {
1680 dev_err(&adapter->pdev->dev,
1681 "Could not enable Wake-on-lan \n");
1682 pci_free_consistent(adapter->pdev, cmd.size, cmd.va,
1683 cmd.dma);
1684 return status;
1685 }
1686 status = be_cmd_enable_magic_wol(adapter,
1687 adapter->netdev->dev_addr, &cmd);
1688 pci_enable_wake(adapter->pdev, PCI_D3hot, 1);
1689 pci_enable_wake(adapter->pdev, PCI_D3cold, 1);
1690 } else {
1691 status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
1692 pci_enable_wake(adapter->pdev, PCI_D3hot, 0);
1693 pci_enable_wake(adapter->pdev, PCI_D3cold, 0);
1694 }
1695
1696 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
1697 return status;
1698}
1699
1662static int be_setup(struct be_adapter *adapter) 1700static int be_setup(struct be_adapter *adapter)
1663{ 1701{
1664 struct net_device *netdev = adapter->netdev; 1702 struct net_device *netdev = adapter->netdev;
@@ -2282,6 +2320,9 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
2282 struct be_adapter *adapter = pci_get_drvdata(pdev); 2320 struct be_adapter *adapter = pci_get_drvdata(pdev);
2283 struct net_device *netdev = adapter->netdev; 2321 struct net_device *netdev = adapter->netdev;
2284 2322
2323 if (adapter->wol)
2324 be_setup_wol(adapter, true);
2325
2285 netif_device_detach(netdev); 2326 netif_device_detach(netdev);
2286 if (netif_running(netdev)) { 2327 if (netif_running(netdev)) {
2287 rtnl_lock(); 2328 rtnl_lock();
@@ -2324,6 +2365,9 @@ static int be_resume(struct pci_dev *pdev)
2324 rtnl_unlock(); 2365 rtnl_unlock();
2325 } 2366 }
2326 netif_device_attach(netdev); 2367 netif_device_attach(netdev);
2368
2369 if (adapter->wol)
2370 be_setup_wol(adapter, false);
2327 return 0; 2371 return 0;
2328} 2372}
2329 2373