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