diff options
author | Amit Kumar Salecha <amit.salecha@qlogic.com> | 2010-02-01 00:25:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-02 18:55:46 -0500 |
commit | cdaff1854f32ac9ddb4733530f617d32188665ed (patch) | |
tree | 5d1e7b5bcf656d0071840431f1f3cbc94b828e21 /drivers/net/qlcnic/qlcnic_hw.c | |
parent | 7eb9855d68faabe0004ed18c2af1f0974d3c2c63 (diff) |
qlcnic: add loopback diagnostic test
Loopback test (offline) added in ethtool self test.
o Set device in loopback mode
o Send packets
o Process receive packets in qlcnic_process_rcv_ring_diag()
o Compare packets
o Reset device in normal mode.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_hw.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hw.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 8724e561ed72..dc6cd69d6d93 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -1221,3 +1221,55 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) | |||
1221 | 1221 | ||
1222 | return rv; | 1222 | return rv; |
1223 | } | 1223 | } |
1224 | |||
1225 | static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag) | ||
1226 | { | ||
1227 | struct qlcnic_nic_req req; | ||
1228 | int rv; | ||
1229 | u64 word; | ||
1230 | |||
1231 | memset(&req, 0, sizeof(struct qlcnic_nic_req)); | ||
1232 | req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); | ||
1233 | |||
1234 | word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK | | ||
1235 | ((u64)adapter->portnum << 16); | ||
1236 | req.req_hdr = cpu_to_le64(word); | ||
1237 | req.words[0] = cpu_to_le64(flag); | ||
1238 | |||
1239 | rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | ||
1240 | if (rv) | ||
1241 | dev_err(&adapter->pdev->dev, | ||
1242 | "%sting loopback mode failed.\n", | ||
1243 | flag ? "Set" : "Reset"); | ||
1244 | return rv; | ||
1245 | } | ||
1246 | |||
1247 | int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter) | ||
1248 | { | ||
1249 | if (qlcnic_set_fw_loopback(adapter, 1)) | ||
1250 | return -EIO; | ||
1251 | |||
1252 | if (qlcnic_nic_set_promisc(adapter, | ||
1253 | VPORT_MISS_MODE_ACCEPT_ALL)) { | ||
1254 | qlcnic_set_fw_loopback(adapter, 0); | ||
1255 | return -EIO; | ||
1256 | } | ||
1257 | |||
1258 | msleep(1000); | ||
1259 | return 0; | ||
1260 | } | ||
1261 | |||
1262 | void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter) | ||
1263 | { | ||
1264 | int mode = VPORT_MISS_MODE_DROP; | ||
1265 | struct net_device *netdev = adapter->netdev; | ||
1266 | |||
1267 | qlcnic_set_fw_loopback(adapter, 0); | ||
1268 | |||
1269 | if (netdev->flags & IFF_PROMISC) | ||
1270 | mode = VPORT_MISS_MODE_ACCEPT_ALL; | ||
1271 | else if (netdev->flags & IFF_ALLMULTI) | ||
1272 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; | ||
1273 | |||
1274 | qlcnic_nic_set_promisc(adapter, mode); | ||
1275 | } | ||