diff options
author | Yevgeny Petrilin <yevgenyp@mellanox.co.il> | 2010-08-23 23:46:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-24 17:54:51 -0400 |
commit | e7c1c2c46201e46f8ce817196507d2ffd3dafd8e (patch) | |
tree | 33579da64d2c5dc4502518496097dcf9737e9eb4 /drivers/net/mlx4/en_rx.c | |
parent | 3005ad40b95168aad530f1179cff47411b3ea8da (diff) |
mlx4_en: Added self diagnostics test implementation
The selftest includes 5 features:
1. Interrupt test: Executing commands and receiving command completion
on all our interrupt vectors.
2. Link test: Verifying we are connected to valid link partner.
3. Speed test: Check that we negotiated link speed correctly.
4. Registers test: Activate HW health check command.
5. Loopback test: Send a packet on loopback interface and catch it on RX side.
Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/mlx4/en_rx.c')
-rw-r--r-- | drivers/net/mlx4/en_rx.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 7a5123c4a366..f421a3d42723 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c | |||
@@ -541,6 +541,21 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, | |||
541 | return skb; | 541 | return skb; |
542 | } | 542 | } |
543 | 543 | ||
544 | static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb) | ||
545 | { | ||
546 | int i; | ||
547 | int offset = ETH_HLEN; | ||
548 | |||
549 | for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) { | ||
550 | if (*(skb->data + offset) != (unsigned char) (i & 0xff)) | ||
551 | goto out_loopback; | ||
552 | } | ||
553 | /* Loopback found */ | ||
554 | priv->loopback_ok = 1; | ||
555 | |||
556 | out_loopback: | ||
557 | dev_kfree_skb_any(skb); | ||
558 | } | ||
544 | 559 | ||
545 | int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) | 560 | int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) |
546 | { | 561 | { |
@@ -655,6 +670,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
655 | goto next; | 670 | goto next; |
656 | } | 671 | } |
657 | 672 | ||
673 | if (unlikely(priv->validate_loopback)) { | ||
674 | validate_loopback(priv, skb); | ||
675 | goto next; | ||
676 | } | ||
677 | |||
658 | skb->ip_summed = ip_summed; | 678 | skb->ip_summed = ip_summed; |
659 | skb->protocol = eth_type_trans(skb, dev); | 679 | skb->protocol = eth_type_trans(skb, dev); |
660 | skb_record_rx_queue(skb, cq->ring); | 680 | skb_record_rx_queue(skb, cq->ring); |