Commit fced9999 authored by Sarveshwar Bandi's avatar Sarveshwar Bandi Committed by David S. Miller

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: default avatarSarveshwar Bandi <sarveshwarb@serverengines.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d7b90141
...@@ -1479,6 +1479,41 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, ...@@ -1479,6 +1479,41 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
return status; return status;
} }
int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
u8 loopback_type, u8 enable)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_set_lmode *req;
int status;
spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err;
}
req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
OPCODE_LOWLEVEL_SET_LOOPBACK_MODE);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
sizeof(*req));
req->src_port = port_num;
req->dest_port = port_num;
req->loopback_type = loopback_type;
req->loopback_state = enable;
status = be_mcc_notify_wait(adapter);
err:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}
int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern)
{ {
......
...@@ -155,6 +155,7 @@ struct be_mcc_mailbox { ...@@ -155,6 +155,7 @@ struct be_mcc_mailbox {
#define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17
#define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18
#define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19
struct be_cmd_req_hdr { struct be_cmd_req_hdr {
u8 opcode; /* dword 0 */ u8 opcode; /* dword 0 */
...@@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test { ...@@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test {
u32 ticks_compl; u32 ticks_compl;
}; };
struct be_cmd_req_set_lmode {
struct be_cmd_req_hdr hdr;
u8 src_port;
u8 dest_port;
u8 loopback_type;
u8 loopback_state;
};
struct be_cmd_resp_set_lmode {
struct be_cmd_resp_hdr resp_hdr;
u8 rsvd0[4];
};
/********************** DDR DMA test *********************/ /********************** DDR DMA test *********************/
struct be_cmd_req_ddrdma_test { struct be_cmd_req_ddrdma_test {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
...@@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, ...@@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
u32 num_pkts, u64 pattern); u32 num_pkts, u64 pattern);
extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
u32 byte_cnt, struct be_dma_mem *cmd); u32 byte_cnt, struct be_dma_mem *cmd);
extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
u8 loopback_type, u8 enable);
...@@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { ...@@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = {
#define BE_MAC_LOOPBACK 0x0 #define BE_MAC_LOOPBACK 0x0
#define BE_PHY_LOOPBACK 0x1 #define BE_PHY_LOOPBACK 0x1
#define BE_ONE_PORT_EXT_LOOPBACK 0x2 #define BE_ONE_PORT_EXT_LOOPBACK 0x2
#define BE_NO_LOOPBACK 0xff
static void static void
be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
...@@ -489,6 +490,19 @@ be_test_ddr_dma(struct be_adapter *adapter) ...@@ -489,6 +490,19 @@ be_test_ddr_dma(struct be_adapter *adapter)
return ret; return ret;
} }
static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
u64 *status)
{
be_cmd_set_loopback(adapter, adapter->port_num,
loopback_type, 1);
*status = be_cmd_loopback_test(adapter, adapter->port_num,
loopback_type, 1500,
2, 0xabc);
be_cmd_set_loopback(adapter, adapter->port_num,
BE_NO_LOOPBACK, 1);
return *status;
}
static void static void
be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
{ {
...@@ -497,23 +511,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) ...@@ -497,23 +511,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
if (test->flags & ETH_TEST_FL_OFFLINE) { if (test->flags & ETH_TEST_FL_OFFLINE) {
data[0] = be_cmd_loopback_test(adapter, adapter->port_num, if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
BE_MAC_LOOPBACK, 1500, &data[0]) != 0) {
2, 0xabc);
if (data[0] != 0)
test->flags |= ETH_TEST_FL_FAILED; test->flags |= ETH_TEST_FL_FAILED;
}
data[1] = be_cmd_loopback_test(adapter, adapter->port_num, if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
BE_PHY_LOOPBACK, 1500, &data[1]) != 0) {
2, 0xabc);
if (data[1] != 0)
test->flags |= ETH_TEST_FL_FAILED; test->flags |= ETH_TEST_FL_FAILED;
}
data[2] = be_cmd_loopback_test(adapter, adapter->port_num, if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
BE_ONE_PORT_EXT_LOOPBACK, &data[2]) != 0) {
1500, 2, 0xabc);
if (data[2] != 0)
test->flags |= ETH_TEST_FL_FAILED; test->flags |= ETH_TEST_FL_FAILED;
}
data[3] = be_test_ddr_dma(adapter); data[3] = be_test_ddr_dma(adapter);
if (data[3] != 0) if (data[3] != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment