Deleted Added
full compact
ubsec.c (108466) ubsec.c (108471)
1/* $FreeBSD: head/sys/dev/ubsec/ubsec.c 108466 2002-12-30 20:22:40Z sam $ */
1/* $FreeBSD: head/sys/dev/ubsec/ubsec.c 108471 2002-12-30 22:16:45Z sam $ */
2/* $OpenBSD: ubsec.c,v 1.115 2002/09/24 18:33:26 jason Exp $ */
3
4/*
5 * Copyright (c) 2000 Jason L. Wright (jason@thought.net)
6 * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org)
7 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com)
8 *
9 * All rights reserved.

--- 166 unchanged lines hidden (view full) ---

176
177#define SWAP32(x) (x) = htole32(ntohl((x)))
178#define HTOLE32(x) (x) = htole32(x)
179
180
181struct ubsec_stats ubsecstats;
182SYSCTL_STRUCT(_kern, OID_AUTO, ubsec_stats, CTLFLAG_RD, &ubsecstats,
183 ubsec_stats, "Broadcom driver statistics");
2/* $OpenBSD: ubsec.c,v 1.115 2002/09/24 18:33:26 jason Exp $ */
3
4/*
5 * Copyright (c) 2000 Jason L. Wright (jason@thought.net)
6 * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org)
7 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com)
8 *
9 * All rights reserved.

--- 166 unchanged lines hidden (view full) ---

176
177#define SWAP32(x) (x) = htole32(ntohl((x)))
178#define HTOLE32(x) (x) = htole32(x)
179
180
181struct ubsec_stats ubsecstats;
182SYSCTL_STRUCT(_kern, OID_AUTO, ubsec_stats, CTLFLAG_RD, &ubsecstats,
183 ubsec_stats, "Broadcom driver statistics");
184static int ubsec_maxbatch = 2; /* XXX tune based on part+sys speed */
184/*
185 * ubsec_maxbatch controls the number of crypto ops to voluntarily
186 * collect into one submission to the hardware. This batching happens
187 * when ops are dispatched from the crypto subsystem with a hint that
188 * more are to follow immediately. These ops must also not be marked
189 * with a ``no delay'' flag.
190 */
191static int ubsec_maxbatch = 1;
185SYSCTL_INT(_kern, OID_AUTO, ubsec_maxbatch, CTLFLAG_RW, &ubsec_maxbatch,
186 0, "Broadcom driver: max ops to batch w/o interrupt");
192SYSCTL_INT(_kern, OID_AUTO, ubsec_maxbatch, CTLFLAG_RW, &ubsec_maxbatch,
193 0, "Broadcom driver: max ops to batch w/o interrupt");
194/*
195 * ubsec_maxaggr controls the number of crypto ops to submit to the
196 * hardware as a unit. This aggregation reduces the number of interrupts
197 * to the host at the expense of increased latency (for all but the last
198 * operation). For network traffic setting this to one yields the highest
199 * performance but at the expense of more interrupt processing.
200 */
201static int ubsec_maxaggr = 1;
202SYSCTL_INT(_kern, OID_AUTO, ubsec_maxaggr, CTLFLAG_RW, &ubsec_maxaggr,
203 0, "Broadcom driver: max ops to aggregate under one interrupt");
187
188static int
189ubsec_probe(device_t dev)
190{
191 if (pci_get_vendor(dev) == PCI_VENDOR_BLUESTEEL &&
192 (pci_get_device(dev) == PCI_PRODUCT_BLUESTEEL_5501 ||
193 pci_get_device(dev) == PCI_PRODUCT_BLUESTEEL_5601))
194 return (0);

--- 361 unchanged lines hidden (view full) ---

556 dmap = q->q_dma;
557
558 if ((dmap->d_dma->d_mcr.mcr_flags & htole16(UBS_MCR_DONE)) == 0)
559 break;
560
561 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q, q_next);
562
563 npkts = q->q_nstacked_mcrs;
204
205static int
206ubsec_probe(device_t dev)
207{
208 if (pci_get_vendor(dev) == PCI_VENDOR_BLUESTEEL &&
209 (pci_get_device(dev) == PCI_PRODUCT_BLUESTEEL_5501 ||
210 pci_get_device(dev) == PCI_PRODUCT_BLUESTEEL_5601))
211 return (0);

--- 361 unchanged lines hidden (view full) ---

573 dmap = q->q_dma;
574
575 if ((dmap->d_dma->d_mcr.mcr_flags & htole16(UBS_MCR_DONE)) == 0)
576 break;
577
578 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q, q_next);
579
580 npkts = q->q_nstacked_mcrs;
581 sc->sc_nqchip -= 1+npkts;
564 /*
565 * search for further sc_qchip ubsec_q's that share
566 * the same MCR, and complete them too, they must be
567 * at the top.
568 */
569 for (i = 0; i < npkts; i++) {
570 if(q->q_stacked_mcr[i]) {
571 ubsec_callback(sc, q->q_stacked_mcr[i]);

--- 84 unchanged lines hidden (view full) ---

656ubsec_feed(struct ubsec_softc *sc)
657{
658 struct ubsec_q *q, *q2;
659 int npkts, i;
660 void *v;
661 u_int32_t stat;
662
663 npkts = sc->sc_nqueue;
582 /*
583 * search for further sc_qchip ubsec_q's that share
584 * the same MCR, and complete them too, they must be
585 * at the top.
586 */
587 for (i = 0; i < npkts; i++) {
588 if(q->q_stacked_mcr[i]) {
589 ubsec_callback(sc, q->q_stacked_mcr[i]);

--- 84 unchanged lines hidden (view full) ---

674ubsec_feed(struct ubsec_softc *sc)
675{
676 struct ubsec_q *q, *q2;
677 int npkts, i;
678 void *v;
679 u_int32_t stat;
680
681 npkts = sc->sc_nqueue;
682 if (npkts > ubsecstats.hst_maxqueue)
683 ubsecstats.hst_maxqueue = npkts;
684 /*
685 * Decide how many ops to combine in a single MCR. We cannot
686 * aggregate more than UBS_MAX_AGGR because this is the number
687 * of slots defined in the data structure. Otherwise we clamp
688 * based on the tunable parameter ubsec_maxaggr. Note that
689 * aggregation can happen in two ways: either by batching ops
690 * from above or because the h/w backs up and throttles us.
691 * Aggregating ops reduces the number of interrupts to the host
692 * but also (potentially) increases the latency for processing
693 * completed ops as we only get an interrupt when all aggregated
694 * ops have completed.
695 */
664 if (npkts > UBS_MAX_AGGR)
665 npkts = UBS_MAX_AGGR;
696 if (npkts > UBS_MAX_AGGR)
697 npkts = UBS_MAX_AGGR;
698 if (npkts > ubsec_maxaggr)
699 npkts = ubsec_maxaggr;
666 if (npkts > ubsecstats.hst_maxbatch)
667 ubsecstats.hst_maxbatch = npkts;
668 if (npkts < 2)
669 goto feed1;
670 ubsecstats.hst_totbatch += npkts-1;
671
672 if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) {
700 if (npkts > ubsecstats.hst_maxbatch)
701 ubsecstats.hst_maxbatch = npkts;
702 if (npkts < 2)
703 goto feed1;
704 ubsecstats.hst_totbatch += npkts-1;
705
706 if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) {
673 if(stat & BS_STAT_DMAERR) {
707 if (stat & BS_STAT_DMAERR) {
674 ubsec_totalreset(sc);
675 ubsecstats.hst_dmaerr++;
708 ubsec_totalreset(sc);
709 ubsecstats.hst_dmaerr++;
676 }
710 } else
711 ubsecstats.hst_mcr1full++;
677 return (0);
678 }
679
680#ifdef UBSEC_DEBUG
681 if (ubsec_debug)
682 printf("merging %d records\n", npkts);
683#endif /* UBSEC_DEBUG */
684

--- 19 unchanged lines hidden (view full) ---

704
705 v = (void*)(((char *)&q2->q_dma->d_dma->d_mcr) + sizeof(struct ubsec_mcr) -
706 sizeof(struct ubsec_mcr_add));
707 bcopy(v, &q->q_dma->d_dma->d_mcradd[i], sizeof(struct ubsec_mcr_add));
708 q->q_stacked_mcr[i] = q2;
709 }
710 q->q_dma->d_dma->d_mcr.mcr_pkts = htole16(npkts);
711 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
712 return (0);
713 }
714
715#ifdef UBSEC_DEBUG
716 if (ubsec_debug)
717 printf("merging %d records\n", npkts);
718#endif /* UBSEC_DEBUG */
719

--- 19 unchanged lines hidden (view full) ---

739
740 v = (void*)(((char *)&q2->q_dma->d_dma->d_mcr) + sizeof(struct ubsec_mcr) -
741 sizeof(struct ubsec_mcr_add));
742 bcopy(v, &q->q_dma->d_dma->d_mcradd[i], sizeof(struct ubsec_mcr_add));
743 q->q_stacked_mcr[i] = q2;
744 }
745 q->q_dma->d_dma->d_mcr.mcr_pkts = htole16(npkts);
746 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
747 sc->sc_nqchip += npkts;
748 if (sc->sc_nqchip > ubsecstats.hst_maxqchip)
749 ubsecstats.hst_maxqchip = sc->sc_nqchip;
712 bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map,
713 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
714 WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr +
715 offsetof(struct ubsec_dmachunk, d_mcr));
716 return (0);
717
718feed1:
719 while (!SIMPLEQ_EMPTY(&sc->sc_queue)) {
720 if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) {
750 bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map,
751 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
752 WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr +
753 offsetof(struct ubsec_dmachunk, d_mcr));
754 return (0);
755
756feed1:
757 while (!SIMPLEQ_EMPTY(&sc->sc_queue)) {
758 if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) {
721 if(stat & BS_STAT_DMAERR) {
759 if (stat & BS_STAT_DMAERR) {
722 ubsec_totalreset(sc);
723 ubsecstats.hst_dmaerr++;
760 ubsec_totalreset(sc);
761 ubsecstats.hst_dmaerr++;
724 }
762 } else
763 ubsecstats.hst_mcr1full++;
725 break;
726 }
727
728 q = SIMPLEQ_FIRST(&sc->sc_queue);
729
730 bus_dmamap_sync(sc->sc_dmat, q->q_src_map,
731 BUS_DMASYNC_PREWRITE);
732 if (q->q_dst_map != NULL)

--- 8 unchanged lines hidden (view full) ---

741 if (ubsec_debug)
742 printf("feed: q->chip %p %08x stat %08x\n",
743 q, (u_int32_t)vtophys(&q->q_dma->d_dma->d_mcr),
744 stat);
745#endif /* UBSEC_DEBUG */
746 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q, q_next);
747 --sc->sc_nqueue;
748 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
764 break;
765 }
766
767 q = SIMPLEQ_FIRST(&sc->sc_queue);
768
769 bus_dmamap_sync(sc->sc_dmat, q->q_src_map,
770 BUS_DMASYNC_PREWRITE);
771 if (q->q_dst_map != NULL)

