Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mlx4_en: eth statistics modification

In native mode display all available staticstics.
In SRIOV mode on VF display only SW counters statistics,
in SRIOV mode on hypervisor display SW counters and errors (got from FW)
statistics.

Signed-off-by: Eugenia Emantayev <eugenia@mellanox.co.il>
Reviewed-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eugenia Emantayev and committed by
David S. Miller
93ece0c1 35fb9afb

+75 -16
+50 -16
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
··· 183 183 static int mlx4_en_get_sset_count(struct net_device *dev, int sset) 184 184 { 185 185 struct mlx4_en_priv *priv = netdev_priv(dev); 186 + int bit_count = hweight64(priv->stats_bitmap); 186 187 187 188 switch (sset) { 188 189 case ETH_SS_STATS: 189 - return NUM_ALL_STATS + 190 + return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) + 190 191 (priv->tx_ring_num + priv->rx_ring_num) * 2; 191 192 case ETH_SS_TEST: 192 193 return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags ··· 202 201 { 203 202 struct mlx4_en_priv *priv = netdev_priv(dev); 204 203 int index = 0; 205 - int i; 204 + int i, j = 0; 206 205 207 206 spin_lock_bh(&priv->stats_lock); 208 207 209 - for (i = 0; i < NUM_MAIN_STATS; i++) 210 - data[index++] = ((unsigned long *) &priv->stats)[i]; 211 - for (i = 0; i < NUM_PORT_STATS; i++) 212 - data[index++] = ((unsigned long *) &priv->port_stats)[i]; 208 + if (!(priv->stats_bitmap)) { 209 + for (i = 0; i < NUM_MAIN_STATS; i++) 210 + data[index++] = 211 + ((unsigned long *) &priv->stats)[i]; 212 + for (i = 0; i < NUM_PORT_STATS; i++) 213 + data[index++] = 214 + ((unsigned long *) &priv->port_stats)[i]; 215 + for (i = 0; i < NUM_PKT_STATS; i++) 216 + data[index++] = 217 + ((unsigned long *) &priv->pkstats)[i]; 218 + } else { 219 + for (i = 0; i < NUM_MAIN_STATS; i++) { 220 + if ((priv->stats_bitmap >> j) & 1) 221 + data[index++] = 222 + ((unsigned long *) &priv->stats)[i]; 223 + j++; 224 + } 225 + for (i = 0; i < NUM_PORT_STATS; i++) { 226 + if ((priv->stats_bitmap >> j) & 1) 227 + data[index++] = 228 + ((unsigned long *) &priv->port_stats)[i]; 229 + j++; 230 + } 231 + } 213 232 for (i = 0; i < priv->tx_ring_num; i++) { 214 233 data[index++] = priv->tx_ring[i].packets; 215 234 data[index++] = priv->tx_ring[i].bytes; ··· 238 217 data[index++] = priv->rx_ring[i].packets; 239 218 data[index++] = priv->rx_ring[i].bytes; 240 219 } 241 - for (i = 0; i < NUM_PKT_STATS; i++) 242 - data[index++] = ((unsigned long *) &priv->pkstats)[i]; 243 220 spin_unlock_bh(&priv->stats_lock); 244 221 245 222 } ··· 266 247 267 248 case ETH_SS_STATS: 268 249 /* Add main counters */ 269 - for (i = 0; i < NUM_MAIN_STATS; i++) 270 - strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); 271 - for (i = 0; i< NUM_PORT_STATS; i++) 272 - strcpy(data + (index++) * ETH_GSTRING_LEN, 273 - main_strings[i + NUM_MAIN_STATS]); 250 + if (!priv->stats_bitmap) { 251 + for (i = 0; i < NUM_MAIN_STATS; i++) 252 + strcpy(data + (index++) * ETH_GSTRING_LEN, 253 + main_strings[i]); 254 + for (i = 0; i < NUM_PORT_STATS; i++) 255 + strcpy(data + (index++) * ETH_GSTRING_LEN, 256 + main_strings[i + 257 + NUM_MAIN_STATS]); 258 + for (i = 0; i < NUM_PKT_STATS; i++) 259 + strcpy(data + (index++) * ETH_GSTRING_LEN, 260 + main_strings[i + 261 + NUM_MAIN_STATS + 262 + NUM_PORT_STATS]); 263 + } else 264 + for (i = 0; i < NUM_MAIN_STATS + NUM_PORT_STATS; i++) { 265 + if ((priv->stats_bitmap >> i) & 1) { 266 + strcpy(data + 267 + (index++) * ETH_GSTRING_LEN, 268 + main_strings[i]); 269 + } 270 + if (!(priv->stats_bitmap >> i)) 271 + break; 272 + } 274 273 for (i = 0; i < priv->tx_ring_num; i++) { 275 274 sprintf(data + (index++) * ETH_GSTRING_LEN, 276 275 "tx%d_packets", i); ··· 301 264 sprintf(data + (index++) * ETH_GSTRING_LEN, 302 265 "rx%d_bytes", i); 303 266 } 304 - for (i = 0; i< NUM_PKT_STATS; i++) 305 - strcpy(data + (index++) * ETH_GSTRING_LEN, 306 - main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); 307 267 break; 308 268 } 309 269 }
+2
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
··· 702 702 /* Schedule multicast task to populate multicast list */ 703 703 queue_work(mdev->workqueue, &priv->mcast_task); 704 704 705 + mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); 706 + 705 707 priv->port_up = true; 706 708 netif_tx_start_all_queues(dev); 707 709 return 0;
+1
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
··· 476 476 struct mlx4_en_perf_stats pstats; 477 477 struct mlx4_en_pkt_stats pkstats; 478 478 struct mlx4_en_port_stats port_stats; 479 + u64 stats_bitmap; 479 480 char *mc_addrs; 480 481 int mc_addrs_cnt; 481 482 struct mlx4_en_stat_out_mbox hw_stats;
+21
drivers/net/ethernet/mellanox/mlx4/port.c
··· 44 44 #define MLX4_VLAN_VALID (1u << 31) 45 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 52 void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) 48 53 { 49 54 int i; ··· 908 903 return mlx4_common_dump_eth_stats(dev, slave, 909 904 vhcr->in_modifier, outbox); 910 905 } 906 + 907 + void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap) 908 + { 909 + if (!mlx4_is_mfunc(dev)) { 910 + *stats_bitmap = 0; 911 + return; 912 + } 913 + 914 + *stats_bitmap = (MLX4_STATS_TRAFFIC_COUNTERS_MASK | 915 + MLX4_STATS_TRAFFIC_DROPS_MASK | 916 + MLX4_STATS_PORT_COUNTERS_MASK); 917 + 918 + if (mlx4_is_master(dev)) 919 + *stats_bitmap |= MLX4_STATS_ERROR_COUNTERS_MASK; 920 + } 921 + EXPORT_SYMBOL(mlx4_set_stats_bitmap);
+1
include/linux/mlx4/device.h
··· 621 621 int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac); 622 622 int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn); 623 623 void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn); 624 + void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap); 624 625 625 626 int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx); 626 627 int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);