diff options
author | Matan Barak <matanb@mellanox.com> | 2015-03-30 10:45:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-31 16:36:51 -0400 |
commit | 0b131561a7d639abb0a194d2d8fae839ce3b99e9 (patch) | |
tree | 88b2bbfd63a14c35d47c9eb2cf57748d8fe173a3 | |
parent | 3da8a36cc5c2a172bb42f8dc89638f5b41d7d7a6 (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.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 74 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 57 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_port.c | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h | 52 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 3 |
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 | ||
2657 | void 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 | |||
2651 | void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, | 2693 | void 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: | |||
131 | int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | 131 | int 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 | |||
242 | out: | 292 | out: |
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); | |||
736 | void mlx4_en_stop_port(struct net_device *dev, int detach); | 740 | void mlx4_en_stop_port(struct net_device *dev, int detach); |
737 | 741 | ||
738 | void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, | 742 | void 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 | ||
741 | void mlx4_en_free_resources(struct mlx4_en_priv *priv); | 747 | void mlx4_en_free_resources(struct mlx4_en_priv *priv); |
742 | int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); | 748 | int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); |
@@ -823,7 +829,10 @@ void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); | |||
823 | int mlx4_en_reset_config(struct net_device *dev, | 829 | int 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 | 832 | void 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); | ||
827 | int mlx4_en_netdev_event(struct notifier_block *this, | 836 | int 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 | |||
48 | struct 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 | |||
57 | struct 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 | |||
70 | struct 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 | |||
91 | enum { | ||
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 | ||
211 | enum { | 212 | enum { |