--- 8 unchanged lines hidden (view full) ---

780 if (ubsec_debug)
781 printf("feed: q->chip %p %08x stat %08x\n",
782 q, (u_int32_t)vtophys(&q->q_dma->d_dma->d_mcr),
783 stat);
784#endif /* UBSEC_DEBUG */
785 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q, q_next);
786 --sc->sc_nqueue;
787 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
788 sc->sc_nqchip++;
749 }
789 }
790 if (sc->sc_nqchip > ubsecstats.hst_maxqchip)
791 ubsecstats.hst_maxqchip = sc->sc_nqchip;
750 return (0);
751}
752
753/*
754 * Allocate a new 'session' and return an encoded session id. 'sidp'
755 * contains our registration id, and should contain an encoded session
756 * id on successful allocation.
757 */

--- 187 unchanged lines hidden (view full) ---

945 struct ubsec_pktctx ctx;
946 struct ubsec_dma *dmap = NULL;
947
948 if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
949 ubsecstats.hst_invalid++;
950 return (EINVAL);
951 }
952 if (UBSEC_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
792 return (0);
793}
794
795/*
796 * Allocate a new 'session' and return an encoded session id. 'sidp'
797 * contains our registration id, and should contain an encoded session
798 * id on successful allocation.
799 */

--- 187 unchanged lines hidden (view full) ---

