This source file includes following definitions.
- ionic_get_lif_stats
- ionic_sw_stats_get_count
- ionic_sw_stats_get_strings
- ionic_sw_stats_get_values
1
2
3
4 #include <linux/kernel.h>
5 #include <linux/mutex.h>
6 #include <linux/netdevice.h>
7
8 #include "ionic.h"
9 #include "ionic_lif.h"
10 #include "ionic_stats.h"
11
12 static const struct ionic_stat_desc ionic_lif_stats_desc[] = {
13 IONIC_LIF_STAT_DESC(tx_packets),
14 IONIC_LIF_STAT_DESC(tx_bytes),
15 IONIC_LIF_STAT_DESC(rx_packets),
16 IONIC_LIF_STAT_DESC(rx_bytes),
17 IONIC_LIF_STAT_DESC(tx_tso),
18 IONIC_LIF_STAT_DESC(tx_no_csum),
19 IONIC_LIF_STAT_DESC(tx_csum),
20 IONIC_LIF_STAT_DESC(rx_csum_none),
21 IONIC_LIF_STAT_DESC(rx_csum_complete),
22 IONIC_LIF_STAT_DESC(rx_csum_error),
23 };
24
25 static const struct ionic_stat_desc ionic_tx_stats_desc[] = {
26 IONIC_TX_STAT_DESC(pkts),
27 IONIC_TX_STAT_DESC(bytes),
28 IONIC_TX_STAT_DESC(clean),
29 IONIC_TX_STAT_DESC(dma_map_err),
30 IONIC_TX_STAT_DESC(linearize),
31 IONIC_TX_STAT_DESC(frags),
32 };
33
34 static const struct ionic_stat_desc ionic_rx_stats_desc[] = {
35 IONIC_RX_STAT_DESC(pkts),
36 IONIC_RX_STAT_DESC(bytes),
37 IONIC_RX_STAT_DESC(dma_map_err),
38 IONIC_RX_STAT_DESC(alloc_err),
39 IONIC_RX_STAT_DESC(csum_none),
40 IONIC_RX_STAT_DESC(csum_complete),
41 IONIC_RX_STAT_DESC(csum_error),
42 };
43
44 static const struct ionic_stat_desc ionic_txq_stats_desc[] = {
45 IONIC_TX_Q_STAT_DESC(stop),
46 IONIC_TX_Q_STAT_DESC(wake),
47 IONIC_TX_Q_STAT_DESC(drop),
48 IONIC_TX_Q_STAT_DESC(dbell_count),
49 };
50
51 static const struct ionic_stat_desc ionic_dbg_cq_stats_desc[] = {
52 IONIC_CQ_STAT_DESC(compl_count),
53 };
54
55 static const struct ionic_stat_desc ionic_dbg_intr_stats_desc[] = {
56 IONIC_INTR_STAT_DESC(rearm_count),
57 };
58
59 static const struct ionic_stat_desc ionic_dbg_napi_stats_desc[] = {
60 IONIC_NAPI_STAT_DESC(poll_count),
61 };
62
63 #define IONIC_NUM_LIF_STATS ARRAY_SIZE(ionic_lif_stats_desc)
64 #define IONIC_NUM_TX_STATS ARRAY_SIZE(ionic_tx_stats_desc)
65 #define IONIC_NUM_RX_STATS ARRAY_SIZE(ionic_rx_stats_desc)
66 #define IONIC_NUM_TX_Q_STATS ARRAY_SIZE(ionic_txq_stats_desc)
67 #define IONIC_NUM_DBG_CQ_STATS ARRAY_SIZE(ionic_dbg_cq_stats_desc)
68 #define IONIC_NUM_DBG_INTR_STATS ARRAY_SIZE(ionic_dbg_intr_stats_desc)
69 #define IONIC_NUM_DBG_NAPI_STATS ARRAY_SIZE(ionic_dbg_napi_stats_desc)
70
71 #define MAX_Q(lif) ((lif)->netdev->real_num_tx_queues)
72
73 static void ionic_get_lif_stats(struct ionic_lif *lif,
74 struct ionic_lif_sw_stats *stats)
75 {
76 struct ionic_tx_stats *tstats;
77 struct ionic_rx_stats *rstats;
78 struct ionic_qcq *txqcq;
79 struct ionic_qcq *rxqcq;
80 int q_num;
81
82 memset(stats, 0, sizeof(*stats));
83
84 for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
85 txqcq = lif_to_txqcq(lif, q_num);
86 if (txqcq && txqcq->stats) {
87 tstats = &txqcq->stats->tx;
88 stats->tx_packets += tstats->pkts;
89 stats->tx_bytes += tstats->bytes;
90 stats->tx_tso += tstats->tso;
91 stats->tx_no_csum += tstats->no_csum;
92 stats->tx_csum += tstats->csum;
93 }
94
95 rxqcq = lif_to_rxqcq(lif, q_num);
96 if (rxqcq && rxqcq->stats) {
97 rstats = &rxqcq->stats->rx;
98 stats->rx_packets += rstats->pkts;
99 stats->rx_bytes += rstats->bytes;
100 stats->rx_csum_none += rstats->csum_none;
101 stats->rx_csum_complete += rstats->csum_complete;
102 stats->rx_csum_error += rstats->csum_error;
103 }
104 }
105 }
106
107 static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
108 {
109 u64 total = 0;
110
111
112 total += IONIC_NUM_LIF_STATS;
113
114
115 total += MAX_Q(lif) * IONIC_NUM_TX_STATS;
116
117
118 total += MAX_Q(lif) * IONIC_NUM_RX_STATS;
119
120 if (test_bit(IONIC_LIF_UP, lif->state) &&
121 test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
122
123 total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS +
124 IONIC_NUM_TX_Q_STATS +
125 IONIC_NUM_DBG_INTR_STATS +
126 IONIC_MAX_NUM_SG_CNTR);
127
128
129 total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS +
130 IONIC_NUM_DBG_INTR_STATS +
131 IONIC_NUM_DBG_NAPI_STATS +
132 IONIC_MAX_NUM_NAPI_CNTR);
133 }
134
135 return total;
136 }
137
138 static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf)
139 {
140 int i, q_num;
141
142 for (i = 0; i < IONIC_NUM_LIF_STATS; i++) {
143 snprintf(*buf, ETH_GSTRING_LEN, ionic_lif_stats_desc[i].name);
144 *buf += ETH_GSTRING_LEN;
145 }
146 for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
147 for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
148 snprintf(*buf, ETH_GSTRING_LEN, "tx_%d_%s",
149 q_num, ionic_tx_stats_desc[i].name);
150 *buf += ETH_GSTRING_LEN;
151 }
152
153 if (test_bit(IONIC_LIF_UP, lif->state) &&
154 test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
155 for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
156 snprintf(*buf, ETH_GSTRING_LEN,
157 "txq_%d_%s",
158 q_num,
159 ionic_txq_stats_desc[i].name);
160 *buf += ETH_GSTRING_LEN;
161 }
162 for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
163 snprintf(*buf, ETH_GSTRING_LEN,
164 "txq_%d_cq_%s",
165 q_num,
166 ionic_dbg_cq_stats_desc[i].name);
167 *buf += ETH_GSTRING_LEN;
168 }
169 for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
170 snprintf(*buf, ETH_GSTRING_LEN,
171 "txq_%d_intr_%s",
172 q_num,
173 ionic_dbg_intr_stats_desc[i].name);
174 *buf += ETH_GSTRING_LEN;
175 }
176 for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) {
177 snprintf(*buf, ETH_GSTRING_LEN,
178 "txq_%d_sg_cntr_%d",
179 q_num, i);
180 *buf += ETH_GSTRING_LEN;
181 }
182 }
183 }
184 for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
185 for (i = 0; i < IONIC_NUM_RX_STATS; i++) {
186 snprintf(*buf, ETH_GSTRING_LEN,
187 "rx_%d_%s",
188 q_num, ionic_rx_stats_desc[i].name);
189 *buf += ETH_GSTRING_LEN;
190 }
191
192 if (test_bit(IONIC_LIF_UP, lif->state) &&
193 test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
194 for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
195 snprintf(*buf, ETH_GSTRING_LEN,
196 "rxq_%d_cq_%s",
197 q_num,
198 ionic_dbg_cq_stats_desc[i].name);
199 *buf += ETH_GSTRING_LEN;
200 }
201 for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
202 snprintf(*buf, ETH_GSTRING_LEN,
203 "rxq_%d_intr_%s",
204 q_num,
205 ionic_dbg_intr_stats_desc[i].name);
206 *buf += ETH_GSTRING_LEN;
207 }
208 for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
209 snprintf(*buf, ETH_GSTRING_LEN,
210 "rxq_%d_napi_%s",
211 q_num,
212 ionic_dbg_napi_stats_desc[i].name);
213 *buf += ETH_GSTRING_LEN;
214 }
215 for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
216 snprintf(*buf, ETH_GSTRING_LEN,
217 "rxq_%d_napi_work_done_%d",
218 q_num, i);
219 *buf += ETH_GSTRING_LEN;
220 }
221 }
222 }
223 }
224
225 static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf)
226 {
227 struct ionic_lif_sw_stats lif_stats;
228 struct ionic_qcq *txqcq, *rxqcq;
229 struct ionic_tx_stats *txstats;
230 struct ionic_rx_stats *rxstats;
231 int i, q_num;
232
233 ionic_get_lif_stats(lif, &lif_stats);
234
235 for (i = 0; i < IONIC_NUM_LIF_STATS; i++) {
236 **buf = IONIC_READ_STAT64(&lif_stats, &ionic_lif_stats_desc[i]);
237 (*buf)++;
238 }
239
240 for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
241 txstats = &lif_to_txstats(lif, q_num);
242
243 for (i = 0; i < IONIC_NUM_TX_STATS; i++) {
244 **buf = IONIC_READ_STAT64(txstats,
245 &ionic_tx_stats_desc[i]);
246 (*buf)++;
247 }
248
249 if (test_bit(IONIC_LIF_UP, lif->state) &&
250 test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
251 txqcq = lif_to_txqcq(lif, q_num);
252 for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) {
253 **buf = IONIC_READ_STAT64(&txqcq->q,
254 &ionic_txq_stats_desc[i]);
255 (*buf)++;
256 }
257 for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
258 **buf = IONIC_READ_STAT64(&txqcq->cq,
259 &ionic_dbg_cq_stats_desc[i]);
260 (*buf)++;
261 }
262 for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
263 **buf = IONIC_READ_STAT64(&txqcq->intr,
264 &ionic_dbg_intr_stats_desc[i]);
265 (*buf)++;
266 }
267 for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) {
268 **buf = txstats->sg_cntr[i];
269 (*buf)++;
270 }
271 }
272 }
273
274 for (q_num = 0; q_num < MAX_Q(lif); q_num++) {
275 rxstats = &lif_to_rxstats(lif, q_num);
276
277 for (i = 0; i < IONIC_NUM_RX_STATS; i++) {
278 **buf = IONIC_READ_STAT64(rxstats,
279 &ionic_rx_stats_desc[i]);
280 (*buf)++;
281 }
282
283 if (test_bit(IONIC_LIF_UP, lif->state) &&
284 test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) {
285 rxqcq = lif_to_rxqcq(lif, q_num);
286 for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) {
287 **buf = IONIC_READ_STAT64(&rxqcq->cq,
288 &ionic_dbg_cq_stats_desc[i]);
289 (*buf)++;
290 }
291 for (i = 0; i < IONIC_NUM_DBG_INTR_STATS; i++) {
292 **buf = IONIC_READ_STAT64(&rxqcq->intr,
293 &ionic_dbg_intr_stats_desc[i]);
294 (*buf)++;
295 }
296 for (i = 0; i < IONIC_NUM_DBG_NAPI_STATS; i++) {
297 **buf = IONIC_READ_STAT64(&rxqcq->napi_stats,
298 &ionic_dbg_napi_stats_desc[i]);
299 (*buf)++;
300 }
301 for (i = 0; i < IONIC_MAX_NUM_NAPI_CNTR; i++) {
302 **buf = rxqcq->napi_stats.work_done_cntr[i];
303 (*buf)++;
304 }
305 }
306 }
307 }
308
309 const struct ionic_stats_group_intf ionic_stats_groups[] = {
310
311 {
312 .get_strings = ionic_sw_stats_get_strings,
313 .get_values = ionic_sw_stats_get_values,
314 .get_count = ionic_sw_stats_get_count,
315 },
316
317 };
318
319 const int ionic_num_stats_grps = ARRAY_SIZE(ionic_stats_groups);