diff options
author | Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> | 2011-06-22 02:52:23 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-24 01:17:07 -0700 |
commit | 22c8c9343258feda9ea9ebb9e5f8cbb727b69454 (patch) | |
tree | fac14dcf287c032ff83c832a253178b90a2228b3 /drivers/net/qlcnic/qlcnic_hw.c | |
parent | 9d6a6440fe30132e4d1f1aadd099345ced9178fb (diff) |
qlcnic: multi protocol internal loopback support added.
Driver will generate loopback traffic pattern and do the test. And
returns result of the test to application.
Updated driver version to 5.0.19.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@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 | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 81de563ee96c..0391a04695dd 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -533,6 +533,56 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) } } +int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u8 flag) +{ + struct qlcnic_nic_req req; + int rv; + + memset(&req, 0, sizeof(struct qlcnic_nic_req)); + + req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); + req.req_hdr = cpu_to_le64(QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK | + ((u64) adapter->portnum << 16) | ((u64) 0x1 << 32)); + + req.words[0] = cpu_to_le64(flag); + + rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); + if (rv != 0) + dev_err(&adapter->pdev->dev, "%sting loopback mode failed\n", + flag ? "Set" : "Reset"); + return rv; +} + +int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) +{ + if (qlcnic_set_fw_loopback(adapter, mode)) + return -EIO; + + if (qlcnic_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL)) { + qlcnic_set_fw_loopback(adapter, mode); + return -EIO; + } + + msleep(1000); + return 0; +} + +void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter) +{ + int mode = VPORT_MISS_MODE_DROP; + struct net_device *netdev = adapter->netdev; + + qlcnic_set_fw_loopback(adapter, 0); + + if (netdev->flags & IFF_PROMISC) + mode = VPORT_MISS_MODE_ACCEPT_ALL; + else if (netdev->flags & IFF_ALLMULTI) + mode = VPORT_MISS_MODE_ACCEPT_MULTI; + + qlcnic_nic_set_promisc(adapter, mode); + msleep(1000); +} + /* * Send the interrupt coalescing parameter set by ethtool to the card. */ |