aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic
diff options
context:
space:
mode:
authorSucheta Chakraborty <sucheta.chakraborty@qlogic.com>2010-12-02 15:41:23 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-03 12:33:20 -0500
commit97319a270da37a5eab14a770f1417d8229245270 (patch)
treeb44c0a44d1ee6f7dc05fdd2a4e03b6a6037639f5 /drivers/net/qlcnic
parent7e300bc8e6736d41e7b92978f415572ac60fd59b (diff)
qlcnic: Disable loopback support
Loopback mode can not be supported in CNA mode. Removing it until FW is fixed. 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')
-rw-r--r--drivers/net/qlcnic/qlcnic.h7
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c104
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c53
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c93
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c55
5 files changed, 1 insertions, 311 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 9513a83b9537..1fd476d280f5 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -798,7 +798,6 @@ struct qlcnic_nic_intr_coalesce {
798#define QLCNIC_H2C_OPCODE_GET_NET_STATS 16 798#define QLCNIC_H2C_OPCODE_GET_NET_STATS 16
799#define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V 17 799#define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V 17
800#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 18 800#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 18
801#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK 19
802#define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE 20 801#define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE 20
803#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 21 802#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 21
804#define QLCNIC_C2C_OPCODE 22 803#define QLCNIC_C2C_OPCODE 22
@@ -1314,21 +1313,15 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
1314int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); 1313int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
1315void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, 1314void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
1316 struct qlcnic_host_tx_ring *tx_ring); 1315 struct qlcnic_host_tx_ring *tx_ring);
1317void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter);
1318int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
1319void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); 1316void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
1320 1317
1321/* Functions from qlcnic_main.c */ 1318/* Functions from qlcnic_main.c */
1322int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter);
1323void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter);
1324int qlcnic_reset_context(struct qlcnic_adapter *); 1319int qlcnic_reset_context(struct qlcnic_adapter *);
1325u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter, 1320u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
1326 u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd); 1321 u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
1327void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); 1322void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
1328int qlcnic_diag_alloc_res(struct net_device *netdev, int test); 1323int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
1329int qlcnic_check_loopback_buff(unsigned char *data);
1330netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); 1324netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
1331void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
1332 1325
1333/* Management functions */ 1326/* Management functions */
1334int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); 1327int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index c38929636488..2aa9d8b2bab3 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -101,8 +101,7 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
101static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { 101static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
102 "Register_Test_on_offline", 102 "Register_Test_on_offline",
103 "Link_Test_on_offline", 103 "Link_Test_on_offline",
104 "Interrupt_Test_offline", 104 "Interrupt_Test_offline"
105 "Loopback_Test_offline"
106}; 105};
107 106
108#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test) 107#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
@@ -643,104 +642,6 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset)
643 } 642 }
644} 643}
645 644
646#define QLC_ILB_PKT_SIZE 64
647#define QLC_NUM_ILB_PKT 16
648#define QLC_ILB_MAX_RCV_LOOP 10
649
650static void qlcnic_create_loopback_buff(unsigned char *data)
651{
652 unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
653 memset(data, 0x4e, QLC_ILB_PKT_SIZE);
654 memset(data, 0xff, 12);
655 memcpy(data + 12, random_data, sizeof(random_data));
656}
657
658int qlcnic_check_loopback_buff(unsigned char *data)
659{
660 unsigned char buff[QLC_ILB_PKT_SIZE];
661 qlcnic_create_loopback_buff(buff);
662 return memcmp(data, buff, QLC_ILB_PKT_SIZE);
663}
664
665static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
666{
667 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
668 struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
669 struct sk_buff *skb;
670 int i, loop, cnt = 0;
671
672 for (i = 0; i < QLC_NUM_ILB_PKT; i++) {
673 skb = dev_alloc_skb(QLC_ILB_PKT_SIZE);
674 qlcnic_create_loopback_buff(skb->data);
675 skb_put(skb, QLC_ILB_PKT_SIZE);
676
677 adapter->diag_cnt = 0;
678 qlcnic_xmit_frame(skb, adapter->netdev);
679
680 loop = 0;
681 do {
682 msleep(1);
683 qlcnic_process_rcv_ring_diag(sds_ring);
684 } while (loop++ < QLC_ILB_MAX_RCV_LOOP &&
685 !adapter->diag_cnt);
686
687 dev_kfree_skb_any(skb);
688
689 if (!adapter->diag_cnt)
690 dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet"
691 " not recevied\n", i + 1);
692 else
693 cnt++;
694 }
695 if (cnt != i) {
696 dev_warn(&adapter->pdev->dev, "ILB Test failed\n");
697 return -1;
698 }
699 return 0;
700}
701
702static int qlcnic_loopback_test(struct net_device *netdev)
703{
704 struct qlcnic_adapter *adapter = netdev_priv(netdev);
705 int max_sds_rings = adapter->max_sds_rings;
706 int ret;
707
708 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
709 dev_warn(&adapter->pdev->dev, "Loopback test not supported"
710 "for non privilege function\n");
711 return 0;
712 }
713
714 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
715 return -EIO;
716
717 if (qlcnic_request_quiscent_mode(adapter)) {
718 clear_bit(__QLCNIC_RESETTING, &adapter->state);
719 return -EIO;
720 }
721
722 ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
723 if (ret)
724 goto clear_it;
725
726 ret = qlcnic_set_ilb_mode(adapter);
727 if (ret)
728 goto done;
729
730 ret = qlcnic_do_ilb_test(adapter);
731
732 qlcnic_clear_ilb_mode(adapter);
733
734done:
735 qlcnic_diag_free_res(netdev, max_sds_rings);
736
737clear_it:
738 qlcnic_clear_quiscent_mode(adapter);
739 adapter->max_sds_rings = max_sds_rings;
740 clear_bit(__QLCNIC_RESETTING, &adapter->state);
741 return ret;
742}
743
744static int qlcnic_irq_test(struct net_device *netdev) 645static int qlcnic_irq_test(struct net_device *netdev)
745{ 646{
746 struct qlcnic_adapter *adapter = netdev_priv(netdev); 647 struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -793,9 +694,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
793 if (data[2]) 694 if (data[2])
794 eth_test->flags |= ETH_TEST_FL_FAILED; 695 eth_test->flags |= ETH_TEST_FL_FAILED;
795 696
796 data[3] = qlcnic_loopback_test(dev);
797 if (data[3])
798 eth_test->flags |= ETH_TEST_FL_FAILED;
799 697
800 } 698 }
801} 699}
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 7a47a2a7ee27..8630118dc4bb 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1234,56 +1234,3 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
1234 1234
1235 return rv; 1235 return rv;
1236} 1236}
1237
1238static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag)
1239{
1240 struct qlcnic_nic_req req;
1241 int rv;
1242 u64 word;
1243
1244 memset(&req, 0, sizeof(struct qlcnic_nic_req));
1245 req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
1246
1247 word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
1248 ((u64)adapter->portnum << 16);
1249 req.req_hdr = cpu_to_le64(word);
1250 req.words[0] = cpu_to_le64(flag);
1251
1252 rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
1253 if (rv)
1254 dev_err(&adapter->pdev->dev,
1255 "%sting loopback mode failed.\n",
1256 flag ? "Set" : "Reset");
1257 return rv;
1258}
1259
1260int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter)
1261{
1262 if (qlcnic_set_fw_loopback(adapter, 1))
1263 return -EIO;
1264
1265 if (qlcnic_nic_set_promisc(adapter,
1266 VPORT_MISS_MODE_ACCEPT_ALL)) {
1267 qlcnic_set_fw_loopback(adapter, 0);
1268 return -EIO;
1269 }
1270
1271 msleep(1000);
1272 return 0;
1273}
1274
1275void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
1276{
1277 int mode = VPORT_MISS_MODE_DROP;
1278 struct net_device *netdev = adapter->netdev;
1279
1280 qlcnic_set_fw_loopback(adapter, 0);
1281
1282 if (netdev->flags & IFF_PROMISC)
1283 mode = VPORT_MISS_MODE_ACCEPT_ALL;
1284 else if (netdev->flags & IFF_ALLMULTI)
1285 mode = VPORT_MISS_MODE_ACCEPT_MULTI;
1286
1287 qlcnic_nic_set_promisc(adapter, mode);
1288 msleep(1000);
1289}
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index c5ea2f4eb980..6d0ec6c7f225 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1690,99 +1690,6 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
1690 spin_unlock(&rds_ring->lock); 1690 spin_unlock(&rds_ring->lock);
1691} 1691}
1692 1692
1693static void dump_skb(struct sk_buff *skb)
1694{
1695 int i;
1696 unsigned char *data = skb->data;
1697
1698 for (i = 0; i < skb->len; i++) {
1699 printk("%02x ", data[i]);
1700 if ((i & 0x0f) == 8)
1701 printk("\n");
1702 }
1703}
1704
1705static struct qlcnic_rx_buffer *
1706qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
1707 struct qlcnic_host_sds_ring *sds_ring,
1708 int ring, u64 sts_data0)
1709{
1710 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
1711 struct qlcnic_rx_buffer *buffer;
1712 struct sk_buff *skb;
1713 struct qlcnic_host_rds_ring *rds_ring;
1714 int index, length, cksum, pkt_offset;
1715
1716 if (unlikely(ring >= adapter->max_rds_rings))
1717 return NULL;
1718
1719 rds_ring = &recv_ctx->rds_rings[ring];
1720
1721 index = qlcnic_get_sts_refhandle(sts_data0);
1722 if (unlikely(index >= rds_ring->num_desc))
1723 return NULL;
1724
1725 buffer = &rds_ring->rx_buf_arr[index];
1726
1727 length = qlcnic_get_sts_totallength(sts_data0);
1728 cksum = qlcnic_get_sts_status(sts_data0);
1729 pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
1730
1731 skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
1732 if (!skb)
1733 return buffer;
1734
1735 if (length > rds_ring->skb_size)
1736 skb_put(skb, rds_ring->skb_size);
1737 else
1738 skb_put(skb, length);
1739
1740 if (pkt_offset)
1741 skb_pull(skb, pkt_offset);
1742
1743 if (!qlcnic_check_loopback_buff(skb->data))
1744 adapter->diag_cnt++;
1745 else
1746 dump_skb(skb);
1747
1748 dev_kfree_skb_any(skb);
1749 adapter->stats.rx_pkts++;
1750 adapter->stats.rxbytes += length;
1751
1752 return buffer;
1753}
1754
1755void
1756qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
1757{
1758 struct qlcnic_adapter *adapter = sds_ring->adapter;
1759 struct status_desc *desc;
1760 struct qlcnic_rx_buffer *rxbuf;
1761 u64 sts_data0;
1762
1763 int opcode, ring, desc_cnt;
1764 u32 consumer = sds_ring->consumer;
1765
1766 desc = &sds_ring->desc_head[consumer];
1767 sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
1768
1769 if (!(sts_data0 & STATUS_OWNER_HOST))
1770 return;
1771
1772 desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
1773 opcode = qlcnic_get_sts_opcode(sts_data0);
1774
1775 ring = qlcnic_get_sts_type(sts_data0);
1776 rxbuf = qlcnic_process_rcv_diag(adapter, sds_ring,
1777 ring, sts_data0);
1778
1779 desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
1780 consumer = get_next_index(consumer, sds_ring->num_desc);
1781
1782 sds_ring->consumer = consumer;
1783 writel(consumer, sds_ring->crb_sts_consumer);
1784}
1785
1786void 1693void
1787qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2, 1694qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2,
1788 u8 alt_mac, u8 *mac) 1695 u8 alt_mac, u8 *mac)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 899df5a81fda..08d4b37f246c 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2859,61 +2859,6 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
2859 qlcnic_api_unlock(adapter); 2859 qlcnic_api_unlock(adapter);
2860} 2860}
2861 2861
2862/* Caller should held RESETTING bit.
2863 * This should be call in sync with qlcnic_request_quiscent_mode.
2864 */
2865void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter)
2866{
2867 qlcnic_clr_drv_state(adapter);
2868 qlcnic_api_lock(adapter);
2869 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
2870 qlcnic_api_unlock(adapter);
2871}
2872
2873/* Caller should held RESETTING bit.
2874 */
2875int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter)
2876{
2877 u8 timeo = adapter->dev_init_timeo / 2;
2878 u32 state;
2879
2880 if (qlcnic_api_lock(adapter))
2881 return -EIO;
2882
2883 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2884 if (state != QLCNIC_DEV_READY)
2885 return -EIO;
2886
2887 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT);
2888 qlcnic_api_unlock(adapter);
2889 QLCDB(adapter, DRV, "NEED QUISCENT state set\n");
2890 qlcnic_idc_debug_info(adapter, 0);
2891
2892 qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT);
2893
2894 do {
2895 msleep(2000);
2896 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2897 if (state == QLCNIC_DEV_QUISCENT)
2898 return 0;
2899 if (!qlcnic_check_drv_state(adapter)) {
2900 if (qlcnic_api_lock(adapter))
2901 return -EIO;
2902 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
2903 QLCNIC_DEV_QUISCENT);
2904 qlcnic_api_unlock(adapter);
2905 QLCDB(adapter, DRV, "QUISCENT mode set\n");
2906 return 0;
2907 }
2908 } while (--timeo);
2909
2910 dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x"
2911 " DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE),
2912 QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE));
2913 qlcnic_clear_quiscent_mode(adapter);
2914 return -EIO;
2915}
2916
2917/*Transit to RESET state from READY state only */ 2862/*Transit to RESET state from READY state only */
2918static void 2863static void
2919qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) 2864qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)