xref: /onnv-gate/usr/src/uts/sun4v/io/n2rng/n2rng_kstat.c (revision 5650:7694397e8118)
14625Sgm89044 /*
24625Sgm89044  * CDDL HEADER START
34625Sgm89044  *
44625Sgm89044  * The contents of this file are subject to the terms of the
54625Sgm89044  * Common Development and Distribution License (the "License").
64625Sgm89044  * You may not use this file except in compliance with the License.
74625Sgm89044  *
84625Sgm89044  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94625Sgm89044  * or http://www.opensolaris.org/os/licensing.
104625Sgm89044  * See the License for the specific language governing permissions
114625Sgm89044  * and limitations under the License.
124625Sgm89044  *
134625Sgm89044  * When distributing Covered Code, include this CDDL HEADER in each
144625Sgm89044  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154625Sgm89044  * If applicable, add the following below this CDDL HEADER, with the
164625Sgm89044  * fields enclosed by brackets "[]" replaced with your own identifying
174625Sgm89044  * information: Portions Copyright [yyyy] [name of copyright owner]
184625Sgm89044  *
194625Sgm89044  * CDDL HEADER END
204625Sgm89044  */
214625Sgm89044 /*
224625Sgm89044  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
234625Sgm89044  * Use is subject to license terms.
244625Sgm89044  */
254625Sgm89044 
264625Sgm89044 #pragma ident	"%Z%%M%	%I%	%E% SMI"
274625Sgm89044 
284625Sgm89044 #include <sys/types.h>
294625Sgm89044 #include <sys/ddi.h>
304625Sgm89044 #include <sys/sunddi.h>
314625Sgm89044 #include <sys/systm.h>
324625Sgm89044 #include <sys/kstat.h>
334625Sgm89044 #include <sys/crypto/common.h>
344625Sgm89044 #include <sys/crypto/spi.h>
354625Sgm89044 #include <sys/n2rng.h>
364625Sgm89044 
374625Sgm89044 /*
384625Sgm89044  * Kernel statistics.
394625Sgm89044  */
404625Sgm89044 static int n2rng_ksupdate(kstat_t *, int);
414625Sgm89044 
424625Sgm89044 /*
434625Sgm89044  * Initialize Kstats.
444625Sgm89044  */
454625Sgm89044 void
n2rng_ksinit(n2rng_t * n2rng)464625Sgm89044 n2rng_ksinit(n2rng_t *n2rng)
474625Sgm89044 {
484625Sgm89044 	int	instance;
49*5650Stwelke 	int	i;
50*5650Stwelke 	int	j;
51*5650Stwelke 	char	buf[64];
524625Sgm89044 
534625Sgm89044 	if (ddi_getprop(DDI_DEV_T_ANY, n2rng->n_dip,
544625Sgm89044 	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "nostats", 0) != 0) {
554625Sgm89044 		/*
564625Sgm89044 		 * sysadmin has explicity disabled stats to prevent
574625Sgm89044 		 * covert channel.
584625Sgm89044 		 */
594625Sgm89044 		return;
604625Sgm89044 	}
614625Sgm89044 
624625Sgm89044 	instance = ddi_get_instance(n2rng->n_dip);
634625Sgm89044 
644625Sgm89044 	/*
654625Sgm89044 	 * Named kstats.
664625Sgm89044 	 */
674625Sgm89044 	n2rng->n_ksp = kstat_create(DRIVER, instance, NULL, "misc",
684625Sgm89044 	    KSTAT_TYPE_NAMED,
694625Sgm89044 	    sizeof (n2rng_stat_t) / sizeof (kstat_named_t),
704625Sgm89044 	    KSTAT_FLAG_WRITABLE);
714625Sgm89044 	if (n2rng->n_ksp == NULL) {
724625Sgm89044 		n2rng_error(n2rng, "unable to create kstats");
734625Sgm89044 	} else {
744625Sgm89044 		n2rng_stat_t *dkp = (n2rng_stat_t *)n2rng->n_ksp->ks_data;
754625Sgm89044 
764625Sgm89044 		kstat_named_init(&dkp->ns_status, "status", KSTAT_DATA_CHAR);
774625Sgm89044 
784625Sgm89044 		kstat_named_init(&dkp->ns_algs[DS_RNGJOBS], "rngjobs",
794625Sgm89044 		    KSTAT_DATA_ULONGLONG);
804625Sgm89044 		kstat_named_init(&dkp->ns_algs[DS_RNGBYTES], "rngbytes",
814625Sgm89044 		    KSTAT_DATA_ULONGLONG);
824625Sgm89044 
83*5650Stwelke 		if (n2rng_iscontrol(n2rng)) {
84*5650Stwelke 
85*5650Stwelke 			for (i = 0; i < n2rng->n_ctl_data->n_num_rngs; i++) {
86*5650Stwelke 				(void) sprintf(buf, "rng%d-state", i);
87*5650Stwelke 				kstat_named_init(&dkp->ns_rngstate[i],
88*5650Stwelke 				    buf, KSTAT_DATA_CHAR);
89*5650Stwelke 				for (j = 0; j < N2RNG_NOSC; j++) {
90*5650Stwelke 					(void) sprintf(buf,
91*5650Stwelke 					    "rng%d-cell%d-bias", i, j);
92*5650Stwelke 					kstat_named_init
93*5650Stwelke 					    (&dkp->ns_rngbias[i][j],
94*5650Stwelke 					    buf, KSTAT_DATA_ULONGLONG);
95*5650Stwelke 					(void) sprintf(buf,
96*5650Stwelke 					    "rng%d-cell%d-entropy", i, j);
97*5650Stwelke 					kstat_named_init
98*5650Stwelke 					    (&dkp->ns_rngentropy[i][j],
99*5650Stwelke 					    buf, KSTAT_DATA_ULONGLONG);
100*5650Stwelke 				}
101*5650Stwelke 			}
102*5650Stwelke 		}
1034625Sgm89044 		n2rng->n_ksp->ks_update = n2rng_ksupdate;
1044625Sgm89044 		n2rng->n_ksp->ks_private = n2rng;
1054625Sgm89044 
1064625Sgm89044 		kstat_install(n2rng->n_ksp);
1074625Sgm89044 	}
1084625Sgm89044 }
1094625Sgm89044 
1104625Sgm89044 /*
1114625Sgm89044  * Deinitialize Kstats.
1124625Sgm89044  */
1134625Sgm89044 void
n2rng_ksdeinit(n2rng_t * n2rng)1144625Sgm89044 n2rng_ksdeinit(n2rng_t *n2rng)
1154625Sgm89044 {
1164625Sgm89044 
1174625Sgm89044 	if (n2rng->n_ksp != NULL) {
1184625Sgm89044 		kstat_delete(n2rng->n_ksp);
1194625Sgm89044 		n2rng->n_ksp = NULL;
1204625Sgm89044 	}
1214625Sgm89044 }
1224625Sgm89044 
1234625Sgm89044 /*
1244625Sgm89044  * Update Kstats.
1254625Sgm89044  */
1264625Sgm89044 int
n2rng_ksupdate(kstat_t * ksp,int rw)1274625Sgm89044 n2rng_ksupdate(kstat_t *ksp, int rw)
1284625Sgm89044 {
1294625Sgm89044 	n2rng_t		*n2rng;
1304625Sgm89044 	n2rng_stat_t	*dkp;
1314625Sgm89044 	int		i;
132*5650Stwelke 	int		j;
1334625Sgm89044 
1344625Sgm89044 	n2rng = (n2rng_t *)ksp->ks_private;
1354625Sgm89044 	dkp = (n2rng_stat_t *)ksp->ks_data;
1364625Sgm89044 
1374625Sgm89044 	if (rw == KSTAT_WRITE) {
1384625Sgm89044 		for (i = 0; i < DS_MAX; i++) {
1394625Sgm89044 			n2rng->n_stats[i] = dkp->ns_algs[i].value.ull;
1404625Sgm89044 		}
1414625Sgm89044 	} else {
1424625Sgm89044 		/* handy status value */
143*5650Stwelke 		if (n2rng_isfailed(n2rng)) {
1444625Sgm89044 			/* device has failed */
145*5650Stwelke 			(void) strcpy(dkp->ns_status.value.c, "failed");
146*5650Stwelke 		} else if (!n2rng_isconfigured(n2rng)) {
147*5650Stwelke 			/* device is not configured */
148*5650Stwelke 			(void) strcpy(dkp->ns_status.value.c, "offline");
1494625Sgm89044 		} else {
1504625Sgm89044 			/* everything looks good */
1514625Sgm89044 			(void) strcpy(dkp->ns_status.value.c, "online");
1524625Sgm89044 		}
1534625Sgm89044 
1544625Sgm89044 		for (i = 0; i < DS_MAX; i++) {
1554625Sgm89044 			dkp->ns_algs[i].value.ull = n2rng->n_stats[i];
1564625Sgm89044 		}
157*5650Stwelke 
158*5650Stwelke 		if (n2rng_iscontrol(n2rng)) {
159*5650Stwelke 			rng_entry_t *rng;
160*5650Stwelke 
161*5650Stwelke 			for (i = 0; i < n2rng->n_ctl_data->n_num_rngs; i++) {
162*5650Stwelke 
163*5650Stwelke 				rng = &n2rng->n_ctl_data->n_rngs[i];
164*5650Stwelke 
165*5650Stwelke 				switch (rng->n_rng_state) {
166*5650Stwelke 				case CTL_STATE_ERROR:
167*5650Stwelke 					(void) strcpy(
168*5650Stwelke 					    dkp->ns_rngstate[i].value.c,
169*5650Stwelke 					    "error");
170*5650Stwelke 					break;
171*5650Stwelke 				case CTL_STATE_HEALTHCHECK:
172*5650Stwelke 					(void) strcpy(
173*5650Stwelke 					    dkp->ns_rngstate[i].value.c,
174*5650Stwelke 					    "healthcheck");
175*5650Stwelke 					break;
176*5650Stwelke 				case CTL_STATE_CONFIGURED:
177*5650Stwelke 					(void) strcpy(
178*5650Stwelke 					    dkp->ns_rngstate[i].value.c,
179*5650Stwelke 					    "online");
180*5650Stwelke 					break;
181*5650Stwelke 				case CTL_STATE_UNCONFIGURED:
182*5650Stwelke 					(void) strcpy(
183*5650Stwelke 					    dkp->ns_rngstate[i].value.c,
184*5650Stwelke 					    "offline");
185*5650Stwelke 					break;
186*5650Stwelke 				default:
187*5650Stwelke 					(void) strcpy(
188*5650Stwelke 					    dkp->ns_rngstate[i].value.c,
189*5650Stwelke 					    "unknown");
190*5650Stwelke 					break;
191*5650Stwelke 				}
192*5650Stwelke 				for (j = 0; j < N2RNG_NOSC; j++) {
193*5650Stwelke 					dkp->ns_rngbias[i][j].value.ull =
194*5650Stwelke 					    rng->n_bias_info[j].bias;
195*5650Stwelke 					dkp->ns_rngentropy[i][j].value.ull =
196*5650Stwelke 					    rng->n_bias_info[j].entropy;
197*5650Stwelke 				}
198*5650Stwelke 			}
199*5650Stwelke 		}
2004625Sgm89044 	}
2014625Sgm89044 
2024625Sgm89044 	return (0);
2034625Sgm89044 }
204