Lines 40-49
__FBSDID("$FreeBSD: src/sys/dev/glxsb/gl
Link Here
|
40 |
#include <sys/random.h> |
40 |
#include <sys/random.h> |
41 |
#include <sys/rman.h> |
41 |
#include <sys/rman.h> |
42 |
#include <sys/rwlock.h> |
42 |
#include <sys/rwlock.h> |
43 |
#include <sys/sysctl.h> |
43 |
#include <sys/sysctl.h> |
44 |
#include <sys/taskqueue.h> |
44 |
#include <sys/taskqueue.h> |
|
|
45 |
#include <vm/uma.h> |
45 |
|
46 |
|
46 |
#include <machine/bus.h> |
47 |
#include <machine/bus.h> |
47 |
#include <machine/cpufunc.h> |
48 |
#include <machine/cpufunc.h> |
48 |
#include <machine/resource.h> |
49 |
#include <machine/resource.h> |
49 |
|
50 |
|
Lines 172-181
struct glxsb_dma_map {
Link Here
|
172 |
struct glxsb_taskop { |
173 |
struct glxsb_taskop { |
173 |
struct glxsb_session *to_ses; /* crypto session */ |
174 |
struct glxsb_session *to_ses; /* crypto session */ |
174 |
struct cryptop *to_crp; /* cryptop to perfom */ |
175 |
struct cryptop *to_crp; /* cryptop to perfom */ |
175 |
struct cryptodesc *to_enccrd; /* enccrd to perform */ |
176 |
struct cryptodesc *to_enccrd; /* enccrd to perform */ |
176 |
struct cryptodesc *to_maccrd; /* maccrd to perform */ |
177 |
struct cryptodesc *to_maccrd; /* maccrd to perform */ |
|
|
178 |
TAILQ_ENTRY(glxsb_taskop) to_next; |
177 |
}; |
179 |
}; |
178 |
|
180 |
|
179 |
struct glxsb_softc { |
181 |
struct glxsb_softc { |
180 |
device_t sc_dev; /* device backpointer */ |
182 |
device_t sc_dev; /* device backpointer */ |
181 |
struct resource *sc_sr; /* resource */ |
183 |
struct resource *sc_sr; /* resource */ |
Lines 190-201
struct glxsb_softc {
Link Here
|
190 |
sc_sessions; /* crypto sessions */ |
192 |
sc_sessions; /* crypto sessions */ |
191 |
struct rwlock sc_sessions_lock;/* sessions lock */ |
193 |
struct rwlock sc_sessions_lock;/* sessions lock */ |
192 |
struct mtx sc_task_mtx; /* task mutex */ |
194 |
struct mtx sc_task_mtx; /* task mutex */ |
193 |
struct taskqueue *sc_tq; /* task queue */ |
195 |
struct taskqueue *sc_tq; /* task queue */ |
194 |
struct task sc_cryptotask; /* task */ |
196 |
struct task sc_cryptotask; /* task */ |
195 |
struct glxsb_taskop sc_to; /* task's crypto operation */ |
197 |
TAILQ_HEAD(to_head, glxsb_taskop) |
196 |
int sc_task_count; /* tasks count */ |
198 |
sc_taskops; /* tasks operations */ |
|
|
199 |
uma_zone_t sc_taskops_zone;/* tasks operations' zone */ |
197 |
}; |
200 |
}; |
198 |
|
201 |
|
199 |
static int glxsb_probe(device_t); |
202 |
static int glxsb_probe(device_t); |
200 |
static int glxsb_attach(device_t); |
203 |
static int glxsb_attach(device_t); |
201 |
static int glxsb_detach(device_t); |
204 |
static int glxsb_detach(device_t); |
Lines 347-363
static int
Link Here
|
347 |
glxsb_detach(device_t dev) |
350 |
glxsb_detach(device_t dev) |
348 |
{ |
351 |
{ |
349 |
struct glxsb_softc *sc = device_get_softc(dev); |
352 |
struct glxsb_softc *sc = device_get_softc(dev); |
350 |
struct glxsb_session *ses; |
353 |
struct glxsb_session *ses; |
351 |
|
354 |
|
|
|
355 |
/* do not detach if there are pending tasks */ |
356 |
if (!mtx_trylock(&sc->sc_task_mtx)) |
357 |
goto busy; |
358 |
if (!TAILQ_EMPTY(&sc->sc_taskops)) { |
359 |
mtx_unlock(&sc->sc_task_mtx); |
360 |
goto busy; |
361 |
} |
362 |
mtx_unlock(&sc->sc_task_mtx); |
363 |
|
364 |
/* do not detach if there are active sessions */ |
352 |
rw_wlock(&sc->sc_sessions_lock); |
365 |
rw_wlock(&sc->sc_sessions_lock); |
353 |
TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) { |
366 |
TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) { |
354 |
if (ses->ses_used) { |
367 |
if (ses->ses_used) { |
355 |
rw_wunlock(&sc->sc_sessions_lock); |
368 |
rw_wunlock(&sc->sc_sessions_lock); |
356 |
device_printf(dev, |
369 |
goto busy; |
357 |
"cannot detach, sessions still active.\n"); |
|
|
358 |
return (EBUSY); |
359 |
} |
370 |
} |
360 |
} |
371 |
} |
361 |
while (!TAILQ_EMPTY(&sc->sc_sessions)) { |
372 |
while (!TAILQ_EMPTY(&sc->sc_sessions)) { |
362 |
ses = TAILQ_FIRST(&sc->sc_sessions); |
373 |
ses = TAILQ_FIRST(&sc->sc_sessions); |
363 |
TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next); |
374 |
TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next); |
Lines 371-381
glxsb_detach(device_t dev)
Link Here
|
371 |
glxsb_dma_free(sc, &sc->sc_dma); |
382 |
glxsb_dma_free(sc, &sc->sc_dma); |
372 |
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_sr); |
383 |
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_sr); |
373 |
taskqueue_free(sc->sc_tq); |
384 |
taskqueue_free(sc->sc_tq); |
374 |
rw_destroy(&sc->sc_sessions_lock); |
385 |
rw_destroy(&sc->sc_sessions_lock); |
375 |
mtx_destroy(&sc->sc_task_mtx); |
386 |
mtx_destroy(&sc->sc_task_mtx); |
|
|
387 |
uma_zdestroy(sc->sc_taskops_zone); |
376 |
return (0); |
388 |
return (0); |
|
|
389 |
|
390 |
busy: |
391 |
device_printf(dev, |
392 |
"cannot detach, sessions still active.\n"); |
393 |
return (EBUSY); |
377 |
} |
394 |
} |
378 |
|
395 |
|
379 |
/* |
396 |
/* |
380 |
* callback for bus_dmamap_load() |
397 |
* callback for bus_dmamap_load() |
381 |
*/ |
398 |
*/ |
Lines 493-505
glxsb_crypto_setup(struct glxsb_softc *s
Link Here
|
493 |
return (ENOMEM); |
510 |
return (ENOMEM); |
494 |
} |
511 |
} |
495 |
|
512 |
|
496 |
TAILQ_INIT(&sc->sc_sessions); |
513 |
TAILQ_INIT(&sc->sc_sessions); |
497 |
sc->sc_sid = 1; |
514 |
sc->sc_sid = 1; |
|
|
515 |
TAILQ_INIT(&sc->sc_taskops); |
516 |
sc->sc_taskops_zone = uma_zcreate("glxsb_taskop", |
517 |
sizeof(struct glxsb_taskop), 0, 0, 0, 0, |
518 |
UMA_ALIGN_PTR, UMA_ZONE_ZINIT); |
498 |
rw_init(&sc->sc_sessions_lock, "glxsb_sessions_lock"); |
519 |
rw_init(&sc->sc_sessions_lock, "glxsb_sessions_lock"); |
499 |
mtx_init(&sc->sc_task_mtx, "glxsb_crypto_mtx", NULL, MTX_DEF); |
520 |
mtx_init(&sc->sc_task_mtx, "glxsb_crypto_mtx", NULL, MTX_DEF); |
500 |
|
521 |
|
|
|
522 |
if (sc->sc_taskops_zone == NULL) { |
523 |
device_printf(sc->sc_dev, "cannot setup taskops zone\n"); |
524 |
goto crypto_fail; |
525 |
} |
501 |
if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0) |
526 |
if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0) |
502 |
goto crypto_fail; |
527 |
goto crypto_fail; |
503 |
if (crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0) != 0) |
528 |
if (crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0) != 0) |
504 |
goto crypto_fail; |
529 |
goto crypto_fail; |
505 |
if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0) |
530 |
if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0) |
Lines 520-529
glxsb_crypto_setup(struct glxsb_softc *s
Link Here
|
520 |
crypto_fail: |
545 |
crypto_fail: |
521 |
device_printf(sc->sc_dev, "cannot register crypto\n"); |
546 |
device_printf(sc->sc_dev, "cannot register crypto\n"); |
522 |
crypto_unregister_all(sc->sc_cid); |
547 |
crypto_unregister_all(sc->sc_cid); |
523 |
rw_destroy(&sc->sc_sessions_lock); |
548 |
rw_destroy(&sc->sc_sessions_lock); |
524 |
mtx_destroy(&sc->sc_task_mtx); |
549 |
mtx_destroy(&sc->sc_task_mtx); |
|
|
550 |
uma_zdestroy(sc->sc_taskops_zone); |
525 |
return (ENOMEM); |
551 |
return (ENOMEM); |
526 |
} |
552 |
} |
527 |
|
553 |
|
528 |
static int |
554 |
static int |
529 |
glxsb_crypto_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) |
555 |
glxsb_crypto_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri) |
Lines 818-870
glxsb_crypto_encdec(struct cryptop *crp,
Link Here
|
818 |
|
844 |
|
819 |
static void |
845 |
static void |
820 |
glxsb_crypto_task(void *arg, int pending) |
846 |
glxsb_crypto_task(void *arg, int pending) |
821 |
{ |
847 |
{ |
822 |
struct glxsb_softc *sc = arg; |
848 |
struct glxsb_softc *sc = arg; |
|
|
849 |
struct glxsb_taskop *taskop; |
823 |
struct glxsb_session *ses; |
850 |
struct glxsb_session *ses; |
824 |
struct cryptop *crp; |
851 |
struct cryptop *crp; |
825 |
struct cryptodesc *enccrd, *maccrd; |
852 |
struct cryptodesc *enccrd, *maccrd; |
826 |
int error; |
853 |
int error; |
827 |
|
854 |
|
828 |
maccrd = sc->sc_to.to_maccrd; |
855 |
for (; pending > 0; pending--) { |
829 |
enccrd = sc->sc_to.to_enccrd; |
856 |
/* pop crypto request */ |
830 |
crp = sc->sc_to.to_crp; |
857 |
mtx_lock(&sc->sc_task_mtx); |
831 |
ses = sc->sc_to.to_ses; |
858 |
taskop = TAILQ_FIRST(&sc->sc_taskops); |
832 |
|
859 |
if (taskop != NULL) { |
833 |
/* Perform data authentication if requested before encryption */ |
860 |
TAILQ_REMOVE(&sc->sc_taskops, taskop, to_next); |
834 |
if (maccrd != NULL && maccrd->crd_next == enccrd) { |
861 |
mtx_unlock(&sc->sc_task_mtx); |
835 |
error = glxsb_hash_process(ses, maccrd, crp); |
862 |
} else { |
836 |
if (error != 0) |
863 |
/* should not happen */ |
837 |
goto out; |
864 |
mtx_unlock(&sc->sc_task_mtx); |
838 |
} |
865 |
continue; |
839 |
|
866 |
} |
840 |
error = glxsb_crypto_encdec(crp, enccrd, ses, sc); |
867 |
maccrd = taskop->to_maccrd; |
841 |
if (error != 0) |
868 |
enccrd = taskop->to_enccrd; |
842 |
goto out; |
869 |
crp = taskop->to_crp; |
|
|
870 |
ses = taskop->to_ses; |
871 |
uma_zfree(sc->sc_taskops_zone, taskop); |
872 |
|
873 |
/* Perform data authentication if requested before encryption */ |
874 |
if (maccrd != NULL && maccrd->crd_next == enccrd) { |
875 |
error = glxsb_hash_process(ses, maccrd, crp); |
876 |
if (error != 0) |
877 |
goto crypto_out; |
878 |
} |
843 |
|
879 |
|
844 |
/* Perform data authentication if requested after encryption */ |
880 |
error = glxsb_crypto_encdec(crp, enccrd, ses, sc); |
845 |
if (maccrd != NULL && enccrd->crd_next == maccrd) { |
|
|
846 |
error = glxsb_hash_process(ses, maccrd, crp); |
847 |
if (error != 0) |
881 |
if (error != 0) |
848 |
goto out; |
882 |
goto crypto_out; |
849 |
} |
|
|
850 |
out: |
851 |
mtx_lock(&sc->sc_task_mtx); |
852 |
sc->sc_task_count--; |
853 |
mtx_unlock(&sc->sc_task_mtx); |
854 |
|
883 |
|
855 |
crp->crp_etype = error; |
884 |
/* Perform data authentication if requested after encryption */ |
856 |
crypto_unblock(sc->sc_cid, CRYPTO_SYMQ); |
885 |
if (maccrd != NULL && enccrd->crd_next == maccrd) { |
857 |
crypto_done(crp); |
886 |
error = glxsb_hash_process(ses, maccrd, crp); |
|
|
887 |
if (error != 0) |
888 |
goto crypto_out; |
889 |
} |
890 |
|
891 |
crypto_out: |
892 |
crp->crp_etype = error; |
893 |
crypto_done(crp); |
894 |
} /* for */ |
858 |
} |
895 |
} |
859 |
|
896 |
|
860 |
static int |
897 |
static int |
861 |
glxsb_crypto_process(device_t dev, struct cryptop *crp, int hint) |
898 |
glxsb_crypto_process(device_t dev, struct cryptop *crp, int hint) |
862 |
{ |
899 |
{ |
863 |
struct glxsb_softc *sc = device_get_softc(dev); |
900 |
struct glxsb_softc *sc = device_get_softc(dev); |
864 |
struct glxsb_session *ses; |
901 |
struct glxsb_session *ses; |
865 |
struct cryptodesc *crd, *enccrd, *maccrd; |
902 |
struct cryptodesc *crd, *enccrd, *maccrd; |
|
|
903 |
struct glxsb_taskop *taskop; |
866 |
uint32_t sid; |
904 |
uint32_t sid; |
867 |
int error = 0; |
905 |
int error = 0; |
868 |
|
906 |
|
869 |
enccrd = maccrd = NULL; |
907 |
enccrd = maccrd = NULL; |
870 |
|
908 |
|
Lines 920-942
glxsb_crypto_process(device_t dev, struc
Link Here
|
920 |
if (ses == NULL || !ses->ses_used) { |
958 |
if (ses == NULL || !ses->ses_used) { |
921 |
error = EINVAL; |
959 |
error = EINVAL; |
922 |
goto fail; |
960 |
goto fail; |
923 |
} |
961 |
} |
924 |
|
962 |
|
|
|
963 |
/* queue the crypto request */ |
925 |
mtx_lock(&sc->sc_task_mtx); |
964 |
mtx_lock(&sc->sc_task_mtx); |
926 |
if (sc->sc_task_count != 0) { |
965 |
taskop = uma_zalloc(sc->sc_taskops_zone, M_NOWAIT); |
|
|
966 |
if (taskop == NULL) { |
927 |
mtx_unlock(&sc->sc_task_mtx); |
967 |
mtx_unlock(&sc->sc_task_mtx); |
928 |
return (ERESTART); |
968 |
error = ENOMEM; |
|
|
969 |
goto fail; |
929 |
} |
970 |
} |
930 |
sc->sc_task_count++; |
971 |
taskop->to_maccrd = maccrd; |
931 |
|
972 |
taskop->to_enccrd = enccrd; |
932 |
sc->sc_to.to_maccrd = maccrd; |
973 |
taskop->to_crp = crp; |
933 |
sc->sc_to.to_enccrd = enccrd; |
974 |
taskop->to_ses = ses; |
934 |
sc->sc_to.to_crp = crp; |
975 |
TAILQ_INSERT_TAIL(&sc->sc_taskops, taskop, to_next); |
935 |
sc->sc_to.to_ses = ses; |
|
|
936 |
mtx_unlock(&sc->sc_task_mtx); |
976 |
mtx_unlock(&sc->sc_task_mtx); |
937 |
|
|
|
938 |
taskqueue_enqueue(sc->sc_tq, &sc->sc_cryptotask); |
977 |
taskqueue_enqueue(sc->sc_tq, &sc->sc_cryptotask); |
939 |
return(0); |
978 |
return(0); |
940 |
|
979 |
|
941 |
fail: |
980 |
fail: |
942 |
crp->crp_etype = error; |
981 |
crp->crp_etype = error; |