diff options
| -rw-r--r-- | drivers/net/benet/be.h | 1 | ||||
| -rw-r--r-- | drivers/net/benet/be_cmds.c | 36 | ||||
| -rw-r--r-- | drivers/net/benet/be_cmds.h | 11 | ||||
| -rw-r--r-- | drivers/net/benet/be_ethtool.c | 32 | ||||
| -rw-r--r-- | drivers/net/benet/be_hw.h | 4 | ||||
| -rw-r--r-- | drivers/net/benet/be_main.c | 44 |
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 | |||
| 1446 | extern 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 | |||
| 1477 | err: | ||
| 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 | ||
| 154 | struct be_cmd_req_hdr { | 155 | struct 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 *******************************/ | ||
| 793 | struct 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 | |||
| 791 | extern int be_pci_fnum_get(struct be_adapter *adapter); | 800 | extern int be_pci_fnum_get(struct be_adapter *adapter); |
| 792 | extern int be_cmd_POST(struct be_adapter *adapter); | 801 | extern int be_cmd_POST(struct be_adapter *adapter); |
| 793 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 802 | extern 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); |
| 853 | extern int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc); | 862 | extern int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc); |
| 863 | extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, | ||
| 864 | struct be_dma_mem *nonemb_cmd); | ||
| 854 | extern int be_cmd_fw_init(struct be_adapter *adapter); | 865 | extern int be_cmd_fw_init(struct be_adapter *adapter); |
| 855 | extern int be_cmd_fw_clean(struct be_adapter *adapter); | 866 | extern 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 | ||
| 414 | static void | ||
| 415 | be_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 | |||
| 428 | static int | ||
| 429 | be_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 | |||
| 414 | static int | 444 | static int |
| 415 | be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) | 445 | be_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) | |||
| 428 | const struct ethtool_ops be_ethtool_ops = { | 458 | const 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 | ||
| 1662 | static 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 | |||
| 1662 | static int be_setup(struct be_adapter *adapter) | 1700 | static 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 | ||
