diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 66 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 21 |
4 files changed, 74 insertions, 16 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 53c66869aecd..70346fd7f9c4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
@@ -183,10 +183,11 @@ static int mlx4_en_set_wol(struct net_device *netdev, | |||
183 | static int mlx4_en_get_sset_count(struct net_device *dev, int sset) | 183 | static int mlx4_en_get_sset_count(struct net_device *dev, int sset) |
184 | { | 184 | { |
185 | struct mlx4_en_priv *priv = netdev_priv(dev); | 185 | struct mlx4_en_priv *priv = netdev_priv(dev); |
186 | int bit_count = hweight64(priv->stats_bitmap); | ||
186 | 187 | ||
187 | switch (sset) { | 188 | switch (sset) { |
188 | case ETH_SS_STATS: | 189 | case ETH_SS_STATS: |
189 | return NUM_ALL_STATS + | 190 | return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) + |
190 | (priv->tx_ring_num + priv->rx_ring_num) * 2; | 191 | (priv->tx_ring_num + priv->rx_ring_num) * 2; |
191 | case ETH_SS_TEST: | 192 | case ETH_SS_TEST: |
192 | return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags | 193 | return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags |
@@ -201,14 +202,34 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, | |||
201 | { | 202 | { |
202 | struct mlx4_en_priv *priv = netdev_priv(dev); | 203 | struct mlx4_en_priv *priv = netdev_priv(dev); |
203 | int index = 0; | 204 | int index = 0; |
204 | int i; | 205 | int i, j = 0; |
205 | 206 | ||
206 | spin_lock_bh(&priv->stats_lock); | 207 | spin_lock_bh(&priv->stats_lock); |
207 | 208 | ||
208 | for (i = 0; i < NUM_MAIN_STATS; i++) | 209 | if (!(priv->stats_bitmap)) { |
209 | data[index++] = ((unsigned long *) &priv->stats)[i]; | 210 | for (i = 0; i < NUM_MAIN_STATS; i++) |
210 | for (i = 0; i < NUM_PORT_STATS; i++) | 211 | data[index++] = |
211 | data[index++] = ((unsigned long *) &priv->port_stats)[i]; | 212 | ((unsigned long *) &priv->stats)[i]; |
213 | for (i = 0; i < NUM_PORT_STATS; i++) | ||
214 | data[index++] = | ||
215 | ((unsigned long *) &priv->port_stats)[i]; | ||
216 | for (i = 0; i < NUM_PKT_STATS; i++) | ||
217 | data[index++] = | ||
218 | ((unsigned long *) &priv->pkstats)[i]; | ||
219 | } else { | ||
220 | for (i = 0; i < NUM_MAIN_STATS; i++) { | ||
221 | if ((priv->stats_bitmap >> j) & 1) | ||
222 | data[index++] = | ||
223 | ((unsigned long *) &priv->stats)[i]; | ||
224 | j++; | ||
225 | } | ||
226 | for (i = 0; i < NUM_PORT_STATS; i++) { | ||
227 | if ((priv->stats_bitmap >> j) & 1) | ||
228 | data[index++] = | ||
229 | ((unsigned long *) &priv->port_stats)[i]; | ||
230 | j++; | ||
231 | } | ||
232 | } | ||
212 | for (i = 0; i < priv->tx_ring_num; i++) { | 233 | for (i = 0; i < priv->tx_ring_num; i++) { |
213 | data[index++] = priv->tx_ring[i].packets; | 234 | data[index++] = priv->tx_ring[i].packets; |
214 | data[index++] = priv->tx_ring[i].bytes; | 235 | data[index++] = priv->tx_ring[i].bytes; |
@@ -217,8 +238,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, | |||
217 | data[index++] = priv->rx_ring[i].packets; | 238 | data[index++] = priv->rx_ring[i].packets; |
218 | data[index++] = priv->rx_ring[i].bytes; | 239 | data[index++] = priv->rx_ring[i].bytes; |
219 | } | 240 | } |
220 | for (i = 0; i < NUM_PKT_STATS; i++) | ||
221 | data[index++] = ((unsigned long *) &priv->pkstats)[i]; | ||
222 | spin_unlock_bh(&priv->stats_lock); | 241 | spin_unlock_bh(&priv->stats_lock); |
223 | 242 | ||
224 | } | 243 | } |
@@ -247,11 +266,29 @@ static void mlx4_en_get_strings(struct net_device *dev, | |||
247 | 266 | ||
248 | case ETH_SS_STATS: | 267 | case ETH_SS_STATS: |
249 | /* Add main counters */ | 268 | /* Add main counters */ |
250 | for (i = 0; i < NUM_MAIN_STATS; i++) | 269 | if (!priv->stats_bitmap) { |
251 | strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); | 270 | for (i = 0; i < NUM_MAIN_STATS; i++) |
252 | for (i = 0; i< NUM_PORT_STATS; i++) | 271 | strcpy(data + (index++) * ETH_GSTRING_LEN, |
253 | strcpy(data + (index++) * ETH_GSTRING_LEN, | 272 | main_strings[i]); |
254 | main_strings[i + NUM_MAIN_STATS]); | 273 | for (i = 0; i < NUM_PORT_STATS; i++) |
274 | strcpy(data + (index++) * ETH_GSTRING_LEN, | ||
275 | main_strings[i + | ||
276 | NUM_MAIN_STATS]); | ||
277 | for (i = 0; i < NUM_PKT_STATS; i++) | ||
278 | strcpy(data + (index++) * ETH_GSTRING_LEN, | ||
279 | main_strings[i + | ||
280 | NUM_MAIN_STATS + | ||
281 | NUM_PORT_STATS]); | ||
282 | } else | ||
283 | for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) { | ||
284 | if ((priv->stats_bitmap >> i) & 1) { | ||
285 | strcpy(data + | ||
286 | (index++) * ETH_GSTRING_LEN, | ||
287 | main_strings[i]); | ||
288 | } | ||
289 | if (!(priv->stats_bitmap >> i)) | ||
290 | break; | ||
291 | } | ||
255 | for (i = 0; i < priv->tx_ring_num; i++) { | 292 | for (i = 0; i < priv->tx_ring_num; i++) { |
256 | sprintf(data + (index++) * ETH_GSTRING_LEN, | 293 | sprintf(data + (index++) * ETH_GSTRING_LEN, |
257 | "tx%d_packets", i); | 294 | "tx%d_packets", i); |
@@ -264,9 +301,6 @@ static void mlx4_en_get_strings(struct net_device *dev, | |||
264 | sprintf(data + (index++) * ETH_GSTRING_LEN, | 301 | sprintf(data + (index++) * ETH_GSTRING_LEN, |
265 | "rx%d_bytes", i); | 302 | "rx%d_bytes", i); |
266 | } | 303 | } |
267 | for (i = 0; i< NUM_PKT_STATS; i++) | ||
268 | strcpy(data + (index++) * ETH_GSTRING_LEN, | ||
269 | main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); | ||
270 | break; | 304 | break; |
271 | } | 305 | } |
272 | } | 306 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index be3f4156aaab..467ae5824875 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -702,6 +702,8 @@ int mlx4_en_start_port(struct net_device *dev) | |||
702 | /* Schedule multicast task to populate multicast list */ | 702 | /* Schedule multicast task to populate multicast list */ |
703 | queue_work(mdev->workqueue, &priv->mcast_task); | 703 | queue_work(mdev->workqueue, &priv->mcast_task); |
704 | 704 | ||
705 | mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); | ||
706 | |||
705 | priv->port_up = true; | 707 | priv->port_up = true; |
706 | netif_tx_start_all_queues(dev); | 708 | netif_tx_start_all_queues(dev); |
707 | return 0; | 709 | return 0; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index f4d189a1290e..35f08840813c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -476,6 +476,7 @@ struct mlx4_en_priv { | |||
476 | struct mlx4_en_perf_stats pstats; | 476 | struct mlx4_en_perf_stats pstats; |
477 | struct mlx4_en_pkt_stats pkstats; | 477 | struct mlx4_en_pkt_stats pkstats; |
478 | struct mlx4_en_port_stats port_stats; | 478 | struct mlx4_en_port_stats port_stats; |
479 | u64 stats_bitmap; | ||
479 | char *mc_addrs; | 480 | char *mc_addrs; |
480 | int mc_addrs_cnt; | 481 | int mc_addrs_cnt; |
481 | struct mlx4_en_stat_out_mbox hw_stats; | 482 | struct mlx4_en_stat_out_mbox hw_stats; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 1a551d69ddcb..f44ae555bf43 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -44,6 +44,11 @@ | |||
44 | #define MLX4_VLAN_VALID (1u << 31) | 44 | #define MLX4_VLAN_VALID (1u << 31) |
45 | #define MLX4_VLAN_MASK 0xfff | 45 | #define MLX4_VLAN_MASK 0xfff |
46 | 46 | ||
47 | #define MLX4_STATS_TRAFFIC_COUNTERS_MASK 0xfULL | ||
48 | #define MLX4_STATS_TRAFFIC_DROPS_MASK 0xc0ULL | ||
49 | #define MLX4_STATS_ERROR_COUNTERS_MASK 0x1ffc30ULL | ||
50 | #define MLX4_STATS_PORT_COUNTERS_MASK 0x1fe00000ULL | ||
51 | |||
47 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) | 52 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) |
48 | { | 53 | { |
49 | int i; | 54 | int i; |
@@ -903,3 +908,19 @@ int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave, | |||
903 | return mlx4_common_dump_eth_stats(dev, slave, | 908 | return mlx4_common_dump_eth_stats(dev, slave, |
904 | vhcr->in_modifier, outbox); | 909 | vhcr->in_modifier, outbox); |
905 | } | 910 | } |
911 | |||
912 | void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap) | ||
913 | { | ||
914 | if (!mlx4_is_mfunc(dev)) { | ||
915 | *stats_bitmap = 0; | ||
916 | return; | ||
917 | } | ||
918 | |||
919 | *stats_bitmap = (MLX4_STATS_TRAFFIC_COUNTERS_MASK | | ||
920 | MLX4_STATS_TRAFFIC_DROPS_MASK | | ||
921 | MLX4_STATS_PORT_COUNTERS_MASK); | ||
922 | |||
923 | if (mlx4_is_master(dev)) | ||
924 | *stats_bitmap |= MLX4_STATS_ERROR_COUNTERS_MASK; | ||
925 | } | ||
926 | EXPORT_SYMBOL(mlx4_set_stats_bitmap); | ||