Skip to content

Commit

Permalink
be2net: Bug fix to config NIC appropriately before loopback test
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sarveshwar Bandi authored and David S. Miller committed Dec 24, 2009
1 parent d7b9014 commit fced999
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 14 deletions.
35 changes: 35 additions & 0 deletions drivers/net/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
16 changes: 16 additions & 0 deletions drivers/net/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
37 changes: 23 additions & 14 deletions drivers/net/benet/be_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
Expand Down

0 comments on commit fced999

Please sign in to comment.