aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_hw.c
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit.salecha@qlogic.com>2010-02-01 00:25:00 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-02 18:55:46 -0500
commitcdaff1854f32ac9ddb4733530f617d32188665ed (patch)
tree5d1e7b5bcf656d0071840431f1f3cbc94b828e21 /drivers/net/qlcnic/qlcnic_hw.c
parent7eb9855d68faabe0004ed18c2af1f0974d3c2c63 (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.c52
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
1225static 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
1247int 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
1262void 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}