aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit.salecha@qlogic.com>2011-06-29 16:00:50 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-01 01:32:50 -0400
commite1428d26b404133dcbcc8f758f0f4f6575afd7b7 (patch)
tree4357abcd05b07f0da8dc1ee42a5f0d134f587ef1
parent0209bcd4d9ee66569d4ea76f9ab2de3a9c740c71 (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.h5
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c26
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c3
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
712static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) 713static 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
750static int qlcnic_iloopback_test(struct net_device *netdev) 751static 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);