diff options
author | Amit Kumar Salecha <amit.salecha@qlogic.com> | 2010-10-04 04:20:09 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-04 22:46:48 -0700 |
commit | 31dee692e22eedaf2540fa543fa9c91df6ab8bda (patch) | |
tree | 10e544e30a4dfe906282b8ddfaf7a9f379bd9535 | |
parent | 21a180cda012e1f93e362dd4a9b0bfd3d8c92940 (diff) |
qlcnic: fix internal loopback test
o Loop 10 times with delay of 1 ms to rcv packet.
o Print garbage packet.
o Try send/receive MAX(16) packet, instead of exit from test,
if a packet is not received.
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_ethtool.c | 26 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 19 |
2 files changed, 37 insertions, 8 deletions
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index cb9463bd6b1..550cfe9a1b1 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -636,6 +636,8 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset) } #define QLC_ILB_PKT_SIZE 64 +#define QLC_NUM_ILB_PKT 16 +#define QLC_ILB_MAX_RCV_LOOP 10 static void qlcnic_create_loopback_buff(unsigned char *data) { @@ -657,24 +659,34 @@ static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; struct sk_buff *skb; - int i; + int i, loop, cnt = 0; - for (i = 0; i < 16; i++) { + for (i = 0; i < QLC_NUM_ILB_PKT; i++) { skb = dev_alloc_skb(QLC_ILB_PKT_SIZE); qlcnic_create_loopback_buff(skb->data); skb_put(skb, QLC_ILB_PKT_SIZE); adapter->diag_cnt = 0; - qlcnic_xmit_frame(skb, adapter->netdev); - msleep(5); - - qlcnic_process_rcv_ring_diag(sds_ring); + loop = 0; + do { + msleep(1); + qlcnic_process_rcv_ring_diag(sds_ring); + } while (loop++ < QLC_ILB_MAX_RCV_LOOP && + !adapter->diag_cnt); dev_kfree_skb_any(skb); + if (!adapter->diag_cnt) - return -1; + dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" + " not recevied\n", i + 1); + else + cnt++; + } + if (cnt != i) { + dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); + return -1; } return 0; } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 5c33d15c874..908a25b5597 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1693,6 +1693,18 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, spin_unlock(&rds_ring->lock); } +static void dump_skb(struct sk_buff *skb) +{ + int i; + unsigned char *data = skb->data; + + for (i = 0; i < skb->len; i++) { + printk("%02x ", data[i]); + if ((i & 0x0f) == 8) + printk("\n"); + } +} + static struct qlcnic_rx_buffer * qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, struct qlcnic_host_sds_ring *sds_ring, @@ -1723,13 +1735,18 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, if (!skb) return buffer; - skb_put(skb, rds_ring->skb_size); + if (length > rds_ring->skb_size) + skb_put(skb, rds_ring->skb_size); + else + skb_put(skb, length); if (pkt_offset) skb_pull(skb, pkt_offset); if (!qlcnic_check_loopback_buff(skb->data)) adapter->diag_cnt++; + else + dump_skb(skb); dev_kfree_skb_any(skb); adapter->stats.rx_pkts++; |