diff options
author | Amit Kumar Salecha <amit.salecha@qlogic.com> | 2011-06-29 16:00:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-01 01:32:50 -0400 |
commit | e1428d26b404133dcbcc8f758f0f4f6575afd7b7 (patch) | |
tree | 4357abcd05b07f0da8dc1ee42a5f0d134f587ef1 | |
parent | 0209bcd4d9ee66569d4ea76f9ab2de3a9c740c71 (diff) |
qlcnic: add external loopback support
o Add external loopback test in self test:
- Send set external loopback mode request to fw.
To quiscent other storage functions.
- Perform test
- Send unset loopback mode request to fw.
o Rename ilb to lb.
o Update driver version 5.0.20.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 5 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ethtool.c | 26 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 3 |
3 files changed, 22 insertions, 12 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index e5454502df6b..9899a7947718 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -36,8 +36,8 @@ | |||
36 | 36 | ||
37 | #define _QLCNIC_LINUX_MAJOR 5 | 37 | #define _QLCNIC_LINUX_MAJOR 5 |
38 | #define _QLCNIC_LINUX_MINOR 0 | 38 | #define _QLCNIC_LINUX_MINOR 0 |
39 | #define _QLCNIC_LINUX_SUBVERSION 19 | 39 | #define _QLCNIC_LINUX_SUBVERSION 20 |
40 | #define QLCNIC_LINUX_VERSIONID "5.0.19" | 40 | #define QLCNIC_LINUX_VERSIONID "5.0.20" |
41 | #define QLCNIC_DRV_IDC_VER 0x01 | 41 | #define QLCNIC_DRV_IDC_VER 0x01 |
42 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 42 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
43 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 43 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
@@ -782,6 +782,7 @@ struct qlcnic_mac_list_s { | |||
782 | #define QLCNIC_IP_DOWN 3 | 782 | #define QLCNIC_IP_DOWN 3 |
783 | 783 | ||
784 | #define QLCNIC_ILB_MODE 0x1 | 784 | #define QLCNIC_ILB_MODE 0x1 |
785 | #define QLCNIC_ELB_MODE 0x2 | ||
785 | 786 | ||
786 | #define QLCNIC_LINKEVENT 0x1 | 787 | #define QLCNIC_LINKEVENT 0x1 |
787 | #define QLCNIC_LB_RESPONSE 0x2 | 788 | #define QLCNIC_LB_RESPONSE 0x2 |
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 743035e4538d..3ea04e7da917 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c | |||
@@ -85,7 +85,8 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { | |||
85 | "Register_Test_on_offline", | 85 | "Register_Test_on_offline", |
86 | "Link_Test_on_offline", | 86 | "Link_Test_on_offline", |
87 | "Interrupt_Test_offline", | 87 | "Interrupt_Test_offline", |
88 | "Loopback_Test_offline" | 88 | "Internal_Loopback_offline", |
89 | "External_Loopback_offline" | ||
89 | }; | 90 | }; |
90 | 91 | ||
91 | #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) | 92 | #define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) |
@@ -709,7 +710,7 @@ int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]) | |||
709 | return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE); | 710 | return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE); |
710 | } | 711 | } |
711 | 712 | ||
712 | static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) | 713 | static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter) |
713 | { | 714 | { |
714 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; | 715 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; |
715 | struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; | 716 | struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; |
@@ -735,19 +736,19 @@ static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) | |||
735 | dev_kfree_skb_any(skb); | 736 | dev_kfree_skb_any(skb); |
736 | 737 | ||
737 | if (!adapter->diag_cnt) | 738 | if (!adapter->diag_cnt) |
738 | dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" | 739 | dev_warn(&adapter->pdev->dev, "LB Test: %dth packet" |
739 | " not recevied\n", i + 1); | 740 | " not recevied\n", i + 1); |
740 | else | 741 | else |
741 | cnt++; | 742 | cnt++; |
742 | } | 743 | } |
743 | if (cnt != i) { | 744 | if (cnt != i) { |
744 | dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); | 745 | dev_warn(&adapter->pdev->dev, "LB Test failed\n"); |
745 | return -1; | 746 | return -1; |
746 | } | 747 | } |
747 | return 0; | 748 | return 0; |
748 | } | 749 | } |
749 | 750 | ||
750 | static int qlcnic_iloopback_test(struct net_device *netdev) | 751 | static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) |
751 | { | 752 | { |
752 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 753 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
753 | int max_sds_rings = adapter->max_sds_rings; | 754 | int max_sds_rings = adapter->max_sds_rings; |
@@ -755,7 +756,8 @@ static int qlcnic_iloopback_test(struct net_device *netdev) | |||
755 | int loop = 0; | 756 | int loop = 0; |
756 | int ret; | 757 | int ret; |
757 | 758 | ||
758 | netdev_info(netdev, "%s: in progress\n", __func__); | 759 | netdev_info(netdev, "%s loopback test in progress\n", |
760 | mode == QLCNIC_ILB_MODE ? "internal" : "external"); | ||
759 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { | 761 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { |
760 | netdev_warn(netdev, "Loopback test not supported for non " | 762 | netdev_warn(netdev, "Loopback test not supported for non " |
761 | "privilege function\n"); | 763 | "privilege function\n"); |
@@ -772,7 +774,7 @@ static int qlcnic_iloopback_test(struct net_device *netdev) | |||
772 | 774 | ||
773 | sds_ring = &adapter->recv_ctx->sds_rings[0]; | 775 | sds_ring = &adapter->recv_ctx->sds_rings[0]; |
774 | 776 | ||
775 | ret = qlcnic_set_lb_mode(adapter, QLCNIC_ILB_MODE); | 777 | ret = qlcnic_set_lb_mode(adapter, mode); |
776 | if (ret) | 778 | if (ret) |
777 | goto free_res; | 779 | goto free_res; |
778 | 780 | ||
@@ -790,7 +792,7 @@ static int qlcnic_iloopback_test(struct net_device *netdev) | |||
790 | goto free_res; | 792 | goto free_res; |
791 | } | 793 | } |
792 | 794 | ||
793 | ret = qlcnic_do_ilb_test(adapter); | 795 | ret = qlcnic_do_lb_test(adapter); |
794 | 796 | ||
795 | qlcnic_clear_lb_mode(adapter); | 797 | qlcnic_clear_lb_mode(adapter); |
796 | 798 | ||
@@ -822,10 +824,16 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, | |||
822 | if (data[2]) | 824 | if (data[2]) |
823 | eth_test->flags |= ETH_TEST_FL_FAILED; | 825 | eth_test->flags |= ETH_TEST_FL_FAILED; |
824 | 826 | ||
825 | data[3] = qlcnic_iloopback_test(dev); | 827 | data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE); |
826 | if (data[3]) | 828 | if (data[3]) |
827 | eth_test->flags |= ETH_TEST_FL_FAILED; | 829 | eth_test->flags |= ETH_TEST_FL_FAILED; |
828 | 830 | ||
831 | if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) { | ||
832 | data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE); | ||
833 | if (data[4]) | ||
834 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
835 | eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE; | ||
836 | } | ||
829 | } | 837 | } |
830 | } | 838 | } |
831 | 839 | ||
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 9d5bee03a587..6ec1baa85f6a 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -1303,7 +1303,8 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, | |||
1303 | dev_info(&netdev->dev, "unsupported cable length %d\n", | 1303 | dev_info(&netdev->dev, "unsupported cable length %d\n", |
1304 | cable_len); | 1304 | cable_len); |
1305 | 1305 | ||
1306 | if (!link_status && (lb_status == 1)) | 1306 | if (!link_status && (lb_status == QLCNIC_ILB_MODE || |
1307 | lb_status == QLCNIC_ELB_MODE)) | ||
1307 | adapter->ahw->loopback_state |= QLCNIC_LINKEVENT; | 1308 | adapter->ahw->loopback_state |= QLCNIC_LINKEVENT; |
1308 | 1309 | ||
1309 | qlcnic_advert_link_change(adapter, link_status); | 1310 | qlcnic_advert_link_change(adapter, link_status); |