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>
This commit is contained in:
Sarveshwar Bandi 2009-12-23 04:41:44 +00:00 committed by David S. Miller
parent d7b9014182
commit fced9999ed
3 changed files with 74 additions and 14 deletions

View File

@ -1479,6 +1479,41 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
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,
u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern)
{

View File

@ -155,6 +155,7 @@ struct be_mcc_mailbox {
#define OPCODE_LOWLEVEL_HOST_DDR_DMA 17
#define OPCODE_LOWLEVEL_LOOPBACK_TEST 18
#define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19
struct be_cmd_req_hdr {
u8 opcode; /* dword 0 */
@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test {
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 *********************/
struct be_cmd_req_ddrdma_test {
struct be_cmd_req_hdr hdr;
@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
u32 num_pkts, u64 pattern);
extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
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);

View File

@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = {
#define BE_MAC_LOOPBACK 0x0
#define BE_PHY_LOOPBACK 0x1
#define BE_ONE_PORT_EXT_LOOPBACK 0x2
#define BE_NO_LOOPBACK 0xff
static void
be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
@ -489,6 +490,19 @@ be_test_ddr_dma(struct be_adapter *adapter)
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
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);
if (test->flags & ETH_TEST_FL_OFFLINE) {
data[0] = be_cmd_loopback_test(adapter, adapter->port_num,
BE_MAC_LOOPBACK, 1500,
2, 0xabc);
if (data[0] != 0)
if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
&data[0]) != 0) {
test->flags |= ETH_TEST_FL_FAILED;
data[1] = be_cmd_loopback_test(adapter, adapter->port_num,
BE_PHY_LOOPBACK, 1500,
2, 0xabc);
if (data[1] != 0)
}
if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
&data[1]) != 0) {
test->flags |= ETH_TEST_FL_FAILED;
data[2] = be_cmd_loopback_test(adapter, adapter->port_num,
BE_ONE_PORT_EXT_LOOPBACK,
1500, 2, 0xabc);
if (data[2] != 0)
}
if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
&data[2]) != 0) {
test->flags |= ETH_TEST_FL_FAILED;
}
data[3] = be_test_ddr_dma(adapter);
if (data[3] != 0)