#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/kstat.h>
#include <sys/crypto/dca.h>
static int dca_ksupdate(kstat_t *, int);
void
dca_ksinit(dca_t *dca)
{
char buf[64];
int instance;
if (ddi_getprop(DDI_DEV_T_ANY, dca->dca_dip,
DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "nostats", 0) != 0) {
return;
}
instance = ddi_get_instance(dca->dca_dip);
(void) sprintf(buf, "%sc%d", DRIVER, instance);
if ((dca->dca_intrstats = kstat_create(DRIVER, instance, buf,
"controller", KSTAT_TYPE_INTR, 1, 0)) == NULL) {
dca_error(dca, "unable to create interrupt kstat");
} else {
kstat_install(dca->dca_intrstats);
}
if ((dca->dca_ksp = kstat_create(DRIVER, instance, NULL, "misc",
KSTAT_TYPE_NAMED, sizeof (dca_stat_t) / sizeof (kstat_named_t),
KSTAT_FLAG_WRITABLE)) == NULL) {
dca_error(dca, "unable to create kstats");
} else {
dca_stat_t *dkp = (dca_stat_t *)dca->dca_ksp->ks_data;
kstat_named_init(&dkp->ds_status, "status", KSTAT_DATA_CHAR);
kstat_named_init(&dkp->ds_mcr[0].ds_submit, "mcr1submit",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[0].ds_flowctl, "mcr1flowctl",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[0].ds_lowater, "mcr1lowater",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[0].ds_hiwater, "mcr1hiwater",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[0].ds_maxreqs, "mcr1maxreqs",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[1].ds_submit, "mcr2submit",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[1].ds_flowctl, "mcr2flowctl",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[1].ds_lowater, "mcr2lowater",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[1].ds_hiwater, "mcr2hiwater",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_mcr[1].ds_maxreqs, "mcr2maxreqs",
KSTAT_DATA_ULONGLONG);
#ifdef DS_RC4JOBS
kstat_named_init(&dkp->ds_algs[DS_RC4JOBS], "rc4jobs",
KSTAT_DATA_ULONGLONG);
#endif
#ifdef DS_RC4BYTES
kstat_named_init(&dkp->ds_algs[DS_RC4BYTES], "rc4bytes",
KSTAT_DATA_ULONGLONG);
#endif
kstat_named_init(&dkp->ds_algs[DS_3DESJOBS], "3desjobs",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_3DESBYTES], "3desbytes",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_RSAPUBLIC], "rsapublic",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_RSAPRIVATE], "rsaprivate",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_DSASIGN], "dsasign",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_DSAVERIFY], "dsaverify",
KSTAT_DATA_ULONGLONG);
#ifdef DS_DHPUBLIC
kstat_named_init(&dkp->ds_algs[DS_DHPUBLIC], "dhpublic",
KSTAT_DATA_ULONGLONG);
#endif
#ifdef DS_DHSECRET
kstat_named_init(&dkp->ds_algs[DS_DHSECRET], "dhsecret",
KSTAT_DATA_ULONGLONG);
#endif
kstat_named_init(&dkp->ds_algs[DS_RNGJOBS], "rngjobs",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_RNGBYTES], "rngbytes",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_RNGSHA1JOBS], "rngsha1jobs",
KSTAT_DATA_ULONGLONG);
kstat_named_init(&dkp->ds_algs[DS_RNGSHA1BYTES],
"rngsha1bytes", KSTAT_DATA_ULONGLONG);
dca->dca_ksp->ks_update = dca_ksupdate;
dca->dca_ksp->ks_private = dca;
kstat_install(dca->dca_ksp);
}
}
int
dca_ksupdate(kstat_t *ksp, int rw)
{
dca_t *dca;
dca_stat_t *dkp;
int i;
dca = (dca_t *)ksp->ks_private;
dkp = (dca_stat_t *)ksp->ks_data;
if (rw == KSTAT_WRITE) {
for (i = 0; i < DS_MAX; i++) {
dca->dca_stats[i] = dkp->ds_algs[i].value.ull;
}
for (i = MCR1; i <= MCR2; i++) {
WORKLIST(dca, i)->dwl_submit =
dkp->ds_mcr[i - 1].ds_submit.value.ull;
WORKLIST(dca, i)->dwl_flowctl =
dkp->ds_mcr[i - 1].ds_flowctl.value.ull;
}
} else {
if (dca->dca_flags & DCA_FAILED) {
(void) strcpy(dkp->ds_status.value.c, "fail");
} else if ((WORKLIST(dca, MCR1)->dwl_drain) ||
(WORKLIST(dca, MCR2)->dwl_drain)) {
(void) strcpy(dkp->ds_status.value.c, "drain");
} else {
(void) strcpy(dkp->ds_status.value.c, "online");
}
for (i = 0; i < DS_MAX; i++) {
dkp->ds_algs[i].value.ull = dca->dca_stats[i];
}
for (i = MCR1; i <= MCR2; i++) {
dkp->ds_mcr[i - 1].ds_submit.value.ull =
WORKLIST(dca, i)->dwl_submit;
dkp->ds_mcr[i - 1].ds_flowctl.value.ull =
WORKLIST(dca, i)->dwl_flowctl;
dkp->ds_mcr[i - 1].ds_lowater.value.ull =
WORKLIST(dca, i)->dwl_lowater;
dkp->ds_mcr[i - 1].ds_hiwater.value.ull =
WORKLIST(dca, i)->dwl_hiwater;
dkp->ds_mcr[i - 1].ds_maxreqs.value.ull =
WORKLIST(dca, i)->dwl_reqspermcr;
}
}
return (0);
}