diff options
author | sam <sam@FreeBSD.org> | 2004-10-15 00:36:07 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2004-10-15 00:36:07 +0000 |
commit | daa06a78b6389b276f2d2e1283273ef8f4f623d5 (patch) | |
tree | 7d0579fc73c46933cfc8c6090ea191128c59ef5c /sys/dev/hifn | |
parent | a76b21d1d4525da5833d6ee1cee37363bd8023eb (diff) | |
download | FreeBSD-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.c | 78 | ||||
-rw-r--r-- | sys/dev/hifn/hifn7751var.h | 11 |
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) |