diff options
author | Sarveshwar Bandi <sarveshwarb@serverengines.com> | 2010-01-08 03:07:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-08 03:07:27 -0500 |
commit | 368c0ca2f0a69b0818fbc1796d8e21ff02a61b4c (patch) | |
tree | 5a087a7e86d65313d50cfa72af9f497d22068cfc | |
parent | a3aa18842a5303fc28fcc4d57dbd16618bd830a0 (diff) |
be2net: implements ethtool function to read eeprom data.
The patch implements a firmware command to fetch the eeprom data.
Signed-off-by: Sarveshwar Bandi <sarveshwarb@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/benet/be_cmds.c | 30 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 16 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 45 |
3 files changed, 91 insertions, 0 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 1b68bd98dc0c..b748c197408f 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1571,3 +1571,33 @@ err: | |||
1571 | spin_unlock_bh(&adapter->mcc_lock); | 1571 | spin_unlock_bh(&adapter->mcc_lock); |
1572 | return status; | 1572 | return status; |
1573 | } | 1573 | } |
1574 | |||
1575 | extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, | ||
1576 | struct be_dma_mem *nonemb_cmd) | ||
1577 | { | ||
1578 | struct be_mcc_wrb *wrb; | ||
1579 | struct be_cmd_req_seeprom_read *req; | ||
1580 | struct be_sge *sge; | ||
1581 | int status; | ||
1582 | |||
1583 | spin_lock_bh(&adapter->mcc_lock); | ||
1584 | |||
1585 | wrb = wrb_from_mccq(adapter); | ||
1586 | req = nonemb_cmd->va; | ||
1587 | sge = nonembedded_sgl(wrb); | ||
1588 | |||
1589 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1, | ||
1590 | OPCODE_COMMON_SEEPROM_READ); | ||
1591 | |||
1592 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1593 | OPCODE_COMMON_SEEPROM_READ, sizeof(*req)); | ||
1594 | |||
1595 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); | ||
1596 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); | ||
1597 | sge->len = cpu_to_le32(nonemb_cmd->size); | ||
1598 | |||
1599 | status = be_mcc_notify_wait(adapter); | ||
1600 | |||
1601 | spin_unlock_bh(&adapter->mcc_lock); | ||
1602 | return status; | ||
1603 | } | ||
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 92b87ef156ed..6eed512bb6d4 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -124,6 +124,7 @@ struct be_mcc_mailbox { | |||
124 | #define OPCODE_COMMON_CQ_CREATE 12 | 124 | #define OPCODE_COMMON_CQ_CREATE 12 |
125 | #define OPCODE_COMMON_EQ_CREATE 13 | 125 | #define OPCODE_COMMON_EQ_CREATE 13 |
126 | #define OPCODE_COMMON_MCC_CREATE 21 | 126 | #define OPCODE_COMMON_MCC_CREATE 21 |
127 | #define OPCODE_COMMON_SEEPROM_READ 30 | ||
127 | #define OPCODE_COMMON_NTWK_RX_FILTER 34 | 128 | #define OPCODE_COMMON_NTWK_RX_FILTER 34 |
128 | #define OPCODE_COMMON_GET_FW_VERSION 35 | 129 | #define OPCODE_COMMON_GET_FW_VERSION 35 |
129 | #define OPCODE_COMMON_SET_FLOW_CONTROL 36 | 130 | #define OPCODE_COMMON_SET_FLOW_CONTROL 36 |
@@ -840,6 +841,19 @@ struct be_cmd_resp_ddrdma_test { | |||
840 | u8 rcv_buff[4096]; | 841 | u8 rcv_buff[4096]; |
841 | }; | 842 | }; |
842 | 843 | ||
844 | /*********************** SEEPROM Read ***********************/ | ||
845 | |||
846 | #define BE_READ_SEEPROM_LEN 1024 | ||
847 | struct be_cmd_req_seeprom_read { | ||
848 | struct be_cmd_req_hdr hdr; | ||
849 | u8 rsvd0[BE_READ_SEEPROM_LEN]; | ||
850 | }; | ||
851 | |||
852 | struct be_cmd_resp_seeprom_read { | ||
853 | struct be_cmd_req_hdr hdr; | ||
854 | u8 seeprom_data[BE_READ_SEEPROM_LEN]; | ||
855 | }; | ||
856 | |||
843 | extern int be_pci_fnum_get(struct be_adapter *adapter); | 857 | extern int be_pci_fnum_get(struct be_adapter *adapter); |
844 | extern int be_cmd_POST(struct be_adapter *adapter); | 858 | extern int be_cmd_POST(struct be_adapter *adapter); |
845 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 859 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
@@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | |||
912 | u32 num_pkts, u64 pattern); | 926 | u32 num_pkts, u64 pattern); |
913 | extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, | 927 | extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, |
914 | u32 byte_cnt, struct be_dma_mem *cmd); | 928 | u32 byte_cnt, struct be_dma_mem *cmd); |
929 | extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, | ||
930 | struct be_dma_mem *nonemb_cmd); | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 298b92cbd689..c5afc0286d4d 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -536,12 +536,57 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) | |||
536 | return be_load_fw(adapter, file_name); | 536 | return be_load_fw(adapter, file_name); |
537 | } | 537 | } |
538 | 538 | ||
539 | static int | ||
540 | be_get_eeprom_len(struct net_device *netdev) | ||
541 | { | ||
542 | return BE_READ_SEEPROM_LEN; | ||
543 | } | ||
544 | |||
545 | static int | ||
546 | be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | ||
547 | uint8_t *data) | ||
548 | { | ||
549 | struct be_adapter *adapter = netdev_priv(netdev); | ||
550 | struct be_dma_mem eeprom_cmd; | ||
551 | struct be_cmd_resp_seeprom_read *resp; | ||
552 | int status; | ||
553 | |||
554 | if (!eeprom->len) | ||
555 | return -EINVAL; | ||
556 | |||
557 | eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16); | ||
558 | |||
559 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); | ||
560 | eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read); | ||
561 | eeprom_cmd.va = pci_alloc_consistent(adapter->pdev, eeprom_cmd.size, | ||
562 | &eeprom_cmd.dma); | ||
563 | |||
564 | if (!eeprom_cmd.va) { | ||
565 | dev_err(&adapter->pdev->dev, | ||
566 | "Memory allocation failure. Could not read eeprom\n"); | ||
567 | return -ENOMEM; | ||
568 | } | ||
569 | |||
570 | status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd); | ||
571 | |||
572 | if (!status) { | ||
573 | resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va; | ||
574 | memcpy(data, resp->seeprom_data, eeprom->len); | ||
575 | } | ||
576 | pci_free_consistent(adapter->pdev, eeprom_cmd.size, eeprom_cmd.va, | ||
577 | eeprom_cmd.dma); | ||
578 | |||
579 | return status; | ||
580 | } | ||
581 | |||
539 | const struct ethtool_ops be_ethtool_ops = { | 582 | const struct ethtool_ops be_ethtool_ops = { |
540 | .get_settings = be_get_settings, | 583 | .get_settings = be_get_settings, |
541 | .get_drvinfo = be_get_drvinfo, | 584 | .get_drvinfo = be_get_drvinfo, |
542 | .get_wol = be_get_wol, | 585 | .get_wol = be_get_wol, |
543 | .set_wol = be_set_wol, | 586 | .set_wol = be_set_wol, |
544 | .get_link = ethtool_op_get_link, | 587 | .get_link = ethtool_op_get_link, |
588 | .get_eeprom_len = be_get_eeprom_len, | ||
589 | .get_eeprom = be_read_eeprom, | ||
545 | .get_coalesce = be_get_coalesce, | 590 | .get_coalesce = be_get_coalesce, |
546 | .set_coalesce = be_set_coalesce, | 591 | .set_coalesce = be_set_coalesce, |
547 | .get_ringparam = be_get_ringparam, | 592 | .get_ringparam = be_get_ringparam, |