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_ethtool.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_ethtool.c')
-rw-r--r-- | drivers/net/mlx4/en_ethtool.c | 79 |
1 files changed, 54 insertions, 25 deletions
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 398d54136967..f7d72d7a8704 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c | |||
@@ -125,6 +125,14 @@ static const char main_strings[][ETH_GSTRING_LEN] = { | |||
125 | #define NUM_MAIN_STATS 21 | 125 | #define NUM_MAIN_STATS 21 |
126 | #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) | 126 | #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) |
127 | 127 | ||
128 | static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= { | ||
129 | "Interupt Test", | ||
130 | "Link Test", | ||
131 | "Speed Test", | ||
132 | "Register Test", | ||
133 | "Loopback Test", | ||
134 | }; | ||
135 | |||
128 | static u32 mlx4_en_get_msglevel(struct net_device *dev) | 136 | static u32 mlx4_en_get_msglevel(struct net_device *dev) |
129 | { | 137 | { |
130 | return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable; | 138 | return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable; |
@@ -146,10 +154,15 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset) | |||
146 | { | 154 | { |
147 | struct mlx4_en_priv *priv = netdev_priv(dev); | 155 | struct mlx4_en_priv *priv = netdev_priv(dev); |
148 | 156 | ||
149 | if (sset != ETH_SS_STATS) | 157 | switch (sset) { |
158 | case ETH_SS_STATS: | ||
159 | return NUM_ALL_STATS + | ||
160 | (priv->tx_ring_num + priv->rx_ring_num) * 2; | ||
161 | case ETH_SS_TEST: | ||
162 | return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2; | ||
163 | default: | ||
150 | return -EOPNOTSUPP; | 164 | return -EOPNOTSUPP; |
151 | 165 | } | |
152 | return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2; | ||
153 | } | 166 | } |
154 | 167 | ||
155 | static void mlx4_en_get_ethtool_stats(struct net_device *dev, | 168 | static void mlx4_en_get_ethtool_stats(struct net_device *dev, |
@@ -181,6 +194,12 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, | |||
181 | 194 | ||
182 | } | 195 | } |
183 | 196 | ||
197 | static void mlx4_en_self_test(struct net_device *dev, | ||
198 | struct ethtool_test *etest, u64 *buf) | ||
199 | { | ||
200 | mlx4_en_ex_selftest(dev, &etest->flags, buf); | ||
201 | } | ||
202 | |||
184 | static void mlx4_en_get_strings(struct net_device *dev, | 203 | static void mlx4_en_get_strings(struct net_device *dev, |
185 | uint32_t stringset, uint8_t *data) | 204 | uint32_t stringset, uint8_t *data) |
186 | { | 205 | { |
@@ -188,30 +207,39 @@ static void mlx4_en_get_strings(struct net_device *dev, | |||
188 | int index = 0; | 207 | int index = 0; |
189 | int i; | 208 | int i; |
190 | 209 | ||
191 | if (stringset != ETH_SS_STATS) | 210 | switch (stringset) { |
192 | return; | 211 | case ETH_SS_TEST: |
193 | 212 | for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++) | |
194 | /* Add main counters */ | 213 | strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); |
195 | for (i = 0; i < NUM_MAIN_STATS; i++) | 214 | if (priv->mdev->dev->caps.loopback_support) |
196 | strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); | 215 | for (; i < MLX4_EN_NUM_SELF_TEST; i++) |
197 | for (i = 0; i < NUM_PORT_STATS; i++) | 216 | strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); |
198 | strcpy(data + (index++) * ETH_GSTRING_LEN, | 217 | break; |
218 | |||
219 | case ETH_SS_STATS: | ||
220 | /* Add main counters */ | ||
221 | for (i = 0; i < NUM_MAIN_STATS; i++) | ||
222 | strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); | ||
223 | for (i = 0; i< NUM_PORT_STATS; i++) | ||
224 | strcpy(data + (index++) * ETH_GSTRING_LEN, | ||
199 | main_strings[i + NUM_MAIN_STATS]); | 225 | main_strings[i + NUM_MAIN_STATS]); |
200 | for (i = 0; i < priv->tx_ring_num; i++) { | 226 | for (i = 0; i < priv->tx_ring_num; i++) { |
201 | sprintf(data + (index++) * ETH_GSTRING_LEN, | 227 | sprintf(data + (index++) * ETH_GSTRING_LEN, |
202 | "tx%d_packets", i); | 228 | "tx%d_packets", i); |
203 | sprintf(data + (index++) * ETH_GSTRING_LEN, | 229 | sprintf(data + (index++) * ETH_GSTRING_LEN, |
204 | "tx%d_bytes", i); | 230 | "tx%d_bytes", i); |
205 | } | 231 | } |
206 | for (i = 0; i < priv->rx_ring_num; i++) { | 232 | for (i = 0; i < priv->rx_ring_num; i++) { |
207 | sprintf(data + (index++) * ETH_GSTRING_LEN, | 233 | sprintf(data + (index++) * ETH_GSTRING_LEN, |
208 | "rx%d_packets", i); | 234 | "rx%d_packets", i); |
209 | sprintf(data + (index++) * ETH_GSTRING_LEN, | 235 | sprintf(data + (index++) * ETH_GSTRING_LEN, |
210 | "rx%d_bytes", i); | 236 | "rx%d_bytes", i); |
211 | } | 237 | } |
212 | for (i = 0; i < NUM_PKT_STATS; i++) | 238 | for (i = 0; i< NUM_PKT_STATS; i++) |
213 | strcpy(data + (index++) * ETH_GSTRING_LEN, | 239 | strcpy(data + (index++) * ETH_GSTRING_LEN, |
214 | main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); | 240 | main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); |
241 | break; | ||
242 | } | ||
215 | } | 243 | } |
216 | 244 | ||
217 | static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 245 | static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
@@ -439,6 +467,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { | |||
439 | .get_strings = mlx4_en_get_strings, | 467 | .get_strings = mlx4_en_get_strings, |
440 | .get_sset_count = mlx4_en_get_sset_count, | 468 | .get_sset_count = mlx4_en_get_sset_count, |
441 | .get_ethtool_stats = mlx4_en_get_ethtool_stats, | 469 | .get_ethtool_stats = mlx4_en_get_ethtool_stats, |
470 | .self_test = mlx4_en_self_test, | ||
442 | .get_wol = mlx4_en_get_wol, | 471 | .get_wol = mlx4_en_get_wol, |
443 | .get_msglevel = mlx4_en_get_msglevel, | 472 | .get_msglevel = mlx4_en_get_msglevel, |
444 | .set_msglevel = mlx4_en_set_msglevel, | 473 | .set_msglevel = mlx4_en_set_msglevel, |