1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27
28
29 /*
30 * Source file containing the implementation of the driver statistics
31 * and related helper functions
32 */
33
34 #include <oce_impl.h>
35 #include <oce_stat.h>
36 #include <oce_buf.h>
37
38
39 static int
40 oce_update_lancer_stats(struct oce_dev *dev, struct oce_stat *stats)
41 {
42 struct mbx_get_pport_stats *hw_stats;
43 int ret;
44
45 hw_stats = (struct mbx_get_pport_stats *)DBUF_VA(dev->stats_dbuf);
46 ret = oce_get_pport_stats(dev, MBX_ASYNC_MQ);
47 if (ret != DDI_SUCCESS) {
48 oce_log(dev, CE_WARN, MOD_CONFIG,
49 "Failed to get stats:%d", ret);
50 return (EIO);
51 }
52
53 /* update the stats */
54 stats->rx_bytes_lo.value.ul =
55 hw_stats->params.rsp.pport_stats.rx_bytes_lo;
56 stats->rx_bytes_hi.value.ul =
57 hw_stats->params.rsp.pport_stats.rx_bytes_hi;
58
59 stats->rx_frames.value.ul =
60 hw_stats->params.rsp.pport_stats.rx_packets_lo;
61 stats->rx_errors.value.ul =
62 hw_stats->params.rsp.pport_stats.rx_crc_errors_lo +
63 hw_stats->params.rsp.pport_stats.rx_alignment_errors_lo +
64 hw_stats->params.rsp.pport_stats.rx_symbol_errors_lo +
65 hw_stats->params.rsp.pport_stats.rx_in_range_errors +
66 hw_stats->params.rsp.pport_stats.rx_out_of_range_errors +
67 hw_stats->params.rsp.pport_stats.rx_frames_too_long_lo +
68 hw_stats->params.rsp.pport_stats.rx_ip_checksum_errors +
69 hw_stats->params.rsp.pport_stats.rx_tcp_checksum_errors +
70 hw_stats->params.rsp.pport_stats.rx_udp_checksum_errors;
71
72 stats->rx_drops.value.ul =
73 hw_stats->params.rsp.pport_stats.rx_dropped_too_small +
74 hw_stats->params.rsp.pport_stats.rx_dropped_too_short +
75 hw_stats->params.rsp.pport_stats.rx_dropped_header_too_small +
76 hw_stats->params.rsp.pport_stats.rx_dropped_invalid_tcp_length +
77 hw_stats->params.rsp.pport_stats.rx_dropped_runt;
78
79 stats->tx_bytes_lo.value.ul =
80 hw_stats->params.rsp.pport_stats.tx_packets_lo;
81 stats->tx_bytes_hi.value.ul =
82 hw_stats->params.rsp.pport_stats.tx_packets_hi;
83
84 stats->tx_frames.value.ul =
85 hw_stats->params.rsp.pport_stats.tx_unicast_packets_lo +
86 hw_stats->params.rsp.pport_stats.tx_multicast_packets_lo +
87 hw_stats->params.rsp.pport_stats.tx_broadcast_packets_lo +
88 hw_stats->params.rsp.pport_stats.tx_pause_frames_lo +
89 hw_stats->params.rsp.pport_stats.tx_control_frames_lo;
90
91 /* Update all Wq errors */
92 stats->tx_errors.value.ul = dev->tx_errors;
93
94 stats->rx_unicast_frames.value.ul =
95 hw_stats->params.rsp.pport_stats.rx_unicast_packets_lo;
96 stats->rx_multicast_frames.value.ul =
97 hw_stats->params.rsp.pport_stats.rx_multicast_packets_lo;
98 stats->rx_broadcast_frames.value.ul =
99 hw_stats->params.rsp.pport_stats.rx_broadcast_packets_lo;
100 stats->rx_crc_errors.value.ul =
101 hw_stats->params.rsp.pport_stats.rx_crc_errors_lo;
102
103 stats->rx_alignment_symbol_errors.value.ul =
104 hw_stats->params.rsp.pport_stats.rx_alignment_errors_lo +
105 hw_stats->params.rsp.pport_stats.rx_symbol_errors_lo;
106 stats->rx_in_range_errors.value.ul =
107 hw_stats->params.rsp.pport_stats.rx_in_range_errors;
108 stats->rx_out_range_errors.value.ul =
109 hw_stats->params.rsp.pport_stats.rx_out_of_range_errors;
110 stats->rx_frame_too_long.value.ul =
111 hw_stats->params.rsp.pport_stats.rx_frames_too_long_lo;
112 stats->rx_address_match_errors.value.ul =
113 hw_stats->params.rsp.pport_stats.rx_address_match_errors;
114
115 stats->rx_pause_frames.value.ul =
116 hw_stats->params.rsp.pport_stats.rx_pause_frames_lo;
117 stats->rx_control_frames.value.ul =
118 hw_stats->params.rsp.pport_stats.rx_control_frames_lo;
119 stats->rx_ip_checksum_errs.value.ul =
120 hw_stats->params.rsp.pport_stats.rx_ip_checksum_errors;
121 stats->rx_tcp_checksum_errs.value.ul =
122 hw_stats->params.rsp.pport_stats.rx_tcp_checksum_errors;
123 stats->rx_udp_checksum_errs.value.ul =
124 hw_stats->params.rsp.pport_stats.rx_udp_checksum_errors;
125 stats->rx_fifo_overflow.value.ul =
126 hw_stats->params.rsp.pport_stats.rx_fifo_overflow;
127 stats->rx_input_fifo_overflow.value.ul =
128 hw_stats->params.rsp.pport_stats.rx_input_fifo_overflow;
129
130 stats->tx_unicast_frames.value.ul =
131 hw_stats->params.rsp.pport_stats.tx_unicast_packets_lo;
132 stats->tx_multicast_frames.value.ul =
133 hw_stats->params.rsp.pport_stats.tx_multicast_packets_lo;
134 stats->tx_broadcast_frames.value.ul =
135 hw_stats->params.rsp.pport_stats.tx_broadcast_packets_lo;
136 stats->tx_pause_frames.value.ul =
137 hw_stats->params.rsp.pport_stats.tx_pause_frames_lo;
138 stats->tx_control_frames.value.ul =
139 hw_stats->params.rsp.pport_stats.tx_control_frames_lo;
140
141
142 stats->rx_drops_too_many_frags.value.ul =
143 hw_stats->params.rsp.pport_stats.rx_drops_too_many_frags_lo;
144 stats->rx_drops_invalid_ring.value.ul =
145 hw_stats->params.rsp.pport_stats.rx_drops_invalid_queue;
146 stats->rx_drops_mtu.value.ul =
147 hw_stats->params.rsp.pport_stats.rx_drops_mtu_lo;
148
149 stats->rx_dropped_too_small.value.ul =
150 hw_stats->params.rsp.pport_stats.rx_dropped_too_small;
151 stats->rx_dropped_too_short.value.ul =
152 hw_stats->params.rsp.pport_stats.rx_dropped_too_short;
153 stats->rx_dropped_header_too_small.value.ul =
154 hw_stats->params.rsp.pport_stats.rx_dropped_header_too_small;
155 stats->rx_dropped_tcp_length.value.ul =
156 hw_stats->params.rsp.pport_stats.rx_dropped_invalid_tcp_length;
157 stats->rx_dropped_runt.value.ul =
158 hw_stats->params.rsp.pport_stats.rx_dropped_runt;
159
160 return (DDI_SUCCESS);
161 }
162
163 /*
164 * function called by kstat to update the stats counters
165 *
166 * ksp - pointer to the kstats structure
167 * rw - flags defining read/write
168 *
169 * return DDI_SUCCESS => success, failure otherwise
170 */
171 static int
172 oce_update_be_stats(struct oce_dev *dev, struct oce_stat *stats)
173 {
174 struct mbx_get_nic_stats *fwcmd;
175 int i, ret;
176
177 ret = oce_get_hw_stats(dev, MBX_ASYNC_MQ);
178 if (ret != DDI_SUCCESS) {
179 return (EIO);
180 }
181
182 /* update the stats */
183 fwcmd = (struct mbx_get_nic_stats *)DBUF_VA(dev->stats_dbuf);
184 if (dev->chip_rev == OC_CNA_GEN2) {
185 struct be_hw_stats_v0 *hw_stats = &fwcmd->params.rsp.v0;
186 struct rx_stats_v0 *rx_stats = &hw_stats->rx;
187 struct rx_port_stats_v0 *port_stats =
188 &rx_stats->port[dev->port_id];
189 struct rx_err_stats_v0 *err_stats = &hw_stats->err_rx;
190
191 stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd;
192 stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd;
193 stats->rx_frames.value.ul = port_stats->rx_total_frames;
194 stats->rx_errors.value.ul = port_stats->rx_crc_errors +
195 port_stats->rx_alignment_symbol_errors +
196 port_stats->rx_in_range_errors +
197 port_stats->rx_out_range_errors +
198 port_stats->rx_frame_too_long +
199 port_stats->rx_ip_checksum_errs +
200 port_stats->rx_tcp_checksum_errs +
201 port_stats->rx_udp_checksum_errs;
202
203 stats->rx_drops.value.ul = port_stats->rx_dropped_too_small +
204 port_stats->rx_dropped_too_short +
205 port_stats->rx_dropped_header_too_small +
206 port_stats->rx_dropped_tcp_length +
207 port_stats->rx_dropped_runt;
208
209 stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd;
210 stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd;
211
212 stats->tx_frames.value.ul = port_stats->tx_unicast_frames +
213 port_stats->tx_multicast_frames +
214 port_stats->tx_broadcast_frames +
215 port_stats->tx_pause_frames +
216 port_stats->tx_control_frames;
217 stats->tx_errors.value.ul = dev->tx_errors;
218
219 stats->rx_unicast_frames.value.ul =
220 port_stats->rx_unicast_frames;
221 stats->rx_multicast_frames.value.ul =
222 port_stats->rx_multicast_frames;
223 stats->rx_broadcast_frames.value.ul =
224 port_stats->rx_broadcast_frames;
225 stats->rx_crc_errors.value.ul =
226 port_stats->rx_crc_errors;
227
228 stats->rx_alignment_symbol_errors.value.ul =
229 port_stats->rx_alignment_symbol_errors;
230 stats->rx_in_range_errors.value.ul =
231 port_stats->rx_in_range_errors;
232 stats->rx_out_range_errors.value.ul =
233 port_stats->rx_out_range_errors;
234 stats->rx_frame_too_long.value.ul =
235 port_stats->rx_frame_too_long;
236 stats->rx_address_match_errors.value.ul =
237 port_stats->rx_address_match_errors;
238
239 stats->rx_pause_frames.value.ul =
240 port_stats->rx_pause_frames;
241 stats->rx_control_frames.value.ul =
242 port_stats->rx_control_frames;
243 stats->rx_ip_checksum_errs.value.ul =
244 port_stats->rx_ip_checksum_errs;
245 stats->rx_tcp_checksum_errs.value.ul =
246 port_stats->rx_tcp_checksum_errs;
247 stats->rx_udp_checksum_errs.value.ul =
248 port_stats->rx_udp_checksum_errs;
249 stats->rx_fifo_overflow.value.ul = port_stats->rx_fifo_overflow;
250 stats->rx_input_fifo_overflow.value.ul =
251 port_stats->rx_input_fifo_overflow;
252
253 stats->tx_unicast_frames.value.ul =
254 port_stats->tx_unicast_frames;
255 stats->tx_multicast_frames.value.ul =
256 port_stats->tx_multicast_frames;
257 stats->tx_broadcast_frames.value.ul =
258 port_stats->tx_broadcast_frames;
259 stats->tx_pause_frames.value.ul =
260 port_stats->tx_pause_frames;
261 stats->tx_control_frames.value.ul =
262 port_stats->tx_control_frames;
263
264
265 stats->rx_drops_no_pbuf.value.ul =
266 rx_stats->rx_drops_no_pbuf;
267 stats->rx_drops_no_txpb.value.ul =
268 rx_stats->rx_drops_no_txpb;
269 stats->rx_drops_no_erx_descr.value.ul =
270 rx_stats->rx_drops_no_erx_descr;
271 stats->rx_drops_no_tpre_descr.value.ul =
272 rx_stats->rx_drops_no_tpre_descr;
273 stats->rx_drops_too_many_frags.value.ul =
274 rx_stats->rx_drops_too_many_frags;
275 stats->rx_drops_invalid_ring.value.ul =
276 rx_stats->rx_drops_invalid_ring;
277 stats->rx_drops_mtu.value.ul =
278 rx_stats->rx_drops_mtu;
279
280 stats->rx_dropped_too_small.value.ul =
281 port_stats->rx_dropped_too_small;
282 stats->rx_dropped_too_short.value.ul =
283 port_stats->rx_dropped_too_short;
284 stats->rx_dropped_header_too_small.value.ul =
285 port_stats->rx_dropped_header_too_small;
286 stats->rx_dropped_tcp_length.value.ul =
287 port_stats->rx_dropped_tcp_length;
288 stats->rx_dropped_runt.value.ul =
289 port_stats->rx_dropped_runt;
290
291 stats->rx_drops_no_fragments.value.ul = 0;
292 for (i = 0; i < dev->nrqs; i++) {
293 stats->rx_drops_no_fragments.value.ul +=
294 err_stats->rx_drops_no_fragments[dev->rq[i].rq_id];
295 }
296
297 stats->rx_priority_pause_frames.value.ul = 0;
298 stats->pmem_fifo_overflow_drop.value.ul = 0;
299 if (dev->port_id) {
300 stats->jabber_events.value.ul =
301 rx_stats->port1_jabber_events;
302 } else {
303 stats->jabber_events.value.ul =
304 rx_stats->port0_jabber_events;
305 }
306 stats->forwarded_packets.value.ul = rx_stats->forwarded_packets;
307
308 } else {
309 struct be_hw_stats_v1 *hw_stats = &fwcmd->params.rsp.v1;
310 struct rx_stats_v1 *rx_stats = &hw_stats->rx;
311 struct rx_port_stats_v1 *port_stats =
312 &rx_stats->port[dev->port_id];
313 struct rx_err_stats_v1 *err_stats = &hw_stats->err_rx;
314
315 stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd;
316 stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd;
317 stats->rx_frames.value.ul = port_stats->rx_total_frames;
318 stats->rx_errors.value.ul = port_stats->rx_crc_errors +
319 port_stats->rx_alignment_symbol_errors +
320 port_stats->rx_in_range_errors +
321 port_stats->rx_out_range_errors +
322 port_stats->rx_frame_too_long +
323 port_stats->rx_ip_checksum_errs +
324 port_stats->rx_tcp_checksum_errs +
325 port_stats->rx_udp_checksum_errs;
326
327 stats->rx_drops.value.ul = port_stats->rx_dropped_too_small +
328 port_stats->rx_dropped_too_short +
329 port_stats->rx_dropped_header_too_small +
330 port_stats->rx_dropped_tcp_length +
331 port_stats->rx_dropped_runt;
332
333 stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd;
334 stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd;
335
336 stats->tx_frames.value.ul = port_stats->tx_unicast_frames +
337 port_stats->tx_multicast_frames +
338 port_stats->tx_broadcast_frames +
339 port_stats->tx_pause_frames +
340 port_stats->tx_control_frames;
341 stats->tx_errors.value.ul = dev->tx_errors;
342
343 stats->rx_unicast_frames.value.ul =
344 port_stats->rx_non_switched_unicast_frames +
345 port_stats->rx_switched_unicast_packets;
346 stats->rx_multicast_frames.value.ul =
347 port_stats->rx_non_switched_multicast_frames +
348 port_stats->rx_switched_multicast_packets;
349 stats->rx_broadcast_frames.value.ul =
350 port_stats->rx_non_switched_broadcast_frames +
351 port_stats->rx_switched_broadcast_packets;
352 stats->rx_crc_errors.value.ul =
353 port_stats->rx_crc_errors;
354
355 stats->rx_alignment_symbol_errors.value.ul =
356 port_stats->rx_alignment_symbol_errors;
357 stats->rx_in_range_errors.value.ul =
358 port_stats->rx_in_range_errors;
359 stats->rx_out_range_errors.value.ul =
360 port_stats->rx_out_range_errors;
361 stats->rx_frame_too_long.value.ul =
362 port_stats->rx_frame_too_long;
363 stats->rx_address_match_errors.value.ul =
364 port_stats->rx_address_match_errors;
365
366 stats->rx_pause_frames.value.ul =
367 port_stats->rx_pause_frames;
368 stats->rx_control_frames.value.ul =
369 port_stats->rx_control_frames;
370 stats->rx_ip_checksum_errs.value.ul =
371 port_stats->rx_ip_checksum_errs;
372 stats->rx_tcp_checksum_errs.value.ul =
373 port_stats->rx_tcp_checksum_errs;
374 stats->rx_udp_checksum_errs.value.ul =
375 port_stats->rx_udp_checksum_errs;
376 stats->rx_fifo_overflow.value.ul =
377 port_stats->rxpp_fifo_overflow_drop;
378 stats->rx_input_fifo_overflow.value.ul =
379 port_stats->rx_input_fifo_overflow_drop;
380
381 stats->tx_unicast_frames.value.ul =
382 port_stats->tx_unicast_frames;
383 stats->tx_multicast_frames.value.ul =
384 port_stats->tx_multicast_frames;
385 stats->tx_broadcast_frames.value.ul =
386 port_stats->tx_broadcast_frames;
387 stats->tx_pause_frames.value.ul =
388 port_stats->tx_pause_frames;
389 stats->tx_control_frames.value.ul =
390 port_stats->tx_control_frames;
391
392
393 stats->rx_drops_no_pbuf.value.ul =
394 rx_stats->rx_drops_no_pbuf;
395 stats->rx_drops_no_txpb.value.ul =
396 rx_stats->rx_drops_no_txpb;
397 stats->rx_drops_no_erx_descr.value.ul =
398 rx_stats->rx_drops_no_erx_descr;
399 stats->rx_drops_no_tpre_descr.value.ul =
400 rx_stats->rx_drops_no_tpre_descr;
401 stats->rx_drops_too_many_frags.value.ul =
402 rx_stats->rx_drops_too_many_frags;
403 stats->rx_drops_invalid_ring.value.ul =
404 rx_stats->rx_drops_invalid_ring;
405 stats->rx_drops_mtu.value.ul =
406 rx_stats->rx_drops_mtu;
407
408 stats->rx_dropped_too_small.value.ul =
409 port_stats->rx_dropped_too_small;
410 stats->rx_dropped_too_short.value.ul =
411 port_stats->rx_dropped_too_short;
412 stats->rx_dropped_header_too_small.value.ul =
413 port_stats->rx_dropped_header_too_small;
414 stats->rx_dropped_tcp_length.value.ul =
415 port_stats->rx_dropped_tcp_length;
416 stats->rx_dropped_runt.value.ul =
417 port_stats->rx_dropped_runt;
418
419 stats->rx_drops_no_fragments.value.ul = 0;
420 for (i = 0; i < dev->nrqs; i++) {
421 stats->rx_drops_no_fragments.value.ul +=
422 err_stats->rx_drops_no_fragments[dev->rq[i].rq_id];
423 }
424
425 stats->rx_priority_pause_frames.value.ul =
426 port_stats->rx_priority_pause_frames;
427 stats->pmem_fifo_overflow_drop.value.ul =
428 port_stats->pmem_fifo_overflow_drop;
429 stats->jabber_events.value.ul = port_stats->jabber_events;
430 stats->forwarded_packets.value.ul = rx_stats->forwarded_packets;
431
432 }
433
434 return (DDI_SUCCESS);
435 } /* oce_update_be_stats */
436
437 /*
438 * function called by kstat to update the stats counters
439 *
440 * ksp - pointer to the kstats structure
441 * rw - flags defining read/write
442 *
443 * return DDI_SUCCESS => success, failure otherwise
444 */
445 static int
446 oce_update_stats(kstat_t *ksp, int rw)
447 {
448 struct oce_dev *dev;
449 struct oce_stat *stats;
450 int ret;
451
452 if (rw == KSTAT_WRITE) {
453 return (EACCES);
454 }
455
456 dev = ksp->ks_private;
457 stats = (struct oce_stat *)ksp->ks_data;
458 mutex_enter(&dev->dev_lock);
459 if (dev->suspended) {
460 mutex_exit(&dev->dev_lock);
461 return (EIO);
462 }
463 mutex_exit(&dev->dev_lock);
464 mutex_enter(&dev->stat_lock);
465 if (LANCER_CHIP(dev)) {
466 ret = oce_update_lancer_stats(dev, stats);
467 } else {
468 ret = oce_update_be_stats(dev, stats);
469 }
470 mutex_exit(&dev->stat_lock);
471 return (ret);
472 } /* oce_update_stats */
473
474 /*
475 * function to setup the kstat_t structure for the device and install it
476 *
477 * dev - software handle to the device
478 *
479 * return DDI_SUCCESS => success, failure otherwise
480 */
481 int
482 oce_stat_init(struct oce_dev *dev)
483 {
484 int ret;
485 struct oce_stat *stats;
486 uint32_t hw_stat_size = 0;
487 uint32_t num_stats = sizeof (struct oce_stat) /
488 sizeof (kstat_named_t);
489
490 /* allocate the kstat */
491 dev->oce_kstats = kstat_create(OCE_MOD_NAME, dev->dev_id, "stats",
492 "net", KSTAT_TYPE_NAMED,
493 num_stats, 0);
494 if (dev->oce_kstats == NULL) {
495 oce_log(dev, CE_WARN, MOD_CONFIG,
496 "kstat creation failed: 0x%p",
497 (void *)dev->oce_kstats);
498 return (DDI_FAILURE);
499 }
500
501 if (LANCER_CHIP(dev))
502 hw_stat_size = sizeof (struct mbx_get_pport_stats);
503 else
504 hw_stat_size = sizeof (struct mbx_get_nic_stats);
505
506 /* allocate the device copy of the stats */
507 ret = oce_alloc_dma_buffer(dev, &dev->stats_dbuf,
508 hw_stat_size, NULL, DDI_DMA_CONSISTENT|DDI_DMA_RDWR);
509 if (ret != DDI_SUCCESS) {
510 oce_log(dev, CE_WARN, MOD_CONFIG,
511 "Could not allocate stats_dbuf 0x%x", ret);
512 kstat_delete(dev->oce_kstats);
513 return (DDI_FAILURE);
514 }
515
516 /* initialize the counters */
517 stats = (struct oce_stat *)dev->oce_kstats->ks_data;
518 kstat_named_init(&stats->rx_bytes_hi, "rx bytes msd", KSTAT_DATA_ULONG);
519 kstat_named_init(&stats->rx_bytes_lo, "rx bytes lsd", KSTAT_DATA_ULONG);
520
521 kstat_named_init(&stats->rx_frames, "rx frames", KSTAT_DATA_ULONG);
522 kstat_named_init(&stats->rx_errors, "rx errors", KSTAT_DATA_ULONG);
523 kstat_named_init(&stats->rx_drops, "rx drops", KSTAT_DATA_ULONG);
524
525 kstat_named_init(&stats->tx_bytes_hi, "tx bytes msd", KSTAT_DATA_ULONG);
526 kstat_named_init(&stats->tx_bytes_lo, "tx bytes lsd", KSTAT_DATA_ULONG);
527
528 kstat_named_init(&stats->tx_frames, "tx frames", KSTAT_DATA_ULONG);
529 kstat_named_init(&stats->tx_errors, "tx errors", KSTAT_DATA_ULONG);
530
531 kstat_named_init(&stats->rx_unicast_frames,
532 "rx unicast frames", KSTAT_DATA_ULONG);
533 kstat_named_init(&stats->rx_multicast_frames,
534 "rx multicast frames", KSTAT_DATA_ULONG);
535 kstat_named_init(&stats->rx_broadcast_frames,
536 "rx broadcast frames", KSTAT_DATA_ULONG);
537 kstat_named_init(&stats->rx_crc_errors,
538 "rx crc errors", KSTAT_DATA_ULONG);
539
540 kstat_named_init(&stats->rx_alignment_symbol_errors,
541 "rx alignment symbol errors", KSTAT_DATA_ULONG);
542 kstat_named_init(&stats->rx_in_range_errors,
543 "rx in range errors", KSTAT_DATA_ULONG);
544 kstat_named_init(&stats->rx_out_range_errors,
545 "rx out range errors", KSTAT_DATA_ULONG);
546 kstat_named_init(&stats->rx_frame_too_long,
547 "rx frame too long", KSTAT_DATA_ULONG);
548 kstat_named_init(&stats->rx_address_match_errors,
549 "rx address match errors", KSTAT_DATA_ULONG);
550
551 kstat_named_init(&stats->rx_pause_frames,
552 "rx pause frames", KSTAT_DATA_ULONG);
553 kstat_named_init(&stats->rx_control_frames,
554 "rx control frames", KSTAT_DATA_ULONG);
555 kstat_named_init(&stats->rx_ip_checksum_errs,
556 "rx ip checksum errors", KSTAT_DATA_ULONG);
557 kstat_named_init(&stats->rx_tcp_checksum_errs,
558 "rx tcp checksum errors", KSTAT_DATA_ULONG);
559 kstat_named_init(&stats->rx_udp_checksum_errs,
560 "rx udp checksum errors", KSTAT_DATA_ULONG);
561 kstat_named_init(&stats->rx_fifo_overflow,
562 "rx fifo overflow", KSTAT_DATA_ULONG);
563 kstat_named_init(&stats->rx_input_fifo_overflow,
564 "rx input fifo overflow", KSTAT_DATA_ULONG);
565
566 kstat_named_init(&stats->tx_unicast_frames,
567 "tx unicast frames", KSTAT_DATA_ULONG);
568 kstat_named_init(&stats->tx_multicast_frames,
569 "tx multicast frames", KSTAT_DATA_ULONG);
570 kstat_named_init(&stats->tx_broadcast_frames,
571 "tx broadcast frames", KSTAT_DATA_ULONG);
572 kstat_named_init(&stats->tx_pause_frames,
573 "tx pause frames", KSTAT_DATA_ULONG);
574 kstat_named_init(&stats->tx_control_frames,
575 "tx control frames", KSTAT_DATA_ULONG);
576
577
578 kstat_named_init(&stats->rx_drops_no_pbuf,
579 "rx_drops_no_pbuf", KSTAT_DATA_ULONG);
580 kstat_named_init(&stats->rx_drops_no_txpb,
581 "rx_drops_no_txpb", KSTAT_DATA_ULONG);
582 kstat_named_init(&stats->rx_drops_no_erx_descr,
583 "rx_drops_no_erx_descr", KSTAT_DATA_ULONG);
584 kstat_named_init(&stats->rx_drops_no_tpre_descr,
585 "rx_drops_no_tpre_descr", KSTAT_DATA_ULONG);
586 kstat_named_init(&stats->rx_drops_too_many_frags,
587 "rx_drops_too_many_frags", KSTAT_DATA_ULONG);
588 kstat_named_init(&stats->rx_drops_invalid_ring,
589 "rx_drops_invalid_ring", KSTAT_DATA_ULONG);
590 kstat_named_init(&stats->rx_drops_mtu,
591 "rx_drops_mtu", KSTAT_DATA_ULONG);
592
593 kstat_named_init(&stats->rx_dropped_too_small,
594 "rx_dropped_too_small", KSTAT_DATA_ULONG);
595 kstat_named_init(&stats->rx_dropped_too_short,
596 "rx_dropped_too_short", KSTAT_DATA_ULONG);
597 kstat_named_init(&stats->rx_dropped_header_too_small,
598 "rx_dropped_header_too_small", KSTAT_DATA_ULONG);
599 kstat_named_init(&stats->rx_dropped_tcp_length,
600 "rx_dropped_tcp_length", KSTAT_DATA_ULONG);
601 kstat_named_init(&stats->rx_dropped_runt,
602 "rx_dropped_runt", KSTAT_DATA_ULONG);
603
604 kstat_named_init(&stats->rx_drops_no_fragments,
605 "rx_drop_no_frag", KSTAT_DATA_ULONG);
606
607 kstat_named_init(&stats->rx_priority_pause_frames,
608 "rx_priority_pause_frames", KSTAT_DATA_ULONG);
609 kstat_named_init(&stats->pmem_fifo_overflow_drop,
610 "pmem_fifo_overflow_drop", KSTAT_DATA_ULONG);
611 kstat_named_init(&stats->jabber_events,
612 "jabber_events", KSTAT_DATA_ULONG);
613 kstat_named_init(&stats->forwarded_packets,
614 "forwarded_packets", KSTAT_DATA_ULONG);
615
616 dev->oce_kstats->ks_update = oce_update_stats;
617 dev->oce_kstats->ks_private = (void *)dev;
618 kstat_install(dev->oce_kstats);
619
620 return (DDI_SUCCESS);
621 } /* oce_stat_init */
622
623 /*
624 * function to undo initialization done in oce_stat_init
625 *
626 * dev - software handle to the device
627 *
628 * return none
629 */
630 void
631 oce_stat_fini(struct oce_dev *dev)
632 {
633 oce_free_dma_buffer(dev, &dev->stats_dbuf);
634 kstat_delete(dev->oce_kstats);
635 dev->oce_kstats = NULL;
636 } /* oce_stat_fini */
637
638 /*
639 * GLDv3 entry for statistic query
640 */
641 int
642 oce_m_stat(void *arg, uint_t stat, uint64_t *val)
643 {
644 struct oce_dev *dev = arg;
645 struct oce_stat *stats;
646 int ret;
647
648 stats = (struct oce_stat *)dev->oce_kstats->ks_data;
649 mutex_enter(&dev->dev_lock);
650
651 if (dev->suspended ||
652 (dev->state & STATE_MAC_STOPPING) ||
653 !(dev->state & STATE_MAC_STARTED)) {
654 mutex_exit(&dev->dev_lock);
655 return (EIO);
656 }
657 mutex_exit(&dev->dev_lock);
658 mutex_enter(&dev->stat_lock);
659
660 if (LANCER_CHIP(dev)) {
661 ret = oce_update_lancer_stats(dev, stats);
662 } else {
663 ret = oce_update_be_stats(dev, stats);
664 }
665 if (ret != DDI_SUCCESS) {
666 mutex_exit(&dev->stat_lock);
667 return (EIO);
668 }
669 switch (stat) {
670 case MAC_STAT_IFSPEED:
671 *val = dev->link_speed * 1000000ull;
672 break;
673
674 case MAC_STAT_RBYTES:
675 *val = (uint64_t)stats->rx_bytes_hi.value.ul << 32 |
676 (uint64_t)stats->rx_bytes_lo.value.ul;
677 break;
678
679 case MAC_STAT_IPACKETS:
680 *val = stats->rx_frames.value.ul;
681 break;
682
683 case MAC_STAT_OBYTES:
684 *val = (uint64_t)stats->tx_bytes_hi.value.ul << 32 |
685 (uint64_t)stats->tx_bytes_lo.value.ul;
686 break;
687
688 case MAC_STAT_OPACKETS:
689 *val = stats->tx_frames.value.ul;
690 break;
691
692 case MAC_STAT_BRDCSTRCV:
693 *val = stats->rx_broadcast_frames.value.ul;
694 break;
695
696 case MAC_STAT_MULTIRCV:
697 *val = stats->rx_multicast_frames.value.ul;
698 break;
699
700 case MAC_STAT_MULTIXMT:
701 *val = stats->tx_multicast_frames.value.ul;
702 break;
703
704 case MAC_STAT_BRDCSTXMT:
705 *val = stats->tx_broadcast_frames.value.ul;
706 break;
707
708 case MAC_STAT_NORCVBUF:
709 *val = stats->rx_fifo_overflow.value.ul;
710 break;
711
712 case MAC_STAT_IERRORS:
713 *val = stats->rx_errors.value.ul;
714 break;
715
716 case MAC_STAT_NOXMTBUF:
717 *val = dev->tx_noxmtbuf;
718 break;
719
720 case MAC_STAT_OERRORS:
721 *val = stats->tx_errors.value.ul;
722 break;
723
724 case ETHER_STAT_LINK_DUPLEX:
725 if (dev->state & STATE_MAC_STARTED)
726 *val = LINK_DUPLEX_FULL;
727 else
728 *val = LINK_DUPLEX_UNKNOWN;
729 break;
730
731 case ETHER_STAT_ALIGN_ERRORS:
732 *val = stats->rx_alignment_symbol_errors.value.ul;
733 break;
734
735 case ETHER_STAT_FCS_ERRORS:
736 *val = stats->rx_crc_errors.value.ul;
737 break;
738
739 case ETHER_STAT_MACRCV_ERRORS:
740 *val = stats->rx_errors.value.ul;
741 break;
742
743 case ETHER_STAT_MACXMT_ERRORS:
744 *val = stats->tx_errors.value.ul;
745 break;
746
747 case ETHER_STAT_TOOLONG_ERRORS:
748 *val = stats->rx_frame_too_long.value.ul;
749 break;
750
751 case ETHER_STAT_CAP_PAUSE:
752 case ETHER_STAT_LINK_PAUSE:
753 if (dev->flow_control & OCE_FC_TX &&
754 dev->flow_control & OCE_FC_RX)
755 *val = LINK_FLOWCTRL_BI;
756 else if (dev->flow_control == OCE_FC_TX)
757 *val = LINK_FLOWCTRL_TX;
758 else if (dev->flow_control == OCE_FC_RX)
759 *val = LINK_FLOWCTRL_RX;
760 else if (dev->flow_control == 0)
761 *val = LINK_FLOWCTRL_NONE;
762 break;
763
764 default:
765 mutex_exit(&dev->stat_lock);
766 return (ENOTSUP);
767 }
768 mutex_exit(&dev->stat_lock);
769 return (0);
770 } /* oce_m_stat */