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/eq.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/eq.c')
-rw-r--r-- | drivers/net/mlx4/eq.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 6d7b2bf210c..552d0fce6f6 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c | |||
@@ -699,3 +699,47 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) | |||
699 | 699 | ||
700 | kfree(priv->eq_table.uar_map); | 700 | kfree(priv->eq_table.uar_map); |
701 | } | 701 | } |
702 | |||
703 | /* A test that verifies that we can accept interrupts on all | ||
704 | * the irq vectors of the device. | ||
705 | * Interrupts are checked using the NOP command. | ||
706 | */ | ||
707 | int mlx4_test_interrupts(struct mlx4_dev *dev) | ||
708 | { | ||
709 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
710 | int i; | ||
711 | int err; | ||
712 | |||
713 | err = mlx4_NOP(dev); | ||
714 | /* When not in MSI_X, there is only one irq to check */ | ||
715 | if (!(dev->flags & MLX4_FLAG_MSI_X)) | ||
716 | return err; | ||
717 | |||
718 | /* A loop over all completion vectors, for each vector we will check | ||
719 | * whether it works by mapping command completions to that vector | ||
720 | * and performing a NOP command | ||
721 | */ | ||
722 | for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) { | ||
723 | /* Temporary use polling for command completions */ | ||
724 | mlx4_cmd_use_polling(dev); | ||
725 | |||
726 | /* Map the new eq to handle all asyncronous events */ | ||
727 | err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, | ||
728 | priv->eq_table.eq[i].eqn); | ||
729 | if (err) { | ||
730 | mlx4_warn(dev, "Failed mapping eq for interrupt test\n"); | ||
731 | mlx4_cmd_use_events(dev); | ||
732 | break; | ||
733 | } | ||
734 | |||
735 | /* Go back to using events */ | ||
736 | mlx4_cmd_use_events(dev); | ||
737 | err = mlx4_NOP(dev); | ||
738 | } | ||
739 | |||
740 | /* Return to default */ | ||
741 | mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, | ||
742 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); | ||
743 | return err; | ||
744 | } | ||
745 | EXPORT_SYMBOL(mlx4_test_interrupts); | ||