summaryrefslogtreecommitdiffstats
path: root/sys/dev/hifn
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2004-10-15 00:36:07 +0000
committersam <sam@FreeBSD.org>2004-10-15 00:36:07 +0000
commitdaa06a78b6389b276f2d2e1283273ef8f4f623d5 (patch)
tree7d0579fc73c46933cfc8c6090ea191128c59ef5c /sys/dev/hifn
parenta76b21d1d4525da5833d6ee1cee37363bd8023eb (diff)
downloadFreeBSD-src-daa06a78b6389b276f2d2e1283273ef8f4f623d5.zip
FreeBSD-src-daa06a78b6389b276f2d2e1283273ef8f4f623d5.tar.gz
Move session state from on-card memory to host memory so we no longer are
constrained to a small number of sessions by the small on-card memories found in newer devices. This is really a stopgap solution as having session state in main memory incurs a (small but noticeable) performance penalty. The better solution is to manage session state so that it's cached on chip. Obtained from: openbsd
Diffstat (limited to 'sys/dev/hifn')
-rw-r--r--sys/dev/hifn/hifn7751.c78
-rw-r--r--sys/dev/hifn/hifn7751var.h11
2 files changed, 46 insertions, 43 deletions
diff --git a/sys/dev/hifn/hifn7751.c b/sys/dev/hifn/hifn7751.c
index c2b5fc9..be57625 100644
--- a/sys/dev/hifn/hifn7751.c
+++ b/sys/dev/hifn/hifn7751.c
@@ -465,10 +465,9 @@ hifn_attach(device_t dev)
rbase = 'M';
rseg /= 1024;
}
- device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram, %u sessions\n",
+ device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram\n",
hifn_partname(sc), rev,
- rseg, rbase, sc->sc_drammodel ? 'd' : 's',
- sc->sc_maxses);
+ rseg, rbase, sc->sc_drammodel ? 'd' : 's');
sc->sc_cid = crypto_get_driverid(0);
if (sc->sc_cid < 0) {
@@ -1465,7 +1464,7 @@ hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
dlen >>= 16;
slen >>= 16;
- base_cmd->session_num = htole16(cmd->session_num |
+ base_cmd->session_num = htole16(
((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
buf_pos += sizeof(hifn_base_command_t);
@@ -2207,17 +2206,44 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
{
struct cryptoini *c;
struct hifn_softc *sc = arg;
- int i, mac = 0, cry = 0;
+ int mac = 0, cry = 0, sesn;
+ struct hifn_session *ses = NULL
KASSERT(sc != NULL, ("hifn_newsession: null softc"));
if (sidp == NULL || cri == NULL || sc == NULL)
return (EINVAL);
- for (i = 0; i < sc->sc_maxses; i++)
- if (sc->sc_sessions[i].hs_state == HS_STATE_FREE)
- break;
- if (i == sc->sc_maxses)
- return (ENOMEM);
+ if (sc->sc_sessions == NULL) {
+ ses = sc->sc_sessions = (struct hifn_session *)malloc(
+ sizeof(*ses), M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ sesn = 0;
+ sc->sc_nsessions = 1;
+ } else {
+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
+ if (!sc->sc_sessions[sesn].hs_used) {
+ ses = &sc->sc_sessions[sesn];
+ break;
+ }
+ }
+
+ if (ses == NULL) {
+ sesn = sc->sc_nsessions;
+ ses = (struct hifn_session *)malloc((sesn + 1) *
+ sizeof(*ses), M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
+ bzero(sc->sc_sessions, sesn * sizeof(*ses));
+ free(sc->sc_sessions, M_DEVBUF);
+ sc->sc_sessions = ses;
+ ses = &sc->sc_sessions[sesn];
+ sc->sc_nsessions++;
+ }
+ }
+ bzero(ses, sizeof(*ses));
+ ses->hs_used = 1;
for (c = cri; c != NULL; c = c->cri_next) {
switch (c->cri_alg) {
@@ -2233,7 +2259,7 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
case CRYPTO_3DES_CBC:
case CRYPTO_AES_CBC:
/* XXX this may read fewer, does it matter? */
- read_random(sc->sc_sessions[i].hs_iv,
+ read_random(ses->hs_iv,
c->cri_alg == CRYPTO_AES_CBC ?
HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
/*FALLTHROUGH*/
@@ -2249,8 +2275,7 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
if (mac == 0 && cry == 0)
return (EINVAL);
- *sidp = HIFN_SID(device_get_unit(sc->sc_dev), i);
- sc->sc_sessions[i].hs_state = HS_STATE_USED;
+ *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
return (0);
}
@@ -2272,7 +2297,7 @@ hifn_freesession(void *arg, u_int64_t tid)
return (EINVAL);
session = HIFN_SESSION(sid);
- if (session >= sc->sc_maxses)
+ if (session >= sc->sc_nsessions)
return (EINVAL);
bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
@@ -2293,7 +2318,7 @@ hifn_process(void *arg, struct cryptop *crp, int hint)
}
session = HIFN_SESSION(crp->crp_sid);
- if (sc == NULL || session >= sc->sc_maxses) {
+ if (sc == NULL || session >= sc->sc_nsessions) {
err = EINVAL;
goto errout;
}
@@ -2381,10 +2406,6 @@ hifn_process(void *arg, struct cryptop *crp, int hint)
switch (enccrd->crd_alg) {
case CRYPTO_ARC4:
cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
- if ((enccrd->crd_flags & CRD_F_ENCRYPT)
- != sc->sc_sessions[session].hs_prev_op)
- sc->sc_sessions[session].hs_state =
- HS_STATE_USED;
break;
case CRYPTO_DES_CBC:
cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
@@ -2442,6 +2463,7 @@ hifn_process(void *arg, struct cryptop *crp, int hint)
cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
cmd->ck = enccrd->crd_key;
cmd->cklen = enccrd->crd_klen >> 3;
+ cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
/*
* Need to specify the size for the AES key in the masks.
@@ -2463,9 +2485,6 @@ hifn_process(void *arg, struct cryptop *crp, int hint)
goto errout;
}
}
-
- if (sc->sc_sessions[session].hs_state == HS_STATE_USED)
- cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
}
if (maccrd) {
@@ -2495,9 +2514,8 @@ hifn_process(void *arg, struct cryptop *crp, int hint)
break;
}
- if ((maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
- maccrd->crd_alg == CRYPTO_MD5_HMAC) &&
- sc->sc_sessions[session].hs_state == HS_STATE_USED) {
+ if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
+ maccrd->crd_alg == CRYPTO_MD5_HMAC) {
cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
bzero(cmd->mac + (maccrd->crd_klen >> 3),
@@ -2511,11 +2529,6 @@ hifn_process(void *arg, struct cryptop *crp, int hint)
err = hifn_crypto(sc, cmd, crp, hint);
if (!err) {
- if (enccrd)
- sc->sc_sessions[session].hs_prev_op =
- enccrd->crd_flags & CRD_F_ENCRYPT;
- if (sc->sc_sessions[session].hs_state == HS_STATE_USED)
- sc->sc_sessions[session].hs_state = HS_STATE_KEY;
return 0;
} else if (err == ERESTART) {
/*
@@ -2612,11 +2625,6 @@ hifn_abort(struct hifn_softc *sc)
}
dma->resk = i; dma->resu = u;
- /* Force upload of key next time */
- for (i = 0; i < sc->sc_maxses; i++)
- if (sc->sc_sessions[i].hs_state == HS_STATE_KEY)
- sc->sc_sessions[i].hs_state = HS_STATE_USED;
-
hifn_reset_board(sc, 1);
hifn_init_dma(sc);
hifn_init_pci_registers(sc);
diff --git a/sys/dev/hifn/hifn7751var.h b/sys/dev/hifn/hifn7751var.h
index b40b819..e3bd2f6 100644
--- a/sys/dev/hifn/hifn7751var.h
+++ b/sys/dev/hifn/hifn7751var.h
@@ -111,8 +111,7 @@ struct hifn_dma {
};
struct hifn_session {
- int hs_state;
- int hs_prev_op; /* XXX collapse into hs_flags? */
+ int hs_used;
u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
};
@@ -130,11 +129,6 @@ struct hifn_session {
#define HIFN_RES_SYNC(sc, i, f) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f))
-/* We use a state machine to on sessions */
-#define HS_STATE_FREE 0 /* unused session entry */
-#define HS_STATE_USED 1 /* allocated, but key not on card */
-#define HS_STATE_KEY 2 /* allocated and key is on card */
-
/*
* Holds data specific to a single HIFN board.
*/
@@ -164,6 +158,8 @@ struct hifn_softc {
int sc_dmansegs;
int32_t sc_cid;
int sc_maxses;
+ int sc_nsessions;
+ struct hifn_session *sc_sessions;
int sc_ramsize;
int sc_flags;
#define HIFN_HAS_RNG 0x1 /* includes random number generator */
@@ -186,7 +182,6 @@ struct hifn_softc {
int sc_needwakeup; /* ops q'd wating on resources */
int sc_curbatch; /* # ops submitted w/o int */
int sc_suspended;
- struct hifn_session sc_sessions[2048];
};
#define HIFN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
OpenPOWER on IntegriCloud