aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2015-03-30 10:45:25 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-31 16:36:51 -0400
commit0b131561a7d639abb0a194d2d8fae839ce3b99e9 (patch)
tree88b2bbfd63a14c35d47c9eb2cf57748d8fe173a3
parent3da8a36cc5c2a172bb42f8dc89638f5b41d7d7a6 (diff)
net/mlx4_en: Add Flow control statistics display via ethtool
Flow control per priority and Global pause counters are now visible via ethtool. The counters shows statistics regarding pauses in the device. Signed-off-by: Matan Barak <matanb@mellanox.com> Signed-off-by: Shani Michaeli <shanim@mellanox.com> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com> Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c74
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c57
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_port.c50
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h13
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h52
-rw-r--r--include/linux/mlx4/device.h3
8 files changed, 255 insertions, 8 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
index cde14fa2f742..8e3260c0eaa5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
@@ -226,6 +226,10 @@ static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev,
226 prof->rx_ppp); 226 prof->rx_ppp);
227 if (err) 227 if (err)
228 en_err(priv, "Failed setting pause params\n"); 228 en_err(priv, "Failed setting pause params\n");
229 else
230 mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
231 prof->rx_ppp, prof->rx_pause,
232 prof->tx_ppp, prof->tx_pause);
229 233
230 return err; 234 return err;
231} 235}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 3e7ed39e8e76..4fc767461b4f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -119,6 +119,48 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
119 "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed", 119 "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
120 "rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload", 120 "rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload",
121 121
122 /* priority flow control statistics rx */
123 "rx_pause_prio_0", "rx_pause_duration_prio_0",
124 "rx_pause_transition_prio_0",
125 "rx_pause_prio_1", "rx_pause_duration_prio_1",
126 "rx_pause_transition_prio_1",
127 "rx_pause_prio_2", "rx_pause_duration_prio_2",
128 "rx_pause_transition_prio_2",
129 "rx_pause_prio_3", "rx_pause_duration_prio_3",
130 "rx_pause_transition_prio_3",
131 "rx_pause_prio_4", "rx_pause_duration_prio_4",
132 "rx_pause_transition_prio_4",
133 "rx_pause_prio_5", "rx_pause_duration_prio_5",
134 "rx_pause_transition_prio_5",
135 "rx_pause_prio_6", "rx_pause_duration_prio_6",
136 "rx_pause_transition_prio_6",
137 "rx_pause_prio_7", "rx_pause_duration_prio_7",
138 "rx_pause_transition_prio_7",
139
140 /* flow control statistics rx */
141 "rx_pause", "rx_pause_duration", "rx_pause_transition",
142
143 /* priority flow control statistics tx */
144 "tx_pause_prio_0", "tx_pause_duration_prio_0",
145 "tx_pause_transition_prio_0",
146 "tx_pause_prio_1", "tx_pause_duration_prio_1",
147 "tx_pause_transition_prio_1",
148 "tx_pause_prio_2", "tx_pause_duration_prio_2",
149 "tx_pause_transition_prio_2",
150 "tx_pause_prio_3", "tx_pause_duration_prio_3",
151 "tx_pause_transition_prio_3",
152 "tx_pause_prio_4", "tx_pause_duration_prio_4",
153 "tx_pause_transition_prio_4",
154 "tx_pause_prio_5", "tx_pause_duration_prio_5",
155 "tx_pause_transition_prio_5",
156 "tx_pause_prio_6", "tx_pause_duration_prio_6",
157 "tx_pause_transition_prio_6",
158 "tx_pause_prio_7", "tx_pause_duration_prio_7",
159 "tx_pause_transition_prio_7",
160
161 /* flow control statistics tx */
162 "tx_pause", "tx_pause_duration", "tx_pause_transition",
163
122 /* packet statistics */ 164 /* packet statistics */
123 "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3", 165 "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
124 "rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0", 166 "rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
@@ -304,6 +346,26 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
304 if (bitmap_iterator_test(&it)) 346 if (bitmap_iterator_test(&it))
305 data[index++] = ((unsigned long *)&priv->port_stats)[i]; 347 data[index++] = ((unsigned long *)&priv->port_stats)[i];
306 348
349 for (i = 0; i < NUM_FLOW_PRIORITY_STATS_RX;
350 i++, bitmap_iterator_inc(&it))
351 if (bitmap_iterator_test(&it))
352 data[index++] =
353 ((u64 *)&priv->rx_priority_flowstats)[i];
354
355 for (i = 0; i < NUM_FLOW_STATS_RX; i++, bitmap_iterator_inc(&it))
356 if (bitmap_iterator_test(&it))
357 data[index++] = ((u64 *)&priv->rx_flowstats)[i];
358
359 for (i = 0; i < NUM_FLOW_PRIORITY_STATS_TX;
360 i++, bitmap_iterator_inc(&it))
361 if (bitmap_iterator_test(&it))
362 data[index++] =
363 ((u64 *)&priv->tx_priority_flowstats)[i];
364
365 for (i = 0; i < NUM_FLOW_STATS_TX; i++, bitmap_iterator_inc(&it))
366 if (bitmap_iterator_test(&it))
367 data[index++] = ((u64 *)&priv->tx_flowstats)[i];
368
307 for (i = 0; i < NUM_PKT_STATS; i++, bitmap_iterator_inc(&it)) 369 for (i = 0; i < NUM_PKT_STATS; i++, bitmap_iterator_inc(&it))
308 if (bitmap_iterator_test(&it)) 370 if (bitmap_iterator_test(&it))
309 data[index++] = ((unsigned long *)&priv->pkstats)[i]; 371 data[index++] = ((unsigned long *)&priv->pkstats)[i];
@@ -364,6 +426,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
364 strcpy(data + (index++) * ETH_GSTRING_LEN, 426 strcpy(data + (index++) * ETH_GSTRING_LEN,
365 main_strings[strings]); 427 main_strings[strings]);
366 428
429 for (i = 0; i < NUM_FLOW_STATS; i++, strings++,
430 bitmap_iterator_inc(&it))
431 if (bitmap_iterator_test(&it))
432 strcpy(data + (index++) * ETH_GSTRING_LEN,
433 main_strings[strings]);
434
367 for (i = 0; i < NUM_PKT_STATS; i++, strings++, 435 for (i = 0; i < NUM_PKT_STATS; i++, strings++,
368 bitmap_iterator_inc(&it)) 436 bitmap_iterator_inc(&it))
369 if (bitmap_iterator_test(&it)) 437 if (bitmap_iterator_test(&it))
@@ -910,6 +978,12 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
910 priv->prof->rx_ppp); 978 priv->prof->rx_ppp);
911 if (err) 979 if (err)
912 en_err(priv, "Failed setting pause params\n"); 980 en_err(priv, "Failed setting pause params\n");
981 else
982 mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
983 priv->prof->rx_ppp,
984 priv->prof->rx_pause,
985 priv->prof->tx_ppp,
986 priv->prof->tx_pause);
913 987
914 return err; 988 return err;
915} 989}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 4542bab9494b..354e254b53cf 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1888,6 +1888,12 @@ static void mlx4_en_clear_stats(struct net_device *dev)
1888 memset(&priv->pstats, 0, sizeof(priv->pstats)); 1888 memset(&priv->pstats, 0, sizeof(priv->pstats));
1889 memset(&priv->pkstats, 0, sizeof(priv->pkstats)); 1889 memset(&priv->pkstats, 0, sizeof(priv->pkstats));
1890 memset(&priv->port_stats, 0, sizeof(priv->port_stats)); 1890 memset(&priv->port_stats, 0, sizeof(priv->port_stats));
1891 memset(&priv->rx_flowstats, 0, sizeof(priv->rx_flowstats));
1892 memset(&priv->tx_flowstats, 0, sizeof(priv->tx_flowstats));
1893 memset(&priv->rx_priority_flowstats, 0,
1894 sizeof(priv->rx_priority_flowstats));
1895 memset(&priv->tx_priority_flowstats, 0,
1896 sizeof(priv->tx_priority_flowstats));
1891 1897
1892 for (i = 0; i < priv->tx_ring_num; i++) { 1898 for (i = 0; i < priv->tx_ring_num; i++) {
1893 priv->tx_ring[i]->bytes = 0; 1899 priv->tx_ring[i]->bytes = 0;
@@ -2648,8 +2654,46 @@ int mlx4_en_netdev_event(struct notifier_block *this,
2648 return NOTIFY_DONE; 2654 return NOTIFY_DONE;
2649} 2655}
2650 2656
2657void mlx4_en_update_pfc_stats_bitmap(struct mlx4_dev *dev,
2658 struct mlx4_en_stats_bitmap *stats_bitmap,
2659 u8 rx_ppp, u8 rx_pause,
2660 u8 tx_ppp, u8 tx_pause)
2661{
2662 int last_i = NUM_MAIN_STATS + NUM_PORT_STATS;
2663
2664 if (!mlx4_is_slave(dev) &&
2665 (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN)) {
2666 mutex_lock(&stats_bitmap->mutex);
2667 bitmap_clear(stats_bitmap->bitmap, last_i, NUM_FLOW_STATS);
2668
2669 if (rx_ppp)
2670 bitmap_set(stats_bitmap->bitmap, last_i,
2671 NUM_FLOW_PRIORITY_STATS_RX);
2672 last_i += NUM_FLOW_PRIORITY_STATS_RX;
2673
2674 if (rx_pause && !(rx_ppp))
2675 bitmap_set(stats_bitmap->bitmap, last_i,
2676 NUM_FLOW_STATS_RX);
2677 last_i += NUM_FLOW_STATS_RX;
2678
2679 if (tx_ppp)
2680 bitmap_set(stats_bitmap->bitmap, last_i,
2681 NUM_FLOW_PRIORITY_STATS_TX);
2682 last_i += NUM_FLOW_PRIORITY_STATS_TX;
2683
2684 if (tx_pause && !(tx_ppp))
2685 bitmap_set(stats_bitmap->bitmap, last_i,
2686 NUM_FLOW_STATS_TX);
2687 last_i += NUM_FLOW_STATS_TX;
2688
2689 mutex_unlock(&stats_bitmap->mutex);
2690 }
2691}
2692
2651void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, 2693void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
2652 struct mlx4_en_stats_bitmap *stats_bitmap) 2694 struct mlx4_en_stats_bitmap *stats_bitmap,
2695 u8 rx_ppp, u8 rx_pause,
2696 u8 tx_ppp, u8 tx_pause)
2653{ 2697{
2654 int last_i = 0; 2698 int last_i = 0;
2655 2699
@@ -2677,6 +2721,11 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
2677 bitmap_set(stats_bitmap->bitmap, last_i, NUM_PORT_STATS); 2721 bitmap_set(stats_bitmap->bitmap, last_i, NUM_PORT_STATS);
2678 last_i += NUM_PORT_STATS; 2722 last_i += NUM_PORT_STATS;
2679 2723
2724 mlx4_en_update_pfc_stats_bitmap(dev, stats_bitmap,
2725 rx_ppp, rx_pause,
2726 tx_ppp, tx_pause);
2727 last_i += NUM_FLOW_STATS;
2728
2680 if (!mlx4_is_slave(dev)) 2729 if (!mlx4_is_slave(dev))
2681 bitmap_set(stats_bitmap->bitmap, last_i, NUM_PKT_STATS); 2730 bitmap_set(stats_bitmap->bitmap, last_i, NUM_PKT_STATS);
2682} 2731}
@@ -2914,7 +2963,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2914 queue_delayed_work(mdev->workqueue, &priv->service_task, 2963 queue_delayed_work(mdev->workqueue, &priv->service_task,
2915 SERVICE_TASK_DELAY); 2964 SERVICE_TASK_DELAY);
2916 2965
2917 mlx4_en_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); 2966 mlx4_en_set_stats_bitmap(mdev->dev, &priv->stats_bitmap,
2967 mdev->profile.prof[priv->port].rx_ppp,
2968 mdev->profile.prof[priv->port].rx_pause,
2969 mdev->profile.prof[priv->port].tx_ppp,
2970 mdev->profile.prof[priv->port].tx_pause);
2918 2971
2919 return 0; 2972 return 0;
2920 2973
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c
index 6cb80072af6c..821ae1278dc9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c
@@ -131,6 +131,7 @@ out:
131int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) 131int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
132{ 132{
133 struct mlx4_en_stat_out_mbox *mlx4_en_stats; 133 struct mlx4_en_stat_out_mbox *mlx4_en_stats;
134 struct mlx4_en_stat_out_flow_control_mbox *flowstats;
134 struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); 135 struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
135 struct net_device_stats *stats = &priv->stats; 136 struct net_device_stats *stats = &priv->stats;
136 struct mlx4_cmd_mailbox *mailbox; 137 struct mlx4_cmd_mailbox *mailbox;
@@ -239,6 +240,55 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
239 priv->pkstats.tx_prio[7] = be64_to_cpu(mlx4_en_stats->TTOT_prio_7); 240 priv->pkstats.tx_prio[7] = be64_to_cpu(mlx4_en_stats->TTOT_prio_7);
240 spin_unlock_bh(&priv->stats_lock); 241 spin_unlock_bh(&priv->stats_lock);
241 242
243 /* 0xffs indicates invalid value */
244 memset(mailbox->buf, 0xff, sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
245
246 if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) {
247 memset(mailbox->buf, 0,
248 sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
249 err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma,
250 in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL,
251 0, MLX4_CMD_DUMP_ETH_STATS,
252 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
253 if (err)
254 goto out;
255 }
256
257 flowstats = mailbox->buf;
258
259 spin_lock_bh(&priv->stats_lock);
260
261 for (i = 0; i < MLX4_NUM_PRIORITIES; i++) {
262 priv->rx_priority_flowstats[i].rx_pause =
263 be64_to_cpu(flowstats[i].rx_pause);
264 priv->rx_priority_flowstats[i].rx_pause_duration =
265 be64_to_cpu(flowstats[i].rx_pause_duration);
266 priv->rx_priority_flowstats[i].rx_pause_transition =
267 be64_to_cpu(flowstats[i].rx_pause_transition);
268 priv->tx_priority_flowstats[i].tx_pause =
269 be64_to_cpu(flowstats[i].tx_pause);
270 priv->tx_priority_flowstats[i].tx_pause_duration =
271 be64_to_cpu(flowstats[i].tx_pause_duration);
272 priv->tx_priority_flowstats[i].tx_pause_transition =
273 be64_to_cpu(flowstats[i].tx_pause_transition);
274 }
275
276 /* if pfc is not in use, all priorities counters have the same value */
277 priv->rx_flowstats.rx_pause =
278 be64_to_cpu(flowstats[0].rx_pause);
279 priv->rx_flowstats.rx_pause_duration =
280 be64_to_cpu(flowstats[0].rx_pause_duration);
281 priv->rx_flowstats.rx_pause_transition =
282 be64_to_cpu(flowstats[0].rx_pause_transition);
283 priv->tx_flowstats.tx_pause =
284 be64_to_cpu(flowstats[0].tx_pause);
285 priv->tx_flowstats.tx_pause_duration =
286 be64_to_cpu(flowstats[0].tx_pause_duration);
287 priv->tx_flowstats.tx_pause_transition =
288 be64_to_cpu(flowstats[0].tx_pause_transition);
289
290 spin_unlock_bh(&priv->stats_lock);
291
242out: 292out:
243 mlx4_free_cmd_mailbox(mdev->dev, mailbox); 293 mlx4_free_cmd_mailbox(mdev->dev, mailbox);
244 return err; 294 return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 4a471f5d1b56..209a6171e59b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -145,7 +145,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
145 [20] = "Recoverable error events support", 145 [20] = "Recoverable error events support",
146 [21] = "Port Remap support", 146 [21] = "Port Remap support",
147 [22] = "QCN support", 147 [22] = "QCN support",
148 [23] = "QP rate limiting support" 148 [23] = "QP rate limiting support",
149 [24] = "Ethernet Flow control statistics support"
149 }; 150 };
150 int i; 151 int i;
151 152
@@ -672,6 +673,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
672#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66 673#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66
673#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67 674#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67
674#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 675#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68
676#define QUERY_DEV_CAP_PORT_FLOWSTATS_COUNTERS_OFFSET 0x70
675#define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70 677#define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70
676#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74 678#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74
677#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 679#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76
@@ -773,6 +775,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
773 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 775 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET);
774 dev_cap->num_ports = field & 0xf; 776 dev_cap->num_ports = field & 0xf;
775 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET); 777 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET);
778 MLX4_GET(field, outbox, QUERY_DEV_CAP_PORT_FLOWSTATS_COUNTERS_OFFSET);
779 if (field & 0x10)
780 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN;
776 dev_cap->max_msg_sz = 1 << (field & 0x1f); 781 dev_cap->max_msg_sz = 1 << (field & 0x1f);
777 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 782 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
778 if (field & 0x80) 783 if (field & 0x80)
@@ -1088,6 +1093,7 @@ out:
1088 return err; 1093 return err;
1089} 1094}
1090 1095
1096#define DEV_CAP_EXT_2_FLAG_PFC_COUNTERS (1 << 28)
1091#define DEV_CAP_EXT_2_FLAG_VLAN_CONTROL (1 << 26) 1097#define DEV_CAP_EXT_2_FLAG_VLAN_CONTROL (1 << 26)
1092#define DEV_CAP_EXT_2_FLAG_80_VFS (1 << 21) 1098#define DEV_CAP_EXT_2_FLAG_80_VFS (1 << 21)
1093#define DEV_CAP_EXT_2_FLAG_FSM (1 << 20) 1099#define DEV_CAP_EXT_2_FLAG_FSM (1 << 20)
@@ -1177,7 +1183,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
1177 /* turn off host side virt features (VST, FSM, etc) for guests */ 1183 /* turn off host side virt features (VST, FSM, etc) for guests */
1178 MLX4_GET(field32, outbox->buf, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1184 MLX4_GET(field32, outbox->buf, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
1179 field32 &= ~(DEV_CAP_EXT_2_FLAG_VLAN_CONTROL | DEV_CAP_EXT_2_FLAG_80_VFS | 1185 field32 &= ~(DEV_CAP_EXT_2_FLAG_VLAN_CONTROL | DEV_CAP_EXT_2_FLAG_80_VFS |
1180 DEV_CAP_EXT_2_FLAG_FSM); 1186 DEV_CAP_EXT_2_FLAG_FSM | DEV_CAP_EXT_2_FLAG_PFC_COUNTERS);
1181 MLX4_PUT(outbox->buf, field32, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1187 MLX4_PUT(outbox->buf, field32, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
1182 1188
1183 /* turn off QCN for guests */ 1189 /* turn off QCN for guests */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index d5d971a408f2..67eeea244eff 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -565,6 +565,10 @@ struct mlx4_en_priv {
565#endif 565#endif
566 struct mlx4_en_perf_stats pstats; 566 struct mlx4_en_perf_stats pstats;
567 struct mlx4_en_pkt_stats pkstats; 567 struct mlx4_en_pkt_stats pkstats;
568 struct mlx4_en_flow_stats_rx rx_priority_flowstats[MLX4_NUM_PRIORITIES];
569 struct mlx4_en_flow_stats_tx tx_priority_flowstats[MLX4_NUM_PRIORITIES];
570 struct mlx4_en_flow_stats_rx rx_flowstats;
571 struct mlx4_en_flow_stats_tx tx_flowstats;
568 struct mlx4_en_port_stats port_stats; 572 struct mlx4_en_port_stats port_stats;
569 struct mlx4_en_stats_bitmap stats_bitmap; 573 struct mlx4_en_stats_bitmap stats_bitmap;
570 struct list_head mc_list; 574 struct list_head mc_list;
@@ -736,7 +740,9 @@ int mlx4_en_start_port(struct net_device *dev);
736void mlx4_en_stop_port(struct net_device *dev, int detach); 740void mlx4_en_stop_port(struct net_device *dev, int detach);
737 741
738void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, 742void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
739 struct mlx4_en_stats_bitmap *stats_bitmap); 743 struct mlx4_en_stats_bitmap *stats_bitmap,
744 u8 rx_ppp, u8 rx_pause,
745 u8 tx_ppp, u8 tx_pause);
740 746
741void mlx4_en_free_resources(struct mlx4_en_priv *priv); 747void mlx4_en_free_resources(struct mlx4_en_priv *priv);
742int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); 748int mlx4_en_alloc_resources(struct mlx4_en_priv *priv);
@@ -823,7 +829,10 @@ void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev);
823int mlx4_en_reset_config(struct net_device *dev, 829int mlx4_en_reset_config(struct net_device *dev,
824 struct hwtstamp_config ts_config, 830 struct hwtstamp_config ts_config,
825 netdev_features_t new_features); 831 netdev_features_t new_features);
826 832void mlx4_en_update_pfc_stats_bitmap(struct mlx4_dev *dev,
833 struct mlx4_en_stats_bitmap *stats_bitmap,
834 u8 rx_ppp, u8 rx_pause,
835 u8 tx_ppp, u8 tx_pause);
827int mlx4_en_netdev_event(struct notifier_block *this, 836int mlx4_en_netdev_event(struct notifier_block *this,
828 unsigned long event, void *ptr); 837 unsigned long event, void *ptr);
829 838
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
index d7183e30b40b..e193680fb527 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
@@ -42,8 +42,58 @@ struct mlx4_en_perf_stats {
42}; 42};
43 43
44#define NUM_MAIN_STATS 21 44#define NUM_MAIN_STATS 21
45
46#define MLX4_NUM_PRIORITIES 8
47
48struct mlx4_en_flow_stats_rx {
49 u64 rx_pause;
50 u64 rx_pause_duration;
51 u64 rx_pause_transition;
52#define NUM_FLOW_STATS_RX 3
53#define NUM_FLOW_PRIORITY_STATS_RX (NUM_FLOW_STATS_RX * \
54 MLX4_NUM_PRIORITIES)
55};
56
57struct mlx4_en_flow_stats_tx {
58 u64 tx_pause;
59 u64 tx_pause_duration;
60 u64 tx_pause_transition;
61#define NUM_FLOW_STATS_TX 3
62#define NUM_FLOW_PRIORITY_STATS_TX (NUM_FLOW_STATS_TX * \
63 MLX4_NUM_PRIORITIES)
64};
65
66#define NUM_FLOW_STATS (NUM_FLOW_STATS_RX + NUM_FLOW_STATS_TX + \
67 NUM_FLOW_PRIORITY_STATS_TX + \
68 NUM_FLOW_PRIORITY_STATS_RX)
69
70struct mlx4_en_stat_out_flow_control_mbox {
71 /* Total number of PAUSE frames received from the far-end port */
72 __be64 rx_pause;
73 /* Total number of microseconds that far-end port requested to pause
74 * transmission of packets
75 */
76 __be64 rx_pause_duration;
77 /* Number of received transmission from XOFF state to XON state */
78 __be64 rx_pause_transition;
79 /* Total number of PAUSE frames sent from the far-end port */
80 __be64 tx_pause;
81 /* Total time in microseconds that transmission of packets has been
82 * paused
83 */
84 __be64 tx_pause_duration;
85 /* Number of transmitter transitions from XOFF state to XON state */
86 __be64 tx_pause_transition;
87 /* Reserverd */
88 __be64 reserved[2];
89};
90
91enum {
92 MLX4_DUMP_ETH_STATS_FLOW_CONTROL = 1 << 12
93};
94
45#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + \ 95#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + \
46 NUM_PERF_STATS) 96 NUM_FLOW_STATS + NUM_PERF_STATS)
47 97
48#define MLX4_FIND_NETDEV_STAT(n) (offsetof(struct net_device_stats, n) / \ 98#define MLX4_FIND_NETDEV_STAT(n) (offsetof(struct net_device_stats, n) / \
49 sizeof(((struct net_device_stats *)0)->n)) 99 sizeof(((struct net_device_stats *)0)->n))
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 49abbe28e230..ab7ebec943b8 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -205,7 +205,8 @@ enum {
205 MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20, 205 MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20,
206 MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21, 206 MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21,
207 MLX4_DEV_CAP_FLAG2_QCN = 1LL << 22, 207 MLX4_DEV_CAP_FLAG2_QCN = 1LL << 22,
208 MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT = 1LL << 23 208 MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT = 1LL << 23,
209 MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN = 1LL << 24
209}; 210};
210 211
211enum { 212enum {