diff options
author | Yevgeny Petrilin <yevgenyp@mellanox.co.il> | 2010-08-24 03:46:18 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-24 21:54:51 (GMT) |
commit | e7c1c2c46201e46f8ce817196507d2ffd3dafd8e (patch) | |
tree | 33579da64d2c5dc4502518496097dcf9737e9eb4 /drivers/net/mlx4/en_rx.c | |
parent | 3005ad40b95168aad530f1179cff47411b3ea8da (diff) | |
download | linux-e7c1c2c46201e46f8ce817196507d2ffd3dafd8e.tar.xz |
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 7a5123c..f421a3d 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, return skb; } +static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb) +{ + int i; + int offset = ETH_HLEN; + + for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) { + if (*(skb->data + offset) != (unsigned char) (i & 0xff)) + goto out_loopback; + } + /* Loopback found */ + priv->loopback_ok = 1; + +out_loopback: + dev_kfree_skb_any(skb); +} int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) { @@ -655,6 +670,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud goto next; } + if (unlikely(priv->validate_loopback)) { + validate_loopback(priv, skb); + goto next; + } + skb->ip_summed = ip_summed; skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, cq->ring); |