| @@ -1,16 +1,15 @@ | | | @@ -1,16 +1,15 @@ |
1 | /* $NetBSD: hifn7751.c,v 1.69 2020/05/17 00:50:24 riastradh Exp $ */ | | 1 | /* $NetBSD: hifn7751.c,v 1.70 2020/05/17 00:52:31 riastradh Exp $ */ |
2 | /* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */ | | 2 | /* $OpenBSD: hifn7751.c,v 1.179 2020/01/11 21:34:03 cheloha Exp $ */ |
3 | /* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */ | | | |
4 | | | 3 | |
5 | /* | | 4 | /* |
6 | * Invertex AEON / Hifn 7751 driver | | 5 | * Invertex AEON / Hifn 7751 driver |
7 | * Copyright (c) 1999 Invertex Inc. All rights reserved. | | 6 | * Copyright (c) 1999 Invertex Inc. All rights reserved. |
8 | * Copyright (c) 1999 Theo de Raadt | | 7 | * Copyright (c) 1999 Theo de Raadt |
9 | * Copyright (c) 2000-2001 Network Security Technologies, Inc. | | 8 | * Copyright (c) 2000-2001 Network Security Technologies, Inc. |
10 | * http://www.netsec.net | | 9 | * http://www.netsec.net |
11 | * Copyright (c) 2003 Hifn Inc. | | 10 | * Copyright (c) 2003 Hifn Inc. |
12 | * | | 11 | * |
13 | * This driver is based on a previous driver by Invertex, for which they | | 12 | * This driver is based on a previous driver by Invertex, for which they |
14 | * requested: Please send any comments, feedback, bug-fixes, or feature | | 13 | * requested: Please send any comments, feedback, bug-fixes, or feature |
15 | * requests to software@invertex.com. | | 14 | * requests to software@invertex.com. |
16 | * | | 15 | * |
| @@ -34,31 +33,31 @@ | | | @@ -34,31 +33,31 @@ |
34 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 33 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
38 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 37 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
39 | * | | 38 | * |
40 | * Effort sponsored in part by the Defense Advanced Research Projects | | 39 | * Effort sponsored in part by the Defense Advanced Research Projects |
41 | * Agency (DARPA) and Air Force Research Laboratory, Air Force | | 40 | * Agency (DARPA) and Air Force Research Laboratory, Air Force |
42 | * Materiel Command, USAF, under agreement number F30602-01-2-0537. | | 41 | * Materiel Command, USAF, under agreement number F30602-01-2-0537. |
43 | * | | 42 | * |
44 | */ | | 43 | */ |
45 | | | 44 | |
46 | /* | | 45 | /* |
47 | * Driver for various Hifn pre-HIPP encryption processors. | | 46 | * Driver for various Hifn encryption processors. |
48 | */ | | 47 | */ |
49 | | | 48 | |
50 | #include <sys/cdefs.h> | | 49 | #include <sys/cdefs.h> |
51 | __KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.69 2020/05/17 00:50:24 riastradh Exp $"); | | 50 | __KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.70 2020/05/17 00:52:31 riastradh Exp $"); |
52 | | | 51 | |
53 | #include <sys/param.h> | | 52 | #include <sys/param.h> |
54 | #include <sys/cprng.h> | | 53 | #include <sys/cprng.h> |
55 | #include <sys/device.h> | | 54 | #include <sys/device.h> |
56 | #include <sys/endian.h> | | 55 | #include <sys/endian.h> |
57 | #include <sys/errno.h> | | 56 | #include <sys/errno.h> |
58 | #include <sys/kernel.h> | | 57 | #include <sys/kernel.h> |
59 | #include <sys/malloc.h> | | 58 | #include <sys/malloc.h> |
60 | #include <sys/mbuf.h> | | 59 | #include <sys/mbuf.h> |
61 | #include <sys/module.h> | | 60 | #include <sys/module.h> |
62 | #include <sys/mutex.h> | | 61 | #include <sys/mutex.h> |
63 | #include <sys/proc.h> | | 62 | #include <sys/proc.h> |
64 | #include <sys/rndsource.h> | | 63 | #include <sys/rndsource.h> |
| @@ -169,27 +168,26 @@ static const struct hifn_product { | | | @@ -169,27 +168,26 @@ static const struct hifn_product { |
169 | "Hifn 7951", | | 168 | "Hifn 7951", |
170 | }, | | 169 | }, |
171 | | | 170 | |
172 | { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955, | | 171 | { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955, |
173 | HIFN_HAS_RNG | HIFN_HAS_PUBLIC | HIFN_IS_7956 | HIFN_HAS_AES, | | 172 | HIFN_HAS_RNG | HIFN_HAS_PUBLIC | HIFN_IS_7956 | HIFN_HAS_AES, |
174 | "Hifn 7955", | | 173 | "Hifn 7955", |
175 | }, | | 174 | }, |
176 | | | 175 | |
177 | { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956, | | 176 | { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956, |
178 | HIFN_HAS_RNG | HIFN_HAS_PUBLIC | HIFN_IS_7956 | HIFN_HAS_AES, | | 177 | HIFN_HAS_RNG | HIFN_HAS_PUBLIC | HIFN_IS_7956 | HIFN_HAS_AES, |
179 | "Hifn 7956", | | 178 | "Hifn 7956", |
180 | }, | | 179 | }, |
181 | | | 180 | |
182 | | | | |
183 | { 0, 0, | | 181 | { 0, 0, |
184 | 0, | | 182 | 0, |
185 | NULL | | 183 | NULL |
186 | } | | 184 | } |
187 | }; | | 185 | }; |
188 | | | 186 | |
189 | static const struct hifn_product * | | 187 | static const struct hifn_product * |
190 | hifn_lookup(const struct pci_attach_args *pa) | | 188 | hifn_lookup(const struct pci_attach_args *pa) |
191 | { | | 189 | { |
192 | const struct hifn_product *hp; | | 190 | const struct hifn_product *hp; |
193 | | | 191 | |
194 | for (hp = hifn_products; hp->hifn_name != NULL; hp++) { | | 192 | for (hp = hifn_products; hp->hifn_name != NULL; hp++) { |
195 | if (PCI_VENDOR(pa->pa_id) == hp->hifn_vendor && | | 193 | if (PCI_VENDOR(pa->pa_id) == hp->hifn_vendor && |
| @@ -800,48 +798,48 @@ static struct pci2id { | | | @@ -800,48 +798,48 @@ static struct pci2id { |
800 | }, { | | 798 | }, { |
801 | PCI_VENDOR_INVERTEX, | | 799 | PCI_VENDOR_INVERTEX, |
802 | PCI_PRODUCT_INVERTEX_AEON, | | 800 | PCI_PRODUCT_INVERTEX_AEON, |
803 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | | 801 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
804 | 0x00, 0x00, 0x00, 0x00, 0x00 } | | 802 | 0x00, 0x00, 0x00, 0x00, 0x00 } |
805 | }, { | | 803 | }, { |
806 | PCI_VENDOR_HIFN, | | 804 | PCI_VENDOR_HIFN, |
807 | PCI_PRODUCT_HIFN_7811, | | 805 | PCI_PRODUCT_HIFN_7811, |
808 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | | 806 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
809 | 0x00, 0x00, 0x00, 0x00, 0x00 } | | 807 | 0x00, 0x00, 0x00, 0x00, 0x00 } |
810 | }, { | | 808 | }, { |
811 | /* | | 809 | /* |
812 | * Other vendors share this PCI ID as well, such as | | 810 | * Other vendors share this PCI ID as well, such as |
813 | * http://www.powercrypt.com, and obviously they also | | 811 | * powercrypt, and obviously they also |
814 | * use the same key. | | 812 | * use the same key. |
815 | */ | | 813 | */ |
816 | PCI_VENDOR_HIFN, | | 814 | PCI_VENDOR_HIFN, |
817 | PCI_PRODUCT_HIFN_7751, | | 815 | PCI_PRODUCT_HIFN_7751, |
818 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | | 816 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
819 | 0x00, 0x00, 0x00, 0x00, 0x00 } | | 817 | 0x00, 0x00, 0x00, 0x00, 0x00 } |
820 | }, | | 818 | }, |
821 | }; | | 819 | }; |
822 | | | 820 | |
823 | /* | | 821 | /* |
824 | * Checks to see if crypto is already enabled. If crypto isn't enable, | | 822 | * Checks to see if crypto is already enabled. If crypto isn't enable, |
825 | * "hifn_enable_crypto" is called to enable it. The check is important, | | 823 | * "hifn_enable_crypto" is called to enable it. The check is important, |
826 | * as enabling crypto twice will lock the board. | | 824 | * as enabling crypto twice will lock the board. |
827 | */ | | 825 | */ |
828 | static const char * | | 826 | static const char * |
829 | hifn_enable_crypto(struct hifn_softc *sc, pcireg_t pciid) | | 827 | hifn_enable_crypto(struct hifn_softc *sc, pcireg_t pciid) |
830 | { | | 828 | { |
831 | uint32_t dmacfg, ramcfg, encl, addr, i; | | 829 | uint32_t dmacfg, ramcfg, encl, addr, i; |
832 | const char *offtbl = NULL; | | 830 | const char *offtbl = NULL; |
833 | | | 831 | |
834 | for (i = 0; i < sizeof(pci2id)/sizeof(pci2id[0]); i++) { | | 832 | for (i = 0; i < __arraycount(pci2id); i++) { |
835 | if (pci2id[i].pci_vendor == PCI_VENDOR(pciid) && | | 833 | if (pci2id[i].pci_vendor == PCI_VENDOR(pciid) && |
836 | pci2id[i].pci_prod == PCI_PRODUCT(pciid)) { | | 834 | pci2id[i].pci_prod == PCI_PRODUCT(pciid)) { |
837 | offtbl = pci2id[i].card_id; | | 835 | offtbl = pci2id[i].card_id; |
838 | break; | | 836 | break; |
839 | } | | 837 | } |
840 | } | | 838 | } |
841 | | | 839 | |
842 | if (offtbl == NULL) { | | 840 | if (offtbl == NULL) { |
843 | #ifdef HIFN_DEBUG | | 841 | #ifdef HIFN_DEBUG |
844 | aprint_debug_dev(sc->sc_dv, "Unknown card!\n"); | | 842 | aprint_debug_dev(sc->sc_dv, "Unknown card!\n"); |
845 | #endif | | 843 | #endif |
846 | return (NULL); | | 844 | return (NULL); |
847 | } | | 845 | } |
| @@ -1219,27 +1217,26 @@ hifn_writeramaddr(struct hifn_softc *sc, | | | @@ -1219,27 +1217,26 @@ hifn_writeramaddr(struct hifn_softc *sc, |
1219 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, | | 1217 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, |
1220 | 0, sc->sc_dmamap->dm_mapsize, | | 1218 | 0, sc->sc_dmamap->dm_mapsize, |
1221 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | | 1219 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
1222 | if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0) | | 1220 | if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0) |
1223 | break; | | 1221 | break; |
1224 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, | | 1222 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, |
1225 | 0, sc->sc_dmamap->dm_mapsize, | | 1223 | 0, sc->sc_dmamap->dm_mapsize, |
1226 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); | | 1224 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); |
1227 | } | | 1225 | } |
1228 | if (r == 0) { | | 1226 | if (r == 0) { |
1229 | printf("%s: writeramaddr -- " | | 1227 | printf("%s: writeramaddr -- " |
1230 | "result[%d](addr %d) still valid\n", | | 1228 | "result[%d](addr %d) still valid\n", |
1231 | device_xname(sc->sc_dv), resi, addr); | | 1229 | device_xname(sc->sc_dv), resi, addr); |
1232 | r = -1; | | | |
1233 | return (-1); | | 1230 | return (-1); |
1234 | } else | | 1231 | } else |
1235 | r = 0; | | 1232 | r = 0; |
1236 | | | 1233 | |
1237 | WRITE_REG_1(sc, HIFN_1_DMA_CSR, | | 1234 | WRITE_REG_1(sc, HIFN_1_DMA_CSR, |
1238 | HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS | | | 1235 | HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS | |
1239 | HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS); | | 1236 | HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS); |
1240 | | | 1237 | |
1241 | return (r); | | 1238 | return (r); |
1242 | } | | 1239 | } |
1243 | | | 1240 | |
1244 | static int | | 1241 | static int |
1245 | hifn_readramaddr(struct hifn_softc *sc, int addr, uint8_t *data) | | 1242 | hifn_readramaddr(struct hifn_softc *sc, int addr, uint8_t *data) |
| @@ -1365,27 +1362,27 @@ hifn_write_command(struct hifn_command * | | | @@ -1365,27 +1362,27 @@ hifn_write_command(struct hifn_command * |
1365 | | | 1362 | |
1366 | base_cmd = (struct hifn_base_command *)buf_pos; | | 1363 | base_cmd = (struct hifn_base_command *)buf_pos; |
1367 | base_cmd->masks = htole16(cmd->base_masks); | | 1364 | base_cmd->masks = htole16(cmd->base_masks); |
1368 | slen = cmd->src_map->dm_mapsize; | | 1365 | slen = cmd->src_map->dm_mapsize; |
1369 | if (cmd->sloplen) | | 1366 | if (cmd->sloplen) |
1370 | dlen = cmd->dst_map->dm_mapsize - cmd->sloplen + | | 1367 | dlen = cmd->dst_map->dm_mapsize - cmd->sloplen + |
1371 | sizeof(uint32_t); | | 1368 | sizeof(uint32_t); |
1372 | else | | 1369 | else |
1373 | dlen = cmd->dst_map->dm_mapsize; | | 1370 | dlen = cmd->dst_map->dm_mapsize; |
1374 | base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO); | | 1371 | base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO); |
1375 | base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO); | | 1372 | base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO); |
1376 | dlen >>= 16; | | 1373 | dlen >>= 16; |
1377 | slen >>= 16; | | 1374 | slen >>= 16; |
1378 | base_cmd->session_num = htole16(cmd->session_num | | | 1375 | base_cmd->session_num = htole16( |
1379 | ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) | | | 1376 | ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) | |
1380 | ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M)); | | 1377 | ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M)); |
1381 | buf_pos += sizeof(struct hifn_base_command); | | 1378 | buf_pos += sizeof(struct hifn_base_command); |
1382 | | | 1379 | |
1383 | if (using_comp) { | | 1380 | if (using_comp) { |
1384 | comp_cmd = (struct hifn_comp_command *)buf_pos; | | 1381 | comp_cmd = (struct hifn_comp_command *)buf_pos; |
1385 | dlen = cmd->compcrd->crd_len; | | 1382 | dlen = cmd->compcrd->crd_len; |
1386 | comp_cmd->source_count = htole16(dlen & 0xffff); | | 1383 | comp_cmd->source_count = htole16(dlen & 0xffff); |
1387 | dlen >>= 16; | | 1384 | dlen >>= 16; |
1388 | comp_cmd->masks = htole16(cmd->comp_masks | | | 1385 | comp_cmd->masks = htole16(cmd->comp_masks | |
1389 | ((dlen << HIFN_COMP_CMD_SRCLEN_S) & HIFN_COMP_CMD_SRCLEN_M)); | | 1386 | ((dlen << HIFN_COMP_CMD_SRCLEN_S) & HIFN_COMP_CMD_SRCLEN_M)); |
1390 | comp_cmd->header_skip = htole16(cmd->compcrd->crd_skip); | | 1387 | comp_cmd->header_skip = htole16(cmd->compcrd->crd_skip); |
1391 | comp_cmd->reserved = 0; | | 1388 | comp_cmd->reserved = 0; |
| @@ -2035,53 +2032,48 @@ out: | | | @@ -2035,53 +2032,48 @@ out: |
2035 | */ | | 2032 | */ |
2036 | static int | | 2033 | static int |
2037 | hifn_newsession(void *arg, uint32_t *sidp, struct cryptoini *cri) | | 2034 | hifn_newsession(void *arg, uint32_t *sidp, struct cryptoini *cri) |
2038 | { | | 2035 | { |
2039 | struct cryptoini *c; | | 2036 | struct cryptoini *c; |
2040 | struct hifn_softc *sc = arg; | | 2037 | struct hifn_softc *sc = arg; |
2041 | int i, mac = 0, cry = 0, comp = 0, retval = EINVAL; | | 2038 | int i, mac = 0, cry = 0, comp = 0, retval = EINVAL; |
2042 | | | 2039 | |
2043 | KASSERT(sc != NULL /*, ("hifn_newsession: null softc")*/); | | 2040 | KASSERT(sc != NULL /*, ("hifn_newsession: null softc")*/); |
2044 | if (sidp == NULL || cri == NULL || sc == NULL) | | 2041 | if (sidp == NULL || cri == NULL || sc == NULL) |
2045 | return retval; | | 2042 | return retval; |
2046 | | | 2043 | |
2047 | mutex_spin_enter(&sc->sc_mtx); | | 2044 | mutex_spin_enter(&sc->sc_mtx); |
2048 | | | | |
2049 | for (i = 0; i < sc->sc_maxses; i++) | | 2045 | for (i = 0; i < sc->sc_maxses; i++) |
2050 | if (sc->sc_sessions[i].hs_state == HS_STATE_FREE) | | 2046 | if (isclr(sc->sc_sessions, i)) |
2051 | break; | | 2047 | break; |
2052 | if (i == sc->sc_maxses) { | | 2048 | if (i == sc->sc_maxses) { |
2053 | retval = ENOMEM; | | 2049 | retval = ENOMEM; |
2054 | goto out; | | 2050 | goto out; |
2055 | } | | 2051 | } |
2056 | | | 2052 | |
2057 | for (c = cri; c != NULL; c = c->cri_next) { | | 2053 | for (c = cri; c != NULL; c = c->cri_next) { |
2058 | switch (c->cri_alg) { | | 2054 | switch (c->cri_alg) { |
2059 | case CRYPTO_MD5: | | 2055 | case CRYPTO_MD5: |
2060 | case CRYPTO_SHA1: | | 2056 | case CRYPTO_SHA1: |
2061 | case CRYPTO_MD5_HMAC_96: | | 2057 | case CRYPTO_MD5_HMAC_96: |
2062 | case CRYPTO_SHA1_HMAC_96: | | 2058 | case CRYPTO_SHA1_HMAC_96: |
2063 | if (mac) { | | 2059 | if (mac) { |
2064 | goto out; | | 2060 | goto out; |
2065 | } | | 2061 | } |
2066 | mac = 1; | | 2062 | mac = 1; |
2067 | break; | | 2063 | break; |
2068 | case CRYPTO_DES_CBC: | | 2064 | case CRYPTO_DES_CBC: |
2069 | case CRYPTO_3DES_CBC: | | 2065 | case CRYPTO_3DES_CBC: |
2070 | case CRYPTO_AES_CBC: | | 2066 | case CRYPTO_AES_CBC: |
2071 | cprng_fast(sc->sc_sessions[i].hs_iv, | | | |
2072 | c->cri_alg == CRYPTO_AES_CBC ? | | | |
2073 | HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); | | | |
2074 | /*FALLTHROUGH*/ | | | |
2075 | case CRYPTO_ARC4: | | 2067 | case CRYPTO_ARC4: |
2076 | if (cry) { | | 2068 | if (cry) { |
2077 | goto out; | | 2069 | goto out; |
2078 | } | | 2070 | } |
2079 | cry = 1; | | 2071 | cry = 1; |
2080 | break; | | 2072 | break; |
2081 | #ifdef CRYPTO_LZS_COMP | | 2073 | #ifdef CRYPTO_LZS_COMP |
2082 | case CRYPTO_LZS_COMP: | | 2074 | case CRYPTO_LZS_COMP: |
2083 | if (comp) { | | 2075 | if (comp) { |
2084 | goto out; | | 2076 | goto out; |
2085 | } | | 2077 | } |
2086 | comp = 1; | | 2078 | comp = 1; |
2087 | break; | | 2079 | break; |
| @@ -2093,27 +2085,27 @@ hifn_newsession(void *arg, uint32_t *sid | | | @@ -2093,27 +2085,27 @@ hifn_newsession(void *arg, uint32_t *sid |
2093 | if (mac == 0 && cry == 0 && comp == 0) { | | 2085 | if (mac == 0 && cry == 0 && comp == 0) { |
2094 | goto out; | | 2086 | goto out; |
2095 | } | | 2087 | } |
2096 | | | 2088 | |
2097 | /* | | 2089 | /* |
2098 | * XXX only want to support compression without chaining to | | 2090 | * XXX only want to support compression without chaining to |
2099 | * MAC/crypt engine right now | | 2091 | * MAC/crypt engine right now |
2100 | */ | | 2092 | */ |
2101 | if ((comp && mac) || (comp && cry)) { | | 2093 | if ((comp && mac) || (comp && cry)) { |
2102 | goto out; | | 2094 | goto out; |
2103 | } | | 2095 | } |
2104 | | | 2096 | |
2105 | *sidp = HIFN_SID(device_unit(sc->sc_dv), i); | | 2097 | *sidp = HIFN_SID(device_unit(sc->sc_dv), i); |
2106 | sc->sc_sessions[i].hs_state = HS_STATE_USED; | | 2098 | setbit(sc->sc_sessions, i); |
2107 | | | 2099 | |
2108 | retval = 0; | | 2100 | retval = 0; |
2109 | out: | | 2101 | out: |
2110 | mutex_spin_exit(&sc->sc_mtx); | | 2102 | mutex_spin_exit(&sc->sc_mtx); |
2111 | return retval; | | 2103 | return retval; |
2112 | } | | 2104 | } |
2113 | | | 2105 | |
2114 | /* | | 2106 | /* |
2115 | * Deallocate a session. | | 2107 | * Deallocate a session. |
2116 | * XXX this routine should run a zero'd mac/encrypt key into context ram. | | 2108 | * XXX this routine should run a zero'd mac/encrypt key into context ram. |
2117 | * XXX to blow away any keys already stored there. | | 2109 | * XXX to blow away any keys already stored there. |
2118 | */ | | 2110 | */ |
2119 | static int | | 2111 | static int |
| @@ -2123,55 +2115,52 @@ hifn_freesession(void *arg, uint64_t tid | | | @@ -2123,55 +2115,52 @@ hifn_freesession(void *arg, uint64_t tid |
2123 | int session; | | 2115 | int session; |
2124 | uint32_t sid = ((uint32_t) tid) & 0xffffffff; | | 2116 | uint32_t sid = ((uint32_t) tid) & 0xffffffff; |
2125 | | | 2117 | |
2126 | KASSERT(sc != NULL /*, ("hifn_freesession: null softc")*/); | | 2118 | KASSERT(sc != NULL /*, ("hifn_freesession: null softc")*/); |
2127 | if (sc == NULL) | | 2119 | if (sc == NULL) |
2128 | return (EINVAL); | | 2120 | return (EINVAL); |
2129 | | | 2121 | |
2130 | mutex_spin_enter(&sc->sc_mtx); | | 2122 | mutex_spin_enter(&sc->sc_mtx); |
2131 | session = HIFN_SESSION(sid); | | 2123 | session = HIFN_SESSION(sid); |
2132 | if (session >= sc->sc_maxses) { | | 2124 | if (session >= sc->sc_maxses) { |
2133 | mutex_spin_exit(&sc->sc_mtx); | | 2125 | mutex_spin_exit(&sc->sc_mtx); |
2134 | return (EINVAL); | | 2126 | return (EINVAL); |
2135 | } | | 2127 | } |
2136 | | | 2128 | clrbit(sc->sc_sessions, session); |
2137 | memset(&sc->sc_sessions[session], 0, sizeof(sc->sc_sessions[session])); | | | |
2138 | mutex_spin_exit(&sc->sc_mtx); | | 2129 | mutex_spin_exit(&sc->sc_mtx); |
2139 | return (0); | | 2130 | return (0); |
2140 | } | | 2131 | } |
2141 | | | 2132 | |
2142 | static int | | 2133 | static int |
2143 | hifn_process(void *arg, struct cryptop *crp, int hint) | | 2134 | hifn_process(void *arg, struct cryptop *crp, int hint) |
2144 | { | | 2135 | { |
2145 | struct hifn_softc *sc = arg; | | 2136 | struct hifn_softc *sc = arg; |
2146 | struct hifn_command *cmd = NULL; | | 2137 | struct hifn_command *cmd = NULL; |
2147 | int session, err, ivlen; | | 2138 | int session, err = 0, ivlen; |
2148 | struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; | | 2139 | struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; |
2149 | | | 2140 | |
2150 | if (crp == NULL || crp->crp_callback == NULL) { | | 2141 | if (crp == NULL || crp->crp_callback == NULL) { |
2151 | hifnstats.hst_invalid++; | | 2142 | hifnstats.hst_invalid++; |
2152 | return (EINVAL); | | 2143 | return (EINVAL); |
2153 | } | | 2144 | } |
2154 | | | 2145 | |
2155 | mutex_spin_enter(&sc->sc_mtx); | | 2146 | mutex_spin_enter(&sc->sc_mtx); |
2156 | session = HIFN_SESSION(crp->crp_sid); | | 2147 | session = HIFN_SESSION(crp->crp_sid); |
2157 | | | 2148 | if (session >= sc->sc_maxses) { |
2158 | if (sc == NULL || session >= sc->sc_maxses) { | | | |
2159 | err = EINVAL; | | 2149 | err = EINVAL; |
2160 | goto errout; | | 2150 | goto errout; |
2161 | } | | 2151 | } |
2162 | | | 2152 | |
2163 | cmd = (struct hifn_command *)malloc(sizeof(struct hifn_command), | | 2153 | cmd = malloc(sizeof(*cmd), M_DEVBUF, M_NOWAIT | M_ZERO); |
2164 | M_DEVBUF, M_NOWAIT|M_ZERO); | | | |
2165 | if (cmd == NULL) { | | 2154 | if (cmd == NULL) { |
2166 | hifnstats.hst_nomem++; | | 2155 | hifnstats.hst_nomem++; |
2167 | err = ENOMEM; | | 2156 | err = ENOMEM; |
2168 | goto errout; | | 2157 | goto errout; |
2169 | } | | 2158 | } |
2170 | | | 2159 | |
2171 | if (crp->crp_flags & CRYPTO_F_IMBUF) { | | 2160 | if (crp->crp_flags & CRYPTO_F_IMBUF) { |
2172 | cmd->srcu.src_m = (struct mbuf *)crp->crp_buf; | | 2161 | cmd->srcu.src_m = (struct mbuf *)crp->crp_buf; |
2173 | cmd->dstu.dst_m = (struct mbuf *)crp->crp_buf; | | 2162 | cmd->dstu.dst_m = (struct mbuf *)crp->crp_buf; |
2174 | } else if (crp->crp_flags & CRYPTO_F_IOV) { | | 2163 | } else if (crp->crp_flags & CRYPTO_F_IOV) { |
2175 | cmd->srcu.src_io = (struct uio *)crp->crp_buf; | | 2164 | cmd->srcu.src_io = (struct uio *)crp->crp_buf; |
2176 | cmd->dstu.dst_io = (struct uio *)crp->crp_buf; | | 2165 | cmd->dstu.dst_io = (struct uio *)crp->crp_buf; |
2177 | } else { | | 2166 | } else { |
| @@ -2193,27 +2182,27 @@ hifn_process(void *arg, struct cryptop * | | | @@ -2193,27 +2182,27 @@ hifn_process(void *arg, struct cryptop * |
2193 | crd1->crd_alg == CRYPTO_MD5) { | | 2182 | crd1->crd_alg == CRYPTO_MD5) { |
2194 | maccrd = crd1; | | 2183 | maccrd = crd1; |
2195 | enccrd = NULL; | | 2184 | enccrd = NULL; |
2196 | } else if (crd1->crd_alg == CRYPTO_DES_CBC || | | 2185 | } else if (crd1->crd_alg == CRYPTO_DES_CBC || |
2197 | crd1->crd_alg == CRYPTO_3DES_CBC || | | 2186 | crd1->crd_alg == CRYPTO_3DES_CBC || |
2198 | crd1->crd_alg == CRYPTO_AES_CBC || | | 2187 | crd1->crd_alg == CRYPTO_AES_CBC || |
2199 | crd1->crd_alg == CRYPTO_ARC4) { | | 2188 | crd1->crd_alg == CRYPTO_ARC4) { |
2200 | if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0) | | 2189 | if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0) |
2201 | cmd->base_masks |= HIFN_BASE_CMD_DECODE; | | 2190 | cmd->base_masks |= HIFN_BASE_CMD_DECODE; |
2202 | maccrd = NULL; | | 2191 | maccrd = NULL; |
2203 | enccrd = crd1; | | 2192 | enccrd = crd1; |
2204 | #ifdef CRYPTO_LZS_COMP | | 2193 | #ifdef CRYPTO_LZS_COMP |
2205 | } else if (crd1->crd_alg == CRYPTO_LZS_COMP) { | | 2194 | } else if (crd1->crd_alg == CRYPTO_LZS_COMP) { |
2206 | return (hifn_compression(sc, crp, cmd)); | | 2195 | return (hifn_compression(sc, crp, cmd)); |
2207 | #endif | | 2196 | #endif |
2208 | } else { | | 2197 | } else { |
2209 | err = EINVAL; | | 2198 | err = EINVAL; |
2210 | goto errout; | | 2199 | goto errout; |
2211 | } | | 2200 | } |
2212 | } else { | | 2201 | } else { |
2213 | if ((crd1->crd_alg == CRYPTO_MD5_HMAC_96 || | | 2202 | if ((crd1->crd_alg == CRYPTO_MD5_HMAC_96 || |
2214 | crd1->crd_alg == CRYPTO_SHA1_HMAC_96 || | | 2203 | crd1->crd_alg == CRYPTO_SHA1_HMAC_96 || |
2215 | crd1->crd_alg == CRYPTO_MD5 || | | 2204 | crd1->crd_alg == CRYPTO_MD5 || |
2216 | crd1->crd_alg == CRYPTO_SHA1) && | | 2205 | crd1->crd_alg == CRYPTO_SHA1) && |
2217 | (crd2->crd_alg == CRYPTO_DES_CBC || | | 2206 | (crd2->crd_alg == CRYPTO_DES_CBC || |
2218 | crd2->crd_alg == CRYPTO_3DES_CBC || | | 2207 | crd2->crd_alg == CRYPTO_3DES_CBC || |
2219 | crd2->crd_alg == CRYPTO_AES_CBC || | | 2208 | crd2->crd_alg == CRYPTO_AES_CBC || |
| @@ -2238,30 +2227,26 @@ hifn_process(void *arg, struct cryptop * | | | @@ -2238,30 +2227,26 @@ hifn_process(void *arg, struct cryptop * |
2238 | * We cannot order the 7751 as requested | | 2227 | * We cannot order the 7751 as requested |
2239 | */ | | 2228 | */ |
2240 | err = EINVAL; | | 2229 | err = EINVAL; |
2241 | goto errout; | | 2230 | goto errout; |
2242 | } | | 2231 | } |
2243 | } | | 2232 | } |
2244 | | | 2233 | |
2245 | if (enccrd) { | | 2234 | if (enccrd) { |
2246 | cmd->enccrd = enccrd; | | 2235 | cmd->enccrd = enccrd; |
2247 | cmd->base_masks |= HIFN_BASE_CMD_CRYPT; | | 2236 | cmd->base_masks |= HIFN_BASE_CMD_CRYPT; |
2248 | switch (enccrd->crd_alg) { | | 2237 | switch (enccrd->crd_alg) { |
2249 | case CRYPTO_ARC4: | | 2238 | case CRYPTO_ARC4: |
2250 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4; | | 2239 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4; |
2251 | if ((enccrd->crd_flags & CRD_F_ENCRYPT) | | | |
2252 | != sc->sc_sessions[session].hs_prev_op) | | | |
2253 | sc->sc_sessions[session].hs_state = | | | |
2254 | HS_STATE_USED; | | | |
2255 | break; | | 2240 | break; |
2256 | case CRYPTO_DES_CBC: | | 2241 | case CRYPTO_DES_CBC: |
2257 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES | | | 2242 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES | |
2258 | HIFN_CRYPT_CMD_MODE_CBC | | | 2243 | HIFN_CRYPT_CMD_MODE_CBC | |
2259 | HIFN_CRYPT_CMD_NEW_IV; | | 2244 | HIFN_CRYPT_CMD_NEW_IV; |
2260 | break; | | 2245 | break; |
2261 | case CRYPTO_3DES_CBC: | | 2246 | case CRYPTO_3DES_CBC: |
2262 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES | | | 2247 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES | |
2263 | HIFN_CRYPT_CMD_MODE_CBC | | | 2248 | HIFN_CRYPT_CMD_MODE_CBC | |
2264 | HIFN_CRYPT_CMD_NEW_IV; | | 2249 | HIFN_CRYPT_CMD_NEW_IV; |
2265 | break; | | 2250 | break; |
2266 | case CRYPTO_AES_CBC: | | 2251 | case CRYPTO_AES_CBC: |
2267 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES | | | 2252 | cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES | |
| @@ -2269,78 +2254,76 @@ hifn_process(void *arg, struct cryptop * | | | @@ -2269,78 +2254,76 @@ hifn_process(void *arg, struct cryptop * |
2269 | HIFN_CRYPT_CMD_NEW_IV; | | 2254 | HIFN_CRYPT_CMD_NEW_IV; |
2270 | break; | | 2255 | break; |
2271 | default: | | 2256 | default: |
2272 | err = EINVAL; | | 2257 | err = EINVAL; |
2273 | goto errout; | | 2258 | goto errout; |
2274 | } | | 2259 | } |
2275 | if (enccrd->crd_alg != CRYPTO_ARC4) { | | 2260 | if (enccrd->crd_alg != CRYPTO_ARC4) { |
2276 | ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ? | | 2261 | ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ? |
2277 | HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); | | 2262 | HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); |
2278 | if (enccrd->crd_flags & CRD_F_ENCRYPT) { | | 2263 | if (enccrd->crd_flags & CRD_F_ENCRYPT) { |
2279 | if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) | | 2264 | if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) |
2280 | memcpy(cmd->iv, enccrd->crd_iv, ivlen); | | 2265 | memcpy(cmd->iv, enccrd->crd_iv, ivlen); |
2281 | else | | 2266 | else |
2282 | bcopy(sc->sc_sessions[session].hs_iv, | | 2267 | cprng_fast(cmd->iv, ivlen); |
2283 | cmd->iv, ivlen); | | | |
2284 | | | 2268 | |
2285 | if ((enccrd->crd_flags & CRD_F_IV_PRESENT) | | 2269 | if ((enccrd->crd_flags & CRD_F_IV_PRESENT) |
2286 | == 0) { | | 2270 | == 0) { |
2287 | if (crp->crp_flags & CRYPTO_F_IMBUF) | | 2271 | if (crp->crp_flags & CRYPTO_F_IMBUF) |
2288 | m_copyback(cmd->srcu.src_m, | | 2272 | m_copyback(cmd->srcu.src_m, |
2289 | enccrd->crd_inject, | | 2273 | enccrd->crd_inject, |
2290 | ivlen, cmd->iv); | | 2274 | ivlen, cmd->iv); |
2291 | else if (crp->crp_flags & CRYPTO_F_IOV) | | 2275 | else if (crp->crp_flags & CRYPTO_F_IOV) |
2292 | cuio_copyback(cmd->srcu.src_io, | | 2276 | cuio_copyback(cmd->srcu.src_io, |
2293 | enccrd->crd_inject, | | 2277 | enccrd->crd_inject, |
2294 | ivlen, cmd->iv); | | 2278 | ivlen, cmd->iv); |
2295 | } | | 2279 | } |
2296 | } else { | | 2280 | } else { |
2297 | if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) | | 2281 | if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) |
2298 | memcpy(cmd->iv, enccrd->crd_iv, ivlen); | | 2282 | memcpy(cmd->iv, enccrd->crd_iv, ivlen); |
2299 | else if (crp->crp_flags & CRYPTO_F_IMBUF) | | 2283 | else if (crp->crp_flags & CRYPTO_F_IMBUF) |
2300 | m_copydata(cmd->srcu.src_m, | | 2284 | m_copydata(cmd->srcu.src_m, |
2301 | enccrd->crd_inject, ivlen, cmd->iv); | | 2285 | enccrd->crd_inject, ivlen, cmd->iv); |
2302 | else if (crp->crp_flags & CRYPTO_F_IOV) | | 2286 | else if (crp->crp_flags & CRYPTO_F_IOV) |
2303 | cuio_copydata(cmd->srcu.src_io, | | 2287 | cuio_copydata(cmd->srcu.src_io, |
2304 | enccrd->crd_inject, ivlen, cmd->iv); | | 2288 | enccrd->crd_inject, |
| | | 2289 | ivlen, cmd->iv); |
2305 | } | | 2290 | } |
2306 | } | | 2291 | } |
2307 | | | 2292 | |
2308 | cmd->ck = enccrd->crd_key; | | 2293 | cmd->ck = enccrd->crd_key; |
2309 | cmd->cklen = enccrd->crd_klen >> 3; | | 2294 | cmd->cklen = enccrd->crd_klen >> 3; |
| | | 2295 | cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY; |
2310 | | | 2296 | |
2311 | /* | | 2297 | /* |
2312 | * Need to specify the size for the AES key in the masks. | | 2298 | * Need to specify the size for the AES key in the masks. |
2313 | */ | | 2299 | */ |
2314 | if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == | | 2300 | if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == |
2315 | HIFN_CRYPT_CMD_ALG_AES) { | | 2301 | HIFN_CRYPT_CMD_ALG_AES) { |
2316 | switch (cmd->cklen) { | | 2302 | switch (cmd->cklen) { |
2317 | case 16: | | 2303 | case 16: |
2318 | cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128; | | 2304 | cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128; |
2319 | break; | | 2305 | break; |
2320 | case 24: | | 2306 | case 24: |
2321 | cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192; | | 2307 | cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192; |
2322 | break; | | 2308 | break; |
2323 | case 32: | | 2309 | case 32: |
2324 | cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256; | | 2310 | cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256; |
2325 | break; | | 2311 | break; |
2326 | default: | | 2312 | default: |
2327 | err = EINVAL; | | 2313 | err = EINVAL; |
2328 | goto errout; | | 2314 | goto errout; |
2329 | } | | 2315 | } |
2330 | } | | 2316 | } |
2331 | | | | |
2332 | if (sc->sc_sessions[session].hs_state == HS_STATE_USED) | | | |
2333 | cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY; | | | |
2334 | } | | 2317 | } |
2335 | | | 2318 | |
2336 | if (maccrd) { | | 2319 | if (maccrd) { |
2337 | cmd->maccrd = maccrd; | | 2320 | cmd->maccrd = maccrd; |
2338 | cmd->base_masks |= HIFN_BASE_CMD_MAC; | | 2321 | cmd->base_masks |= HIFN_BASE_CMD_MAC; |
2339 | | | 2322 | |
2340 | switch (maccrd->crd_alg) { | | 2323 | switch (maccrd->crd_alg) { |
2341 | case CRYPTO_MD5: | | 2324 | case CRYPTO_MD5: |
2342 | cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 | | | 2325 | cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 | |
2343 | HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH | | | 2326 | HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH | |
2344 | HIFN_MAC_CMD_POS_IPSEC; | | 2327 | HIFN_MAC_CMD_POS_IPSEC; |
2345 | break; | | 2328 | break; |
2346 | case CRYPTO_MD5_HMAC_96: | | 2329 | case CRYPTO_MD5_HMAC_96: |
| @@ -2350,68 +2333,63 @@ hifn_process(void *arg, struct cryptop * | | | @@ -2350,68 +2333,63 @@ hifn_process(void *arg, struct cryptop * |
2350 | break; | | 2333 | break; |
2351 | case CRYPTO_SHA1: | | 2334 | case CRYPTO_SHA1: |
2352 | cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 | | | 2335 | cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 | |
2353 | HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH | | | 2336 | HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH | |
2354 | HIFN_MAC_CMD_POS_IPSEC; | | 2337 | HIFN_MAC_CMD_POS_IPSEC; |
2355 | break; | | 2338 | break; |
2356 | case CRYPTO_SHA1_HMAC_96: | | 2339 | case CRYPTO_SHA1_HMAC_96: |
2357 | cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 | | | 2340 | cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 | |
2358 | HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC | | | 2341 | HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC | |
2359 | HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC; | | 2342 | HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC; |
2360 | break; | | 2343 | break; |
2361 | } | | 2344 | } |
2362 | | | 2345 | |
2363 | if ((maccrd->crd_alg == CRYPTO_SHA1_HMAC_96 || | | 2346 | if (maccrd->crd_alg == CRYPTO_SHA1_HMAC_96 || |
2364 | maccrd->crd_alg == CRYPTO_MD5_HMAC_96) && | | 2347 | maccrd->crd_alg == CRYPTO_MD5_HMAC_96) { |
2365 | sc->sc_sessions[session].hs_state == HS_STATE_USED) { | | | |
2366 | cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY; | | 2348 | cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY; |
2367 | memcpy(cmd->mac, maccrd->crd_key, maccrd->crd_klen >> 3); | | 2349 | memcpy(cmd->mac, maccrd->crd_key, maccrd->crd_klen >> 3); |
2368 | memset(cmd->mac + (maccrd->crd_klen >> 3), 0, | | 2350 | memset(cmd->mac + (maccrd->crd_klen >> 3), 0, |
2369 | HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3)); | | 2351 | HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3)); |
2370 | } | | 2352 | } |
2371 | } | | 2353 | } |
2372 | | | 2354 | |
2373 | cmd->crp = crp; | | 2355 | cmd->crp = crp; |
2374 | cmd->session_num = session; | | 2356 | cmd->session_num = session; |
2375 | cmd->softc = sc; | | 2357 | cmd->softc = sc; |
2376 | | | 2358 | |
2377 | err = hifn_crypto(sc, cmd, crp, hint); | | 2359 | err = hifn_crypto(sc, cmd, crp, hint); |
2378 | if (err == 0) { | | 2360 | if (err == 0) { |
2379 | if (enccrd) | | | |
2380 | sc->sc_sessions[session].hs_prev_op = | | | |
2381 | enccrd->crd_flags & CRD_F_ENCRYPT; | | | |
2382 | if (sc->sc_sessions[session].hs_state == HS_STATE_USED) | | | |
2383 | sc->sc_sessions[session].hs_state = HS_STATE_KEY; | | | |
2384 | mutex_spin_exit(&sc->sc_mtx); | | | |
2385 | return 0; | | 2361 | return 0; |
2386 | } else if (err == ERESTART) { | | 2362 | } else if (err == ERESTART) { |
2387 | /* | | 2363 | /* |
2388 | * There weren't enough resources to dispatch the request | | 2364 | * There weren't enough resources to dispatch the request |
2389 | * to the part. Notify the caller so they'll requeue this | | 2365 | * to the part. Notify the caller so they'll requeue this |
2390 | * request and resubmit it again soon. | | 2366 | * request and resubmit it again soon. |
2391 | */ | | 2367 | */ |
2392 | #ifdef HIFN_DEBUG | | 2368 | #ifdef HIFN_DEBUG |
2393 | if (hifn_debug) | | 2369 | if (hifn_debug) |
2394 | printf("%s: requeue request\n", device_xname(sc->sc_dv)); | | 2370 | printf("%s: requeue request\n", device_xname(sc->sc_dv)); |
2395 | #endif | | 2371 | #endif |
2396 | free(cmd, M_DEVBUF); | | 2372 | free(cmd, M_DEVBUF); |
2397 | sc->sc_needwakeup |= CRYPTO_SYMQ; | | 2373 | sc->sc_needwakeup |= CRYPTO_SYMQ; |
2398 | mutex_spin_exit(&sc->sc_mtx); | | 2374 | mutex_spin_exit(&sc->sc_mtx); |
2399 | return (err); | | 2375 | return (err); |
2400 | } | | 2376 | } |
2401 | | | 2377 | |
2402 | errout: | | 2378 | errout: |
2403 | if (cmd != NULL) | | 2379 | if (cmd != NULL) { |
| | | 2380 | explicit_memset(cmd, 0, sizeof(*cmd)); |
2404 | free(cmd, M_DEVBUF); | | 2381 | free(cmd, M_DEVBUF); |
| | | 2382 | } |
2405 | if (err == EINVAL) | | 2383 | if (err == EINVAL) |
2406 | hifnstats.hst_invalid++; | | 2384 | hifnstats.hst_invalid++; |
2407 | else | | 2385 | else |
2408 | hifnstats.hst_nomem++; | | 2386 | hifnstats.hst_nomem++; |
2409 | crp->crp_etype = err; | | 2387 | crp->crp_etype = err; |
2410 | mutex_spin_exit(&sc->sc_mtx); | | 2388 | mutex_spin_exit(&sc->sc_mtx); |
2411 | crypto_done(crp); | | 2389 | crypto_done(crp); |
2412 | return (0); | | 2390 | return (0); |
2413 | } | | 2391 | } |
2414 | | | 2392 | |
2415 | static void | | 2393 | static void |
2416 | hifn_abort(struct hifn_softc *sc) | | 2394 | hifn_abort(struct hifn_softc *sc) |
2417 | { | | 2395 | { |
| @@ -2455,55 +2433,51 @@ hifn_abort(struct hifn_softc *sc) | | | @@ -2455,55 +2433,51 @@ hifn_abort(struct hifn_softc *sc) |
2455 | /* | | 2433 | /* |
2456 | * XXX should be EAGAIN, delayed until | | 2434 | * XXX should be EAGAIN, delayed until |
2457 | * after the reset. | | 2435 | * after the reset. |
2458 | */ | | 2436 | */ |
2459 | crp->crp_etype = ENOMEM; | | 2437 | crp->crp_etype = ENOMEM; |
2460 | bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); | | 2438 | bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); |
2461 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); | | 2439 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); |
2462 | } else | | 2440 | } else |
2463 | crp->crp_etype = ENOMEM; | | 2441 | crp->crp_etype = ENOMEM; |
2464 | | | 2442 | |
2465 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); | | 2443 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); |
2466 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); | | 2444 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); |
2467 | | | 2445 | |
| | | 2446 | explicit_memset(cmd, 0, sizeof(*cmd)); |
2468 | free(cmd, M_DEVBUF); | | 2447 | free(cmd, M_DEVBUF); |
2469 | if (crp->crp_etype != EAGAIN) | | 2448 | if (crp->crp_etype != EAGAIN) |
2470 | crypto_done(crp); | | 2449 | crypto_done(crp); |
2471 | } | | 2450 | } |
2472 | | | 2451 | |
2473 | if (++i == HIFN_D_RES_RSIZE) | | 2452 | if (++i == HIFN_D_RES_RSIZE) |
2474 | i = 0; | | 2453 | i = 0; |
2475 | u--; | | 2454 | u--; |
2476 | } | | 2455 | } |
2477 | dma->resk = i; dma->resu = u; | | 2456 | dma->resk = i; dma->resu = u; |
2478 | | | 2457 | |
2479 | /* Force upload of key next time */ | | | |
2480 | for (i = 0; i < sc->sc_maxses; i++) | | | |
2481 | if (sc->sc_sessions[i].hs_state == HS_STATE_KEY) | | | |
2482 | sc->sc_sessions[i].hs_state = HS_STATE_USED; | | | |
2483 | | | | |
2484 | hifn_reset_board(sc, 1); | | 2458 | hifn_reset_board(sc, 1); |
2485 | hifn_init_dma(sc); | | 2459 | hifn_init_dma(sc); |
2486 | hifn_init_pci_registers(sc); | | 2460 | hifn_init_pci_registers(sc); |
2487 | } | | 2461 | } |
2488 | | | 2462 | |
2489 | static void | | 2463 | static void |
2490 | hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, uint8_t *resbuf) | | 2464 | hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, uint8_t *resbuf) |
2491 | { | | 2465 | { |
2492 | struct hifn_dma *dma = sc->sc_dma; | | 2466 | struct hifn_dma *dma = sc->sc_dma; |
2493 | struct cryptop *crp = cmd->crp; | | 2467 | struct cryptop *crp = cmd->crp; |
2494 | struct cryptodesc *crd; | | 2468 | struct cryptodesc *crd; |
2495 | struct mbuf *m; | | 2469 | struct mbuf *m; |
2496 | int totlen, i, u, ivlen; | | 2470 | int totlen, i, u; |
2497 | | | 2471 | |
2498 | if (cmd->src_map == cmd->dst_map) | | 2472 | if (cmd->src_map == cmd->dst_map) |
2499 | bus_dmamap_sync(sc->sc_dmat, cmd->src_map, | | 2473 | bus_dmamap_sync(sc->sc_dmat, cmd->src_map, |
2500 | 0, cmd->src_map->dm_mapsize, | | 2474 | 0, cmd->src_map->dm_mapsize, |
2501 | BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); | | 2475 | BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); |
2502 | else { | | 2476 | else { |
2503 | bus_dmamap_sync(sc->sc_dmat, cmd->src_map, | | 2477 | bus_dmamap_sync(sc->sc_dmat, cmd->src_map, |
2504 | 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); | | 2478 | 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); |
2505 | bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, | | 2479 | bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, |
2506 | 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); | | 2480 | 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); |
2507 | } | | 2481 | } |
2508 | | | 2482 | |
2509 | if (crp->crp_flags & CRYPTO_F_IMBUF) { | | 2483 | if (crp->crp_flags & CRYPTO_F_IMBUF) { |
| @@ -2517,79 +2491,54 @@ hifn_callback(struct hifn_softc *sc, str | | | @@ -2517,79 +2491,54 @@ hifn_callback(struct hifn_softc *sc, str |
2517 | } else | | 2491 | } else |
2518 | totlen -= m->m_len; | | 2492 | totlen -= m->m_len; |
2519 | } | | 2493 | } |
2520 | cmd->dstu.dst_m->m_pkthdr.len = | | 2494 | cmd->dstu.dst_m->m_pkthdr.len = |
2521 | cmd->srcu.src_m->m_pkthdr.len; | | 2495 | cmd->srcu.src_m->m_pkthdr.len; |
2522 | m_freem(cmd->srcu.src_m); | | 2496 | m_freem(cmd->srcu.src_m); |
2523 | } | | 2497 | } |
2524 | } | | 2498 | } |
2525 | | | 2499 | |
2526 | if (cmd->sloplen != 0) { | | 2500 | if (cmd->sloplen != 0) { |
2527 | if (crp->crp_flags & CRYPTO_F_IMBUF) | | 2501 | if (crp->crp_flags & CRYPTO_F_IMBUF) |
2528 | m_copyback((struct mbuf *)crp->crp_buf, | | 2502 | m_copyback((struct mbuf *)crp->crp_buf, |
2529 | cmd->src_map->dm_mapsize - cmd->sloplen, | | 2503 | cmd->src_map->dm_mapsize - cmd->sloplen, |
2530 | cmd->sloplen, (void *)&dma->slop[cmd->slopidx]); | | 2504 | cmd->sloplen, &dma->slop[cmd->slopidx]); |
2531 | else if (crp->crp_flags & CRYPTO_F_IOV) | | 2505 | else if (crp->crp_flags & CRYPTO_F_IOV) |
2532 | cuio_copyback((struct uio *)crp->crp_buf, | | 2506 | cuio_copyback((struct uio *)crp->crp_buf, |
2533 | cmd->src_map->dm_mapsize - cmd->sloplen, | | 2507 | cmd->src_map->dm_mapsize - cmd->sloplen, |
2534 | cmd->sloplen, (void *)&dma->slop[cmd->slopidx]); | | 2508 | cmd->sloplen, &dma->slop[cmd->slopidx]); |
2535 | } | | 2509 | } |
2536 | | | 2510 | |
2537 | i = dma->dstk; u = dma->dstu; | | 2511 | i = dma->dstk; u = dma->dstu; |
2538 | while (u != 0) { | | 2512 | while (u != 0) { |
2539 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, | | 2513 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, |
2540 | offsetof(struct hifn_dma, dstr[i]), sizeof(struct hifn_desc), | | 2514 | offsetof(struct hifn_dma, dstr[i]), sizeof(struct hifn_desc), |
2541 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | | 2515 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
2542 | if (dma->dstr[i].l & htole32(HIFN_D_VALID)) { | | 2516 | if (dma->dstr[i].l & htole32(HIFN_D_VALID)) { |
2543 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, | | 2517 | bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, |
2544 | offsetof(struct hifn_dma, dstr[i]), | | 2518 | offsetof(struct hifn_dma, dstr[i]), |
2545 | sizeof(struct hifn_desc), | | 2519 | sizeof(struct hifn_desc), |
2546 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); | | 2520 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); |
2547 | break; | | 2521 | break; |
2548 | } | | 2522 | } |
2549 | if (++i == (HIFN_D_DST_RSIZE + 1)) | | 2523 | if (++i == (HIFN_D_DST_RSIZE + 1)) |
2550 | i = 0; | | 2524 | i = 0; |
2551 | else | | 2525 | else |
2552 | u--; | | 2526 | u--; |
2553 | } | | 2527 | } |
2554 | dma->dstk = i; dma->dstu = u; | | 2528 | dma->dstk = i; dma->dstu = u; |
2555 | | | 2529 | |
2556 | hifnstats.hst_obytes += cmd->dst_map->dm_mapsize; | | 2530 | hifnstats.hst_obytes += cmd->dst_map->dm_mapsize; |
2557 | | | 2531 | |
2558 | if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) == | | | |
2559 | HIFN_BASE_CMD_CRYPT) { | | | |
2560 | for (crd = crp->crp_desc; crd; crd = crd->crd_next) { | | | |
2561 | if (crd->crd_alg != CRYPTO_DES_CBC && | | | |
2562 | crd->crd_alg != CRYPTO_3DES_CBC && | | | |
2563 | crd->crd_alg != CRYPTO_AES_CBC) | | | |
2564 | continue; | | | |
2565 | ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ? | | | |
2566 | HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); | | | |
2567 | if (crp->crp_flags & CRYPTO_F_IMBUF) | | | |
2568 | m_copydata((struct mbuf *)crp->crp_buf, | | | |
2569 | crd->crd_skip + crd->crd_len - ivlen, | | | |
2570 | ivlen, | | | |
2571 | cmd->softc->sc_sessions[cmd->session_num].hs_iv); | | | |
2572 | else if (crp->crp_flags & CRYPTO_F_IOV) { | | | |
2573 | cuio_copydata((struct uio *)crp->crp_buf, | | | |
2574 | crd->crd_skip + crd->crd_len - ivlen, | | | |
2575 | ivlen, | | | |
2576 | cmd->softc->sc_sessions[cmd->session_num].hs_iv); | | | |
2577 | } | | | |
2578 | /* XXX We do not handle contig data */ | | | |
2579 | break; | | | |
2580 | } | | | |
2581 | } | | | |
2582 | | | | |
2583 | if (cmd->base_masks & HIFN_BASE_CMD_MAC) { | | 2532 | if (cmd->base_masks & HIFN_BASE_CMD_MAC) { |
2584 | uint8_t *macbuf; | | 2533 | uint8_t *macbuf; |
2585 | | | 2534 | |
2586 | macbuf = resbuf + sizeof(struct hifn_base_result); | | 2535 | macbuf = resbuf + sizeof(struct hifn_base_result); |
2587 | if (cmd->base_masks & HIFN_BASE_CMD_COMP) | | 2536 | if (cmd->base_masks & HIFN_BASE_CMD_COMP) |
2588 | macbuf += sizeof(struct hifn_comp_result); | | 2537 | macbuf += sizeof(struct hifn_comp_result); |
2589 | macbuf += sizeof(struct hifn_mac_result); | | 2538 | macbuf += sizeof(struct hifn_mac_result); |
2590 | | | 2539 | |
2591 | for (crd = crp->crp_desc; crd; crd = crd->crd_next) { | | 2540 | for (crd = crp->crp_desc; crd; crd = crd->crd_next) { |
2592 | int len; | | 2541 | int len; |
2593 | | | 2542 | |
2594 | if (crd->crd_alg == CRYPTO_MD5) | | 2543 | if (crd->crd_alg == CRYPTO_MD5) |
2595 | len = 16; | | 2544 | len = 16; |
| @@ -2606,26 +2555,27 @@ hifn_callback(struct hifn_softc *sc, str | | | @@ -2606,26 +2555,27 @@ hifn_callback(struct hifn_softc *sc, str |
2606 | crd->crd_inject, len, macbuf); | | 2555 | crd->crd_inject, len, macbuf); |
2607 | else if ((crp->crp_flags & CRYPTO_F_IOV) && crp->crp_mac) | | 2556 | else if ((crp->crp_flags & CRYPTO_F_IOV) && crp->crp_mac) |
2608 | memcpy(crp->crp_mac, (void *)macbuf, len); | | 2557 | memcpy(crp->crp_mac, (void *)macbuf, len); |
2609 | break; | | 2558 | break; |
2610 | } | | 2559 | } |
2611 | } | | 2560 | } |
2612 | | | 2561 | |
2613 | if (cmd->src_map != cmd->dst_map) { | | 2562 | if (cmd->src_map != cmd->dst_map) { |
2614 | bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); | | 2563 | bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); |
2615 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); | | 2564 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); |
2616 | } | | 2565 | } |
2617 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); | | 2566 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); |
2618 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); | | 2567 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); |
| | | 2568 | explicit_memset(cmd, 0, sizeof(*cmd)); |
2619 | free(cmd, M_DEVBUF); | | 2569 | free(cmd, M_DEVBUF); |
2620 | crypto_done(crp); | | 2570 | crypto_done(crp); |
2621 | } | | 2571 | } |
2622 | | | 2572 | |
2623 | #ifdef CRYPTO_LZS_COMP | | 2573 | #ifdef CRYPTO_LZS_COMP |
2624 | | | 2574 | |
2625 | static int | | 2575 | static int |
2626 | hifn_compression(struct hifn_softc *sc, struct cryptop *crp, | | 2576 | hifn_compression(struct hifn_softc *sc, struct cryptop *crp, |
2627 | struct hifn_command *cmd) | | 2577 | struct hifn_command *cmd) |
2628 | { | | 2578 | { |
2629 | struct cryptodesc *crd = crp->crp_desc; | | 2579 | struct cryptodesc *crd = crp->crp_desc; |
2630 | int s, err = 0; | | 2580 | int s, err = 0; |
2631 | | | 2581 | |
| @@ -2730,26 +2680,27 @@ hifn_compression(struct hifn_softc *sc, | | | @@ -2730,26 +2680,27 @@ hifn_compression(struct hifn_softc *sc, |
2730 | return (0); | | 2680 | return (0); |
2731 | | | 2681 | |
2732 | fail: | | 2682 | fail: |
2733 | if (cmd->dst_map != NULL) { | | 2683 | if (cmd->dst_map != NULL) { |
2734 | if (cmd->dst_map->dm_nsegs > 0) | | 2684 | if (cmd->dst_map->dm_nsegs > 0) |
2735 | bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); | | 2685 | bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); |
2736 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); | | 2686 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); |
2737 | } | | 2687 | } |
2738 | if (cmd->src_map != NULL) { | | 2688 | if (cmd->src_map != NULL) { |
2739 | if (cmd->src_map->dm_nsegs > 0) | | 2689 | if (cmd->src_map->dm_nsegs > 0) |
2740 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); | | 2690 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); |
2741 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); | | 2691 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); |
2742 | } | | 2692 | } |
| | | 2693 | explicit_memset(cmd, 0, sizeof(*cmd)); |
2743 | free(cmd, M_DEVBUF); | | 2694 | free(cmd, M_DEVBUF); |
2744 | if (err == EINVAL) | | 2695 | if (err == EINVAL) |
2745 | hifnstats.hst_invalid++; | | 2696 | hifnstats.hst_invalid++; |
2746 | else | | 2697 | else |
2747 | hifnstats.hst_nomem++; | | 2698 | hifnstats.hst_nomem++; |
2748 | crp->crp_etype = err; | | 2699 | crp->crp_etype = err; |
2749 | crypto_done(crp); | | 2700 | crypto_done(crp); |
2750 | return (0); | | 2701 | return (0); |
2751 | } | | 2702 | } |
2752 | | | 2703 | |
2753 | static int | | 2704 | static int |
2754 | hifn_compress_enter(struct hifn_softc *sc, struct hifn_command *cmd) | | 2705 | hifn_compress_enter(struct hifn_softc *sc, struct hifn_command *cmd) |
2755 | { | | 2706 | { |
| @@ -2779,34 +2730,33 @@ hifn_compress_enter(struct hifn_softc *s | | | @@ -2779,34 +2730,33 @@ hifn_compress_enter(struct hifn_softc *s |
2779 | /* .p for command/result already set */ | | 2730 | /* .p for command/result already set */ |
2780 | dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_VALID | HIFN_D_LAST | | | 2731 | dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_VALID | HIFN_D_LAST | |
2781 | HIFN_D_MASKDONEIRQ); | | 2732 | HIFN_D_MASKDONEIRQ); |
2782 | HIFN_CMDR_SYNC(sc, cmdi, | | 2733 | HIFN_CMDR_SYNC(sc, cmdi, |
2783 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); | | 2734 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); |
2784 | dma->cmdu++; | | 2735 | dma->cmdu++; |
2785 | if (sc->sc_c_busy == 0) { | | 2736 | if (sc->sc_c_busy == 0) { |
2786 | WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); | | 2737 | WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); |
2787 | sc->sc_c_busy = 1; | | 2738 | sc->sc_c_busy = 1; |
2788 | SET_LED(sc, HIFN_MIPSRST_LED0); | | 2739 | SET_LED(sc, HIFN_MIPSRST_LED0); |
2789 | } | | 2740 | } |
2790 | | | 2741 | |
2791 | /* | | 2742 | /* |
2792 | * We don't worry about missing an interrupt (which a "command wait" | | 2743 | * Always enable the command wait interrupt. We are obviously |
2793 | * interrupt salvages us from), unless there is more than one command | | 2744 | * missing an interrupt or two somewhere. Enabling the command wait |
2794 | * in the queue. | | 2745 | * interrupt will guarantee we get called periodically until all |
| | | 2746 | * of the queues are drained and thus work around this. |
2795 | */ | | 2747 | */ |
2796 | if (dma->cmdu > 1) { | | 2748 | sc->sc_dmaier |= HIFN_DMAIER_C_WAIT; |
2797 | sc->sc_dmaier |= HIFN_DMAIER_C_WAIT; | | 2749 | WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); |
2798 | WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); | | | |
2799 | } | | | |
2800 | | | 2750 | |
2801 | hifnstats.hst_ipackets++; | | 2751 | hifnstats.hst_ipackets++; |
2802 | hifnstats.hst_ibytes += cmd->src_map->dm_mapsize; | | 2752 | hifnstats.hst_ibytes += cmd->src_map->dm_mapsize; |
2803 | | | 2753 | |
2804 | hifn_dmamap_load_src(sc, cmd); | | 2754 | hifn_dmamap_load_src(sc, cmd); |
2805 | if (sc->sc_s_busy == 0) { | | 2755 | if (sc->sc_s_busy == 0) { |
2806 | WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); | | 2756 | WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); |
2807 | sc->sc_s_busy = 1; | | 2757 | sc->sc_s_busy = 1; |
2808 | SET_LED(sc, HIFN_MIPSRST_LED1); | | 2758 | SET_LED(sc, HIFN_MIPSRST_LED1); |
2809 | } | | 2759 | } |
2810 | | | 2760 | |
2811 | /* | | 2761 | /* |
2812 | * Unlike other descriptors, we don't mask done interrupt from | | 2762 | * Unlike other descriptors, we don't mask done interrupt from |
| @@ -2943,86 +2893,87 @@ hifn_callback_comp(struct hifn_softc *sc | | | @@ -2943,86 +2893,87 @@ hifn_callback_comp(struct hifn_softc *sc |
2943 | if (m->m_flags & M_PKTHDR) | | 2893 | if (m->m_flags & M_PKTHDR) |
2944 | m->m_pkthdr.len = olen; | | 2894 | m->m_pkthdr.len = olen; |
2945 | crp->crp_buf = (void *)m; | | 2895 | crp->crp_buf = (void *)m; |
2946 | for (; m != NULL; m = m->m_next) { | | 2896 | for (; m != NULL; m = m->m_next) { |
2947 | if (olen >= m->m_len) | | 2897 | if (olen >= m->m_len) |
2948 | olen -= m->m_len; | | 2898 | olen -= m->m_len; |
2949 | else { | | 2899 | else { |
2950 | m->m_len = olen; | | 2900 | m->m_len = olen; |
2951 | olen = 0; | | 2901 | olen = 0; |
2952 | } | | 2902 | } |
2953 | } | | 2903 | } |
2954 | | | 2904 | |
2955 | m_freem(cmd->srcu.src_m); | | 2905 | m_freem(cmd->srcu.src_m); |
| | | 2906 | explicit_memset(cmd, 0, sizeof(*cmd)); |
2956 | free(cmd, M_DEVBUF); | | 2907 | free(cmd, M_DEVBUF); |
2957 | crp->crp_etype = 0; | | 2908 | crp->crp_etype = 0; |
2958 | crypto_done(crp); | | 2909 | crypto_done(crp); |
2959 | return; | | 2910 | return; |
2960 | | | 2911 | |
2961 | out: | | 2912 | out: |
2962 | if (cmd->dst_map != NULL) { | | 2913 | if (cmd->dst_map != NULL) { |
2963 | if (cmd->src_map->dm_nsegs != 0) | | 2914 | if (cmd->src_map->dm_nsegs != 0) |
2964 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); | | 2915 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); |
2965 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); | | 2916 | bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); |
2966 | } | | 2917 | } |
2967 | if (cmd->src_map != NULL) { | | 2918 | if (cmd->src_map != NULL) { |
2968 | if (cmd->src_map->dm_nsegs != 0) | | 2919 | if (cmd->src_map->dm_nsegs != 0) |
2969 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); | | 2920 | bus_dmamap_unload(sc->sc_dmat, cmd->src_map); |
2970 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); | | 2921 | bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); |
2971 | } | | 2922 | } |
2972 | if (cmd->dstu.dst_m != NULL) | | 2923 | m_freem(cmd->dstu.dst_m); |
2973 | m_freem(cmd->dstu.dst_m); | | 2924 | explicit_memset(cmd, 0, sizeof(*cmd)); |
2974 | free(cmd, M_DEVBUF); | | 2925 | free(cmd, M_DEVBUF); |
2975 | crp->crp_etype = err; | | 2926 | crp->crp_etype = err; |
2976 | crypto_done(crp); | | 2927 | crypto_done(crp); |
2977 | } | | 2928 | } |
2978 | | | 2929 | |
2979 | static struct mbuf * | | 2930 | static struct mbuf * |
2980 | hifn_mkmbuf_chain(int totlen, struct mbuf *mtemplate) | | 2931 | hifn_mkmbuf_chain(int totlen, struct mbuf *mtemplate) |
2981 | { | | 2932 | { |
2982 | int len; | | 2933 | int len; |
2983 | struct mbuf *m, *m0, *mlast; | | 2934 | struct mbuf *m, *m0, *mlast; |
2984 | | | 2935 | |
2985 | if (mtemplate->m_flags & M_PKTHDR) { | | 2936 | if (mtemplate->m_flags & M_PKTHDR) { |
2986 | len = MHLEN; | | 2937 | len = MHLEN; |
2987 | MGETHDR(m0, M_DONTWAIT, MT_DATA); | | 2938 | MGETHDR(m0, M_DONTWAIT, MT_DATA); |
2988 | } else { | | 2939 | } else { |
2989 | len = MLEN; | | 2940 | len = MLEN; |
2990 | MGET(m0, M_DONTWAIT, MT_DATA); | | 2941 | MGET(m0, M_DONTWAIT, MT_DATA); |
2991 | } | | 2942 | } |
2992 | if (m0 == NULL) | | 2943 | if (m0 == NULL) |
2993 | return (NULL); | | 2944 | return (NULL); |
2994 | if (len == MHLEN) | | 2945 | if (len == MHLEN) |
2995 | m_copy_pkthdr(m0, mtemplate); | | 2946 | m_copy_pkthdr(m0, mtemplate); |
2996 | MCLGET(m0, M_DONTWAIT); | | 2947 | MCLGET(m0, M_DONTWAIT); |
2997 | if (!(m0->m_flags & M_EXT)) { | | 2948 | if (!(m0->m_flags & M_EXT)) { |
2998 | m_freem(m0); | | 2949 | m_freem(m0); |
2999 | return (NULL); | | 2950 | return (NULL); |
3000 | } | | 2951 | } |
3001 | len = MCLBYTES; | | 2952 | len = MCLBYTES; |
3002 | | | 2953 | |
3003 | totlen -= len; | | 2954 | totlen -= len; |
3004 | m0->m_pkthdr.len = m0->m_len = len; | | 2955 | m0->m_pkthdr.len = m0->m_len = len; |
3005 | mlast = m0; | | 2956 | mlast = m0; |
3006 | | | 2957 | |
3007 | while (totlen > 0) { | | 2958 | while (totlen > 0) { |
3008 | MGET(m, M_DONTWAIT, MT_DATA); | | 2959 | MGET(m, M_DONTWAIT, MT_DATA); |
3009 | if (m == NULL) { | | 2960 | if (m == NULL) { |
3010 | m_freem(m0); | | 2961 | m_freem(m0); |
3011 | return (NULL); | | 2962 | return (NULL); |
3012 | } | | 2963 | } |
3013 | MCLGET(m, M_DONTWAIT); | | 2964 | MCLGET(m, M_DONTWAIT); |
3014 | if (!(m->m_flags & M_EXT)) { | | 2965 | if (!(m->m_flags & M_EXT)) { |
3015 | m_freem(m); | | 2966 | m_free(m); |
3016 | m_freem(m0); | | 2967 | m_freem(m0); |
3017 | return (NULL); | | 2968 | return (NULL); |
3018 | } | | 2969 | } |
3019 | len = MCLBYTES; | | 2970 | len = MCLBYTES; |
3020 | m->m_len = len; | | 2971 | m->m_len = len; |
3021 | if (m0->m_flags & M_PKTHDR) | | 2972 | if (m0->m_flags & M_PKTHDR) |
3022 | m0->m_pkthdr.len += len; | | 2973 | m0->m_pkthdr.len += len; |
3023 | totlen -= len; | | 2974 | totlen -= len; |
3024 | | | 2975 | |
3025 | mlast->m_next = m; | | 2976 | mlast->m_next = m; |
3026 | mlast = m; | | 2977 | mlast = m; |
3027 | } | | 2978 | } |
3028 | | | 2979 | |