diff options
author | Sarveshwar Bandi <sarveshwarb@serverengines.com> | 2009-12-22 23:41:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-23 23:58:14 -0500 |
commit | fced9999ed7f6975fbb2350a73048918ba60a773 (patch) | |
tree | ec62516793df52ef31d7a0f1ddeeddec5aa1b3df /drivers/net | |
parent | d7b901418250f00eaaa18f9135d09ba61b72a5bc (diff) |
be2net: Bug fix to config NIC appropriately before loopback test
NIC controller has to be set to an appropriate mode before doing a loopback
test. Test will fail otherwise.
Signed-off-by: Sarveshwar Bandi <sarveshwarb@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/benet/be_cmds.c | 35 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 16 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 37 |
3 files changed, 74 insertions, 14 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index a27fdb35eebf..102ade134165 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1479,6 +1479,41 @@ err: | |||
1479 | return status; | 1479 | return status; |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | ||
1483 | u8 loopback_type, u8 enable) | ||
1484 | { | ||
1485 | struct be_mcc_wrb *wrb; | ||
1486 | struct be_cmd_req_set_lmode *req; | ||
1487 | int status; | ||
1488 | |||
1489 | spin_lock_bh(&adapter->mcc_lock); | ||
1490 | |||
1491 | wrb = wrb_from_mccq(adapter); | ||
1492 | if (!wrb) { | ||
1493 | status = -EBUSY; | ||
1494 | goto err; | ||
1495 | } | ||
1496 | |||
1497 | req = embedded_payload(wrb); | ||
1498 | |||
1499 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
1500 | OPCODE_LOWLEVEL_SET_LOOPBACK_MODE); | ||
1501 | |||
1502 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, | ||
1503 | OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, | ||
1504 | sizeof(*req)); | ||
1505 | |||
1506 | req->src_port = port_num; | ||
1507 | req->dest_port = port_num; | ||
1508 | req->loopback_type = loopback_type; | ||
1509 | req->loopback_state = enable; | ||
1510 | |||
1511 | status = be_mcc_notify_wait(adapter); | ||
1512 | err: | ||
1513 | spin_unlock_bh(&adapter->mcc_lock); | ||
1514 | return status; | ||
1515 | } | ||
1516 | |||
1482 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | 1517 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, |
1483 | u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) | 1518 | u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) |
1484 | { | 1519 | { |
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 92b87ef156ed..c002b8391b4d 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -155,6 +155,7 @@ struct be_mcc_mailbox { | |||
155 | 155 | ||
156 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 | 156 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 |
157 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 | 157 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 |
158 | #define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19 | ||
158 | 159 | ||
159 | struct be_cmd_req_hdr { | 160 | struct be_cmd_req_hdr { |
160 | u8 opcode; /* dword 0 */ | 161 | u8 opcode; /* dword 0 */ |
@@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test { | |||
821 | u32 ticks_compl; | 822 | u32 ticks_compl; |
822 | }; | 823 | }; |
823 | 824 | ||
825 | struct be_cmd_req_set_lmode { | ||
826 | struct be_cmd_req_hdr hdr; | ||
827 | u8 src_port; | ||
828 | u8 dest_port; | ||
829 | u8 loopback_type; | ||
830 | u8 loopback_state; | ||
831 | }; | ||
832 | |||
833 | struct be_cmd_resp_set_lmode { | ||
834 | struct be_cmd_resp_hdr resp_hdr; | ||
835 | u8 rsvd0[4]; | ||
836 | }; | ||
837 | |||
824 | /********************** DDR DMA test *********************/ | 838 | /********************** DDR DMA test *********************/ |
825 | struct be_cmd_req_ddrdma_test { | 839 | struct be_cmd_req_ddrdma_test { |
826 | struct be_cmd_req_hdr hdr; | 840 | struct be_cmd_req_hdr hdr; |
@@ -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_set_loopback(struct be_adapter *adapter, u8 port_num, | ||
930 | u8 loopback_type, u8 enable); | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 298b92cbd689..da66d15e2223 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { | |||
118 | #define BE_MAC_LOOPBACK 0x0 | 118 | #define BE_MAC_LOOPBACK 0x0 |
119 | #define BE_PHY_LOOPBACK 0x1 | 119 | #define BE_PHY_LOOPBACK 0x1 |
120 | #define BE_ONE_PORT_EXT_LOOPBACK 0x2 | 120 | #define BE_ONE_PORT_EXT_LOOPBACK 0x2 |
121 | #define BE_NO_LOOPBACK 0xff | ||
121 | 122 | ||
122 | static void | 123 | static void |
123 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | 124 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) |
@@ -489,6 +490,19 @@ err: | |||
489 | return ret; | 490 | return ret; |
490 | } | 491 | } |
491 | 492 | ||
493 | static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, | ||
494 | u64 *status) | ||
495 | { | ||
496 | be_cmd_set_loopback(adapter, adapter->port_num, | ||
497 | loopback_type, 1); | ||
498 | *status = be_cmd_loopback_test(adapter, adapter->port_num, | ||
499 | loopback_type, 1500, | ||
500 | 2, 0xabc); | ||
501 | be_cmd_set_loopback(adapter, adapter->port_num, | ||
502 | BE_NO_LOOPBACK, 1); | ||
503 | return *status; | ||
504 | } | ||
505 | |||
492 | static void | 506 | static void |
493 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | 507 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) |
494 | { | 508 | { |
@@ -497,23 +511,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | |||
497 | memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); | 511 | memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); |
498 | 512 | ||
499 | if (test->flags & ETH_TEST_FL_OFFLINE) { | 513 | if (test->flags & ETH_TEST_FL_OFFLINE) { |
500 | data[0] = be_cmd_loopback_test(adapter, adapter->port_num, | 514 | if (be_loopback_test(adapter, BE_MAC_LOOPBACK, |
501 | BE_MAC_LOOPBACK, 1500, | 515 | &data[0]) != 0) { |
502 | 2, 0xabc); | ||
503 | if (data[0] != 0) | ||
504 | test->flags |= ETH_TEST_FL_FAILED; | 516 | test->flags |= ETH_TEST_FL_FAILED; |
505 | 517 | } | |
506 | data[1] = be_cmd_loopback_test(adapter, adapter->port_num, | 518 | if (be_loopback_test(adapter, BE_PHY_LOOPBACK, |
507 | BE_PHY_LOOPBACK, 1500, | 519 | &data[1]) != 0) { |
508 | 2, 0xabc); | ||
509 | if (data[1] != 0) | ||
510 | test->flags |= ETH_TEST_FL_FAILED; | 520 | test->flags |= ETH_TEST_FL_FAILED; |
511 | 521 | } | |
512 | data[2] = be_cmd_loopback_test(adapter, adapter->port_num, | 522 | if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK, |
513 | BE_ONE_PORT_EXT_LOOPBACK, | 523 | &data[2]) != 0) { |
514 | 1500, 2, 0xabc); | ||
515 | if (data[2] != 0) | ||
516 | test->flags |= ETH_TEST_FL_FAILED; | 524 | test->flags |= ETH_TEST_FL_FAILED; |
525 | } | ||
517 | 526 | ||
518 | data[3] = be_test_ddr_dma(adapter); | 527 | data[3] = be_test_ddr_dma(adapter); |
519 | if (data[3] != 0) | 528 | if (data[3] != 0) |