1*906Sgm89044 /*
2*906Sgm89044 * CDDL HEADER START
3*906Sgm89044 *
4*906Sgm89044 * The contents of this file are subject to the terms of the
5*906Sgm89044 * Common Development and Distribution License (the "License").
6*906Sgm89044 * You may not use this file except in compliance with the License.
7*906Sgm89044 *
8*906Sgm89044 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*906Sgm89044 * or http://www.opensolaris.org/os/licensing.
10*906Sgm89044 * See the License for the specific language governing permissions
11*906Sgm89044 * and limitations under the License.
12*906Sgm89044 *
13*906Sgm89044 * When distributing Covered Code, include this CDDL HEADER in each
14*906Sgm89044 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*906Sgm89044 * If applicable, add the following below this CDDL HEADER, with the
16*906Sgm89044 * fields enclosed by brackets "[]" replaced with your own identifying
17*906Sgm89044 * information: Portions Copyright [yyyy] [name of copyright owner]
18*906Sgm89044 *
19*906Sgm89044 * CDDL HEADER END
20*906Sgm89044 */
21*906Sgm89044
22*906Sgm89044 /*
23*906Sgm89044 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*906Sgm89044 * Use is subject to license terms.
25*906Sgm89044 */
26*906Sgm89044
27*906Sgm89044 #pragma ident "%Z%%M% %I% %E% SMI"
28*906Sgm89044
29*906Sgm89044 /*
30*906Sgm89044 * Deimos - cryptographic acceleration based upon Broadcom 582x.
31*906Sgm89044 */
32*906Sgm89044
33*906Sgm89044 #include <sys/types.h>
34*906Sgm89044 #include <sys/ddi.h>
35*906Sgm89044 #include <sys/sunddi.h>
36*906Sgm89044 #include <sys/kstat.h>
37*906Sgm89044 #include <sys/crypto/dca.h>
38*906Sgm89044
39*906Sgm89044 /*
40*906Sgm89044 * Kernel statistics.
41*906Sgm89044 */
42*906Sgm89044 static int dca_ksupdate(kstat_t *, int);
43*906Sgm89044
44*906Sgm89044 /*
45*906Sgm89044 * Initialize Kstats.
46*906Sgm89044 */
47*906Sgm89044 void
dca_ksinit(dca_t * dca)48*906Sgm89044 dca_ksinit(dca_t *dca)
49*906Sgm89044 {
50*906Sgm89044 char buf[64];
51*906Sgm89044 int instance;
52*906Sgm89044
53*906Sgm89044 if (ddi_getprop(DDI_DEV_T_ANY, dca->dca_dip,
54*906Sgm89044 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "nostats", 0) != 0) {
55*906Sgm89044 /*
56*906Sgm89044 * sysadmin has explicity disabled stats to prevent
57*906Sgm89044 * covert channel.
58*906Sgm89044 */
59*906Sgm89044 return;
60*906Sgm89044 }
61*906Sgm89044
62*906Sgm89044 instance = ddi_get_instance(dca->dca_dip);
63*906Sgm89044
64*906Sgm89044 /*
65*906Sgm89044 * Interrupt kstats.
66*906Sgm89044 */
67*906Sgm89044 (void) sprintf(buf, "%sc%d", DRIVER, instance);
68*906Sgm89044 if ((dca->dca_intrstats = kstat_create(DRIVER, instance, buf,
69*906Sgm89044 "controller", KSTAT_TYPE_INTR, 1, 0)) == NULL) {
70*906Sgm89044 dca_error(dca, "unable to create interrupt kstat");
71*906Sgm89044 } else {
72*906Sgm89044 kstat_install(dca->dca_intrstats);
73*906Sgm89044 }
74*906Sgm89044
75*906Sgm89044 /*
76*906Sgm89044 * Named kstats.
77*906Sgm89044 */
78*906Sgm89044 if ((dca->dca_ksp = kstat_create(DRIVER, instance, NULL, "misc",
79*906Sgm89044 KSTAT_TYPE_NAMED, sizeof (dca_stat_t) / sizeof (kstat_named_t),
80*906Sgm89044 KSTAT_FLAG_WRITABLE)) == NULL) {
81*906Sgm89044 dca_error(dca, "unable to create kstats");
82*906Sgm89044 } else {
83*906Sgm89044 dca_stat_t *dkp = (dca_stat_t *)dca->dca_ksp->ks_data;
84*906Sgm89044 kstat_named_init(&dkp->ds_status, "status", KSTAT_DATA_CHAR);
85*906Sgm89044 kstat_named_init(&dkp->ds_mcr[0].ds_submit, "mcr1submit",
86*906Sgm89044 KSTAT_DATA_ULONGLONG);
87*906Sgm89044 kstat_named_init(&dkp->ds_mcr[0].ds_flowctl, "mcr1flowctl",
88*906Sgm89044 KSTAT_DATA_ULONGLONG);
89*906Sgm89044 kstat_named_init(&dkp->ds_mcr[0].ds_lowater, "mcr1lowater",
90*906Sgm89044 KSTAT_DATA_ULONGLONG);
91*906Sgm89044 kstat_named_init(&dkp->ds_mcr[0].ds_hiwater, "mcr1hiwater",
92*906Sgm89044 KSTAT_DATA_ULONGLONG);
93*906Sgm89044 kstat_named_init(&dkp->ds_mcr[0].ds_maxreqs, "mcr1maxreqs",
94*906Sgm89044 KSTAT_DATA_ULONGLONG);
95*906Sgm89044 kstat_named_init(&dkp->ds_mcr[1].ds_submit, "mcr2submit",
96*906Sgm89044 KSTAT_DATA_ULONGLONG);
97*906Sgm89044 kstat_named_init(&dkp->ds_mcr[1].ds_flowctl, "mcr2flowctl",
98*906Sgm89044 KSTAT_DATA_ULONGLONG);
99*906Sgm89044 kstat_named_init(&dkp->ds_mcr[1].ds_lowater, "mcr2lowater",
100*906Sgm89044 KSTAT_DATA_ULONGLONG);
101*906Sgm89044 kstat_named_init(&dkp->ds_mcr[1].ds_hiwater, "mcr2hiwater",
102*906Sgm89044 KSTAT_DATA_ULONGLONG);
103*906Sgm89044 kstat_named_init(&dkp->ds_mcr[1].ds_maxreqs, "mcr2maxreqs",
104*906Sgm89044 KSTAT_DATA_ULONGLONG);
105*906Sgm89044 #ifdef DS_RC4JOBS
106*906Sgm89044 /* rc4 */
107*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RC4JOBS], "rc4jobs",
108*906Sgm89044 KSTAT_DATA_ULONGLONG);
109*906Sgm89044 #endif
110*906Sgm89044 #ifdef DS_RC4BYTES
111*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RC4BYTES], "rc4bytes",
112*906Sgm89044 KSTAT_DATA_ULONGLONG);
113*906Sgm89044 #endif
114*906Sgm89044 /* 3des */
115*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_3DESJOBS], "3desjobs",
116*906Sgm89044 KSTAT_DATA_ULONGLONG);
117*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_3DESBYTES], "3desbytes",
118*906Sgm89044 KSTAT_DATA_ULONGLONG);
119*906Sgm89044 /* rsa */
120*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RSAPUBLIC], "rsapublic",
121*906Sgm89044 KSTAT_DATA_ULONGLONG);
122*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RSAPRIVATE], "rsaprivate",
123*906Sgm89044 KSTAT_DATA_ULONGLONG);
124*906Sgm89044 /* dsa */
125*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_DSASIGN], "dsasign",
126*906Sgm89044 KSTAT_DATA_ULONGLONG);
127*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_DSAVERIFY], "dsaverify",
128*906Sgm89044 KSTAT_DATA_ULONGLONG);
129*906Sgm89044 #ifdef DS_DHPUBLIC
130*906Sgm89044 /* diffie-hellman */
131*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_DHPUBLIC], "dhpublic",
132*906Sgm89044 KSTAT_DATA_ULONGLONG);
133*906Sgm89044 #endif
134*906Sgm89044 #ifdef DS_DHSECRET
135*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_DHSECRET], "dhsecret",
136*906Sgm89044 KSTAT_DATA_ULONGLONG);
137*906Sgm89044 #endif
138*906Sgm89044 /* random number jobs */
139*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RNGJOBS], "rngjobs",
140*906Sgm89044 KSTAT_DATA_ULONGLONG);
141*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RNGBYTES], "rngbytes",
142*906Sgm89044 KSTAT_DATA_ULONGLONG);
143*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RNGSHA1JOBS], "rngsha1jobs",
144*906Sgm89044 KSTAT_DATA_ULONGLONG);
145*906Sgm89044 kstat_named_init(&dkp->ds_algs[DS_RNGSHA1BYTES],
146*906Sgm89044 "rngsha1bytes", KSTAT_DATA_ULONGLONG);
147*906Sgm89044 dca->dca_ksp->ks_update = dca_ksupdate;
148*906Sgm89044 dca->dca_ksp->ks_private = dca;
149*906Sgm89044 kstat_install(dca->dca_ksp);
150*906Sgm89044 }
151*906Sgm89044 }
152*906Sgm89044
153*906Sgm89044 /*
154*906Sgm89044 * Update Kstats.
155*906Sgm89044 */
156*906Sgm89044 int
dca_ksupdate(kstat_t * ksp,int rw)157*906Sgm89044 dca_ksupdate(kstat_t *ksp, int rw)
158*906Sgm89044 {
159*906Sgm89044 dca_t *dca;
160*906Sgm89044 dca_stat_t *dkp;
161*906Sgm89044 int i;
162*906Sgm89044
163*906Sgm89044 dca = (dca_t *)ksp->ks_private;
164*906Sgm89044 dkp = (dca_stat_t *)ksp->ks_data;
165*906Sgm89044
166*906Sgm89044 if (rw == KSTAT_WRITE) {
167*906Sgm89044 for (i = 0; i < DS_MAX; i++) {
168*906Sgm89044 dca->dca_stats[i] = dkp->ds_algs[i].value.ull;
169*906Sgm89044 }
170*906Sgm89044 for (i = MCR1; i <= MCR2; i++) {
171*906Sgm89044 WORKLIST(dca, i)->dwl_submit =
172*906Sgm89044 dkp->ds_mcr[i - 1].ds_submit.value.ull;
173*906Sgm89044 WORKLIST(dca, i)->dwl_flowctl =
174*906Sgm89044 dkp->ds_mcr[i - 1].ds_flowctl.value.ull;
175*906Sgm89044 /* hiwater, lowater, and maxreqs are read only */
176*906Sgm89044 }
177*906Sgm89044 } else {
178*906Sgm89044 /* handy status value */
179*906Sgm89044 if (dca->dca_flags & DCA_FAILED) {
180*906Sgm89044 /* device has failed */
181*906Sgm89044 (void) strcpy(dkp->ds_status.value.c, "fail");
182*906Sgm89044 } else if ((WORKLIST(dca, MCR1)->dwl_drain) ||
183*906Sgm89044 (WORKLIST(dca, MCR2)->dwl_drain)) {
184*906Sgm89044 /* device is draining for DR */
185*906Sgm89044 (void) strcpy(dkp->ds_status.value.c, "drain");
186*906Sgm89044 } else {
187*906Sgm89044 /* everything looks good */
188*906Sgm89044 (void) strcpy(dkp->ds_status.value.c, "online");
189*906Sgm89044 }
190*906Sgm89044
191*906Sgm89044 for (i = 0; i < DS_MAX; i++) {
192*906Sgm89044 dkp->ds_algs[i].value.ull = dca->dca_stats[i];
193*906Sgm89044 }
194*906Sgm89044 for (i = MCR1; i <= MCR2; i++) {
195*906Sgm89044 dkp->ds_mcr[i - 1].ds_submit.value.ull =
196*906Sgm89044 WORKLIST(dca, i)->dwl_submit;
197*906Sgm89044 dkp->ds_mcr[i - 1].ds_flowctl.value.ull =
198*906Sgm89044 WORKLIST(dca, i)->dwl_flowctl;
199*906Sgm89044 dkp->ds_mcr[i - 1].ds_lowater.value.ull =
200*906Sgm89044 WORKLIST(dca, i)->dwl_lowater;
201*906Sgm89044 dkp->ds_mcr[i - 1].ds_hiwater.value.ull =
202*906Sgm89044 WORKLIST(dca, i)->dwl_hiwater;
203*906Sgm89044 dkp->ds_mcr[i - 1].ds_maxreqs.value.ull =
204*906Sgm89044 WORKLIST(dca, i)->dwl_reqspermcr;
205*906Sgm89044 }
206*906Sgm89044 }
207*906Sgm89044 return (0);
208*906Sgm89044 }
209