1 /*- 2 * BSD LICENSE 3 * 4 * Copyright 2015 6WIND S.A. 5 * Copyright 2015 Mellanox. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of 6WIND S.A. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* DPDK headers don't like -pedantic. */ 35 #ifdef PEDANTIC 36 #pragma GCC diagnostic ignored "-pedantic" 37 #endif 38 #include <rte_ethdev.h> 39 #ifdef PEDANTIC 40 #pragma GCC diagnostic error "-pedantic" 41 #endif 42 43 #include "mlx5.h" 44 #include "mlx5_rxtx.h" 45 #include "mlx5_defs.h" 46 47 /** 48 * DPDK callback to get device statistics. 49 * 50 * @param dev 51 * Pointer to Ethernet device structure. 52 * @param[out] stats 53 * Stats structure output buffer. 54 */ 55 void 56 mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 57 { 58 struct priv *priv = mlx5_get_priv(dev); 59 struct rte_eth_stats tmp = {0}; 60 unsigned int i; 61 unsigned int idx; 62 63 priv_lock(priv); 64 /* Add software counters. */ 65 for (i = 0; (i != priv->rxqs_n); ++i) { 66 struct rxq *rxq = (*priv->rxqs)[i]; 67 68 if (rxq == NULL) 69 continue; 70 idx = rxq->stats.idx; 71 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { 72 #ifdef MLX5_PMD_SOFT_COUNTERS 73 tmp.q_ipackets[idx] += rxq->stats.ipackets; 74 tmp.q_ibytes[idx] += rxq->stats.ibytes; 75 #endif 76 tmp.q_errors[idx] += (rxq->stats.idropped + 77 rxq->stats.rx_nombuf); 78 } 79 #ifdef MLX5_PMD_SOFT_COUNTERS 80 tmp.ipackets += rxq->stats.ipackets; 81 tmp.ibytes += rxq->stats.ibytes; 82 #endif 83 tmp.ierrors += rxq->stats.idropped; 84 tmp.rx_nombuf += rxq->stats.rx_nombuf; 85 } 86 for (i = 0; (i != priv->txqs_n); ++i) { 87 struct txq *txq = (*priv->txqs)[i]; 88 89 if (txq == NULL) 90 continue; 91 idx = txq->stats.idx; 92 if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) { 93 #ifdef MLX5_PMD_SOFT_COUNTERS 94 tmp.q_opackets[idx] += txq->stats.opackets; 95 tmp.q_obytes[idx] += txq->stats.obytes; 96 #endif 97 tmp.q_errors[idx] += txq->stats.odropped; 98 } 99 #ifdef MLX5_PMD_SOFT_COUNTERS 100 tmp.opackets += txq->stats.opackets; 101 tmp.obytes += txq->stats.obytes; 102 #endif 103 tmp.oerrors += txq->stats.odropped; 104 } 105 #ifndef MLX5_PMD_SOFT_COUNTERS 106 /* FIXME: retrieve and add hardware counters. */ 107 #endif 108 *stats = tmp; 109 priv_unlock(priv); 110 } 111 112 /** 113 * DPDK callback to clear device statistics. 114 * 115 * @param dev 116 * Pointer to Ethernet device structure. 117 */ 118 void 119 mlx5_stats_reset(struct rte_eth_dev *dev) 120 { 121 struct priv *priv = dev->data->dev_private; 122 unsigned int i; 123 unsigned int idx; 124 125 priv_lock(priv); 126 for (i = 0; (i != priv->rxqs_n); ++i) { 127 if ((*priv->rxqs)[i] == NULL) 128 continue; 129 idx = (*priv->rxqs)[i]->stats.idx; 130 (*priv->rxqs)[i]->stats = 131 (struct mlx5_rxq_stats){ .idx = idx }; 132 } 133 for (i = 0; (i != priv->txqs_n); ++i) { 134 if ((*priv->txqs)[i] == NULL) 135 continue; 136 idx = (*priv->txqs)[i]->stats.idx; 137 (*priv->txqs)[i]->stats = 138 (struct mlx5_txq_stats){ .idx = idx }; 139 } 140 #ifndef MLX5_PMD_SOFT_COUNTERS 141 /* FIXME: reset hardware counters. */ 142 #endif 143 priv_unlock(priv); 144 } 145