xref: /titanic_44/usr/src/uts/common/io/nge/nge_kstats.c (revision 2a9459bdd821c1cf59590a7a9069ac9c591e8a6b)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * This file may contain confidential information of Nvidia
8  * and should not be distributed in source form without approval
9  * from Sun Legal.
10  */
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 #include "nge.h"
15 
16 #undef	NGE_DBG
17 #define	NGE_DBG		NGE_DBG_STATS	/* debug flag for this code	*/
18 
19 /*
20  * Table of Hardware-defined Statistics Block Offsets and Names
21  */
22 #define	KS_NAME(s)			{ KS_ ## s, #s }
23 
24 const nge_ksindex_t nge_statistics[] = {
25 
26 	KS_NAME(ifHOutOctets),
27 	KS_NAME(ifHOutZeroRetranCount),
28 	KS_NAME(ifHOutOneRetranCount),
29 	KS_NAME(ifHOutMoreRetranCount),
30 	KS_NAME(ifHOutColCount),
31 	KS_NAME(ifHOutFifoovCount),
32 	KS_NAME(ifHOutLOCCount),
33 	KS_NAME(ifHOutExDecCount),
34 	KS_NAME(ifHOutRetryCount),
35 	KS_NAME(ifHInFrameErrCount),
36 	KS_NAME(ifHInExtraOctErrCount),
37 	KS_NAME(ifHInLColErrCount),
38 	KS_NAME(ifHInOversizeErrCount),
39 	KS_NAME(ifHInFovErrCount),
40 	KS_NAME(ifHInFCSErrCount),
41 	KS_NAME(ifHInAlignErrCount),
42 	KS_NAME(ifHInLenErrCount),
43 	KS_NAME(ifHInUniPktsCount),
44 	KS_NAME(ifHInBroadPksCount),
45 	KS_NAME(ifHInMulPksCount),
46 	{ KS_STATS_SIZE, NULL }
47 };
48 
49 /*
50  * Local datatype for defining tables of (Offset, Name) pairs
51  */
52 static int
53 nge_statistics_update(kstat_t *ksp, int flag)
54 {
55 	uint32_t regno;
56 	nge_t *ngep;
57 	nge_statistics_t *istp;
58 	nge_hw_statistics_t *hw_stp;
59 	kstat_named_t *knp;
60 	const nge_ksindex_t *ksip;
61 
62 	if (flag != KSTAT_READ)
63 		return (EACCES);
64 
65 	ngep = ksp->ks_private;
66 	istp = &ngep->statistics;
67 	hw_stp = &istp->hw_statistics;
68 	knp = ksp->ks_data;
69 
70 	/*
71 	 * Transfer the statistics values from the hardware statistics regs
72 	 */
73 	for (ksip = nge_statistics; ksip->name != NULL; ++knp, ++ksip) {
74 		regno = KS_BASE + ksip->index * sizeof (uint32_t);
75 		hw_stp->a[ksip->index] = nge_reg_get32(ngep, regno);
76 		knp->value.ui64 += hw_stp->a[ksip->index];
77 	}
78 
79 	return (0);
80 }
81 
82 
83 static const nge_ksindex_t nge_chipinfo[] = {
84 	{ 0,				"businfo"		},
85 	{ 1,				"command"		},
86 	{ 2,				"vendor_id"		},
87 	{ 3,				"device_id"		},
88 	{ 4,				"subsystem_vendor_id"	},
89 	{ 5,				"subsystem_device_id"	},
90 	{ 6,				"revision_id"		},
91 	{ 7,				"cache_line_size"	},
92 	{ 8,				"latency_timer"		},
93 	{ 9,				"phy_mode"		},
94 	{ 10,				"phy_id"		},
95 	{ 11,				"hw_mac_addr"		},
96 	{ 12,				"&bus_type"		},
97 	{ 13,				"&bus_speed"		},
98 	{ 14,				"&bus_size"		},
99 	{ -1,				NULL 			}
100 };
101 
102 static const nge_ksindex_t nge_debuginfo[] = {
103 	{ 0,				"rx_realloc"		},
104 	{ 1,				"rx_realloc_fails"	},
105 	{ 2,				"rx_realloc_DMA_fails"	},
106 	{ 3,				"rx_realloc_MP_fails"	},
107 	{ 4,				"rx_rcfree"		},
108 	{ 5,				"context_switch"	},
109 	{ 6,				"ip_hsum_err"		},
110 	{ 7,				"tcp_hsum_err"		},
111 	{ 8,				"tc_next"		},
112 	{ 9,				"tx_next"		},
113 	{ 10,				"tx_free"		},
114 	{ 11,				"tx_flow"		},
115 	{ 12,				"rx_prod"		},
116 	{ 13,				"rx_hold"		},
117 	{ 14,				"rx_nobuf"		},
118 	{ 15,				"rx_err"		},
119 	{16,				"tx_err"		},
120 	{17,				"tx_stall"		},
121 	{ -1,				NULL 			}
122 };
123 
124 static int
125 nge_chipinfo_update(kstat_t *ksp, int flag)
126 {
127 	nge_t *ngep;
128 	kstat_named_t *knp;
129 	chip_info_t *infop;
130 
131 	if (flag != KSTAT_READ)
132 		return (EACCES);
133 
134 	ngep = ksp->ks_private;
135 	infop = &ngep->chipinfo;
136 	knp = ksp->ks_data;
137 
138 	(knp++)->value.ui64 = infop->businfo;
139 	(knp++)->value.ui64 = infop->command;
140 	(knp++)->value.ui64 = infop->vendor;
141 	(knp++)->value.ui64 = infop->device;
142 	(knp++)->value.ui64 = infop->subven;
143 	(knp++)->value.ui64 = infop->subdev;
144 	(knp++)->value.ui64 = infop->revision;
145 	(knp++)->value.ui64 = infop->clsize;
146 	(knp++)->value.ui64 = infop->latency;
147 	(knp++)->value.ui64 = ngep->phy_mode;
148 	(knp++)->value.ui64 = ngep->phy_id;
149 	(knp++)->value.ui64 = infop->hw_mac_addr;
150 	return (0);
151 }
152 
153 static int
154 nge_debuginfo_update(kstat_t *ksp, int flag)
155 {
156 	nge_t *ngep;
157 	kstat_named_t *knp;
158 	nge_sw_statistics_t *sw_stp;
159 
160 	if (flag != KSTAT_READ)
161 		return (EACCES);
162 
163 	ngep = ksp->ks_private;
164 	sw_stp = &ngep->statistics.sw_statistics;
165 	knp = ksp->ks_data;
166 
167 	(knp++)->value.ui64 = sw_stp->recv_realloc;
168 	(knp++)->value.ui64 = sw_stp->kmem_alloc_err;
169 	(knp++)->value.ui64 = sw_stp->dma_alloc_err;
170 	(knp++)->value.ui64 = sw_stp->mp_alloc_err;
171 	(knp++)->value.ui64 = sw_stp->recy_free;
172 	(knp++)->value.ui64 = sw_stp->load_context;
173 	(knp++)->value.ui64 = sw_stp->ip_hwsum_err;
174 	(knp++)->value.ui64 = sw_stp->tcp_hwsum_err;
175 	(knp++)->value.ui64 = ngep->send->tc_next;
176 	(knp++)->value.ui64 = ngep->send->tx_next;
177 	(knp++)->value.ui64 = ngep->send->tx_free;
178 	(knp++)->value.ui64 = ngep->send->tx_flow;
179 	(knp++)->value.ui64 = ngep->recv->prod_index;
180 	(knp++)->value.ui64 = ngep->buff->rx_hold;
181 	(knp++)->value.ui64 = sw_stp->rx_nobuffer;
182 	(knp++)->value.ui64 = sw_stp->rx_err;
183 	(knp++)->value.ui64 = sw_stp->tx_stop_err;
184 	(knp++)->value.ui64 = sw_stp->tx_stall;
185 	return (0);
186 }
187 
188 static kstat_t *
189 nge_setup_named_kstat(nge_t *ngep, int instance, char *name,
190 	const nge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
191 {
192 	kstat_t *ksp;
193 	kstat_named_t *knp;
194 	char *np;
195 	int type;
196 
197 	size /= sizeof (nge_ksindex_t);
198 	ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net",
199 	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
200 	if (ksp == NULL)
201 		return (NULL);
202 
203 	ksp->ks_private = ngep;
204 	ksp->ks_update = update;
205 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
206 		switch (*np) {
207 		default:
208 			type = KSTAT_DATA_UINT64;
209 			break;
210 		case '%':
211 			np += 1;
212 			type = KSTAT_DATA_UINT32;
213 			break;
214 
215 		case '$':
216 			np ++;
217 			type = KSTAT_DATA_STRING;
218 			break;
219 		case '&':
220 			np ++;
221 			type = KSTAT_DATA_CHAR;
222 			break;
223 		}
224 		kstat_named_init(knp, np, type);
225 	}
226 	kstat_install(ksp);
227 
228 	return (ksp);
229 }
230 
231 /*
232  * Create kstats corresponding to NDD parameters
233  */
234 static kstat_t *
235 nge_setup_params_kstat(nge_t *ngep, int instance, char *name,
236 	int (*update)(kstat_t *, int))
237 {
238 	kstat_t *ksp;
239 	kstat_named_t *knp;
240 	int i;
241 
242 	ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net",
243 	    KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT);
244 	if (ksp != NULL) {
245 		ksp->ks_private = ngep;
246 		ksp->ks_update = update;
247 		for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i)
248 			kstat_named_init(knp, ngep->nd_params[i].ndp_name+1,
249 			    KSTAT_DATA_UINT64);
250 		kstat_install(ksp);
251 	}
252 
253 	return (ksp);
254 }
255 
256 void
257 nge_init_kstats(nge_t *ngep, int instance)
258 {
259 	const nge_ksindex_t *ksip;
260 
261 	NGE_TRACE(("nge_init_kstats($%p, %d)", (void *)ngep, instance));
262 	for (ksip = nge_statistics; ksip->name != NULL;  ++ksip) {
263 		(void) nge_reg_get32(ngep,
264 		    (nge_regno_t)(KS_BASE + sizeof (uint32_t)*ksip->index));
265 	}
266 
267 	ngep->nge_kstats[NGE_KSTAT_STATS] = nge_setup_named_kstat(ngep,
268 	    instance, "statistics", nge_statistics,
269 	    sizeof (nge_statistics), nge_statistics_update);
270 
271 	ngep->nge_kstats[NGE_KSTAT_CHIPID] = nge_setup_named_kstat(ngep,
272 	    instance, "chipinfo", nge_chipinfo,
273 	    sizeof (nge_chipinfo), nge_chipinfo_update);
274 
275 	ngep->nge_kstats[NGE_KSTAT_DEBUG] = nge_setup_named_kstat(ngep,
276 	    instance, "driver-debug", nge_debuginfo,
277 	    sizeof (nge_debuginfo), nge_debuginfo_update);
278 
279 }
280 
281 void
282 nge_fini_kstats(nge_t *ngep)
283 {
284 	int i;
285 
286 	NGE_TRACE(("nge_fini_kstats($%p)", (void *)ngep));
287 	for (i = NGE_KSTAT_COUNT;  --i >= 0; )
288 		if (ngep->nge_kstats[i] != NULL)
289 			kstat_delete(ngep->nge_kstats[i]);
290 }
291 
292 int
293 nge_m_stat(void *arg, uint_t stat, uint64_t *val)
294 {
295 	nge_t *ngep = arg;
296 	nge_statistics_t *nstp = &ngep->statistics;
297 	nge_hw_statistics_t *hw_stp = &nstp->hw_statistics;
298 	nge_sw_statistics_t *sw_stp = &nstp->sw_statistics;
299 
300 	switch (stat) {
301 	case MAC_STAT_IFSPEED:
302 		*val = ngep->param_link_speed * 1000000ull;
303 		break;
304 
305 	case MAC_STAT_MULTIRCV:
306 		*val = hw_stp->s.InMulPksCount;
307 		break;
308 
309 	case MAC_STAT_BRDCSTRCV:
310 		*val = hw_stp->s.InBroadPksCount;
311 		break;
312 
313 	case MAC_STAT_NORCVBUF:
314 		*val = sw_stp->rx_nobuffer;
315 		break;
316 
317 	case MAC_STAT_IERRORS:
318 		*val = hw_stp->s.InFrameErrCount +
319 		    hw_stp->s.InExtraOctErrCount +
320 		    hw_stp->s.InLColErrCount +
321 		    hw_stp->s.InOversizeErrCount +
322 		    hw_stp->s.InFovErrCount +
323 		    hw_stp->s.InFCSErrCount +
324 		    hw_stp->s.InAlignErrCount +
325 		    hw_stp->s.InLenErrCount;
326 		break;
327 
328 	case MAC_STAT_OERRORS:
329 		*val = hw_stp->s.OutFifoovCount +
330 		    hw_stp->s.OutLOCCount +
331 		    hw_stp->s.OutExDecCount +
332 		    hw_stp->s.OutRetryCount;
333 		break;
334 
335 	case MAC_STAT_COLLISIONS:
336 		*val = hw_stp->s.OutColCount;
337 		break;
338 
339 	case MAC_STAT_RBYTES:
340 		*val = sw_stp->rbytes;
341 		break;
342 
343 	case MAC_STAT_IPACKETS:
344 		*val = sw_stp->recv_count;
345 		break;
346 
347 	case MAC_STAT_OBYTES:
348 		*val = sw_stp->obytes;
349 		break;
350 
351 	case MAC_STAT_OPACKETS:
352 		*val = sw_stp->xmit_count;
353 		break;
354 
355 	case ETHER_STAT_ALIGN_ERRORS:
356 		*val = hw_stp->s.InAlignErrCount;
357 		break;
358 
359 	case ETHER_STAT_FCS_ERRORS:
360 		*val = hw_stp->s.InFCSErrCount;
361 		break;
362 
363 	case ETHER_STAT_FIRST_COLLISIONS:
364 		*val = hw_stp->s.OutZeroRetranCount;
365 		break;
366 
367 	case ETHER_STAT_MULTI_COLLISIONS:
368 		*val =  hw_stp->s.OutOneRetranCount +
369 		    hw_stp->s.OutMoreRetranCount;
370 		break;
371 
372 	case ETHER_STAT_DEFER_XMTS:
373 		*val = hw_stp->s.OutExDecCount;
374 		break;
375 
376 	case ETHER_STAT_TX_LATE_COLLISIONS:
377 		*val = hw_stp->s.OutColCount;
378 		break;
379 
380 	case ETHER_STAT_EX_COLLISIONS:
381 		*val = hw_stp->s.OutRetryCount;
382 		break;
383 
384 	case ETHER_STAT_CARRIER_ERRORS:
385 		*val = hw_stp->s.OutLOCCount;
386 		break;
387 
388 	case ETHER_STAT_TOOLONG_ERRORS:
389 		*val = hw_stp->s.InOversizeErrCount;
390 		break;
391 
392 	case ETHER_STAT_XCVR_ADDR:
393 		*val = ngep->phy_xmii_addr;
394 		break;
395 
396 	case ETHER_STAT_XCVR_ID:
397 		*val = ngep->phy_id;
398 		break;
399 
400 	case ETHER_STAT_XCVR_INUSE:
401 		*val = XCVR_1000T;
402 		break;
403 
404 	case ETHER_STAT_CAP_1000FDX:
405 		*val = 1;
406 		break;
407 
408 	case ETHER_STAT_CAP_1000HDX:
409 		*val = 0;
410 		break;
411 
412 	case ETHER_STAT_CAP_100FDX:
413 		*val = 1;
414 		break;
415 
416 	case ETHER_STAT_CAP_100HDX:
417 		*val = 1;
418 		break;
419 
420 	case ETHER_STAT_CAP_10FDX:
421 		*val = 1;
422 		break;
423 
424 	case ETHER_STAT_CAP_10HDX:
425 		*val = 1;
426 		break;
427 
428 	case ETHER_STAT_CAP_ASMPAUSE:
429 		*val = 1;
430 		break;
431 
432 	case ETHER_STAT_CAP_PAUSE:
433 		*val = 1;
434 		break;
435 
436 	case ETHER_STAT_CAP_AUTONEG:
437 		*val = 1;
438 		break;
439 
440 	case ETHER_STAT_ADV_CAP_1000FDX:
441 		*val = ngep->param_adv_1000fdx;
442 		break;
443 
444 	case ETHER_STAT_ADV_CAP_1000HDX:
445 		*val = ngep->param_adv_1000hdx;
446 		break;
447 
448 	case ETHER_STAT_ADV_CAP_100FDX:
449 		*val = ngep->param_adv_100fdx;
450 		break;
451 
452 	case ETHER_STAT_ADV_CAP_100HDX:
453 		*val = ngep->param_adv_100hdx;
454 		break;
455 
456 	case ETHER_STAT_ADV_CAP_10FDX:
457 		*val = ngep->param_adv_10fdx;
458 		break;
459 
460 	case ETHER_STAT_ADV_CAP_10HDX:
461 		*val = ngep->param_adv_10hdx;
462 		break;
463 
464 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
465 		*val = ngep->param_adv_asym_pause;
466 		break;
467 
468 	case ETHER_STAT_ADV_CAP_PAUSE:
469 		*val = ngep->param_adv_pause;
470 		break;
471 
472 	case ETHER_STAT_ADV_CAP_AUTONEG:
473 		*val = ngep->param_adv_autoneg;
474 		break;
475 
476 	case ETHER_STAT_LP_CAP_1000FDX:
477 		*val = ngep->param_lp_1000fdx;
478 		break;
479 
480 	case ETHER_STAT_LP_CAP_1000HDX:
481 		*val = ngep->param_lp_1000hdx;
482 		break;
483 
484 	case ETHER_STAT_LP_CAP_100FDX:
485 		*val = ngep->param_lp_100fdx;
486 		break;
487 
488 	case ETHER_STAT_LP_CAP_100HDX:
489 		*val = ngep->param_lp_100hdx;
490 		break;
491 
492 	case ETHER_STAT_LP_CAP_10FDX:
493 		*val = ngep->param_lp_10fdx;
494 		break;
495 
496 	case ETHER_STAT_LP_CAP_10HDX:
497 		*val = ngep->param_lp_10hdx;
498 		break;
499 
500 	case ETHER_STAT_LP_CAP_ASMPAUSE:
501 		*val = ngep->param_lp_asym_pause;
502 		break;
503 
504 	case ETHER_STAT_LP_CAP_PAUSE:
505 		*val = ngep->param_lp_pause;
506 		break;
507 
508 	case ETHER_STAT_LP_CAP_AUTONEG:
509 		*val = ngep->param_lp_autoneg;
510 		break;
511 
512 	case ETHER_STAT_LINK_ASMPAUSE:
513 		*val = ngep->param_adv_asym_pause &&
514 		    ngep->param_lp_asym_pause &&
515 		    ngep->param_adv_pause != ngep->param_lp_pause;
516 		break;
517 
518 	case ETHER_STAT_LINK_PAUSE:
519 		*val = ngep->param_link_rx_pause;
520 		break;
521 
522 	case ETHER_STAT_LINK_AUTONEG:
523 		*val = ngep->param_link_autoneg;
524 		break;
525 
526 	case ETHER_STAT_LINK_DUPLEX:
527 		*val = ngep->param_link_duplex;
528 		break;
529 
530 	default:
531 		return (ENOTSUP);
532 	}
533 
534 	return (0);
535 }
536