987 struct ubsec_pktctx ctx;
988 struct ubsec_dma *dmap = NULL;
989
990 if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
991 ubsecstats.hst_invalid++;
992 return (EINVAL);
993 }
994 if (UBSEC_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
953 ubsecstats.hst_invalid++;
995 ubsecstats.hst_badsession++;
954 return (EINVAL);
955 }
956
957 UBSEC_LOCK(sc);
958
959 if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) {
960 ubsecstats.hst_queuefull++;
961 sc->sc_needwakeup |= CRYPTO_SYMQ;

--- 14 unchanged lines hidden (view full) ---

976
977 if (crp->crp_flags & CRYPTO_F_IMBUF) {
978 q->q_src_m = (struct mbuf *)crp->crp_buf;
979 q->q_dst_m = (struct mbuf *)crp->crp_buf;
980 } else if (crp->crp_flags & CRYPTO_F_IOV) {
981 q->q_src_io = (struct uio *)crp->crp_buf;
982 q->q_dst_io = (struct uio *)crp->crp_buf;
983 } else {
996 return (EINVAL);
997 }
998
999 UBSEC_LOCK(sc);
1000
1001 if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) {
1002 ubsecstats.hst_queuefull++;
1003 sc->sc_needwakeup |= CRYPTO_SYMQ;

--- 14 unchanged lines hidden (view full) ---

1018
1019 if (crp->crp_flags & CRYPTO_F_IMBUF) {
1020 q->q_src_m = (struct mbuf *)crp->crp_buf;
1021 q->q_dst_m = (struct mbuf *)crp->crp_buf;
1022 } else if (crp->crp_flags & CRYPTO_F_IOV) {
1023 q->q_src_io = (struct uio *)crp->crp_buf;
1024 q->q_dst_io = (struct uio *)crp->crp_buf;
1025 } else {
984 ubsecstats.hst_invalid++;
1026 ubsecstats.hst_badflags++;
985 err = EINVAL;
986 goto errout; /* XXX we don't handle contiguous blocks! */
987 }
988
989 bzero(&dmap->d_dma->d_mcr, sizeof(struct ubsec_mcr));
990
991 dmap->d_dma->d_mcr.mcr_pkts = htole16(1);
992 dmap->d_dma->d_mcr.mcr_flags = 0;
993 q->q_crp = crp;
994
995 crd1 = crp->crp_desc;
996 if (crd1 == NULL) {
1027 err = EINVAL;
1028 goto errout; /* XXX we don't handle contiguous blocks! */
1029 }
1030
1031 bzero(&dmap->d_dma->d_mcr, sizeof(struct ubsec_mcr));
1032
1033 dmap->d_dma->d_mcr.mcr_pkts = htole16(1);
1034 dmap->d_dma->d_mcr.mcr_flags = 0;
1035 q->q_crp = crp;
1036
1037 crd1 = crp->crp_desc;
1038 if (crd1 == NULL) {
997 ubsecstats.hst_invalid++;
1039 ubsecstats.hst_nodesc++;
998 err = EINVAL;
999 goto errout;
1000 }
1001 crd2 = crd1->crd_next;
1002
1003 if (crd2 == NULL) {
1004 if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
1005 crd1->crd_alg == CRYPTO_SHA1_HMAC) {
1006 maccrd = crd1;
1007 enccrd = NULL;
1008 } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
1009 crd1->crd_alg == CRYPTO_3DES_CBC) {
1010 maccrd = NULL;
1011 enccrd = crd1;
1012 } else {
1040 err = EINVAL;
1041 goto errout;
1042 }
1043 crd2 = crd1->crd_next;
1044
1045 if (crd2 == NULL) {
1046 if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
1047 crd1->crd_alg == CRYPTO_SHA1_HMAC) {
1048 maccrd = crd1;
1049 enccrd = NULL;
1050 } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
1051 crd1->crd_alg == CRYPTO_3DES_CBC) {
1052 maccrd = NULL;
1053 enccrd = crd1;
1054 } else {
1013 ubsecstats.hst_invalid++;
1055 ubsecstats.hst_badalg++;
1014 err = EINVAL;
1015 goto errout;
1016 }
1017 } else {
1018 if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
1019 crd1->crd_alg == CRYPTO_SHA1_HMAC) &&
1020 (crd2->crd_alg == CRYPTO_DES_CBC ||
1021 crd2->crd_alg == CRYPTO_3DES_CBC) &&

