xref: /titanic_52/usr/src/uts/common/io/rge/rge_kstats.c (revision 0d2a8e5eea8ac6ea0f5c517f0c481329b57d5459)
1c7fd2ed0Sgs150176 /*
2c7fd2ed0Sgs150176  * CDDL HEADER START
3c7fd2ed0Sgs150176  *
4c7fd2ed0Sgs150176  * The contents of this file are subject to the terms of the
5ba2e4443Sseb  * Common Development and Distribution License (the "License").
6ba2e4443Sseb  * You may not use this file except in compliance with the License.
7c7fd2ed0Sgs150176  *
8c7fd2ed0Sgs150176  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c7fd2ed0Sgs150176  * or http://www.opensolaris.org/os/licensing.
10c7fd2ed0Sgs150176  * See the License for the specific language governing permissions
11c7fd2ed0Sgs150176  * and limitations under the License.
12c7fd2ed0Sgs150176  *
13c7fd2ed0Sgs150176  * When distributing Covered Code, include this CDDL HEADER in each
14c7fd2ed0Sgs150176  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c7fd2ed0Sgs150176  * If applicable, add the following below this CDDL HEADER, with the
16c7fd2ed0Sgs150176  * fields enclosed by brackets "[]" replaced with your own identifying
17c7fd2ed0Sgs150176  * information: Portions Copyright [yyyy] [name of copyright owner]
18c7fd2ed0Sgs150176  *
19c7fd2ed0Sgs150176  * CDDL HEADER END
20c7fd2ed0Sgs150176  */
21c7fd2ed0Sgs150176 /*
22*0d2a8e5eSgd78059  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23c7fd2ed0Sgs150176  * Use is subject to license terms.
24c7fd2ed0Sgs150176  */
25c7fd2ed0Sgs150176 
26c7fd2ed0Sgs150176 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27c7fd2ed0Sgs150176 
28c7fd2ed0Sgs150176 #include "rge.h"
29c7fd2ed0Sgs150176 
30c7fd2ed0Sgs150176 #define	RGE_DBG		RGE_DBG_STATS	/* debug flag for this code	*/
31c7fd2ed0Sgs150176 
32c7fd2ed0Sgs150176 /*
33c7fd2ed0Sgs150176  * Local datatype for defining tables of (Offset, Name) pairs
34c7fd2ed0Sgs150176  */
35c7fd2ed0Sgs150176 typedef struct {
36c7fd2ed0Sgs150176 	offset_t	index;
37c7fd2ed0Sgs150176 	char		*name;
38c7fd2ed0Sgs150176 } rge_ksindex_t;
39c7fd2ed0Sgs150176 
40c7fd2ed0Sgs150176 static const rge_ksindex_t rge_driverinfo[] = {
41c7fd2ed0Sgs150176 	{ 0,		"rx_ring_addr"		},
42c7fd2ed0Sgs150176 	{ 1,		"rx_next"		},
43c7fd2ed0Sgs150176 	{ 2,		"rx_free"		},
44c7fd2ed0Sgs150176 	{ 3,		"rx_bcopy"		},
45c7fd2ed0Sgs150176 	{ 4,		"tx_ring_addr"		},
46c7fd2ed0Sgs150176 	{ 5,		"tx_next"		},
47c7fd2ed0Sgs150176 	{ 6,		"tx_free"		},
48c7fd2ed0Sgs150176 	{ 7,		"tx_flow"		},
49c7fd2ed0Sgs150176 	{ 8,		"resched_needed"	},
50c7fd2ed0Sgs150176 	{ 9,		"watchdog"		},
51c7fd2ed0Sgs150176 	{ 10,		"rx_config"		},
52c7fd2ed0Sgs150176 	{ 11,		"tx_config"		},
53c7fd2ed0Sgs150176 	{ 12,		"mac_ver"		},
54c7fd2ed0Sgs150176 	{ 13,		"phy_ver"		},
55c7fd2ed0Sgs150176 	{ 14,		"chip_reset"		},
56c7fd2ed0Sgs150176 	{ 15,		"phy_reset"		},
57*0d2a8e5eSgd78059 	{ 16,		"loop_mode"		},
58c7fd2ed0Sgs150176 	{ -1,		NULL 			}
59c7fd2ed0Sgs150176 };
60c7fd2ed0Sgs150176 
61c7fd2ed0Sgs150176 static int
62c7fd2ed0Sgs150176 rge_driverinfo_update(kstat_t *ksp, int flag)
63c7fd2ed0Sgs150176 {
64c7fd2ed0Sgs150176 	rge_t *rgep;
65c7fd2ed0Sgs150176 	kstat_named_t *knp;
66c7fd2ed0Sgs150176 
67c7fd2ed0Sgs150176 	if (flag != KSTAT_READ)
68c7fd2ed0Sgs150176 		return (EACCES);
69c7fd2ed0Sgs150176 
70c7fd2ed0Sgs150176 	rgep = ksp->ks_private;
71c7fd2ed0Sgs150176 	knp = ksp->ks_data;
72c7fd2ed0Sgs150176 
73c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->dma_area_rxdesc.cookie.dmac_laddress;
74c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->rx_next;
75c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->rx_free;
76c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->rx_bcopy;
77c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->dma_area_txdesc.cookie.dmac_laddress;
78c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->tx_next;
79c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->tx_free;
80c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->tx_flow;
81c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->resched_needed;
82c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->watchdog;
83c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->chipid.rxconfig;
84c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->chipid.txconfig;
85c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->chipid.mac_ver;
86c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->chipid.phy_ver;
87c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->stats.chip_reset;
88c7fd2ed0Sgs150176 	(knp++)->value.ui64 = rgep->stats.phy_reset;
89*0d2a8e5eSgd78059 	(knp++)->value.ui64 = rgep->param_loop_mode;
90c7fd2ed0Sgs150176 
91c7fd2ed0Sgs150176 	return (0);
92c7fd2ed0Sgs150176 }
93c7fd2ed0Sgs150176 
94c7fd2ed0Sgs150176 static kstat_t *
95c7fd2ed0Sgs150176 rge_setup_named_kstat(rge_t *rgep, int instance, char *name,
96c7fd2ed0Sgs150176 	const rge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
97c7fd2ed0Sgs150176 {
98c7fd2ed0Sgs150176 	kstat_t *ksp;
99c7fd2ed0Sgs150176 	kstat_named_t *knp;
100c7fd2ed0Sgs150176 	char *np;
101c7fd2ed0Sgs150176 	int type;
102c7fd2ed0Sgs150176 
103c7fd2ed0Sgs150176 	size /= sizeof (rge_ksindex_t);
104c7fd2ed0Sgs150176 	ksp = kstat_create(RGE_DRIVER_NAME, instance, name, "net",
105c7fd2ed0Sgs150176 		KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
106c7fd2ed0Sgs150176 	if (ksp == NULL)
107c7fd2ed0Sgs150176 		return (NULL);
108c7fd2ed0Sgs150176 
109c7fd2ed0Sgs150176 	ksp->ks_private = rgep;
110c7fd2ed0Sgs150176 	ksp->ks_update = update;
111c7fd2ed0Sgs150176 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
112c7fd2ed0Sgs150176 		switch (*np) {
113c7fd2ed0Sgs150176 		default:
114c7fd2ed0Sgs150176 			type = KSTAT_DATA_UINT64;
115c7fd2ed0Sgs150176 			break;
116c7fd2ed0Sgs150176 		case '%':
117c7fd2ed0Sgs150176 			np += 1;
118c7fd2ed0Sgs150176 			type = KSTAT_DATA_UINT32;
119c7fd2ed0Sgs150176 			break;
120c7fd2ed0Sgs150176 		case '$':
121c7fd2ed0Sgs150176 			np += 1;
122c7fd2ed0Sgs150176 			type = KSTAT_DATA_STRING;
123c7fd2ed0Sgs150176 			break;
124c7fd2ed0Sgs150176 		case '&':
125c7fd2ed0Sgs150176 			np += 1;
126c7fd2ed0Sgs150176 			type = KSTAT_DATA_CHAR;
127c7fd2ed0Sgs150176 			break;
128c7fd2ed0Sgs150176 		}
129c7fd2ed0Sgs150176 		kstat_named_init(knp, np, type);
130c7fd2ed0Sgs150176 	}
131c7fd2ed0Sgs150176 	kstat_install(ksp);
132c7fd2ed0Sgs150176 
133c7fd2ed0Sgs150176 	return (ksp);
134c7fd2ed0Sgs150176 }
135c7fd2ed0Sgs150176 
136c7fd2ed0Sgs150176 void
137c7fd2ed0Sgs150176 rge_init_kstats(rge_t *rgep, int instance)
138c7fd2ed0Sgs150176 {
139c7fd2ed0Sgs150176 	rgep->rge_kstats[RGE_KSTAT_DRIVER] = rge_setup_named_kstat(rgep,
140c7fd2ed0Sgs150176 		instance, "driverinfo", rge_driverinfo,
141c7fd2ed0Sgs150176 		sizeof (rge_driverinfo), rge_driverinfo_update);
142c7fd2ed0Sgs150176 }
143c7fd2ed0Sgs150176 
144c7fd2ed0Sgs150176 void
145c7fd2ed0Sgs150176 rge_fini_kstats(rge_t *rgep)
146c7fd2ed0Sgs150176 {
147c7fd2ed0Sgs150176 	int i;
148c7fd2ed0Sgs150176 
149c7fd2ed0Sgs150176 	for (i = RGE_KSTAT_COUNT; --i >= 0; )
150c7fd2ed0Sgs150176 		if (rgep->rge_kstats[i] != NULL) {
151c7fd2ed0Sgs150176 			kstat_delete(rgep->rge_kstats[i]);
152c7fd2ed0Sgs150176 		}
153c7fd2ed0Sgs150176 }
154c7fd2ed0Sgs150176 
155ba2e4443Sseb int
156ba2e4443Sseb rge_m_stat(void *arg, uint_t stat, uint64_t *val)
157c7fd2ed0Sgs150176 {
158c7fd2ed0Sgs150176 	rge_t *rgep = arg;
159c7fd2ed0Sgs150176 	rge_hw_stats_t *bstp;
160c7fd2ed0Sgs150176 
161c7fd2ed0Sgs150176 	mutex_enter(rgep->genlock);
162c7fd2ed0Sgs150176 	rge_hw_stats_dump(rgep);
163c7fd2ed0Sgs150176 	mutex_exit(rgep->genlock);
164c7fd2ed0Sgs150176 	bstp = rgep->hw_stats;
165c7fd2ed0Sgs150176 
166c7fd2ed0Sgs150176 	switch (stat) {
167c7fd2ed0Sgs150176 	case MAC_STAT_IFSPEED:
168ba2e4443Sseb 		*val = rgep->param_link_speed * 1000000ull;
169c7fd2ed0Sgs150176 		break;
170c7fd2ed0Sgs150176 
171c7fd2ed0Sgs150176 	case MAC_STAT_MULTIRCV:
172ba2e4443Sseb 		*val = RGE_BSWAP_32(bstp->multi_rcv);
173c7fd2ed0Sgs150176 		break;
174c7fd2ed0Sgs150176 
175c7fd2ed0Sgs150176 	case MAC_STAT_BRDCSTRCV:
176ba2e4443Sseb 		*val = RGE_BSWAP_64(bstp->brdcst_rcv);
177c7fd2ed0Sgs150176 		break;
178c7fd2ed0Sgs150176 
179c7fd2ed0Sgs150176 	case MAC_STAT_NORCVBUF:
180ba2e4443Sseb 		*val = RGE_BSWAP_16(bstp->in_discards);
181c7fd2ed0Sgs150176 		break;
182c7fd2ed0Sgs150176 
183c7fd2ed0Sgs150176 	case MAC_STAT_IERRORS:
184ba2e4443Sseb 		*val = RGE_BSWAP_32(bstp->rcv_err);
185c7fd2ed0Sgs150176 		break;
186c7fd2ed0Sgs150176 
187c7fd2ed0Sgs150176 	case MAC_STAT_OERRORS:
188ba2e4443Sseb 		*val = RGE_BSWAP_64(bstp->xmt_err);
189c7fd2ed0Sgs150176 		break;
190c7fd2ed0Sgs150176 
191c7fd2ed0Sgs150176 	case MAC_STAT_COLLISIONS:
192ba2e4443Sseb 		*val = RGE_BSWAP_32(bstp->xmt_1col + bstp->xmt_mcol);
193c7fd2ed0Sgs150176 		break;
194c7fd2ed0Sgs150176 
195c7fd2ed0Sgs150176 	case MAC_STAT_RBYTES:
196ba2e4443Sseb 		*val = rgep->stats.rbytes;
197c7fd2ed0Sgs150176 		break;
198c7fd2ed0Sgs150176 
199c7fd2ed0Sgs150176 	case MAC_STAT_IPACKETS:
200ba2e4443Sseb 		*val = RGE_BSWAP_64(bstp->rcv_ok);
201c7fd2ed0Sgs150176 		break;
202c7fd2ed0Sgs150176 
203c7fd2ed0Sgs150176 	case MAC_STAT_OBYTES:
204ba2e4443Sseb 		*val = rgep->stats.obytes;
205c7fd2ed0Sgs150176 		break;
206c7fd2ed0Sgs150176 
207c7fd2ed0Sgs150176 	case MAC_STAT_OPACKETS:
208ba2e4443Sseb 		*val = RGE_BSWAP_64(bstp->xmt_ok);
209c7fd2ed0Sgs150176 		break;
210c7fd2ed0Sgs150176 
211ba2e4443Sseb 	case ETHER_STAT_ALIGN_ERRORS:
212ba2e4443Sseb 		*val = RGE_BSWAP_16(bstp->frame_err);
213c7fd2ed0Sgs150176 		break;
214c7fd2ed0Sgs150176 
215ba2e4443Sseb 	case ETHER_STAT_FIRST_COLLISIONS:
216ba2e4443Sseb 		*val = RGE_BSWAP_32(bstp->xmt_1col);
217c7fd2ed0Sgs150176 		break;
218c7fd2ed0Sgs150176 
219ba2e4443Sseb 	case ETHER_STAT_MULTI_COLLISIONS:
220ba2e4443Sseb 		*val = RGE_BSWAP_32(bstp->xmt_mcol);
221c7fd2ed0Sgs150176 		break;
222c7fd2ed0Sgs150176 
223ba2e4443Sseb 	case ETHER_STAT_DEFER_XMTS:
224ba2e4443Sseb 		*val = rgep->stats.defer;
225c7fd2ed0Sgs150176 		break;
226c7fd2ed0Sgs150176 
227ba2e4443Sseb 	case ETHER_STAT_XCVR_ADDR:
228ba2e4443Sseb 		*val = rgep->phy_mii_addr;
229c7fd2ed0Sgs150176 		break;
230c7fd2ed0Sgs150176 
231ba2e4443Sseb 	case ETHER_STAT_XCVR_ID:
232c7fd2ed0Sgs150176 		mutex_enter(rgep->genlock);
233ba2e4443Sseb 		*val = rge_mii_get16(rgep, MII_PHYIDH);
234ba2e4443Sseb 		*val <<= 16;
235ba2e4443Sseb 		*val |= rge_mii_get16(rgep, MII_PHYIDL);
236c7fd2ed0Sgs150176 		mutex_exit(rgep->genlock);
237c7fd2ed0Sgs150176 		break;
238c7fd2ed0Sgs150176 
239ba2e4443Sseb 	case ETHER_STAT_XCVR_INUSE:
240ba2e4443Sseb 		*val = XCVR_1000T;
241c7fd2ed0Sgs150176 		break;
242c7fd2ed0Sgs150176 
243ba2e4443Sseb 	case ETHER_STAT_CAP_1000FDX:
244ba2e4443Sseb 		*val = 1;
245c7fd2ed0Sgs150176 		break;
246c7fd2ed0Sgs150176 
247ba2e4443Sseb 	case ETHER_STAT_CAP_1000HDX:
248ba2e4443Sseb 		*val = 0;
249c7fd2ed0Sgs150176 		break;
250c7fd2ed0Sgs150176 
251ba2e4443Sseb 	case ETHER_STAT_CAP_100FDX:
252ba2e4443Sseb 		*val = 1;
253c7fd2ed0Sgs150176 		break;
254c7fd2ed0Sgs150176 
255ba2e4443Sseb 	case ETHER_STAT_CAP_100HDX:
256ba2e4443Sseb 		*val = 1;
257c7fd2ed0Sgs150176 		break;
258c7fd2ed0Sgs150176 
259ba2e4443Sseb 	case ETHER_STAT_CAP_10FDX:
260ba2e4443Sseb 		*val = 1;
261c7fd2ed0Sgs150176 		break;
262c7fd2ed0Sgs150176 
263ba2e4443Sseb 	case ETHER_STAT_CAP_10HDX:
264ba2e4443Sseb 		*val = 1;
265c7fd2ed0Sgs150176 		break;
266c7fd2ed0Sgs150176 
267ba2e4443Sseb 	case ETHER_STAT_CAP_ASMPAUSE:
268ba2e4443Sseb 		*val = 1;
269c7fd2ed0Sgs150176 		break;
270c7fd2ed0Sgs150176 
271ba2e4443Sseb 	case ETHER_STAT_CAP_PAUSE:
272ba2e4443Sseb 		*val = 1;
273c7fd2ed0Sgs150176 		break;
274c7fd2ed0Sgs150176 
275ba2e4443Sseb 	case ETHER_STAT_CAP_AUTONEG:
276ba2e4443Sseb 		*val = 1;
277c7fd2ed0Sgs150176 		break;
278c7fd2ed0Sgs150176 
279ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_1000FDX:
280ba2e4443Sseb 		*val = rgep->param_adv_1000fdx;
281c7fd2ed0Sgs150176 		break;
282c7fd2ed0Sgs150176 
283ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_1000HDX:
284ba2e4443Sseb 		*val = rgep->param_adv_1000hdx;
285c7fd2ed0Sgs150176 		break;
286c7fd2ed0Sgs150176 
287ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_100FDX:
288ba2e4443Sseb 		*val = rgep->param_adv_100fdx;
289c7fd2ed0Sgs150176 		break;
290c7fd2ed0Sgs150176 
291ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_100HDX:
292ba2e4443Sseb 		*val = rgep->param_adv_100hdx;
293c7fd2ed0Sgs150176 		break;
294c7fd2ed0Sgs150176 
295ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_10FDX:
296ba2e4443Sseb 		*val = rgep->param_adv_10fdx;
297c7fd2ed0Sgs150176 		break;
298c7fd2ed0Sgs150176 
299ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_10HDX:
300ba2e4443Sseb 		*val = rgep->param_adv_10hdx;
301c7fd2ed0Sgs150176 		break;
302c7fd2ed0Sgs150176 
303ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
304ba2e4443Sseb 		*val = rgep->param_adv_asym_pause;
305c7fd2ed0Sgs150176 		break;
306c7fd2ed0Sgs150176 
307ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_PAUSE:
308ba2e4443Sseb 		*val = rgep->param_adv_pause;
309c7fd2ed0Sgs150176 		break;
310c7fd2ed0Sgs150176 
311ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_AUTONEG:
312ba2e4443Sseb 		*val = rgep->param_adv_autoneg;
313c7fd2ed0Sgs150176 		break;
314c7fd2ed0Sgs150176 
315ba2e4443Sseb 	case ETHER_STAT_LINK_DUPLEX:
316ba2e4443Sseb 		*val = rgep->param_link_duplex;
317c7fd2ed0Sgs150176 		break;
318c7fd2ed0Sgs150176 
319c7fd2ed0Sgs150176 	default:
320ba2e4443Sseb 		return (ENOTSUP);
321c7fd2ed0Sgs150176 	}
322c7fd2ed0Sgs150176 
323ba2e4443Sseb 	return (0);
324c7fd2ed0Sgs150176 }
325