xref: /illumos-gate/usr/src/uts/common/io/rge/rge_kstats.c (revision 03831d35)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include "rge.h"
30 
31 #define	RGE_DBG		RGE_DBG_STATS	/* debug flag for this code	*/
32 
33 /*
34  * Local datatype for defining tables of (Offset, Name) pairs
35  */
36 typedef struct {
37 	offset_t	index;
38 	char		*name;
39 } rge_ksindex_t;
40 
41 static int
42 rge_params_update(kstat_t *ksp, int flag)
43 {
44 	rge_t *rgep;
45 	kstat_named_t *knp;
46 	int i;
47 
48 	if (flag != KSTAT_READ)
49 		return (EACCES);
50 
51 	rgep = ksp->ks_private;
52 	for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i)
53 		knp->value.ui64 = rgep->nd_params[i].ndp_val;
54 
55 	return (0);
56 }
57 
58 
59 static const rge_ksindex_t rge_driverinfo[] = {
60 	{ 0,		"rx_ring_addr"		},
61 	{ 1,		"rx_next"		},
62 	{ 2,		"rx_free"		},
63 	{ 3,		"rx_bcopy"		},
64 	{ 4,		"tx_ring_addr"		},
65 	{ 5,		"tx_next"		},
66 	{ 6,		"tx_free"		},
67 	{ 7,		"tx_flow"		},
68 	{ 8,		"resched_needed"	},
69 	{ 9,		"watchdog"		},
70 	{ 10,		"rx_config"		},
71 	{ 11,		"tx_config"		},
72 	{ 12,		"mac_ver"		},
73 	{ 13,		"phy_ver"		},
74 	{ 14,		"chip_reset"		},
75 	{ 15,		"phy_reset"		},
76 	{ -1,		NULL 			}
77 };
78 
79 static int
80 rge_driverinfo_update(kstat_t *ksp, int flag)
81 {
82 	rge_t *rgep;
83 	kstat_named_t *knp;
84 
85 	if (flag != KSTAT_READ)
86 		return (EACCES);
87 
88 	rgep = ksp->ks_private;
89 	knp = ksp->ks_data;
90 
91 	(knp++)->value.ui64 = rgep->dma_area_rxdesc.cookie.dmac_laddress;
92 	(knp++)->value.ui64 = rgep->rx_next;
93 	(knp++)->value.ui64 = rgep->rx_free;
94 	(knp++)->value.ui64 = rgep->rx_bcopy;
95 	(knp++)->value.ui64 = rgep->dma_area_txdesc.cookie.dmac_laddress;
96 	(knp++)->value.ui64 = rgep->tx_next;
97 	(knp++)->value.ui64 = rgep->tx_free;
98 	(knp++)->value.ui64 = rgep->tx_flow;
99 	(knp++)->value.ui64 = rgep->resched_needed;
100 	(knp++)->value.ui64 = rgep->watchdog;
101 	(knp++)->value.ui64 = rgep->chipid.rxconfig;
102 	(knp++)->value.ui64 = rgep->chipid.txconfig;
103 	(knp++)->value.ui64 = rgep->chipid.mac_ver;
104 	(knp++)->value.ui64 = rgep->chipid.phy_ver;
105 	(knp++)->value.ui64 = rgep->stats.chip_reset;
106 	(knp++)->value.ui64 = rgep->stats.phy_reset;
107 
108 	return (0);
109 }
110 
111 static kstat_t *
112 rge_setup_named_kstat(rge_t *rgep, int instance, char *name,
113 	const rge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
114 {
115 	kstat_t *ksp;
116 	kstat_named_t *knp;
117 	char *np;
118 	int type;
119 
120 	size /= sizeof (rge_ksindex_t);
121 	ksp = kstat_create(RGE_DRIVER_NAME, instance, name, "net",
122 		KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
123 	if (ksp == NULL)
124 		return (NULL);
125 
126 	ksp->ks_private = rgep;
127 	ksp->ks_update = update;
128 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
129 		switch (*np) {
130 		default:
131 			type = KSTAT_DATA_UINT64;
132 			break;
133 		case '%':
134 			np += 1;
135 			type = KSTAT_DATA_UINT32;
136 			break;
137 		case '$':
138 			np += 1;
139 			type = KSTAT_DATA_STRING;
140 			break;
141 		case '&':
142 			np += 1;
143 			type = KSTAT_DATA_CHAR;
144 			break;
145 		}
146 		kstat_named_init(knp, np, type);
147 	}
148 	kstat_install(ksp);
149 
150 	return (ksp);
151 }
152 
153 /*
154  * Create kstats corresponding to NDD parameters
155  */
156 static kstat_t *
157 rge_setup_params_kstat(rge_t *rgep, int instance, char *name,
158 	int (*update)(kstat_t *, int))
159 {
160 	kstat_t *ksp;
161 	kstat_named_t *knp;
162 	int i;
163 
164 	ksp = kstat_create(RGE_DRIVER_NAME, instance, name, "net",
165 		KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT);
166 	if (ksp != NULL) {
167 		ksp->ks_private = rgep;
168 		ksp->ks_update = update;
169 		for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i)
170 			kstat_named_init(knp, rgep->nd_params[i].ndp_name+1,
171 				KSTAT_DATA_UINT64);
172 		kstat_install(ksp);
173 	}
174 
175 	return (ksp);
176 }
177 
178 void
179 rge_init_kstats(rge_t *rgep, int instance)
180 {
181 	rgep->rge_kstats[RGE_KSTAT_PARAMS] = rge_setup_params_kstat(rgep,
182 		instance, "parameters", rge_params_update);
183 
184 	rgep->rge_kstats[RGE_KSTAT_DRIVER] = rge_setup_named_kstat(rgep,
185 		instance, "driverinfo", rge_driverinfo,
186 		sizeof (rge_driverinfo), rge_driverinfo_update);
187 }
188 
189 void
190 rge_fini_kstats(rge_t *rgep)
191 {
192 	int i;
193 
194 	for (i = RGE_KSTAT_COUNT; --i >= 0; )
195 		if (rgep->rge_kstats[i] != NULL) {
196 			kstat_delete(rgep->rge_kstats[i]);
197 		}
198 }
199 
200 uint64_t
201 rge_m_stat(void *arg, enum mac_stat stat)
202 {
203 	rge_t *rgep = arg;
204 	rge_hw_stats_t *bstp;
205 	uint64_t val = 0;
206 
207 	mutex_enter(rgep->genlock);
208 	rge_hw_stats_dump(rgep);
209 	mutex_exit(rgep->genlock);
210 	bstp = rgep->hw_stats;
211 
212 	switch (stat) {
213 	case MAC_STAT_IFSPEED:
214 		val = rgep->param_link_speed * 1000000ull;
215 		break;
216 
217 	case MAC_STAT_MULTIRCV:
218 		val = RGE_BSWAP_32(bstp->multi_rcv);
219 		break;
220 
221 	case MAC_STAT_BRDCSTRCV:
222 		val = RGE_BSWAP_64(bstp->brdcst_rcv);
223 		break;
224 
225 	case MAC_STAT_NORCVBUF:
226 		val = RGE_BSWAP_16(bstp->in_discards);
227 		break;
228 
229 	case MAC_STAT_IERRORS:
230 		val = RGE_BSWAP_32(bstp->rcv_err);
231 		break;
232 
233 	case MAC_STAT_OERRORS:
234 		val = RGE_BSWAP_64(bstp->xmt_err);
235 		break;
236 
237 	case MAC_STAT_COLLISIONS:
238 		val = RGE_BSWAP_32(bstp->xmt_1col + bstp->xmt_mcol);
239 		break;
240 
241 	case MAC_STAT_RBYTES:
242 		val = rgep->stats.rbytes;
243 		break;
244 
245 	case MAC_STAT_IPACKETS:
246 		val = RGE_BSWAP_64(bstp->rcv_ok);
247 		break;
248 
249 	case MAC_STAT_OBYTES:
250 		val = rgep->stats.obytes;
251 		break;
252 
253 	case MAC_STAT_OPACKETS:
254 		val = RGE_BSWAP_64(bstp->xmt_ok);
255 		break;
256 
257 	case MAC_STAT_ALIGN_ERRORS:
258 		val = RGE_BSWAP_16(bstp->frame_err);
259 		break;
260 
261 	case MAC_STAT_FIRST_COLLISIONS:
262 		val = RGE_BSWAP_32(bstp->xmt_1col);
263 		break;
264 
265 	case MAC_STAT_MULTI_COLLISIONS:
266 		val = RGE_BSWAP_32(bstp->xmt_mcol);
267 		break;
268 
269 	case MAC_STAT_DEFER_XMTS:
270 		val = rgep->stats.defer;
271 		break;
272 
273 	case MAC_STAT_XCVR_ADDR:
274 		val = rgep->phy_mii_addr;
275 		break;
276 
277 	case MAC_STAT_XCVR_ID:
278 		mutex_enter(rgep->genlock);
279 		val = rge_mii_get16(rgep, MII_PHYIDH);
280 		val <<= 16;
281 		val |= rge_mii_get16(rgep, MII_PHYIDL);
282 		mutex_exit(rgep->genlock);
283 		break;
284 
285 	case MAC_STAT_XCVR_INUSE:
286 		val = XCVR_1000T;
287 		break;
288 
289 	case MAC_STAT_CAP_1000FDX:
290 		val = 1;
291 		break;
292 
293 	case MAC_STAT_CAP_1000HDX:
294 		val = 0;
295 		break;
296 
297 	case MAC_STAT_CAP_100FDX:
298 		val = 1;
299 		break;
300 
301 	case MAC_STAT_CAP_100HDX:
302 		val = 1;
303 		break;
304 
305 	case MAC_STAT_CAP_10FDX:
306 		val = 1;
307 		break;
308 
309 	case MAC_STAT_CAP_10HDX:
310 		val = 1;
311 		break;
312 
313 	case MAC_STAT_CAP_ASMPAUSE:
314 		val = 1;
315 		break;
316 
317 	case MAC_STAT_CAP_PAUSE:
318 		val = 1;
319 		break;
320 
321 	case MAC_STAT_CAP_AUTONEG:
322 		val = 1;
323 		break;
324 
325 	case MAC_STAT_ADV_CAP_1000FDX:
326 		val = rgep->param_adv_1000fdx;
327 		break;
328 
329 	case MAC_STAT_ADV_CAP_1000HDX:
330 		val = rgep->param_adv_1000hdx;
331 		break;
332 
333 	case MAC_STAT_ADV_CAP_100FDX:
334 		val = rgep->param_adv_100fdx;
335 		break;
336 
337 	case MAC_STAT_ADV_CAP_100HDX:
338 		val = rgep->param_adv_100hdx;
339 		break;
340 
341 	case MAC_STAT_ADV_CAP_10FDX:
342 		val = rgep->param_adv_10fdx;
343 		break;
344 
345 	case MAC_STAT_ADV_CAP_10HDX:
346 		val = rgep->param_adv_10hdx;
347 		break;
348 
349 	case MAC_STAT_ADV_CAP_ASMPAUSE:
350 		val = rgep->param_adv_asym_pause;
351 		break;
352 
353 	case MAC_STAT_ADV_CAP_PAUSE:
354 		val = rgep->param_adv_pause;
355 		break;
356 
357 	case MAC_STAT_ADV_CAP_AUTONEG:
358 		val = rgep->param_adv_autoneg;
359 		break;
360 
361 	case MAC_STAT_LINK_DUPLEX:
362 		val = rgep->param_link_duplex;
363 		break;
364 
365 #ifdef	DEBUG
366 	default:
367 		/*
368 		 * Shouldn't reach here...
369 		 */
370 		cmn_err(CE_PANIC,
371 		    "rge_m_stat: unrecognized parameter value = %d",
372 		    stat);
373 #endif
374 	}
375 
376 	return (val);
377 }
378