--- 6 unchanged lines hidden (view full) ---

1028 crd2->crd_alg == CRYPTO_SHA1_HMAC) &&
1029 (crd1->crd_flags & CRD_F_ENCRYPT)) {
1030 enccrd = crd1;
1031 maccrd = crd2;
1032 } else {
1033 /*
1034 * We cannot order the ubsec as requested
1035 */
1056 err = EINVAL;
1057 goto errout;
1058 }
1059 } else {
1060 if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
1061 crd1->crd_alg == CRYPTO_SHA1_HMAC) &&
1062 (crd2->crd_alg == CRYPTO_DES_CBC ||
1063 crd2->crd_alg == CRYPTO_3DES_CBC) &&

--- 6 unchanged lines hidden (view full) ---

1070 crd2->crd_alg == CRYPTO_SHA1_HMAC) &&
1071 (crd1->crd_flags & CRD_F_ENCRYPT)) {
1072 enccrd = crd1;
1073 maccrd = crd2;
1074 } else {
1075 /*
1076 * We cannot order the ubsec as requested
1077 */
1036 ubsecstats.hst_invalid++;
1078 ubsecstats.hst_badalg++;
1037 err = EINVAL;
1038 goto errout;
1039 }
1040 }
1041
1042 if (enccrd) {
1043 encoffset = enccrd->crd_skip;
1044 ctx.pc_flags |= htole16(UBS_PKTCTX_ENC_3DES);

--- 295 unchanged lines hidden (view full) ---

1340 q->q_dst_map);
1341 q->q_dst_map = NULL;
1342 ubsecstats.hst_noload++;
1343 err = ENOMEM;
1344 goto errout;
1345 }
1346 }
1347 } else {
1079 err = EINVAL;
1080 goto errout;
1081 }
1082 }
1083
1084 if (enccrd) {
1085 encoffset = enccrd->crd_skip;
1086 ctx.pc_flags |= htole16(UBS_PKTCTX_ENC_3DES);

--- 295 unchanged lines hidden (view full) ---

1382 q->q_dst_map);
1383 q->q_dst_map = NULL;
1384 ubsecstats.hst_noload++;
1385 err = ENOMEM;
1386 goto errout;
1387 }
1388 }
1389 } else {
1348 ubsecstats.hst_invalid++;
1390 ubsecstats.hst_badflags++;
1349 err = EINVAL;
1350 goto errout;
1351 }
1352
1353#ifdef UBSEC_DEBUG
1354 if (ubsec_debug)
1355 printf("dst skip: %d\n", dskip);
1356#endif

--- 527 unchanged lines hidden (view full) ---

1884{
1885 struct ubsec_q *q;
1886
1887 while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) {
1888 q = SIMPLEQ_FIRST(&sc->sc_qchip);
1889 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q, q_next);
1890 ubsec_free_q(sc, q);
1891 }
1391 err = EINVAL;
1392 goto errout;
1393 }
1394
1395#ifdef UBSEC_DEBUG
1396 if (ubsec_debug)
1397 printf("dst skip: %d\n", dskip);
1398#endif

--- 527 unchanged lines hidden (view full) ---

1926{
1927 struct ubsec_q *q;
1928
1929 while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) {
1930 q = SIMPLEQ_FIRST(&sc->sc_qchip);
1931 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q, q_next);
1932 ubsec_free_q(sc, q);
1933 }
1934 sc->sc_nqchip = 0;
1892}
1893
1894/*
1895 * free a ubsec_q
1896 * It is assumed that the caller is within spimp()
1897 */
1898static int
1899ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q)

--- 866 unchanged lines hidden ---
1935}
1936
1937/*
1938 * free a ubsec_q
1939 * It is assumed that the caller is within spimp()
1940 */
1941static int
1942ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q)

--- 866 unchanged lines hidden ---