From 0a828ff411488e1a963fd133dc1a6a59163b1769 Mon Sep 17 00:00:00 2001 From: bluhm Date: Thu, 21 Oct 2021 18:36:41 +0000 Subject: [PATCH] Remove hifn(4), safe(4), and ubsec(4) crypto drivers. They require the asynchronous crypto API which makes progress in MP difficult. The hardware is rarely available. They support only obsolete crypto algorithms. Scheduling crypto tasks via PCI is probably slower than the CPU, especailly as modern CPUs have their own accelerators. --- distrib/sets/lists/comp/mi | 6 - distrib/sets/lists/man/mi | 3 - share/man/man4/Makefile | 8 +- share/man/man4/hifn.4 | 114 -- share/man/man4/pci.4 | 10 +- share/man/man4/safe.4 | 75 - share/man/man4/ubsec.4 | 100 -- sys/arch/alpha/conf/GENERIC | 7 +- sys/arch/amd64/conf/GENERIC | 7 +- sys/arch/i386/conf/GENERIC | 5 +- sys/arch/macppc/conf/GENERIC | 6 +- sys/arch/sparc64/conf/GENERIC | 6 +- sys/dev/pci/files.pci | 17 +- sys/dev/pci/hifn7751.c | 2771 --------------------------------- sys/dev/pci/hifn7751reg.h | 523 ------- sys/dev/pci/hifn7751var.h | 324 ---- sys/dev/pci/safe.c | 1829 ---------------------- sys/dev/pci/safereg.h | 413 ----- sys/dev/pci/safevar.h | 205 --- sys/dev/pci/ubsec.c | 1742 --------------------- sys/dev/pci/ubsecreg.h | 252 --- sys/dev/pci/ubsecvar.h | 175 --- 22 files changed, 12 insertions(+), 8586 deletions(-) delete mode 100644 share/man/man4/hifn.4 delete mode 100644 share/man/man4/safe.4 delete mode 100644 share/man/man4/ubsec.4 delete mode 100644 sys/dev/pci/hifn7751.c delete mode 100644 sys/dev/pci/hifn7751reg.h delete mode 100644 sys/dev/pci/hifn7751var.h delete mode 100644 sys/dev/pci/safe.c delete mode 100644 sys/dev/pci/safereg.h delete mode 100644 sys/dev/pci/safevar.h delete mode 100644 sys/dev/pci/ubsec.c delete mode 100644 sys/dev/pci/ubsecreg.h delete mode 100644 sys/dev/pci/ubsecvar.h diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index dd17957a219..242acdac677 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -542,8 +542,6 @@ ./usr/include/dev/pci/gcu_var.h ./usr/include/dev/pci/glxreg.h ./usr/include/dev/pci/glxvar.h -./usr/include/dev/pci/hifn7751reg.h -./usr/include/dev/pci/hifn7751var.h ./usr/include/dev/pci/i82365_pcivar.h ./usr/include/dev/pci/ichreg.h ./usr/include/dev/pci/if_agereg.h @@ -645,13 +643,9 @@ ./usr/include/dev/pci/ppbreg.h ./usr/include/dev/pci/pucvar.h ./usr/include/dev/pci/qlereg.h -./usr/include/dev/pci/safereg.h -./usr/include/dev/pci/safevar.h ./usr/include/dev/pci/siop_pci_common.h ./usr/include/dev/pci/tgareg.h ./usr/include/dev/pci/tgavar.h -./usr/include/dev/pci/ubsecreg.h -./usr/include/dev/pci/ubsecvar.h ./usr/include/dev/pci/vga_pcivar.h ./usr/include/dev/pci/virtio_pcireg.h ./usr/include/dev/pci/ydsreg.h diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi index de5af1404cc..71d480d1774 100644 --- a/distrib/sets/lists/man/mi +++ b/distrib/sets/lists/man/mi @@ -1429,7 +1429,6 @@ ./usr/share/man/man4/hds.4 ./usr/share/man/man4/hiclock.4 ./usr/share/man/man4/hidwusb.4 -./usr/share/man/man4/hifn.4 ./usr/share/man/man4/hil.4 ./usr/share/man/man4/hilid.4 ./usr/share/man/man4/hilkbd.4 @@ -1840,7 +1839,6 @@ ./usr/share/man/man4/rtwn.4 ./usr/share/man/man4/rum.4 ./usr/share/man/man4/run.4 -./usr/share/man/man4/safe.4 ./usr/share/man/man4/safte.4 ./usr/share/man/man4/sbus.4 ./usr/share/man/man4/schsio.4 @@ -1995,7 +1993,6 @@ ./usr/share/man/man4/ubcmtp.4 ./usr/share/man/man4/uberry.4 ./usr/share/man/man4/ubsa.4 -./usr/share/man/man4/ubsec.4 ./usr/share/man/man4/ucc.4 ./usr/share/man/man4/uchcom.4 ./usr/share/man/man4/ucom.4 diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index cfa5cb1e1a4..93adc23a020 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.808 2021/09/25 18:40:08 kn Exp $ +# $OpenBSD: Makefile,v 1.809 2021/10/21 18:36:41 bluhm Exp $ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \ acpi.4 acpiac.4 acpials.4 acpiasus.4 acpibat.4 \ @@ -38,7 +38,7 @@ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \ gdt.4 gentbi.4 gem.4 gfrtc.4 gif.4 glenv.4 glkgpio.4 gpio.4 \ gpiocharger.4 gpiodcf.4 \ gpioiic.4 gpioleds.4 gpioow.4 graphaudio.4 gre.4 gscsio.4 \ - hds.4 hiclock.4 hidwusb.4 hifn.4 hil.4 hilid.4 hilkbd.4 hilms.4 \ + hds.4 hiclock.4 hidwusb.4 hil.4 hilid.4 hilkbd.4 hilms.4 \ hireset.4 hitemp.4 hme.4 hotplug.4 hsq.4 \ hvn.4 hvs.4 hyperv.4 \ iatp.4 iavf.4 ichiic.4 ichwdt.4 icmp.4 icmp6.4 icsphy.4 ifmedia.4 \ @@ -74,7 +74,7 @@ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \ rkemmcphy.4 rkgpio.4 rkgrf.4 rkiic.4 rkiis.4 rkpcie.4 rkpinctrl.4 \ rkpmic.4 rkpwm.4 rkrng.4 rktcphy.4 rktemp.4 rkvop.4 \ rl.4 rlphy.4 route.4 rsu.4 rtsx.4 rum.4 run.4 rtw.4 rtwn.4 \ - safe.4 safte.4 sbus.4 schsio.4 scsi.4 sd.4 \ + safte.4 sbus.4 schsio.4 scsi.4 sd.4 \ sdmmc.4 sdhc.4 se.4 ses.4 sf.4 sili.4 \ simpleamp.4 simpleaudio.4 simplefb.4 simplepanel.4 siop.4 sis.4 sk.4 \ sm.4 smsc.4 softraid.4 spdmem.4 sdtemp.4 speaker.4 sppp.4 sqphy.4 \ @@ -85,7 +85,7 @@ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \ tlphy.4 thmc.4 tpm.4 tpmr.4 tqphy.4 trm.4 trunk.4 tsl.4 tty.4 \ tun.4 tap.4 twe.4 \ txp.4 txphy.4 uaudio.4 uaq.4 uark.4 uath.4 ubcmtp.4 uberry.4 ubsa.4 \ - ubsec.4 ucc.4 ucom.4 uchcom.4 ucrcom.4 ucycom.4 ukspan.4 uslhcom.4 \ + ucc.4 ucom.4 uchcom.4 ucrcom.4 ucycom.4 ukspan.4 uslhcom.4 \ udav.4 udcf.4 udl.4 udp.4 udsbr.4 \ uftdi.4 ugen.4 ugl.4 ugold.4 uguru.4 uhci.4 uhid.4 uhidev.4 uhidpp.4 \ uipaq.4 ujoy.4 uk.4 ukbd.4 \ diff --git a/share/man/man4/hifn.4 b/share/man/man4/hifn.4 deleted file mode 100644 index fe729334a54..00000000000 --- a/share/man/man4/hifn.4 +++ /dev/null @@ -1,114 +0,0 @@ -.\" $OpenBSD: hifn.4,v 1.51 2016/09/27 17:06:24 schwarze Exp $ -.\" -.\" Copyright (c) 2000 Theo de Raadt -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd $Mdocdate: September 27 2016 $ -.Dt HIFN 4 -.Os -.Sh NAME -.Nm hifn -.Nd Hifn 7751/7811/7951/7955/7956/9751 crypto accelerator -.Sh SYNOPSIS -.Cd "hifn* at pci?" -.Sh DESCRIPTION -The -.Nm -driver supports various cards containing the Hifn 7751, Hifn 7811, Hifn 7951, -Hifn 7955, Hifn 7956, or Hifn 9751 chipsets, such as: -.Bl -tag -width namenamenamena -offset indent -.It Invertex AEON -Comes as 128KB SRAM model, or 2MB DRAM model. -.It Hifn 7751 -Reference board with 512KB SRAM. -.It PowerCrypt -Comes with 512KB SRAM. -.It PowerCrypt 5x -Contains a 7956 and supports symmetric encryption (including AES), -random number, and modular exponentiation operations. -.It XL-Crypt -Only board based on 7811 (which is faster than 7751 and has -a random number generator). -.It NetSec 7751 -7751 board with 1MB of SRAM. -.It Soekris Engineering vpn1201 and vpn1211 -Contains a 7951 and supports symmetric encryption and random number operations. -.It Soekris Engineering vpn1401 and vpn1411 -Contains a 7955 and supports symmetric encryption (including AES), -random number, and modular exponentiation operations. -.It Hifn 9751 -Reference board with 512KB SRAM. -This is really a Hifn 7751 which only supports compression. -.El -.Pp -The -.Tn Hifn 7751 , -.Tn Hifn 7811 , -.Tn Hifn 7951 , -.Tn Hifn 7955 , -and -.Tn Hifn 7956 -chips all support acceleration of Triple-DES, -MD5-HMAC, SHA1-HMAC, and LZS operations for -.Xr ipsec 4 . -The -.Tn Hifn 7955 -and -.Tn Hifn 7956 -chips additionally support AES-CBC. -The -.Tn Hifn 9751 -only supports LZS. -.Pp -The -.Tn Hifn 7811 , -.Tn Hifn 7951 , -.Tn Hifn 7955 , -and -.Tn Hifn 7956 -will also supply data to the kernel -.Xr random 4 -subsystem. -.Sh SEE ALSO -.Xr crypt 3 , -.Xr intro 4 , -.Xr ipsec 4 , -.Xr pci 4 , -.Xr random 4 , -.Xr crypto 9 -.Sh HISTORY -The -.Nm -device driver appeared in -.Ox 2.7 . -.Sh BUGS -The 7751 chip starts out at initialization by only supporting compression. -A proprietary algorithm, which has been reverse engineered, is required to -unlock the cryptographic functionality of the chip. -It is possible for vendors to make boards which have a lock ID not known -to the driver, but all vendors currently just use the obvious ID which is -13 bytes of 0. -.Pp -The 7951, 7955 and 7956 have support for public key operations -which are not yet supported. diff --git a/share/man/man4/pci.4 b/share/man/man4/pci.4 index cc067de7ecd..87ff66fc50d 100644 --- a/share/man/man4/pci.4 +++ b/share/man/man4/pci.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pci.4,v 1.391 2021/09/08 20:33:42 jmc Exp $ +.\" $OpenBSD: pci.4,v 1.392 2021/10/21 18:36:41 bluhm Exp $ .\" $NetBSD: pci.4,v 1.29 2000/04/01 00:32:23 tsarna Exp $ .\" .\" Copyright (c) 2000 Theo de Raadt. All rights reserved. @@ -31,7 +31,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: September 8 2021 $ +.Dd $Mdocdate: October 21 2021 $ .Dt PCI 4 .Os .Sh NAME @@ -344,12 +344,6 @@ Intel PRO/Wireless 3945ABG IEEE 802.11a/b/g wireless network device AMD cryptographic co-processor .It Xr glxsb 4 Geode LX Security Block crypto accelerator -.It Xr hifn 4 -Hifn 7751/7811/7951/7955/7956/9751 crypto accelerator -.It Xr safe 4 -SafeNet crypto accelerator -.It Xr ubsec 4 -Broadcom and BlueSteel uBsec 5x0x crypto accelerator .El .Ss Serial interfaces .Bl -tag -width 10n -offset ind -compact diff --git a/share/man/man4/safe.4 b/share/man/man4/safe.4 deleted file mode 100644 index 88902bc455d..00000000000 --- a/share/man/man4/safe.4 +++ /dev/null @@ -1,75 +0,0 @@ -.\" $OpenBSD: safe.4,v 1.11 2015/12/10 21:00:51 naddy Exp $ -.\" -.\" Copyright (c) 2003 Sam Leffler, Errno Consulting -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: /repoman/r/ncvs/src/share/man/man4/safe.4,v 1.1 2003/07/21 21:52:14 sam Exp $ -.\" -.Dd $Mdocdate: December 10 2015 $ -.Dt SAFE 4 -.Os -.Sh NAME -.Nm safe -.Nd SafeNet crypto accelerator -.Sh SYNOPSIS -.Cd "safe* at pci?" -.Sh DESCRIPTION -The -.Nm -driver supports cards containing any of the following chips: -.Bl -tag -width "SafeNet 1141" -offset indent -.It SafeNet 1141 -The original chipset. -Supports DES, Triple-DES, AES, MD5, and SHA-1 symmetric crypto operations, -RNG, public key operations, and full IPsec packet processing. -.It SafeNet 1741 -A faster version of the 1141. -.El -.Pp -The -.Nm -driver registers itself to accelerate Triple-DES, AES, MD5-HMAC, -and SHA1-HMAC operations for -.Xr ipsec 4 . -.Pp -Additionally, the driver provides input to the -.Xr random 4 -subsystem. -.Sh DIAGNOSTICS -.Bl -diag -.It "safe0: Reduce max DMA size to N words for rev X.Y" -The 1.0 silicon has major -.Xr pci 4 -bugs and may lock the bus completely. -There is no easy workaround. -.El -.Sh SEE ALSO -.Xr crypt 3 , -.Xr intro 4 , -.Xr ipsec 4 , -.Xr pci 4 , -.Xr random 4 , -.Xr crypto 9 -.Sh BUGS -Early silicon revisions can wedge the PCI bus. diff --git a/share/man/man4/ubsec.4 b/share/man/man4/ubsec.4 deleted file mode 100644 index 272d2acaac5..00000000000 --- a/share/man/man4/ubsec.4 +++ /dev/null @@ -1,100 +0,0 @@ -.\" $OpenBSD: ubsec.4,v 1.37 2018/03/01 20:48:11 jmc Exp $ -.\" -.\" Copyright (c) 2000 Jason L. Wright (jason@thought.net) -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd $Mdocdate: March 1 2018 $ -.Dt UBSEC 4 -.Os -.Sh NAME -.Nm ubsec -.Nd Broadcom and BlueSteel uBsec 5x0x crypto accelerator -.Sh SYNOPSIS -.Cd "ubsec* at pci?" -.Sh DESCRIPTION -The -.Nm -driver supports cards containing any of the following chips: -.Bl -tag -width "Broadcom BCM5821" -offset indent -.It Bluesteel 5501 -The original chipset. -This extremely rare unit -was not very fast, lacked an RNG, and had a number of other bugs. -.It Bluesteel 5601 -A faster and fixed version of the original, with a random number -unit and large number engine added. -.It Broadcom BCM5801 -A BCM5805 without public key engine or random number generator. -.It Broadcom BCM5802 -A slower version of the BCM5805. -.It Broadcom BCM5805 -Faster version of Bluesteel 5601. -.It Broadcom BCM5820 -64 bit version of the chip, and significantly more advanced. -.It Broadcom BCM5821 -Faster version of the BCM5820. -This is the chip found on the Sun Crypto Accelerator 1000. -.It Broadcom BCM5822 -Faster version of the BCM5820. -.It Broadcom BCM5823 -Faster version of the BCM5822 that also supports AES. -.It Broadcom BCM5825 -Faster PCI Express or PCI-X version of the chip. -.It Broadcom BCM5860 -IPsec/SSL Security Processor that is faster and has more features. -.It Broadcom BCM5861 -Faster version of the BCM5860. -.It Broadcom BCM5862 -Faster version of the BCM5861. -.El -.Pp -The -.Nm -driver registers itself to accelerate Triple-DES, MD5-HMAC, -and SHA1-HMAC operations for -.Xr ipsec 4 . -The driver also supports acceleration of AES-CBC with the BCM5823 or newer. -.Pp -On all models except the Bluesteel 5501 and Broadcom 5801, the driver -registers itself to provide random data to the -.Xr random 4 -subsystem. -.Sh SEE ALSO -.Xr crypt 3 , -.Xr intro 4 , -.Xr ipsec 4 , -.Xr pci 4 , -.Xr random 4 , -.Xr crypto 9 -.Sh HISTORY -The -.Nm -device driver appeared in -.Ox 2.8 . -.Sh BUGS -The BCM5801 and BCM5802 have not actually been tested. -Also, some of the newer chips support AES-CTR (AES Counter Mode) but -it is not supported by the driver. -The advanced SSL/TLS acceleration features of the BCM5860 or newer -are not supported by the driver. diff --git a/sys/arch/alpha/conf/GENERIC b/sys/arch/alpha/conf/GENERIC index b917872b1f4..cfb212b95bb 100644 --- a/sys/arch/alpha/conf/GENERIC +++ b/sys/arch/alpha/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.269 2021/08/20 05:23:18 anton Exp $ +# $OpenBSD: GENERIC,v 1.270 2021/10/21 18:36:41 bluhm Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -421,11 +421,6 @@ wsdisplay* at tga? wskbd* at pckbd? mux 1 wsmouse* at pms? mux 0 -# crypto support -hifn* at pci? # Hi/fn 7751 crypto card -ubsec* at pci? # Bluesteel Networks 5xxx crypto card -safe* at pci? # SafeNet SafeXcel 1141/1741 - # 1-Wire devices option ONEWIREVERBOSE owid* at onewire? # ID diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index 8235404bd47..2821a47f4a3 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.502 2021/09/14 08:19:58 jan Exp $ +# $OpenBSD: GENERIC,v 1.503 2021/10/21 18:36:42 bluhm Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -672,11 +672,6 @@ radio* at bktr? #wdt0 at pci? # Ind Computer Source PCI-WDT50x driver -# crypto support -hifn* at pci? # Hi/fn 7751 crypto card -ubsec* at pci? # Bluesteel Networks 5xxx crypto card -safe* at pci? # SafeNet SafeXcel 1141/1741 - xspd0 at pci? # XenSource Platform Device # 1-Wire devices diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index d82693d7f36..a8535059e60 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.857 2021/08/20 05:23:18 anton Exp $ +# $OpenBSD: GENERIC,v 1.858 2021/10/21 18:36:42 bluhm Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -742,9 +742,6 @@ radio* at fms? joy* at isapnp? # crypto support -hifn* at pci? # Hi/fn 7751 crypto card -ubsec* at pci? # Bluesteel Networks 5xxx crypto card -safe* at pci? # SafeNet SafeXcel 1141/1741 glxsb* at pci? # AMD Geode LX series processor security block # GPIO ``pin bus'' drivers diff --git a/sys/arch/macppc/conf/GENERIC b/sys/arch/macppc/conf/GENERIC index 7c364fe9454..eb356ac1515 100644 --- a/sys/arch/macppc/conf/GENERIC +++ b/sys/arch/macppc/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.274 2021/08/20 05:23:18 anton Exp $g +# $OpenBSD: GENERIC,v 1.275 2021/10/21 18:36:42 bluhm Exp $g # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -127,10 +127,6 @@ ciphy* at mii? # Cicada CS8201 10/100/1000 copper PHY ipgphy* at mii? # IC Plus IP1000A PHYs ukphy* at mii? # generic unknown PHYs -# crypto -hifn* at pci? # Hifn7751/7811/7951 -ubsec* at pci? # Broadcom 58xx -safe* at pci? # SafeNet SafeXcel 1141/1741 pwdog0 at pci? # Quancom PWDOG1 watchdog timer macintr0 at macobio? # old interrupt controller diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC index d3ec9a066ed..ad2f35faebe 100644 --- a/sys/arch/sparc64/conf/GENERIC +++ b/sys/arch/sparc64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.319 2021/08/20 05:23:19 anton Exp $ +# $OpenBSD: GENERIC,v 1.320 2021/10/21 18:36:42 bluhm Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -130,10 +130,6 @@ ahci* at pci? flags 0x0000 # AHCI SATA controllers sili* at pci? # Silicon Image 3124/3132/3531 SATA controllers nvme* at pci? # NVMe controllers -# PCI crypto -hifn* at pci? # Hifn 7751/7811/7951 -ubsec* at pci? # Broadcom 580[125]/582[012] - # PCI sound auacer* at pci? # Acer Labs M5455 autri* at pci? flags 0x0000 # Trident 4D WAVE diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index 0bde7450cc8..a20459798b9 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.355 2021/09/02 10:11:21 mlarkin Exp $ +# $OpenBSD: files.pci,v 1.356 2021/10/21 18:36:42 bluhm Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -420,21 +420,6 @@ device nep: ether, ifnet, ifmedia, mii attach nep at pci file dev/pci/if_nep.c nep -# Hi/fn 7751/7811/7951 -device hifn: crypto -attach hifn at pci -file dev/pci/hifn7751.c hifn - -# Bluesteelnet (Broadcom) 5501/5601 -device ubsec: crypto -attach ubsec at pci -file dev/pci/ubsec.c ubsec - -# Safenet SafeXcel 1141 -device safe: crypto -attach safe at pci -file dev/pci/safe.c safe - # Winbond W89C840F ethernet device wb: ether, ifnet, mii, ifmedia, mii_phy attach wb at pci diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c deleted file mode 100644 index cae21a06000..00000000000 --- a/sys/dev/pci/hifn7751.c +++ /dev/null @@ -1,2771 +0,0 @@ -/* $OpenBSD: hifn7751.c,v 1.181 2021/10/13 13:08:58 bluhm Exp $ */ - -/* - * Invertex AEON / Hifn 7751 driver - * Copyright (c) 1999 Invertex Inc. All rights reserved. - * Copyright (c) 1999 Theo de Raadt - * Copyright (c) 2000-2001 Network Security Technologies, Inc. - * http://www.netsec.net - * Copyright (c) 2003 Hifn Inc. - - * This driver is based on a previous driver by Invertex, for which they - * requested: Please send any comments, feedback, bug-fixes, or feature - * requests to software@invertex.com. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -/* - * Driver for various Hifn encryption processors. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#undef HIFN_DEBUG - -/* - * Prototypes and count for the pci_device structure - */ -int hifn_probe(struct device *, void *, void *); -void hifn_attach(struct device *, struct device *, void *); - -struct cfattach hifn_ca = { - sizeof(struct hifn_softc), hifn_probe, hifn_attach, -}; - -struct cfdriver hifn_cd = { - 0, "hifn", DV_DULL -}; - -void hifn_reset_board(struct hifn_softc *, int); -void hifn_reset_puc(struct hifn_softc *); -void hifn_puc_wait(struct hifn_softc *); -int hifn_enable_crypto(struct hifn_softc *, pcireg_t); -void hifn_set_retry(struct hifn_softc *); -void hifn_init_dma(struct hifn_softc *); -void hifn_init_pci_registers(struct hifn_softc *); -int hifn_sramsize(struct hifn_softc *); -int hifn_dramsize(struct hifn_softc *); -int hifn_ramtype(struct hifn_softc *); -void hifn_sessions(struct hifn_softc *); -int hifn_intr(void *); -u_int hifn_write_command(struct hifn_command *, u_int8_t *); -u_int32_t hifn_next_signature(u_int32_t a, u_int cnt); -int hifn_newsession(u_int32_t *, struct cryptoini *); -int hifn_freesession(u_int64_t); -int hifn_process(struct cryptop *); -void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *); -int hifn_crypto(struct hifn_softc *, struct hifn_command *, - struct cryptop *); -int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *); -int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *); -int hifn_dmamap_aligned(bus_dmamap_t); -int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *); -int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *); -int hifn_init_pubrng(struct hifn_softc *); -void hifn_rng(void *); -void hifn_tick(void *); -void hifn_abort(struct hifn_softc *); -void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *); -void hifn_write_4(struct hifn_softc *, int, bus_size_t, u_int32_t); -u_int32_t hifn_read_4(struct hifn_softc *, int, bus_size_t); -int hifn_compression(struct hifn_softc *, struct cryptop *, - struct hifn_command *); -struct mbuf *hifn_mkmbuf_chain(int, struct mbuf *); -int hifn_compress_enter(struct hifn_softc *, struct hifn_command *); -void hifn_callback_comp(struct hifn_softc *, struct hifn_command *, - u_int8_t *); - -struct hifn_stats hifnstats; - -const struct pci_matchid hifn_devices[] = { - { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955 }, - { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956 }, - { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751 }, -}; - -int -hifn_probe(struct device *parent, void *match, void *aux) -{ - return (pci_matchbyid((struct pci_attach_args *)aux, hifn_devices, - nitems(hifn_devices))); -} - -void -hifn_attach(struct device *parent, struct device *self, void *aux) -{ - struct hifn_softc *sc = (struct hifn_softc *)self; - struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; - const char *intrstr = NULL; - char rbase; - bus_size_t iosize0, iosize1; - u_int16_t ena; - int rseg; - caddr_t kva; - int algs[CRYPTO_ALGORITHM_MAX + 1]; - - sc->sc_pci_pc = pa->pa_pc; - sc->sc_pci_tag = pa->pa_tag; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7951)) - sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7955 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7956)) - sc->sc_flags = HIFN_IS_7956 | HIFN_HAS_AES | HIFN_HAS_RNG | - HIFN_HAS_PUBLIC; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7811) - sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG | HIFN_HAS_LEDS | - HIFN_NO_BURSTWRITE; - - if (pci_mapreg_map(pa, HIFN_BAR0, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_st0, &sc->sc_sh0, NULL, &iosize0, 0)) { - printf(": can't find mem space %d\n", 0); - return; - } - - if (pci_mapreg_map(pa, HIFN_BAR1, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_st1, &sc->sc_sh1, NULL, &iosize1, 0)) { - printf(": can't find mem space %d\n", 1); - goto fail_io0; - } - - hifn_set_retry(sc); - - if (sc->sc_flags & HIFN_NO_BURSTWRITE) { - sc->sc_waw_lastgroup = -1; - sc->sc_waw_lastreg = 1; - } - - sc->sc_dmat = pa->pa_dmat; - if (bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_dma), 1, - sizeof(*sc->sc_dma), 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) { - printf(": can't create dma map\n"); - goto fail_io1; - } - if (bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_dma), PAGE_SIZE, 0, - sc->sc_dmasegs, 1, &sc->sc_dmansegs, - BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { - printf(": can't alloc dma buffer\n"); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - goto fail_io1; - } - if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs, - sizeof(*sc->sc_dma), &kva, BUS_DMA_NOWAIT)) { - printf(": can't map dma buffers (%lu bytes)\n", - (u_long)sizeof(*sc->sc_dma)); - bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - goto fail_io1; - } - if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, kva, - sizeof(*sc->sc_dma), NULL, BUS_DMA_NOWAIT)) { - printf(": can't load dma map\n"); - bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(*sc->sc_dma)); - bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - goto fail_io1; - } - sc->sc_dma = (struct hifn_dma *)kva; - - hifn_reset_board(sc, 0); - - if (hifn_enable_crypto(sc, pa->pa_id) != 0) { - printf("%s: crypto enabling failed\n", sc->sc_dv.dv_xname); - goto fail_mem; - } - hifn_reset_puc(sc); - - hifn_init_dma(sc); - hifn_init_pci_registers(sc); - - if (sc->sc_flags & HIFN_IS_7956) - sc->sc_drammodel = 1; - else if (hifn_ramtype(sc)) - goto fail_mem; - - if (sc->sc_drammodel == 0) - hifn_sramsize(sc); - else - hifn_dramsize(sc); - - /* - * Workaround for NetSec 7751 rev A: half ram size because two - * of the address lines were left floating - */ - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETSEC && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETSEC_7751 && - PCI_REVISION(pa->pa_class) == 0x61) - sc->sc_ramsize >>= 1; - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - goto fail_mem; - } - intrstr = pci_intr_string(pc, ih); - sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, hifn_intr, sc, - self->dv_xname); - if (sc->sc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - goto fail_mem; - } - - hifn_sessions(sc); - - rseg = sc->sc_ramsize / 1024; - rbase = 'K'; - if (sc->sc_ramsize >= (1024 * 1024)) { - rbase = 'M'; - rseg /= 1024; - } - printf("%d%cB %cram, %s\n", rseg, rbase, - sc->sc_drammodel ? 'd' : 's', intrstr); - - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) - goto fail_intr; - - WRITE_REG_0(sc, HIFN_0_PUCNFG, - READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID); - ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA; - - bzero(algs, sizeof(algs)); - - algs[CRYPTO_LZS_COMP] = CRYPTO_ALG_FLAG_SUPPORTED; - switch (ena) { - case HIFN_PUSTAT_ENA_2: - algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - /*FALLTHROUGH*/ - case HIFN_PUSTAT_ENA_1: - algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (sc->sc_flags & HIFN_HAS_AES) - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - - crypto_register(sc->sc_cid, algs, hifn_newsession, - hifn_freesession, hifn_process); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, - sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG)) - hifn_init_pubrng(sc); - - timeout_set(&sc->sc_tickto, hifn_tick, sc); - timeout_add_sec(&sc->sc_tickto, 1); - - return; - -fail_intr: - pci_intr_disestablish(pc, sc->sc_ih); -fail_mem: - bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap); - bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(*sc->sc_dma)); - bus_dmamem_free(sc->sc_dmat, sc->sc_dmasegs, sc->sc_dmansegs); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); - - /* Turn off DMA polling */ - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - -fail_io1: - bus_space_unmap(sc->sc_st1, sc->sc_sh1, iosize1); -fail_io0: - bus_space_unmap(sc->sc_st0, sc->sc_sh0, iosize0); -} - -int -hifn_init_pubrng(struct hifn_softc *sc) -{ - u_int32_t r; - int i; - - if ((sc->sc_flags & HIFN_IS_7811) == 0) { - /* Reset 7951 public key/rng engine */ - WRITE_REG_1(sc, HIFN_1_PUB_RESET, - READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET); - - for (i = 0; i < 100; i++) { - DELAY(1000); - if ((READ_REG_1(sc, HIFN_1_PUB_RESET) & - HIFN_PUBRST_RESET) == 0) - break; - } - - if (i == 100) { - printf("%s: public key init failed\n", - sc->sc_dv.dv_xname); - return (1); - } - } - - /* Enable the rng, if available */ - if (sc->sc_flags & HIFN_HAS_RNG) { - if (sc->sc_flags & HIFN_IS_7811) { - r = READ_REG_1(sc, HIFN_1_7811_RNGENA); - if (r & HIFN_7811_RNGENA_ENA) { - r &= ~HIFN_7811_RNGENA_ENA; - WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r); - } - WRITE_REG_1(sc, HIFN_1_7811_RNGCFG, - HIFN_7811_RNGCFG_DEFL); - r |= HIFN_7811_RNGENA_ENA; - WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r); - } else - WRITE_REG_1(sc, HIFN_1_RNG_CONFIG, - READ_REG_1(sc, HIFN_1_RNG_CONFIG) | - HIFN_RNGCFG_ENA); - - sc->sc_rngfirst = 1; - sc->sc_rngms = 10; - timeout_set(&sc->sc_rngto, hifn_rng, sc); - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); - } - - /* Enable public key engine, if available */ - if (sc->sc_flags & HIFN_HAS_PUBLIC) { - WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE); - sc->sc_dmaier |= HIFN_DMAIER_PUBDONE; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - } - - return (0); -} - -void -hifn_rng(void *vsc) -{ - struct hifn_softc *sc = vsc; - u_int32_t num1, sts, num2; - int i; - - if (sc->sc_flags & HIFN_IS_7811) { - for (i = 0; i < 5; i++) { - sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS); - if (sts & HIFN_7811_RNGSTS_UFL) { - printf("%s: RNG underflow: disabling\n", - sc->sc_dv.dv_xname); - return; - } - if ((sts & HIFN_7811_RNGSTS_RDY) == 0) - break; - - /* - * There are at least two words in the RNG FIFO - * at this point. - */ - num1 = READ_REG_1(sc, HIFN_1_7811_RNGDAT); - num2 = READ_REG_1(sc, HIFN_1_7811_RNGDAT); - if (sc->sc_rngfirst) - sc->sc_rngfirst = 0; - else { - enqueue_randomness(num1); - enqueue_randomness(num2); - } - } - } else { - num1 = READ_REG_1(sc, HIFN_1_RNG_DATA); - - if (sc->sc_rngfirst) - sc->sc_rngfirst = 0; - else - enqueue_randomness(num1); - } - - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); -} - -void -hifn_puc_wait(struct hifn_softc *sc) -{ - int i; - - for (i = 5000; i > 0; i--) { - DELAY(1); - if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET)) - break; - } - if (!i) - printf("%s: proc unit did not reset\n", sc->sc_dv.dv_xname); -} - -/* - * Reset the processing unit. - */ -void -hifn_reset_puc(struct hifn_softc *sc) -{ - /* Reset processing unit */ - WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA); - hifn_puc_wait(sc); -} - -void -hifn_set_retry(struct hifn_softc *sc) -{ - u_int32_t r; - - r = pci_conf_read(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_TRDY_TIMEOUT); - r &= 0xffff0000; - pci_conf_write(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_TRDY_TIMEOUT, r); -} - -/* - * Resets the board. Values in the regesters are left as is - * from the reset (i.e. initial values are assigned elsewhere). - */ -void -hifn_reset_board(struct hifn_softc *sc, int full) -{ - u_int32_t reg; - - /* - * Set polling in the DMA configuration register to zero. 0x7 avoids - * resetting the board and zeros out the other fields. - */ - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - - /* - * Now that polling has been disabled, we have to wait 1 ms - * before resetting the board. - */ - DELAY(1000); - - /* Reset the DMA unit */ - if (full) { - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE); - DELAY(1000); - } else { - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, - HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET); - hifn_reset_puc(sc); - } - - bzero(sc->sc_dma, sizeof(*sc->sc_dma)); - - /* Bring dma unit out of reset */ - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - - hifn_puc_wait(sc); - - hifn_set_retry(sc); - - if (sc->sc_flags & HIFN_IS_7811) { - for (reg = 0; reg < 1000; reg++) { - if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) & - HIFN_MIPSRST_CRAMINIT) - break; - DELAY(1000); - } - if (reg == 1000) - printf(": cram init timeout\n"); - } -} - -u_int32_t -hifn_next_signature(u_int32_t a, u_int cnt) -{ - int i; - u_int32_t v; - - for (i = 0; i < cnt; i++) { - - /* get the parity */ - v = a & 0x80080125; - v ^= v >> 16; - v ^= v >> 8; - v ^= v >> 4; - v ^= v >> 2; - v ^= v >> 1; - - a = (v & 1) ^ (a << 1); - } - - return a; -} - -struct pci2id { - u_short pci_vendor; - u_short pci_prod; - char card_id[13]; -} pci2id[] = { - { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7951, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7955, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7956, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_NETSEC, - PCI_PRODUCT_NETSEC_7751, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_INVERTEX, - PCI_PRODUCT_INVERTEX_AEON, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7811, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, { - /* - * Other vendors share this PCI ID as well, such as - * powercrypt, and obviously they also - * use the same key. - */ - PCI_VENDOR_HIFN, - PCI_PRODUCT_HIFN_7751, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 } - }, -}; - -/* - * Checks to see if crypto is already enabled. If crypto isn't enable, - * "hifn_enable_crypto" is called to enable it. The check is important, - * as enabling crypto twice will lock the board. - */ -int -hifn_enable_crypto(struct hifn_softc *sc, pcireg_t pciid) -{ - u_int32_t dmacfg, ramcfg, encl, addr, i; - char *offtbl = NULL; - - for (i = 0; i < nitems(pci2id); i++) { - if (pci2id[i].pci_vendor == PCI_VENDOR(pciid) && - pci2id[i].pci_prod == PCI_PRODUCT(pciid)) { - offtbl = pci2id[i].card_id; - break; - } - } - - if (offtbl == NULL) { -#ifdef HIFN_DEBUG - printf(": Unknown card!\n"); -#endif - return (1); - } - - ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG); - dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG); - - /* - * The RAM config register's encrypt level bit needs to be set before - * every read performed on the encryption level register. - */ - WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID); - - encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA; - - /* - * Make sure we don't re-unlock. Two unlocks kills chip until the - * next reboot. - */ - if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) { -#ifdef HIFN_DEBUG - printf(": Strong Crypto already enabled!\n"); -#endif - goto report; - } - - if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) { -#ifdef HIFN_DEBUG - printf(": Unknown encryption level\n"); -#endif - return 1; - } - - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK | - HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); - DELAY(1000); - addr = READ_REG_1(sc, HIFN_1_UNLOCK_SECRET1); - DELAY(1000); - WRITE_REG_1(sc, HIFN_1_UNLOCK_SECRET2, 0); - DELAY(1000); - - for (i = 0; i <= 12; i++) { - addr = hifn_next_signature(addr, offtbl[i] + 0x101); - WRITE_REG_1(sc, HIFN_1_UNLOCK_SECRET2, addr); - - DELAY(1000); - } - - WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID); - encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA; - -#ifdef HIFN_DEBUG - if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2) - printf(": engine is permanently locked until next system reset"); - else - printf(": engine enabled successfully!"); -#endif - -report: - WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg); - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg); - - switch (encl) { - case HIFN_PUSTAT_ENA_0: - offtbl = "LZS"; - break; - case HIFN_PUSTAT_ENA_1: - offtbl = "LZS DES"; - break; - case HIFN_PUSTAT_ENA_2: - offtbl = "LZS 3DES ARC4 MD5 SHA1"; - break; - default: - offtbl = "disabled"; - break; - } - printf(": %s", offtbl); - if (sc->sc_flags & HIFN_HAS_RNG) - printf(" RNG"); - if (sc->sc_flags & HIFN_HAS_AES) - printf(" AES"); - if (sc->sc_flags & HIFN_HAS_PUBLIC) - printf(" PK"); - printf(", "); - - return (0); -} - -/* - * Give initial values to the registers listed in the "Register Space" - * section of the HIFN Software Development reference manual. - */ -void -hifn_init_pci_registers(struct hifn_softc *sc) -{ - /* write fixed values needed by the Initialization registers */ - WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA); - WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD); - WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER); - - /* write all 4 ring address registers */ - WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, cmdr[0])); - WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, srcr[0])); - WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, dstr[0])); - WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, resr[0])); - - DELAY(2000); - - /* write status register */ - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS | - HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS | - HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST | - HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER | - HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST | - HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER | - HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST | - HIFN_DMACSR_S_WAIT | - HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST | - HIFN_DMACSR_C_WAIT | - HIFN_DMACSR_ENGINE | - ((sc->sc_flags & HIFN_HAS_PUBLIC) ? - HIFN_DMACSR_PUBDONE : 0) | - ((sc->sc_flags & HIFN_IS_7811) ? - HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0)); - - sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0; - sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT | - HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER | - HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT | - HIFN_DMAIER_ENGINE | - ((sc->sc_flags & HIFN_IS_7811) ? - HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0); - sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - CLR_LED(sc, HIFN_MIPSRST_LED0 | HIFN_MIPSRST_LED1 | HIFN_MIPSRST_LED2); - - if (sc->sc_flags & HIFN_IS_7956) { - WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | - HIFN_PUCNFG_TCALLPHASES | - HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32); - WRITE_REG_1(sc, HIFN_1_PLL, HIFN_PLL_7956); - } else { - WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | - HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES | - HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 | - (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM)); - } - - WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER); - WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | - HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST | - ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) | - ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL)); -} - -/* - * The maximum number of sessions supported by the card - * is dependent on the amount of context ram, which - * encryption algorithms are enabled, and how compression - * is configured. This should be configured before this - * routine is called. - */ -void -hifn_sessions(struct hifn_softc *sc) -{ - u_int32_t pucnfg; - int ctxsize; - - pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG); - - if (pucnfg & HIFN_PUCNFG_COMPSING) { - if (pucnfg & HIFN_PUCNFG_ENCCNFG) - ctxsize = 128; - else - ctxsize = 512; - /* - * 7955/7956 has internal context memory of 32K - */ - if (sc->sc_flags & HIFN_IS_7956) - sc->sc_maxses = 32768 / ctxsize; - else - sc->sc_maxses = 1 + - ((sc->sc_ramsize - 32768) / ctxsize); - } - else - sc->sc_maxses = sc->sc_ramsize / 16384; - - if (sc->sc_maxses > 2048) - sc->sc_maxses = 2048; -} - -/* - * Determine ram type (sram or dram). Board should be just out of a reset - * state when this is called. - */ -int -hifn_ramtype(struct hifn_softc *sc) -{ - u_int8_t data[8], dataexpect[8]; - int i; - - for (i = 0; i < sizeof(data); i++) - data[i] = dataexpect[i] = 0x55; - if (hifn_writeramaddr(sc, 0, data)) - return (-1); - if (hifn_readramaddr(sc, 0, data)) - return (-1); - if (bcmp(data, dataexpect, sizeof(data)) != 0) { - sc->sc_drammodel = 1; - return (0); - } - - for (i = 0; i < sizeof(data); i++) - data[i] = dataexpect[i] = 0xaa; - if (hifn_writeramaddr(sc, 0, data)) - return (-1); - if (hifn_readramaddr(sc, 0, data)) - return (-1); - if (bcmp(data, dataexpect, sizeof(data)) != 0) { - sc->sc_drammodel = 1; - return (0); - } - - return (0); -} - -#define HIFN_SRAM_MAX (32 << 20) -#define HIFN_SRAM_STEP_SIZE 16384 -#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE) - -int -hifn_sramsize(struct hifn_softc *sc) -{ - u_int32_t a; - u_int8_t data[8]; - u_int8_t dataexpect[sizeof(data)]; - int32_t i; - - for (i = 0; i < sizeof(data); i++) - data[i] = dataexpect[i] = i ^ 0x5a; - - for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) { - a = i * HIFN_SRAM_STEP_SIZE; - bcopy(&i, data, sizeof(i)); - hifn_writeramaddr(sc, a, data); - } - - for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) { - a = i * HIFN_SRAM_STEP_SIZE; - bcopy(&i, dataexpect, sizeof(i)); - if (hifn_readramaddr(sc, a, data) < 0) - return (0); - if (bcmp(data, dataexpect, sizeof(data)) != 0) - return (0); - sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE; - } - - return (0); -} - -/* - * XXX For dram boards, one should really try all of the - * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG - * is already set up correctly. - */ -int -hifn_dramsize(struct hifn_softc *sc) -{ - u_int32_t cnfg; - - if (sc->sc_flags & HIFN_IS_7956) { - /* - * 7956/7956 have a fixed internal ram of only 32K. - */ - sc->sc_ramsize = 32768; - } else { - cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) & - HIFN_PUCNFG_DRAMMASK; - sc->sc_ramsize = 1 << ((cnfg >> 13) + 18); - } - return (0); -} - -void -hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, - int *dstp, int *resp) -{ - struct hifn_dma *dma = sc->sc_dma; - - if (dma->cmdi == HIFN_D_CMD_RSIZE) { - dma->cmdi = 0; - dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *cmdp = dma->cmdi++; - dma->cmdk = dma->cmdi; - - if (dma->srci == HIFN_D_SRC_RSIZE) { - dma->srci = 0; - dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *srcp = dma->srci++; - dma->srck = dma->srci; - - if (dma->dsti == HIFN_D_DST_RSIZE) { - dma->dsti = 0; - dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *dstp = dma->dsti++; - dma->dstk = dma->dsti; - - if (dma->resi == HIFN_D_RES_RSIZE) { - dma->resi = 0; - dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - *resp = dma->resi++; - dma->resk = dma->resi; -} - -int -hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data) -{ - struct hifn_dma *dma = sc->sc_dma; - struct hifn_base_command wc; - const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ; - int r, cmdi, resi, srci, dsti; - - wc.masks = htole16(3 << 13); - wc.session_num = htole16(addr >> 14); - wc.total_source_count = htole16(8); - wc.total_dest_count = htole16(addr & 0x3fff); - - hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi); - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA | - HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA); - - /* build write command */ - bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND); - *(struct hifn_base_command *)dma->command_bufs[cmdi] = wc; - bcopy(data, &dma->test_src, sizeof(dma->test_src)); - - dma->srcr[srci].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr - + offsetof(struct hifn_dma, test_src)); - dma->dstr[dsti].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr - + offsetof(struct hifn_dma, test_dst)); - - dma->cmdr[cmdi].l = htole32(16 | masks); - dma->srcr[srci].l = htole32(8 | masks); - dma->dstr[dsti].l = htole32(4 | masks); - dma->resr[resi].l = htole32(4 | masks); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - for (r = 10000; r >= 0; r--) { - DELAY(10); - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0) - break; - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - if (r == 0) { - printf("%s: writeramaddr -- " - "result[%d](addr %d) still valid\n", - sc->sc_dv.dv_xname, resi, addr); - - return (-1); - } else - r = 0; - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS | - HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS); - - return (r); -} - -int -hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data) -{ - struct hifn_dma *dma = sc->sc_dma; - struct hifn_base_command rc; - const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ; - int r, cmdi, srci, dsti, resi; - - rc.masks = htole16(2 << 13); - rc.session_num = htole16(addr >> 14); - rc.total_source_count = htole16(addr & 0x3fff); - rc.total_dest_count = htole16(8); - - hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi); - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA | - HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA); - - bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND); - *(struct hifn_base_command *)dma->command_bufs[cmdi] = rc; - - dma->srcr[srci].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, test_src)); - dma->test_src = 0; - dma->dstr[dsti].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, test_dst)); - dma->test_dst = 0; - dma->cmdr[cmdi].l = htole32(8 | masks); - dma->srcr[srci].l = htole32(8 | masks); - dma->dstr[dsti].l = htole32(8 | masks); - dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - for (r = 10000; r >= 0; r--) { - DELAY(10); - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0) - break; - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - 0, sc->sc_dmamap->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - if (r == 0) { - printf("%s: readramaddr -- " - "result[%d](addr %d) still valid\n", - sc->sc_dv.dv_xname, resi, addr); - r = -1; - } else { - r = 0; - bcopy(&dma->test_dst, data, sizeof(dma->test_dst)); - } - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, - HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS | - HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS); - - return (r); -} - -/* - * Initialize the descriptor rings. - */ -void -hifn_init_dma(struct hifn_softc *sc) -{ - struct hifn_dma *dma = sc->sc_dma; - int i; - - hifn_set_retry(sc); - - /* initialize static pointer values */ - for (i = 0; i < HIFN_D_CMD_RSIZE; i++) - dma->cmdr[i].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, command_bufs[i][0])); - for (i = 0; i < HIFN_D_RES_RSIZE; i++) - dma->resr[i].p = htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, result_bufs[i][0])); - - dma->cmdr[HIFN_D_CMD_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, cmdr[0])); - dma->srcr[HIFN_D_SRC_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, srcr[0])); - dma->dstr[HIFN_D_DST_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, dstr[0])); - dma->resr[HIFN_D_RES_RSIZE].p = - htole32(sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, resr[0])); - - dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0; - dma->cmdi = dma->srci = dma->dsti = dma->resi = 0; - dma->cmdk = dma->srck = dma->dstk = dma->resk = 0; -} - -/* - * Writes out the raw command buffer space. Returns the - * command buffer size. - */ -u_int -hifn_write_command(struct hifn_command *cmd, u_int8_t *buf) -{ - u_int8_t *buf_pos; - struct hifn_base_command *base_cmd; - struct hifn_mac_command *mac_cmd; - struct hifn_crypt_command *cry_cmd; - struct hifn_comp_command *comp_cmd; - int using_mac, using_crypt, using_comp, len, ivlen; - u_int32_t dlen, slen; - - buf_pos = buf; - using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC; - using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT; - using_comp = cmd->base_masks & HIFN_BASE_CMD_COMP; - - base_cmd = (struct hifn_base_command *)buf_pos; - base_cmd->masks = htole16(cmd->base_masks); - slen = cmd->src_map->dm_mapsize; - if (cmd->sloplen) - dlen = cmd->dst_map->dm_mapsize - cmd->sloplen + - sizeof(u_int32_t); - else - dlen = cmd->dst_map->dm_mapsize; - base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO); - base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO); - dlen >>= 16; - slen >>= 16; - 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(struct hifn_base_command); - - if (using_comp) { - comp_cmd = (struct hifn_comp_command *)buf_pos; - dlen = cmd->compcrd->crd_len; - comp_cmd->source_count = htole16(dlen & 0xffff); - dlen >>= 16; - comp_cmd->masks = htole16(cmd->comp_masks | - ((dlen << HIFN_COMP_CMD_SRCLEN_S) & HIFN_COMP_CMD_SRCLEN_M)); - comp_cmd->header_skip = htole16(cmd->compcrd->crd_skip); - comp_cmd->reserved = 0; - buf_pos += sizeof(struct hifn_comp_command); - } - - if (using_mac) { - mac_cmd = (struct hifn_mac_command *)buf_pos; - dlen = cmd->maccrd->crd_len; - mac_cmd->source_count = htole16(dlen & 0xffff); - dlen >>= 16; - mac_cmd->masks = htole16(cmd->mac_masks | - ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M)); - mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip); - mac_cmd->reserved = 0; - buf_pos += sizeof(struct hifn_mac_command); - } - - if (using_crypt) { - cry_cmd = (struct hifn_crypt_command *)buf_pos; - dlen = cmd->enccrd->crd_len; - cry_cmd->source_count = htole16(dlen & 0xffff); - dlen >>= 16; - cry_cmd->masks = htole16(cmd->cry_masks | - ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M)); - cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip); - cry_cmd->reserved = 0; - buf_pos += sizeof(struct hifn_crypt_command); - } - - if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) { - bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH); - buf_pos += HIFN_MAC_KEY_LENGTH; - } - - if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) { - switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) { - case HIFN_CRYPT_CMD_ALG_3DES: - bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH); - buf_pos += HIFN_3DES_KEY_LENGTH; - break; - case HIFN_CRYPT_CMD_ALG_DES: - bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH); - buf_pos += HIFN_DES_KEY_LENGTH; - break; - case HIFN_CRYPT_CMD_ALG_RC4: - len = 256; - do { - int clen; - - clen = MIN(cmd->cklen, len); - bcopy(cmd->ck, buf_pos, clen); - len -= clen; - buf_pos += clen; - } while (len > 0); - bzero(buf_pos, 4); - buf_pos += 4; - break; - case HIFN_CRYPT_CMD_ALG_AES: - /* - * AES key are variable 128, 192 and - * 256 bits (16, 24 and 32 bytes). - */ - bcopy(cmd->ck, buf_pos, cmd->cklen); - buf_pos += cmd->cklen; - break; - } - } - - if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) { - if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == - HIFN_CRYPT_CMD_ALG_AES) - ivlen = HIFN_AES_IV_LENGTH; - else - ivlen = HIFN_IV_LENGTH; - bcopy(cmd->iv, buf_pos, ivlen); - buf_pos += ivlen; - } - - if ((cmd->base_masks & (HIFN_BASE_CMD_MAC | HIFN_BASE_CMD_CRYPT | - HIFN_BASE_CMD_COMP)) == 0) { - bzero(buf_pos, 8); - buf_pos += 8; - } - - return (buf_pos - buf); -} - -int -hifn_dmamap_aligned(bus_dmamap_t map) -{ - int i; - - for (i = 0; i < map->dm_nsegs; i++) { - if (map->dm_segs[i].ds_addr & 3) - return (0); - if ((i != (map->dm_nsegs - 1)) && - (map->dm_segs[i].ds_len & 3)) - return (0); - } - return (1); -} - -int -hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd) -{ - struct hifn_dma *dma = sc->sc_dma; - bus_dmamap_t map = cmd->dst_map; - u_int32_t p, l; - int idx, used = 0, i; - - idx = dma->dsti; - for (i = 0; i < map->dm_nsegs - 1; i++) { - dma->dstr[idx].p = htole32(map->dm_segs[i].ds_addr); - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | map->dm_segs[i].ds_len); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - used++; - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - idx = 0; - } - } - - if (cmd->sloplen == 0) { - p = map->dm_segs[i].ds_addr; - l = HIFN_D_VALID | HIFN_D_MASKDONEIRQ | HIFN_D_LAST | - map->dm_segs[i].ds_len; - } else { - p = sc->sc_dmamap->dm_segs[0].ds_addr + - offsetof(struct hifn_dma, slop[cmd->slopidx]); - l = HIFN_D_VALID | HIFN_D_MASKDONEIRQ | HIFN_D_LAST | - sizeof(u_int32_t); - - if ((map->dm_segs[i].ds_len - cmd->sloplen) != 0) { - dma->dstr[idx].p = htole32(map->dm_segs[i].ds_addr); - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | - (map->dm_segs[i].ds_len - cmd->sloplen)); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - used++; - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - idx = 0; - } - } - } - dma->dstr[idx].p = htole32(p); - dma->dstr[idx].l = htole32(l); - HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - used++; - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP | - HIFN_D_MASKDONEIRQ); - HIFN_DSTR_SYNC(sc, idx, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - idx = 0; - } - - dma->dsti = idx; - dma->dstu += used; - return (idx); -} - -int -hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd) -{ - struct hifn_dma *dma = sc->sc_dma; - bus_dmamap_t map = cmd->src_map; - int idx, i; - u_int32_t last = 0; - - idx = dma->srci; - for (i = 0; i < map->dm_nsegs; i++) { - if (i == map->dm_nsegs - 1) - last = HIFN_D_LAST; - - dma->srcr[idx].p = htole32(map->dm_segs[i].ds_addr); - dma->srcr[idx].l = htole32(map->dm_segs[i].ds_len | - HIFN_D_VALID | HIFN_D_MASKDONEIRQ | last); - HIFN_SRCR_SYNC(sc, idx, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - - if (++idx == HIFN_D_SRC_RSIZE) { - dma->srcr[idx].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - idx = 0; - } - } - dma->srci = idx; - dma->srcu += map->dm_nsegs; - return (idx); -} - -int -hifn_crypto(struct hifn_softc *sc, struct hifn_command *cmd, - struct cryptop *crp) -{ - struct hifn_dma *dma = sc->sc_dma; - u_int32_t cmdlen; - int cmdi, resi, s, err = 0; - - if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map)) - return (ENOMEM); - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_srcmap1; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_srcmap1; - } - } else { - err = EINVAL; - goto err_srcmap1; - } - - if (hifn_dmamap_aligned(cmd->src_map)) { - cmd->sloplen = cmd->src_map->dm_mapsize & 3; - if (crp->crp_flags & CRYPTO_F_IOV) - cmd->dstu.dst_io = cmd->srcu.src_io; - else if (crp->crp_flags & CRYPTO_F_IMBUF) - cmd->dstu.dst_m = cmd->srcu.src_m; - cmd->dst_map = cmd->src_map; - } else { - if (crp->crp_flags & CRYPTO_F_IOV) { - err = EINVAL; - goto err_srcmap; - } else if (crp->crp_flags & CRYPTO_F_IMBUF) { - int totlen, len; - struct mbuf *m, *m0, *mlast; - - totlen = cmd->src_map->dm_mapsize; - if (cmd->srcu.src_m->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m0, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m0, M_DONTWAIT, MT_DATA); - } - if (m0 == NULL) { - err = ENOMEM; - goto err_srcmap; - } - if (len == MHLEN) { - err = m_dup_pkthdr(m0, cmd->srcu.src_m, - M_DONTWAIT); - if (err) { - m_free(m0); - goto err_srcmap; - } - } - if (totlen >= MINCLSIZE) { - MCLGET(m0, M_DONTWAIT); - if (m0->m_flags & M_EXT) - len = MCLBYTES; - } - totlen -= len; - m0->m_pkthdr.len = m0->m_len = len; - mlast = m0; - - while (totlen > 0) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - err = ENOMEM; - m_freem(m0); - goto err_srcmap; - } - len = MLEN; - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) - len = MCLBYTES; - } - - m->m_len = len; - if (m0->m_flags & M_PKTHDR) - m0->m_pkthdr.len += len; - totlen -= len; - - mlast->m_next = m; - mlast = m; - } - cmd->dstu.dst_m = m0; - } - } - - if (cmd->dst_map == NULL) { - if (bus_dmamap_create(sc->sc_dmat, - HIFN_MAX_SEGLEN * MAX_SCATTER, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->dst_map)) { - err = ENOMEM; - goto err_srcmap; - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_dstmap1; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto err_dstmap1; - } - } - } - -#ifdef HIFN_DEBUG - printf("%s: Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n", - sc->sc_dv.dv_xname, - READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER), - dma->cmdu, dma->srcu, dma->dstu, dma->resu, - cmd->src_map->dm_nsegs, cmd->dst_map->dm_nsegs); -#endif - - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - } - - s = splnet(); - - /* - * need 1 cmd, and 1 res - * need N src, and N dst - */ - if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE || - (dma->resu + 1) > HIFN_D_RES_RSIZE) { - splx(s); - err = ENOMEM; - goto err_dstmap; - } - if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE || - (dma->dstu + cmd->dst_map->dm_nsegs + 1) > HIFN_D_DST_RSIZE) { - splx(s); - err = ENOMEM; - goto err_dstmap; - } - - if (dma->cmdi == HIFN_D_CMD_RSIZE) { - dma->cmdi = 0; - dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - cmdi = dma->cmdi++; - cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]); - HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE); - - /* .p for command/result already set */ - dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_VALID | HIFN_D_LAST | - HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, cmdi, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - dma->cmdu++; - if (sc->sc_c_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); - sc->sc_c_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED0); - } - - /* - * Always enable the command wait interrupt. We are obviously - * missing an interrupt or two somewhere. Enabling the command wait - * interrupt will guarantee we get called periodically until all - * of the queues are drained and thus work around this. - */ - sc->sc_dmaier |= HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - - hifnstats.hst_ipackets++; - hifnstats.hst_ibytes += cmd->src_map->dm_mapsize; - - hifn_dmamap_load_src(sc, cmd); - if (sc->sc_s_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); - sc->sc_s_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED1); - } - - /* - * Unlike other descriptors, we don't mask done interrupt from - * result descriptor. - */ -#ifdef HIFN_DEBUG - printf("load res\n"); -#endif - if (dma->resi == HIFN_D_RES_RSIZE) { - dma->resi = 0; - dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - resi = dma->resi++; - dma->hifn_commands[resi] = cmd; - HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD); - dma->resr[resi].l = htole32(HIFN_MAX_RESULT | - HIFN_D_VALID | HIFN_D_LAST); - HIFN_RESR_SYNC(sc, resi, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - dma->resu++; - if (sc->sc_r_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA); - sc->sc_r_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED2); - } - - if (cmd->sloplen) - cmd->slopidx = resi; - - hifn_dmamap_load_dst(sc, cmd); - - if (sc->sc_d_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); - sc->sc_d_busy = 1; - } - -#ifdef HIFN_DEBUG - printf("%s: command: stat %8x ier %8x\n", - sc->sc_dv.dv_xname, - READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER)); -#endif - - sc->sc_active = 5; - cmd->cmd_callback = hifn_callback; - splx(s); - return (err); /* success */ - -err_dstmap: - if (cmd->src_map != cmd->dst_map) - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); -err_dstmap1: - if (cmd->src_map != cmd->dst_map) - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); -err_srcmap: - if (crp->crp_flags & CRYPTO_F_IMBUF && - cmd->srcu.src_m != cmd->dstu.dst_m) - m_freem(cmd->dstu.dst_m); - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); -err_srcmap1: - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - return (err); -} - -void -hifn_tick(void *vsc) -{ - struct hifn_softc *sc = vsc; - int s; - - s = splnet(); - if (sc->sc_active == 0) { - struct hifn_dma *dma = sc->sc_dma; - u_int32_t r = 0; - - if (dma->cmdu == 0 && sc->sc_c_busy) { - sc->sc_c_busy = 0; - r |= HIFN_DMACSR_C_CTRL_DIS; - CLR_LED(sc, HIFN_MIPSRST_LED0); - } - if (dma->srcu == 0 && sc->sc_s_busy) { - sc->sc_s_busy = 0; - r |= HIFN_DMACSR_S_CTRL_DIS; - CLR_LED(sc, HIFN_MIPSRST_LED1); - } - if (dma->dstu == 0 && sc->sc_d_busy) { - sc->sc_d_busy = 0; - r |= HIFN_DMACSR_D_CTRL_DIS; - } - if (dma->resu == 0 && sc->sc_r_busy) { - sc->sc_r_busy = 0; - r |= HIFN_DMACSR_R_CTRL_DIS; - CLR_LED(sc, HIFN_MIPSRST_LED2); - } - if (r) - WRITE_REG_1(sc, HIFN_1_DMA_CSR, r); - } - else - sc->sc_active--; - splx(s); - timeout_add_sec(&sc->sc_tickto, 1); -} - -int -hifn_intr(void *arg) -{ - struct hifn_softc *sc = arg; - struct hifn_dma *dma = sc->sc_dma; - u_int32_t dmacsr, restart; - int i, u; - - dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR); - -#ifdef HIFN_DEBUG - printf("%s: irq: stat %08x ien %08x u %d/%d/%d/%d\n", - sc->sc_dv.dv_xname, - dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), - dma->cmdu, dma->srcu, dma->dstu, dma->resu); -#endif - - /* Nothing in the DMA unit interrupted */ - if ((dmacsr & sc->sc_dmaier) == 0) - return (0); - - WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier); - - if (dmacsr & HIFN_DMACSR_ENGINE) - WRITE_REG_0(sc, HIFN_0_PUISR, READ_REG_0(sc, HIFN_0_PUISR)); - - if ((sc->sc_flags & HIFN_HAS_PUBLIC) && - (dmacsr & HIFN_DMACSR_PUBDONE)) - WRITE_REG_1(sc, HIFN_1_PUB_STATUS, - READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE); - - restart = dmacsr & (HIFN_DMACSR_R_OVER | HIFN_DMACSR_D_OVER); - if (restart) - printf("%s: overrun %x\n", sc->sc_dv.dv_xname, dmacsr); - - if (sc->sc_flags & HIFN_IS_7811) { - if (dmacsr & HIFN_DMACSR_ILLR) - printf("%s: illegal read\n", sc->sc_dv.dv_xname); - if (dmacsr & HIFN_DMACSR_ILLW) - printf("%s: illegal write\n", sc->sc_dv.dv_xname); - } - - restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT | - HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT); - if (restart) { - printf("%s: abort, resetting.\n", sc->sc_dv.dv_xname); - hifnstats.hst_abort++; - hifn_abort(sc); - return (1); - } - - if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->resu == 0)) { - /* - * If no slots to process and we receive a "waiting on - * command" interrupt, we disable the "waiting on command" - * (by clearing it). - */ - sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - } - - /* clear the rings */ - i = dma->resk; - while (dma->resu != 0) { - HIFN_RESR_SYNC(sc, i, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->resr[i].l & htole32(HIFN_D_VALID)) { - HIFN_RESR_SYNC(sc, i, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - - if (i != HIFN_D_RES_RSIZE) { - struct hifn_command *cmd; - - HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD); - cmd = dma->hifn_commands[i]; - - (*cmd->cmd_callback)(sc, cmd, dma->result_bufs[i]); - hifnstats.hst_opackets++; - } - - if (++i == (HIFN_D_RES_RSIZE + 1)) - i = 0; - else - dma->resu--; - } - dma->resk = i; - - i = dma->srck; u = dma->srcu; - while (u != 0) { - HIFN_SRCR_SYNC(sc, i, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->srcr[i].l & htole32(HIFN_D_VALID)) { - HIFN_SRCR_SYNC(sc, i, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (++i == (HIFN_D_SRC_RSIZE + 1)) - i = 0; - else - u--; - } - dma->srck = i; dma->srcu = u; - - i = dma->cmdk; u = dma->cmdu; - while (u != 0) { - HIFN_CMDR_SYNC(sc, i, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) { - HIFN_CMDR_SYNC(sc, i, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (i != HIFN_D_CMD_RSIZE) { - u--; - HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE); - } - if (++i == (HIFN_D_CMD_RSIZE + 1)) - i = 0; - } - dma->cmdk = i; dma->cmdu = u; - - return (1); -} - -/* - * Allocate a new 'session' and return an encoded session id. 'sidp' - * contains our registration id, and should contain an encoded session - * id on successful allocation. - */ -int -hifn_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct cryptoini *c; - struct hifn_softc *sc = NULL; - int i, mac = 0, cry = 0, comp = 0, sesn; - struct hifn_session *ses = NULL; - - if (sidp == NULL || cri == NULL) - return (EINVAL); - - for (i = 0; i < hifn_cd.cd_ndevs; i++) { - sc = hifn_cd.cd_devs[i]; - if (sc == NULL) - break; - if (sc->sc_cid == (*sidp)) - break; - } - if (sc == NULL) - return (EINVAL); - - 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 = mallocarray((sesn + 1), sizeof(*ses), - M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses)); - explicit_bzero(sc->sc_sessions, sesn * sizeof(*ses)); - free(sc->sc_sessions, M_DEVBUF, 0); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - bzero(ses, sizeof(*ses)); - - for (c = cri; c != NULL; c = c->cri_next) { - switch (c->cri_alg) { - case CRYPTO_MD5_HMAC: - case CRYPTO_SHA1_HMAC: - if (mac) - return (EINVAL); - mac = 1; - break; - case CRYPTO_3DES_CBC: - case CRYPTO_AES_CBC: - if (cry) - return (EINVAL); - cry = 1; - break; - case CRYPTO_LZS_COMP: - if (comp) - return (EINVAL); - comp = 1; - break; - default: - return (EINVAL); - } - } - if (mac == 0 && cry == 0 && comp == 0) - return (EINVAL); - - /* - * XXX only want to support compression without chaining to - * MAC/crypt engine right now - */ - if ((comp && mac) || (comp && cry)) - return (EINVAL); - - *sidp = HIFN_SID(sc->sc_dv.dv_unit, sesn); - ses->hs_used = 1; - - return (0); -} - -/* - * Deallocate a session. - * XXX this routine should run a zero'd mac/encrypt key into context ram. - * XXX to blow away any keys already stored there. - */ -int -hifn_freesession(u_int64_t tid) -{ - struct hifn_softc *sc; - int card, session; - u_int32_t sid = ((u_int32_t)tid) & 0xffffffff; - - card = HIFN_CARD(sid); - if (card >= hifn_cd.cd_ndevs || hifn_cd.cd_devs[card] == NULL) - return (EINVAL); - - sc = hifn_cd.cd_devs[card]; - session = HIFN_SESSION(sid); - if (session >= sc->sc_nsessions) - return (EINVAL); - - bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session])); - return (0); -} - -int -hifn_process(struct cryptop *crp) -{ - struct hifn_command *cmd = NULL; - int card, session, err = 0, ivlen; - struct hifn_softc *sc; - struct cryptodesc *crd1, *crd2 = NULL, *maccrd, *enccrd; - - if (crp->crp_ilen == 0) { - err = EINVAL; - goto errout; - } - - card = HIFN_CARD(crp->crp_sid); - if (card >= hifn_cd.cd_ndevs || hifn_cd.cd_devs[card] == NULL) { - err = EINVAL; - goto errout; - } - - sc = hifn_cd.cd_devs[card]; - session = HIFN_SESSION(crp->crp_sid); - if (session >= sc->sc_nsessions) { - err = EINVAL; - goto errout; - } - - cmd = malloc(sizeof(*cmd), M_DEVBUF, M_NOWAIT | M_ZERO); - if (cmd == NULL) { - err = ENOMEM; - goto errout; - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - cmd->srcu.src_m = (struct mbuf *)crp->crp_buf; - cmd->dstu.dst_m = (struct mbuf *)crp->crp_buf; - } else if (crp->crp_flags & CRYPTO_F_IOV) { - cmd->srcu.src_io = (struct uio *)crp->crp_buf; - cmd->dstu.dst_io = (struct uio *)crp->crp_buf; - } else { - err = EINVAL; - goto errout; /* XXX we don't handle contiguous buffers! */ - } - - if (crp->crp_ndesc < 1) { - err = EINVAL; - goto errout; - } - crd1 = &crp->crp_desc[0]; - if (crp->crp_ndesc >= 2) - crd2 = &crp->crp_desc[1]; - - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) { - maccrd = crd1; - enccrd = NULL; - } else if (crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) { - if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0) - cmd->base_masks |= HIFN_BASE_CMD_DECODE; - maccrd = NULL; - enccrd = crd1; - } else if (crd1->crd_alg == CRYPTO_LZS_COMP) { - return (hifn_compression(sc, crp, cmd)); - } else { - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) && - (crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC) && - ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { - cmd->base_masks = HIFN_BASE_CMD_DECODE; - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - /* - * We cannot order the 7751 as requested - */ - err = EINVAL; - goto errout; - } - } - - if (enccrd) { - cmd->enccrd = enccrd; - cmd->base_masks |= HIFN_BASE_CMD_CRYPT; - switch (enccrd->crd_alg) { - case CRYPTO_3DES_CBC: - cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES | - HIFN_CRYPT_CMD_MODE_CBC | - HIFN_CRYPT_CMD_NEW_IV; - break; - case CRYPTO_AES_CBC: - cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES | - HIFN_CRYPT_CMD_MODE_CBC | - HIFN_CRYPT_CMD_NEW_IV; - break; - default: - err = EINVAL; - goto errout; - } - ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ? - HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); - if (enccrd->crd_flags & CRD_F_ENCRYPT) { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, cmd->iv, ivlen); - else - arc4random_buf(cmd->iv, ivlen); - - if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - err = m_copyback(cmd->srcu.src_m, - enccrd->crd_inject, - ivlen, cmd->iv, M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback(cmd->srcu.src_io, - enccrd->crd_inject, - ivlen, cmd->iv); - if (err) - goto errout; - } - } else { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, cmd->iv, ivlen); - else if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata(cmd->srcu.src_m, - enccrd->crd_inject, ivlen, cmd->iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata(cmd->srcu.src_io, - enccrd->crd_inject, ivlen, cmd->iv); - } - - 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. - */ - if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == - HIFN_CRYPT_CMD_ALG_AES) { - switch (cmd->cklen) { - case 16: - cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128; - break; - case 24: - cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192; - break; - case 32: - cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256; - break; - default: - err = EINVAL; - goto errout; - } - } - } - - if (maccrd) { - cmd->maccrd = maccrd; - cmd->base_masks |= HIFN_BASE_CMD_MAC; - - switch (maccrd->crd_alg) { - case CRYPTO_MD5_HMAC: - cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 | - HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC | - HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC; - break; - case CRYPTO_SHA1_HMAC: - cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 | - HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC | - HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC; - break; - } - - 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), - HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3)); - } - } - - cmd->crp = crp; - cmd->session_num = session; - cmd->softc = sc; - - err = hifn_crypto(sc, cmd, crp); - if (!err) - return 0; - -errout: - if (cmd != NULL) { - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - } - if (err == EINVAL) - hifnstats.hst_invalid++; - else - hifnstats.hst_nomem++; - crp->crp_etype = err; - crypto_done(crp); - return (0); -} - -void -hifn_abort(struct hifn_softc *sc) -{ - struct hifn_dma *dma = sc->sc_dma; - struct hifn_command *cmd; - struct cryptop *crp; - int i, u; - - i = dma->resk; u = dma->resu; - while (u != 0) { - cmd = dma->hifn_commands[i]; - crp = cmd->crp; - - if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) { - /* Salvage what we can. */ - hifnstats.hst_opackets++; - (*cmd->cmd_callback)(sc, cmd, dma->result_bufs[i]); - } else { - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, - BUS_DMASYNC_POSTREAD); - } - - if (cmd->srcu.src_m != cmd->dstu.dst_m) { - m_freem(cmd->srcu.src_m); - crp->crp_buf = (caddr_t)cmd->dstu.dst_m; - } - - /* non-shared buffers cannot be restarted */ - if (cmd->src_map != cmd->dst_map) { - /* - * XXX should be EAGAIN, delayed until - * after the reset. - */ - crp->crp_etype = ENOMEM; - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } else - crp->crp_etype = ENOMEM; - - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - if (crp->crp_etype != EAGAIN) - crypto_done(crp); - } - - if (++i == HIFN_D_RES_RSIZE) - i = 0; - u--; - } - dma->resk = i; dma->resu = u; - - hifn_reset_board(sc, 1); - hifn_init_dma(sc); - hifn_init_pci_registers(sc); -} - -void -hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, - u_int8_t *resbuf) -{ - struct hifn_dma *dma = sc->sc_dma; - struct cryptop *crp = cmd->crp; - struct cryptodesc *crd; - struct mbuf *m; - int totlen, i, u; - - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (cmd->srcu.src_m != cmd->dstu.dst_m) { - crp->crp_buf = (caddr_t)cmd->dstu.dst_m; - totlen = cmd->src_map->dm_mapsize; - for (m = cmd->dstu.dst_m; m != NULL; m = m->m_next) { - if (totlen < m->m_len) { - m->m_len = totlen; - totlen = 0; - } else - totlen -= m->m_len; - } - cmd->dstu.dst_m->m_pkthdr.len = - cmd->srcu.src_m->m_pkthdr.len; - m_freem(cmd->srcu.src_m); - } - } - - if (cmd->sloplen != 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - crp->crp_etype = - m_copyback((struct mbuf *)crp->crp_buf, - cmd->src_map->dm_mapsize - cmd->sloplen, - cmd->sloplen, &dma->slop[cmd->slopidx], - M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback((struct uio *)crp->crp_buf, - cmd->src_map->dm_mapsize - cmd->sloplen, - cmd->sloplen, &dma->slop[cmd->slopidx]); - if (crp->crp_etype) - goto out; - } - - i = dma->dstk; u = dma->dstu; - while (u != 0) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), sizeof(struct hifn_desc), - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->dstr[i].l & htole32(HIFN_D_VALID)) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), - sizeof(struct hifn_desc), - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (++i == (HIFN_D_DST_RSIZE + 1)) - i = 0; - else - u--; - } - dma->dstk = i; dma->dstu = u; - - hifnstats.hst_obytes += cmd->dst_map->dm_mapsize; - - if (cmd->base_masks & HIFN_BASE_CMD_MAC) { - u_int8_t *macbuf; - - macbuf = resbuf + sizeof(struct hifn_base_result); - if (cmd->base_masks & HIFN_BASE_CMD_COMP) - macbuf += sizeof(struct hifn_comp_result); - macbuf += sizeof(struct hifn_mac_result); - - for (i = 0; i < crp->crp_ndesc; i++) { - int len; - - crd = &crp->crp_desc[i]; - - if (crd->crd_alg == CRYPTO_MD5_HMAC || - crd->crd_alg == CRYPTO_SHA1_HMAC) - len = 12; - else - continue; - - if (crp->crp_flags & CRYPTO_F_IMBUF) - crp->crp_etype = - m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, len, macbuf, M_NOWAIT); - else if ((crp->crp_flags & CRYPTO_F_IOV) && crp->crp_mac) - bcopy((caddr_t)macbuf, crp->crp_mac, len); - break; - } - } - -out: - if (cmd->src_map != cmd->dst_map) { - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - crypto_done(crp); -} - -int -hifn_compression(struct hifn_softc *sc, struct cryptop *crp, - struct hifn_command *cmd) -{ - struct cryptodesc *crd = &crp->crp_desc[0]; - int s, err = 0; - - cmd->compcrd = crd; - cmd->base_masks |= HIFN_BASE_CMD_COMP; - - if ((crp->crp_flags & CRYPTO_F_IMBUF) == 0) { - /* - * XXX can only handle mbufs right now since we can - * XXX dynamically resize them. - */ - err = EINVAL; - return (ENOMEM); - } - - if ((crd->crd_flags & CRD_F_COMP) == 0) - cmd->base_masks |= HIFN_BASE_CMD_DECODE; - if (crd->crd_alg == CRYPTO_LZS_COMP) - cmd->comp_masks |= HIFN_COMP_CMD_ALG_LZS | - HIFN_COMP_CMD_CLEARHIST; - - if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map)) { - err = ENOMEM; - goto fail; - } - - if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, - HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->dst_map)) { - err = ENOMEM; - goto fail; - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - int len; - - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - - len = cmd->src_map->dm_mapsize / MCLBYTES; - if ((cmd->src_map->dm_mapsize % MCLBYTES) != 0) - len++; - len *= MCLBYTES; - - if ((crd->crd_flags & CRD_F_COMP) == 0) - len *= 4; - - if (len > HIFN_MAX_DMALEN) - len = HIFN_MAX_DMALEN; - - cmd->dstu.dst_m = hifn_mkmbuf_chain(len, cmd->srcu.src_m); - if (cmd->dstu.dst_m == NULL) { - err = ENOMEM; - goto fail; - } - - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map, - cmd->srcu.src_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - if (bus_dmamap_load_uio(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_io, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto fail; - } - } - - if (cmd->src_map == cmd->dst_map) - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, - BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); - else { - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - } - - cmd->crp = crp; - /* - * Always use session 0. The modes of compression we use are - * stateless and there is always at least one compression - * context, zero. - */ - cmd->session_num = 0; - cmd->softc = sc; - - s = splnet(); - err = hifn_compress_enter(sc, cmd); - splx(s); - - if (err != 0) - goto fail; - return (0); - -fail: - if (cmd->dst_map != NULL) { - if (cmd->dst_map->dm_nsegs > 0) - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } - if (cmd->src_map != NULL) { - if (cmd->src_map->dm_nsegs > 0) - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - } - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - if (err == EINVAL) - hifnstats.hst_invalid++; - else - hifnstats.hst_nomem++; - crp->crp_etype = err; - crypto_done(crp); - return (0); -} - -/* - * must be called at splnet() - */ -int -hifn_compress_enter(struct hifn_softc *sc, struct hifn_command *cmd) -{ - struct hifn_dma *dma = sc->sc_dma; - int cmdi, resi; - u_int32_t cmdlen; - - if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE || - (dma->resu + 1) > HIFN_D_CMD_RSIZE) - return (ENOMEM); - - if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE || - (dma->dstu + cmd->dst_map->dm_nsegs) > HIFN_D_DST_RSIZE) - return (ENOMEM); - - if (dma->cmdi == HIFN_D_CMD_RSIZE) { - dma->cmdi = 0; - dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - cmdi = dma->cmdi++; - cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]); - HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE); - - /* .p for command/result already set */ - dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_VALID | HIFN_D_LAST | - HIFN_D_MASKDONEIRQ); - HIFN_CMDR_SYNC(sc, cmdi, - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - dma->cmdu++; - if (sc->sc_c_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); - sc->sc_c_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED0); - } - - /* - * Always enable the command wait interrupt. We are obviously - * missing an interrupt or two somewhere. Enabling the command wait - * interrupt will guarantee we get called periodically until all - * of the queues are drained and thus work around this. - */ - sc->sc_dmaier |= HIFN_DMAIER_C_WAIT; - WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); - - hifnstats.hst_ipackets++; - hifnstats.hst_ibytes += cmd->src_map->dm_mapsize; - - hifn_dmamap_load_src(sc, cmd); - if (sc->sc_s_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); - sc->sc_s_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED1); - } - - /* - * Unlike other descriptors, we don't mask done interrupt from - * result descriptor. - */ - if (dma->resi == HIFN_D_RES_RSIZE) { - dma->resi = 0; - dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); - HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } - resi = dma->resi++; - dma->hifn_commands[resi] = cmd; - HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD); - dma->resr[resi].l = htole32(HIFN_MAX_RESULT | - HIFN_D_VALID | HIFN_D_LAST); - HIFN_RESR_SYNC(sc, resi, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - dma->resu++; - if (sc->sc_r_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA); - sc->sc_r_busy = 1; - SET_LED(sc, HIFN_MIPSRST_LED2); - } - - if (cmd->sloplen) - cmd->slopidx = resi; - - hifn_dmamap_load_dst(sc, cmd); - - if (sc->sc_d_busy == 0) { - WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); - sc->sc_d_busy = 1; - } - sc->sc_active = 5; - cmd->cmd_callback = hifn_callback_comp; - return (0); -} - -void -hifn_callback_comp(struct hifn_softc *sc, struct hifn_command *cmd, - u_int8_t *resbuf) -{ - struct hifn_base_result baseres; - struct cryptop *crp = cmd->crp; - struct hifn_dma *dma = sc->sc_dma; - struct mbuf *m; - int err = 0, i, u; - u_int32_t olen; - bus_size_t dstsize; - - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - - dstsize = cmd->dst_map->dm_mapsize; - bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); - - bcopy(resbuf, &baseres, sizeof(struct hifn_base_result)); - - i = dma->dstk; u = dma->dstu; - while (u != 0) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), sizeof(struct hifn_desc), - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - if (dma->dstr[i].l & htole32(HIFN_D_VALID)) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, - offsetof(struct hifn_dma, dstr[i]), - sizeof(struct hifn_desc), - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - break; - } - if (++i == (HIFN_D_DST_RSIZE + 1)) - i = 0; - else - u--; - } - dma->dstk = i; dma->dstu = u; - - if (baseres.flags & htole16(HIFN_BASE_RES_DSTOVERRUN)) { - bus_size_t xlen; - - xlen = dstsize; - - m_freem(cmd->dstu.dst_m); - - if (xlen == HIFN_MAX_DMALEN) { - /* We've done all we can. */ - err = E2BIG; - goto out; - } - - xlen += MCLBYTES; - - if (xlen > HIFN_MAX_DMALEN) - xlen = HIFN_MAX_DMALEN; - - cmd->dstu.dst_m = hifn_mkmbuf_chain(xlen, - cmd->srcu.src_m); - if (cmd->dstu.dst_m == NULL) { - err = ENOMEM; - goto out; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, - cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { - err = ENOMEM; - goto out; - } - - bus_dmamap_sync(sc->sc_dmat, cmd->src_map, - 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, - 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - - /* already at splnet... */ - err = hifn_compress_enter(sc, cmd); - if (err != 0) - goto out; - return; - } - - olen = dstsize - (letoh16(baseres.dst_cnt) | - (((letoh16(baseres.session) & HIFN_BASE_RES_DSTLEN_M) >> - HIFN_BASE_RES_DSTLEN_S) << 16)); - - crp->crp_olen = olen - cmd->compcrd->crd_skip; - - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - - m = cmd->dstu.dst_m; - if (m->m_flags & M_PKTHDR) - m->m_pkthdr.len = olen; - crp->crp_buf = (caddr_t)m; - for (; m != NULL; m = m->m_next) { - if (olen >= m->m_len) - olen -= m->m_len; - else { - m->m_len = olen; - olen = 0; - } - } - - m_freem(cmd->srcu.src_m); - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - crp->crp_etype = 0; - crypto_done(crp); - return; - -out: - if (cmd->dst_map != NULL) { - if (cmd->src_map->dm_nsegs != 0) - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); - } - if (cmd->src_map != NULL) { - if (cmd->src_map->dm_nsegs != 0) - bus_dmamap_unload(sc->sc_dmat, cmd->src_map); - bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); - } - m_freem(cmd->dstu.dst_m); - explicit_bzero(cmd, sizeof(*cmd)); - free(cmd, M_DEVBUF, sizeof *cmd); - crp->crp_etype = err; - crypto_done(crp); -} - -struct mbuf * -hifn_mkmbuf_chain(int totlen, struct mbuf *mtemplate) -{ - int len; - struct mbuf *m, *m0, *mlast; - - if (mtemplate->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m0, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m0, M_DONTWAIT, MT_DATA); - } - if (m0 == NULL) - return (NULL); - if (len == MHLEN) { - if (m_dup_pkthdr(m0, mtemplate, M_DONTWAIT)) { - m_free(m0); - return (NULL); - } - } - MCLGET(m0, M_DONTWAIT); - if (!(m0->m_flags & M_EXT)) { - m_freem(m0); - return (NULL); - } - len = MCLBYTES; - - totlen -= len; - m0->m_pkthdr.len = m0->m_len = len; - mlast = m0; - - while (totlen > 0) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(m0); - return (NULL); - } - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_free(m); - m_freem(m0); - return (NULL); - } - len = MCLBYTES; - m->m_len = len; - if (m0->m_flags & M_PKTHDR) - m0->m_pkthdr.len += len; - totlen -= len; - - mlast->m_next = m; - mlast = m; - } - - return (m0); -} - -void -hifn_write_4(struct hifn_softc *sc, int reggrp, bus_size_t reg, - u_int32_t val) -{ - /* - * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0 - * and Group 1 registers; avoid conditions that could create - * burst writes by doing a read in between the writes. - */ - if (sc->sc_flags & HIFN_NO_BURSTWRITE) { - if (sc->sc_waw_lastgroup == reggrp && - sc->sc_waw_lastreg == reg - 4) { - bus_space_read_4(sc->sc_st1, sc->sc_sh1, HIFN_1_REVID); - } - sc->sc_waw_lastgroup = reggrp; - sc->sc_waw_lastreg = reg; - } - if (reggrp == 0) - bus_space_write_4(sc->sc_st0, sc->sc_sh0, reg, val); - else - bus_space_write_4(sc->sc_st1, sc->sc_sh1, reg, val); - -} - -u_int32_t -hifn_read_4(struct hifn_softc *sc, int reggrp, bus_size_t reg) -{ - if (sc->sc_flags & HIFN_NO_BURSTWRITE) { - sc->sc_waw_lastgroup = -1; - sc->sc_waw_lastreg = 1; - } - if (reggrp == 0) - return (bus_space_read_4(sc->sc_st0, sc->sc_sh0, reg)); - return (bus_space_read_4(sc->sc_st1, sc->sc_sh1, reg)); -} diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h deleted file mode 100644 index a1bc208181e..00000000000 --- a/sys/dev/pci/hifn7751reg.h +++ /dev/null @@ -1,523 +0,0 @@ -/* $OpenBSD: hifn7751reg.h,v 1.46 2014/12/19 22:44:58 guenther Exp $ */ - -/* - * Invertex AEON / Hifn 7751 driver - * Copyright (c) 1999 Invertex Inc. All rights reserved. - * Copyright (c) 1999 Theo de Raadt - * Copyright (c) 2000-2001 Network Security Technologies, Inc. - * http://www.netsec.net - * - * Please send any comments, feedback, bug-fixes, or feature requests to - * software@invertex.com. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ -#ifndef __HIFN_H__ -#define __HIFN_H__ - -#include - -/* - * Some PCI configuration space offset defines. The names were made - * identical to the names used by the Linux kernel. - */ -#define HIFN_BAR0 (PCI_MAPREG_START + 0) /* PUC register map */ -#define HIFN_BAR1 (PCI_MAPREG_START + 4) /* DMA register map */ -#define HIFN_RETRY_TIMEOUT 0x41 -#define HIFN_TRDY_TIMEOUT 0x40 - -/* - * The values below should multiple of 4 -- and be large enough to handle - * any command the driver implements. - * - * MAX_COMMAND = base command + mac command + encrypt command + - * mac-key + rc4-key - * MAX_RESULT = base result + comp result + mac result + mac + encrypt result - * - * - */ -#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260) -#define HIFN_MAX_RESULT (8 + 4 + 4 + 20 + 4) - -/* - * hifn_desc_t - * - * Holds an individual descriptor for any of the rings. - */ -struct hifn_desc { - volatile u_int32_t l; /* length and status bits */ - volatile u_int32_t p; -}; - -/* - * Masks for the "length" field of struct hifn_desc. - */ -#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */ -#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */ -#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */ -#define HIFN_D_OVER 0x08000000 /* overflow */ -#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */ -#define HIFN_D_JUMP 0x40000000 /* jump descriptor */ -#define HIFN_D_VALID 0x80000000 /* valid bit */ - -/* - * Processing Unit Registers (offset from BASEREG0) - */ -#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */ -#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */ -#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */ -#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */ -#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */ -#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */ -#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */ -#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */ -#define HIFN_0_SPACESIZE 0x20 /* Register space size */ - -/* Processing Unit Control Register (HIFN_0_PUCTRL) */ -#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */ -#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */ -#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */ -#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */ -#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */ - -/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */ -#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */ -#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */ -#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */ -#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */ -#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */ -#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */ -#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */ -#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */ -#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */ -#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */ - -/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */ -#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */ -#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */ -#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */ -#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */ -#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */ -#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */ -#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */ -#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */ -#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */ -#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */ -#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */ -#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */ -#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */ -#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */ -#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */ -#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */ -#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */ -#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */ -#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */ -#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */ -#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */ -#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */ -#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */ - -/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */ -#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */ -#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */ -#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */ -#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */ -#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */ -#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */ -#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */ -#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */ -#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */ -#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */ - -/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */ -#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */ -#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */ -#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */ -#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */ -#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */ -#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */ -#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */ -#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */ -#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */ -#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */ -#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */ -#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */ -#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */ -#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */ -#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */ -#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */ -#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */ - -/* FIFO Status Register (HIFN_0_FIFOSTAT) */ -#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */ -#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */ - -/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */ -#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as 1 */ - -/* - * DMA Interface Registers (offset from BASEREG1) - */ -#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */ -#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */ -#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */ -#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */ -#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */ -#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */ -#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */ -#define HIFN_1_PLL 0x4c /* 795x: PLL config */ -#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */ -#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */ -#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */ -#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */ -#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */ -#define HIFN_1_REVID 0x98 /* Revision ID */ -#define HIFN_1_UNLOCK_SECRET1 0xf4 -#define HIFN_1_UNLOCK_SECRET2 0xfc -#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */ -#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */ -#define HIFN_1_PUB_OPLEN 0x304 /* Public Operand Length */ -#define HIFN_1_PUB_OP 0x308 /* Public Operand */ -#define HIFN_1_PUB_STATUS 0x30c /* Public Status */ -#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */ -#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */ -#define HIFN_1_RNG_DATA 0x318 /* RNG data */ -#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */ -#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */ - -/* DMA Status and Control Register (HIFN_1_DMA_CSR) */ -#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */ -#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */ -#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */ -#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */ -#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */ -#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */ -#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */ -#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */ -#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */ -#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */ -#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */ -#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */ -#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */ -#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */ -#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */ -#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */ -#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */ -#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */ -#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */ -#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */ -#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */ -#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */ -#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */ -#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */ -#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */ -#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */ -#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */ -#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */ -#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */ -#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */ -#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */ -#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */ -#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */ -#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */ -#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */ -#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */ -#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */ -#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */ - -/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */ -#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */ -#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */ -#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */ -#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */ -#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */ -#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */ -#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */ -#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */ -#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */ -#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */ -#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */ -#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */ -#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */ -#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */ -#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */ -#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */ -#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */ -#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */ -#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */ -#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */ -#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */ -#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */ - -/* DMA Configuration Register (HIFN_1_DMA_CNFG) */ -#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */ -#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */ -#define HIFN_DMACNFG_UNLOCK 0x00000800 -#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */ -#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */ -#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */ -#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */ -#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */ - -/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */ -#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */ - -/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */ -#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */ -#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */ -#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */ - -/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */ -#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */ -#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */ - -/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */ -#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */ -#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */ -#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */ -#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */ -#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */ -#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */ -#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */ -#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */ -#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */ - -/* PLL config register (HIFN_1_PLL) */ -#define HIFN_PLL_7956 0x00001d18 /* 7956 PLL config value */ - -/* Revision ID */ -#define HIFN_REVID_7811_PB3_2 0x00000002 /* 7811PB3/2 */ - -/* Public key reset register (HIFN_1_PUB_RESET) */ -#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */ - -/* Public base address register (HIFN_1_PUB_BASE) */ -#define HIFN_PUBBASE_ADDR 0x00003fff /* base address */ - -/* Public operand length register (HIFN_1_PUB_OPLEN) */ -#define HIFN_PUBOPLEN_MOD_M 0x0000007f /* modulus length mask */ -#define HIFN_PUBOPLEN_MOD_S 0 /* modulus length shift */ -#define HIFN_PUBOPLEN_EXP_M 0x0003ff80 /* exponent length mask */ -#define HIFN_PUBOPLEN_EXP_S 7 /* exponent length shift */ -#define HIFN_PUBOPLEN_RED_M 0x003c0000 /* reducend length mask */ -#define HIFN_PUBOPLEN_RED_S 18 /* reducend length shift */ - -/* Public operation register (HIFN_1_PUB_OP) */ -#define HIFN_PUBOP_AOFFSET_M 0x0000007f /* A offset mask */ -#define HIFN_PUBOP_AOFFSET_S 0 /* A offset shift */ -#define HIFN_PUBOP_BOFFSET_M 0x00000f80 /* B offset mask */ -#define HIFN_PUBOP_BOFFSET_S 7 /* B offset shift */ -#define HIFN_PUBOP_MOFFSET_M 0x0003f000 /* M offset mask */ -#define HIFN_PUBOP_MOFFSET_S 12 /* M offset shift */ -#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */ -#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */ -#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */ -#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */ -#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */ -#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */ -#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */ -#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */ -#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */ -#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */ -#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */ -#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */ -#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular RED */ -#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular EXP */ - -/* Public status register (HIFN_1_PUB_STATUS) */ -#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */ -#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */ - -/* Public interrupt enable register (HIFN_1_PUB_IEN) */ -#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */ - -/* Random number generator config register (HIFN_1_RNG_CONFIG) */ -#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */ - -/********************************************************************* - * Structs for board commands - * - *********************************************************************/ - -/* - * Structure to help build up the command data structure. - */ -struct hifn_base_command { - volatile u_int16_t masks; - volatile u_int16_t session_num; - volatile u_int16_t total_source_count; - volatile u_int16_t total_dest_count; -}; - -#define HIFN_BASE_CMD_COMP 0x0100 /* enable compression engine */ -#define HIFN_BASE_CMD_PAD 0x0200 /* enable padding engine */ -#define HIFN_BASE_CMD_MAC 0x0400 /* enable MAC engine */ -#define HIFN_BASE_CMD_CRYPT 0x0800 /* enable crypt engine */ -#define HIFN_BASE_CMD_DECODE 0x2000 -#define HIFN_BASE_CMD_SRCLEN_M 0xc000 -#define HIFN_BASE_CMD_SRCLEN_S 14 -#define HIFN_BASE_CMD_DSTLEN_M 0x3000 -#define HIFN_BASE_CMD_DSTLEN_S 12 -#define HIFN_BASE_CMD_LENMASK_HI 0x30000 -#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff - -/* - * Structure to help build up the command data structure. - */ -struct hifn_crypt_command { - volatile u_int16_t masks; - volatile u_int16_t header_skip; - volatile u_int16_t source_count; - volatile u_int16_t reserved; -}; - -#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */ -#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */ -#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */ -#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */ -#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */ -#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */ -#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */ -#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */ -#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */ -#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */ -#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */ -#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */ -#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */ -#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */ -#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */ -#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */ -#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */ -#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000 -#define HIFN_CRYPT_CMD_SRCLEN_S 14 - -/* - * Structure to help build up the command data structure. - */ -struct hifn_mac_command { - volatile u_int16_t masks; - volatile u_int16_t header_skip; - volatile u_int16_t source_count; - volatile u_int16_t reserved; -}; - -#define HIFN_MAC_CMD_ALG_MASK 0x0001 -#define HIFN_MAC_CMD_ALG_SHA1 0x0000 -#define HIFN_MAC_CMD_ALG_MD5 0x0001 -#define HIFN_MAC_CMD_MODE_MASK 0x000c -#define HIFN_MAC_CMD_MODE_HMAC 0x0000 -#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004 -#define HIFN_MAC_CMD_MODE_HASH 0x0008 -#define HIFN_MAC_CMD_MODE_FULL 0x0004 -#define HIFN_MAC_CMD_TRUNC 0x0010 -#define HIFN_MAC_CMD_RESULT 0x0020 -#define HIFN_MAC_CMD_APPEND 0x0040 -#define HIFN_MAC_CMD_SRCLEN_M 0xc000 -#define HIFN_MAC_CMD_SRCLEN_S 14 - -/* - * MAC POS IPsec initiates authentication after encryption on encodes - * and before decryption on decodes. - */ -#define HIFN_MAC_CMD_POS_IPSEC 0x0200 -#define HIFN_MAC_CMD_NEW_KEY 0x0800 - -struct hifn_comp_command { - volatile u_int16_t masks; - volatile u_int16_t header_skip; - volatile u_int16_t source_count; - volatile u_int16_t reserved; -}; - -#define HIFN_COMP_CMD_SRCLEN_M 0xc000 -#define HIFN_COMP_CMD_SRCLEN_S 14 -#define HIFN_COMP_CMD_ONE 0x0100 /* must be one */ -#define HIFN_COMP_CMD_CLEARHIST 0x0010 /* clear history */ -#define HIFN_COMP_CMD_UPDATEHIST 0x0008 /* update history */ -#define HIFN_COMP_CMD_LZS_STRIP0 0x0004 /* LZS: strip zero */ -#define HIFN_COMP_CMD_MPPC_RESTART 0x0004 /* MPPC: restart */ -#define HIFN_COMP_CMD_ALG_MASK 0x0001 /* compression mode: */ -#define HIFN_COMP_CMD_ALG_MPPC 0x0001 /* MPPC */ -#define HIFN_COMP_CMD_ALG_LZS 0x0000 /* LZS */ - -struct hifn_base_result { - volatile u_int16_t flags; - volatile u_int16_t session; - volatile u_int16_t src_cnt; /* 15:0 of source count */ - volatile u_int16_t dst_cnt; /* 15:0 of dest count */ -}; - -#define HIFN_BASE_RES_DSTOVERRUN 0x0200 /* destination overrun */ -#define HIFN_BASE_RES_SRCLEN_M 0xc000 /* 17:16 of source count */ -#define HIFN_BASE_RES_SRCLEN_S 14 -#define HIFN_BASE_RES_DSTLEN_M 0x3000 /* 17:16 of dest count */ -#define HIFN_BASE_RES_DSTLEN_S 12 - -struct hifn_comp_result { - volatile u_int16_t flags; - volatile u_int16_t crc; -}; - -#define HIFN_COMP_RES_LCB_M 0xff00 /* longitudinal check byte */ -#define HIFN_COMP_RES_LCB_S 8 -#define HIFN_COMP_RES_RESTART 0x0004 /* MPPC: restart */ -#define HIFN_COMP_RES_ENDMARKER 0x0002 /* LZS: end marker seen */ -#define HIFN_COMP_RES_SRC_NOTZERO 0x0001 /* source expired */ - -struct hifn_mac_result { - volatile u_int16_t flags; - volatile u_int16_t reserved; - /* followed by 0, 6, 8, or 10 u_int16_t's of the MAC, then crypt */ -}; - -#define HIFN_MAC_RES_MISCOMPARE 0x0002 /* compare failed */ -#define HIFN_MAC_RES_SRC_NOTZERO 0x0001 /* source expired */ - -struct hifn_crypt_result { - volatile u_int16_t flags; - volatile u_int16_t reserved; -}; - -#define HIFN_CRYPT_RES_SRC_NOTZERO 0x0001 /* source expired */ - -/* - * The poll frequency and poll scalar defines are unshifted values used - * to set fields in the DMA Configuration Register. - */ -#ifndef HIFN_POLL_FREQUENCY -#define HIFN_POLL_FREQUENCY 0x1 -#endif - -#ifndef HIFN_POLL_SCALAR -#define HIFN_POLL_SCALAR 0x0 -#endif - -#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */ -#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */ -#endif /* __HIFN_H__ */ diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h deleted file mode 100644 index fb70f44fe47..00000000000 --- a/sys/dev/pci/hifn7751var.h +++ /dev/null @@ -1,324 +0,0 @@ -/* $OpenBSD: hifn7751var.h,v 1.54 2020/01/11 21:34:04 cheloha Exp $ */ - -/* - * Invertex AEON / Hifn 7751 driver - * Copyright (c) 1999 Invertex Inc. All rights reserved. - * Copyright (c) 1999 Theo de Raadt - * Copyright (c) 2000-2001 Network Security Technologies, Inc. - * http://www.netsec.net - * - * Please send any comments, feedback, bug-fixes, or feature requests to - * software@invertex.com. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -#ifndef __HIFN7751VAR_H__ -#define __HIFN7751VAR_H__ - -#ifdef _KERNEL - -/* - * Some configurable values for the driver - */ -#define HIFN_D_CMD_RSIZE 24 /* command descriptors */ -#define HIFN_D_SRC_RSIZE 80 /* source descriptors */ -#define HIFN_D_DST_RSIZE 80 /* destination descriptors */ -#define HIFN_D_RES_RSIZE 24 /* result descriptors */ - -/* - * Length values for cryptography - */ -#define HIFN_DES_KEY_LENGTH 8 -#define HIFN_3DES_KEY_LENGTH 24 -#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH -#define HIFN_IV_LENGTH 8 -#define HIFN_AES_IV_LENGTH 16 -#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH - -/* - * Length values for authentication - */ -#define HIFN_MAC_KEY_LENGTH 64 -#define HIFN_MD5_LENGTH 16 -#define HIFN_SHA1_LENGTH 20 -#define HIFN_MAC_TRUNC_LENGTH 12 - -#define MAX_SCATTER 64 - -/* - * Data structure to hold all 4 rings and any other ring related data. - */ -struct hifn_dma { - /* - * Descriptor rings. We add +1 to the size to accommodate the - * jump descriptor. - */ - struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1]; - struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1]; - struct hifn_desc dstr[HIFN_D_DST_RSIZE+1]; - struct hifn_desc resr[HIFN_D_RES_RSIZE+1]; - - struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE]; - - u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND]; - u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT]; - u_int32_t slop[HIFN_D_CMD_RSIZE]; - - u_int64_t test_src, test_dst; - - /* - * Our current positions for insertion and removal from the descriptor - * rings. - */ - int cmdi, srci, dsti, resi; - volatile int cmdu, srcu, dstu, resu; - int cmdk, srck, dstk, resk; -}; - -struct hifn_session { - int hs_used; -}; - -#define HIFN_RING_SYNC(sc, r, i, f) \ - bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ - offsetof(struct hifn_dma, r[i]), sizeof(struct hifn_desc), (f)) - -#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f)) -#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f)) -#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f)) -#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f)) - -#define HIFN_CMD_SYNC(sc, i, f) \ - bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ - offsetof(struct hifn_dma, command_bufs[(i)][0]), \ - HIFN_MAX_COMMAND, (f)) - -#define HIFN_RES_SYNC(sc, i, f) \ - bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ - offsetof(struct hifn_dma, result_bufs[(i)][0]), \ - HIFN_MAX_RESULT, (f)) - -/* - * Holds data specific to a single HIFN board. - */ -struct hifn_softc { - struct device sc_dv; /* generic device */ - void * sc_ih; /* interrupt handler cookie */ - u_int32_t sc_dmaier; - u_int32_t sc_drammodel; /* 1=dram, 0=sram */ - - bus_space_handle_t sc_sh0, sc_sh1; - bus_space_tag_t sc_st0, sc_st1; - bus_dma_tag_t sc_dmat; - - struct hifn_dma *sc_dma; - bus_dmamap_t sc_dmamap; - bus_dma_segment_t sc_dmasegs[1]; - int sc_dmansegs; - int32_t sc_cid; - int sc_maxses; - int sc_nsessions; - int sc_ramsize; - int sc_flags; -#define HIFN_HAS_RNG 0x01 /* includes random number generator */ -#define HIFN_HAS_PUBLIC 0x02 /* includes public key support */ -#define HIFN_IS_7811 0x04 /* Hifn 7811 part */ -#define HIFN_NO_BURSTWRITE 0x08 /* can't handle PCI burst writes */ -#define HIFN_HAS_LEDS 0x10 /* Has LEDs to blink */ -#define HIFN_HAS_AES 0x20 /* includes AES support */ -#define HIFN_IS_7956 0x40 /* Hifn 7955/7956 part */ - struct timeout sc_rngto, sc_tickto; - int sc_rngfirst; - int sc_rngms; /* timeout interval (milliseconds) */ - int sc_c_busy, sc_s_busy, sc_d_busy, sc_r_busy, sc_active; - struct hifn_session *sc_sessions; - pci_chipset_tag_t sc_pci_pc; - pcitag_t sc_pci_tag; - bus_size_t sc_waw_lastreg; - int sc_waw_lastgroup; -}; - -#define WRITE_REG_0(sc,reg,val) hifn_write_4((sc), 0, (reg), (val)) -#define WRITE_REG_1(sc,reg,val) hifn_write_4((sc), 1, (reg), (val)) -#define READ_REG_0(sc,reg) hifn_read_4((sc), 0, (reg)) -#define READ_REG_1(sc,reg) hifn_read_4((sc), 1, (reg)) - -#define SET_LED(sc,v) \ - if (sc->sc_flags & HIFN_HAS_LEDS) \ - WRITE_REG_1(sc, HIFN_1_7811_MIPSRST, \ - READ_REG_1(sc, HIFN_1_7811_MIPSRST) | (v)) -#define CLR_LED(sc,v) \ - if (sc->sc_flags & HIFN_HAS_LEDS) \ - WRITE_REG_1(sc, HIFN_1_7811_MIPSRST, \ - READ_REG_1(sc, HIFN_1_7811_MIPSRST) & ~(v)) - -/* - * struct hifn_command - * - * This is the control structure used to pass commands to hifn_encrypt(). - * - * flags - * ----- - * Flags is the bitwise "or" values for command configuration. A single - * encrypt direction needs to be set: - * - * HIFN_ENCODE or HIFN_DECODE - * - * To use cryptography, a single crypto algorithm must be included: - * - * HIFN_CRYPT_3DES or HIFN_CRYPT_DES - * - * To use authentication, a single MAC algorithm must be included: - * - * HIFN_MAC_MD5 or HIFN_MAC_SHA1 - * - * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash. - * If the value below is set, hash values are truncated or assumed - * truncated to 12 bytes: - * - * HIFN_MAC_TRUNC - * - * Keys for encryption and authentication can be sent as part of a command, - * or the last key value used with a particular session can be retrieved - * and used again if either of these flags are not specified. - * - * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY - * - * session_num - * ----------- - * A number between 0 and 2048 (for DRAM models) or a number between - * 0 and 768 (for SRAM models). Those who don't want to use session - * numbers should leave value at zero and send a new crypt key and/or - * new MAC key on every command. If you use session numbers and - * don't send a key with a command, the last key sent for that same - * session number will be used. - * - * Warning: Using session numbers and multiboard at the same time - * is currently broken. - * - * mbuf - * ---- - * Either fill in the mbuf pointer and npa=0 or - * fill packp[] and packl[] and set npa to > 0 - * - * mac_header_skip - * --------------- - * The number of bytes of the source_buf that are skipped over before - * authentication begins. This must be a number between 0 and 2^16-1 - * and can be used by IPsec implementers to skip over IP headers. - * *** Value ignored if authentication not used *** - * - * crypt_header_skip - * ----------------- - * The number of bytes of the source_buf that are skipped over before - * the cryptographic operation begins. This must be a number between 0 - * and 2^16-1. For IPsec, this number will always be 8 bytes larger - * than the auth_header_skip (to skip over the ESP header). - * *** Value ignored if cryptography not used *** - * - */ -struct hifn_command { - u_int16_t session_num; - u_int16_t base_masks, cry_masks, mac_masks, comp_masks; - u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH]; - int cklen; - int sloplen, slopidx; - - union { - struct mbuf *src_m; - struct uio *src_io; - } srcu; - bus_dmamap_t src_map; - - union { - struct mbuf *dst_m; - struct uio *dst_io; - } dstu; - bus_dmamap_t dst_map; - - struct hifn_softc *softc; - struct cryptop *crp; - struct cryptodesc *enccrd, *maccrd, *compcrd; - void (*cmd_callback)(struct hifn_softc *, struct hifn_command *, - u_int8_t *); -}; - -/* - * Return values for hifn_crypto() - */ -#define HIFN_CRYPTO_SUCCESS 0 -#define HIFN_CRYPTO_BAD_INPUT (-1) -#define HIFN_CRYPTO_RINGS_FULL (-2) - -/************************************************************************** - * - * Function: hifn_crypto - * - * Purpose: Called by external drivers to begin an encryption on the - * HIFN board. - * - * Blocking/Non-blocking Issues - * ============================ - * The driver cannot block in hifn_crypto (no calls to tsleep) currently. - * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough - * room in any of the rings for the request to proceed. - * - * Return Values - * ============= - * 0 for success, negative values on error - * - * Defines for negative error codes are: - * - * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings. - * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking - * behaviour was requested. - * - *************************************************************************/ - -/* - * Convert back and forth from 'sid' to 'card' and 'session' - */ -#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28) -#define HIFN_SESSION(sid) ((sid) & 0x000007ff) -#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff)) - -#endif /* _KERNEL */ - -struct hifn_stats { - u_int64_t hst_ibytes; - u_int64_t hst_obytes; - u_int32_t hst_ipackets; - u_int32_t hst_opackets; - u_int32_t hst_invalid; - u_int32_t hst_nomem; - u_int32_t hst_abort; -}; - -#endif /* __HIFN7751VAR_H__ */ diff --git a/sys/dev/pci/safe.c b/sys/dev/pci/safe.c deleted file mode 100644 index d95b0b3c8b6..00000000000 --- a/sys/dev/pci/safe.c +++ /dev/null @@ -1,1829 +0,0 @@ -/* $OpenBSD: safe.c,v 1.46 2021/10/13 13:08:58 bluhm Exp $ */ - -/*- - * Copyright (c) 2003 Sam Leffler, Errno Consulting - * Copyright (c) 2003 Global Technology Associates, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safe.c,v 1.1 2003/07/21 21:46:07 sam Exp $ - */ - -/* - * SafeNet SafeXcel-1141 hardware crypto accelerator - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifndef bswap32 -#define bswap32(x) (x) = ntohl((u_int32_t)(x)) -#endif - -#define KASSERT_X(x,y) - -/* - * Prototypes and count for the pci_device structure - */ -int safe_probe(struct device *, void *, void *); -void safe_attach(struct device *, struct device *, void *); - -struct cfattach safe_ca = { - sizeof(struct safe_softc), safe_probe, safe_attach -}; - -struct cfdriver safe_cd = { - 0, "safe", DV_DULL -}; - -int safe_intr(void *); -int safe_newsession(u_int32_t *, struct cryptoini *); -int safe_freesession(u_int64_t); -int safe_process(struct cryptop *); -void safe_callback(struct safe_softc *, struct safe_ringentry *); -void safe_feed(struct safe_softc *, struct safe_ringentry *); -void safe_mcopy(struct mbuf *, struct mbuf *, u_int); -void safe_rng_init(struct safe_softc *); -void safe_rng(void *); -int safe_dma_malloc(struct safe_softc *, bus_size_t, - struct safe_dma_alloc *, int); -#define safe_dma_sync(_sc, _dma, _flags) \ - bus_dmamap_sync((_sc)->sc_dmat, (_dma)->dma_map, 0, \ - (_dma)->dma_map->dm_mapsize, (_flags)) -void safe_dma_free(struct safe_softc *, struct safe_dma_alloc *); -int safe_dmamap_aligned(const struct safe_operand *); -int safe_dmamap_uniform(const struct safe_operand *); - -void safe_reset_board(struct safe_softc *); -void safe_init_board(struct safe_softc *); -void safe_init_pciregs(struct safe_softc *); -void safe_cleanchip(struct safe_softc *); -static __inline u_int32_t safe_rng_read(struct safe_softc *); - -int safe_free_entry(struct safe_softc *, struct safe_ringentry *); - -#ifdef SAFE_DEBUG -int safe_debug; -#define DPRINTF(_x) if (safe_debug) printf _x - -void safe_dump_dmastatus(struct safe_softc *, const char *); -void safe_dump_intrstate(struct safe_softc *, const char *); -void safe_dump_ringstate(struct safe_softc *, const char *); -void safe_dump_request(struct safe_softc *, const char *, - struct safe_ringentry *); -void safe_dump_ring(struct safe_softc *sc, const char *tag); -#else -#define DPRINTF(_x) -#endif - -#define READ_REG(sc,r) \ - bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r)) - -#define WRITE_REG(sc,reg,val) \ - bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val) - -struct safe_stats safestats; - -int safe_rnginterval = 1; /* poll once a second */ -int safe_rngbufsize = 16; /* 64 bytes each poll */ -int safe_rngmaxalarm = 8; /* max alarms before reset */ - -int -safe_probe(struct device *parent, void *match, void *aux) -{ - struct pci_attach_args *pa = aux; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SAFENET && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SAFENET_SAFEXCEL) - return (1); - return (0); -} - -void -safe_attach(struct device *parent, struct device *self, void *aux) -{ - struct safe_softc *sc = (struct safe_softc *)self; - struct pci_attach_args *pa = aux; - pci_intr_handle_t ih; - const char *intrstr = NULL; - bus_size_t iosize; - bus_addr_t raddr; - u_int32_t devinfo; - int algs[CRYPTO_ALGORITHM_MAX + 1], i; - - /* XXX handle power management */ - - sc->sc_dmat = pa->pa_dmat; - - /* - * Setup memory-mapping of PCI registers. - */ - if (pci_mapreg_map(pa, SAFE_BAR, PCI_MAPREG_TYPE_MEM, 0, - &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) { - printf(": can't map register space\n"); - goto bad; - } - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - goto bad1; - } - intrstr = pci_intr_string(pa->pa_pc, ih); - sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, safe_intr, sc, - self->dv_xname); - if (sc->sc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - goto bad2; - } - - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) { - printf(": could not get crypto driver id\n"); - goto bad3; - } - - sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) & - (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN); - - /* - * Allocate packet engine descriptors. - */ - if (safe_dma_malloc(sc, - SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry), - &sc->sc_ringalloc, 0)) { - printf(": cannot allocate PE descriptor ring\n"); - goto bad4; - } - /* - * Hookup the static portion of all our data structures. - */ - sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr; - sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE; - sc->sc_front = sc->sc_ring; - sc->sc_back = sc->sc_ring; - raddr = sc->sc_ringalloc.dma_paddr; - bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry)); - for (i = 0; i < SAFE_MAX_NQUEUE; i++) { - struct safe_ringentry *re = &sc->sc_ring[i]; - - re->re_desc.d_sa = raddr + - offsetof(struct safe_ringentry, re_sa); - re->re_sa.sa_staterec = raddr + - offsetof(struct safe_ringentry, re_sastate); - - raddr += sizeof (struct safe_ringentry); - } - - /* - * Allocate scatter and gather particle descriptors. - */ - if (safe_dma_malloc(sc, SAFE_TOTAL_SPART * sizeof (struct safe_pdesc), - &sc->sc_spalloc, 0)) { - printf(": cannot allocate source particle descriptor ring\n"); - safe_dma_free(sc, &sc->sc_ringalloc); - goto bad4; - } - sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr; - sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART; - sc->sc_spfree = sc->sc_spring; - bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc)); - - if (safe_dma_malloc(sc, SAFE_TOTAL_DPART * sizeof (struct safe_pdesc), - &sc->sc_dpalloc, 0)) { - printf(": cannot allocate destination particle " - "descriptor ring\n"); - safe_dma_free(sc, &sc->sc_spalloc); - safe_dma_free(sc, &sc->sc_ringalloc); - goto bad4; - } - sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr; - sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART; - sc->sc_dpfree = sc->sc_dpring; - bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc)); - - printf(":"); - - devinfo = READ_REG(sc, SAFE_DEVINFO); - if (devinfo & SAFE_DEVINFO_RNG) - printf(" RNG"); - - bzero(algs, sizeof(algs)); - if (devinfo & SAFE_DEVINFO_DES) { - printf(" 3DES"); - algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (devinfo & SAFE_DEVINFO_AES) { - printf(" AES"); - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (devinfo & SAFE_DEVINFO_MD5) { - printf(" MD5"); - algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - if (devinfo & SAFE_DEVINFO_SHA1) { - printf(" SHA1"); - algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - } - crypto_register(sc->sc_cid, algs, safe_newsession, - safe_freesession, safe_process); - /* XXX other supported algorithms? */ - - printf(", %s\n", intrstr); - - safe_reset_board(sc); /* reset h/w */ - safe_init_pciregs(sc); /* init pci settings */ - safe_init_board(sc); /* init h/w */ - - if (devinfo & SAFE_DEVINFO_RNG) { - safe_rng_init(sc); - - timeout_set(&sc->sc_rngto, safe_rng, sc); - timeout_add_sec(&sc->sc_rngto, safe_rnginterval); - } - return; - -bad4: - /* XXX crypto_unregister_all(sc->sc_cid); */ -bad3: - pci_intr_disestablish(pa->pa_pc, sc->sc_ih); -bad2: - /* pci_intr_unmap? */; -bad1: - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); -bad: - return; -} - -int -safe_process(struct cryptop *crp) -{ - int err = 0, i, nicealign, uniform, s; - struct safe_softc *sc; - struct cryptodesc *crd1, *crd2 = NULL, *maccrd, *enccrd; - int bypass, oplen, ivsize, card; - int16_t coffset; - struct safe_session *ses; - struct safe_ringentry *re; - struct safe_sarec *sa; - struct safe_pdesc *pd; - u_int32_t cmd0, cmd1, staterec, iv[4]; - - s = splnet(); - - card = SAFE_CARD(crp->crp_sid); - if (card >= safe_cd.cd_ndevs || safe_cd.cd_devs[card] == NULL) { - safestats.st_invalid++; - splx(s); - return (EINVAL); - } - sc = safe_cd.cd_devs[card]; - - if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) { - safestats.st_badsession++; - splx(s); - return (EINVAL); - } - - if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) { - safestats.st_ringfull++; - splx(s); - return (ERESTART); - } - re = sc->sc_front; - - staterec = re->re_sa.sa_staterec; /* save */ - /* NB: zero everything but the PE descriptor */ - bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc)); - re->re_sa.sa_staterec = staterec; /* restore */ - - re->re_crp = crp; - re->re_sesn = SAFE_SESSION(crp->crp_sid); - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - re->re_src_m = (struct mbuf *)crp->crp_buf; - re->re_dst_m = (struct mbuf *)crp->crp_buf; - } else if (crp->crp_flags & CRYPTO_F_IOV) { - re->re_src_io = (struct uio *)crp->crp_buf; - re->re_dst_io = (struct uio *)crp->crp_buf; - } else { - safestats.st_badflags++; - err = EINVAL; - goto errout; /* XXX we don't handle contiguous blocks! */ - } - - sa = &re->re_sa; - ses = &sc->sc_sessions[re->re_sesn]; - - if (crp->crp_ndesc < 1) { - safestats.st_nodesc++; - err = EINVAL; - goto errout; - } - crd1 = &crp->crp_desc[0]; - if (crp->crp_ndesc >= 2) - crd2 = &crp->crp_desc[1]; - - cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */ - cmd1 = 0; - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) { - maccrd = crd1; - enccrd = NULL; - cmd0 |= SAFE_SA_CMD0_OP_HASH; - } else if (crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) { - maccrd = NULL; - enccrd = crd1; - cmd0 |= SAFE_SA_CMD0_OP_CRYPT; - } else { - safestats.st_badalg++; - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) && - (crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC) && - ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - safestats.st_badalg++; - err = EINVAL; - goto errout; - } - cmd0 |= SAFE_SA_CMD0_OP_BOTH; - } - - if (enccrd) { - if (enccrd->crd_alg == CRYPTO_3DES_CBC) { - cmd0 |= SAFE_SA_CMD0_3DES; - cmd1 |= SAFE_SA_CMD1_CBC; - ivsize = 2*sizeof(u_int32_t); - } else if (enccrd->crd_alg == CRYPTO_AES_CBC) { - cmd0 |= SAFE_SA_CMD0_AES; - cmd1 |= SAFE_SA_CMD1_CBC; - if (ses->ses_klen == 128) - cmd1 |= SAFE_SA_CMD1_AES128; - else if (ses->ses_klen == 192) - cmd1 |= SAFE_SA_CMD1_AES192; - else - cmd1 |= SAFE_SA_CMD1_AES256; - ivsize = 4*sizeof(u_int32_t); - } else { - cmd0 |= SAFE_SA_CMD0_CRYPT_NULL; - ivsize = 0; - } - - /* - * Setup encrypt/decrypt state. When using basic ops - * we can't use an inline IV because hash/crypt offset - * must be from the end of the IV to the start of the - * crypt data and this leaves out the preceding header - * from the hash calculation. Instead we place the IV - * in the state record and set the hash/crypt offset to - * copy both the header+IV. - */ - if (enccrd->crd_flags & CRD_F_ENCRYPT) { - cmd0 |= SAFE_SA_CMD0_OUTBOUND; - - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, iv, ivsize); - else - arc4random_buf(iv, ivsize); - - if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - err = m_copyback(re->re_src_m, - enccrd->crd_inject, ivsize, iv, - M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback(re->re_src_io, - enccrd->crd_inject, ivsize, iv); - if (err) - goto errout; - } - for (i = 0; i < ivsize / sizeof(iv[0]); i++) - re->re_sastate.sa_saved_iv[i] = htole32(iv[i]); - cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV; - } else { - cmd0 |= SAFE_SA_CMD0_INBOUND; - - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, iv, ivsize); - else if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata(re->re_src_m, enccrd->crd_inject, - ivsize, iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata(re->re_src_io, enccrd->crd_inject, - ivsize, (caddr_t)iv); - for (i = 0; i < ivsize / sizeof(iv[0]); i++) - re->re_sastate.sa_saved_iv[i] = htole32(iv[i]); - cmd0 |= SAFE_SA_CMD0_IVLD_STATE; - } - /* - * For basic encryption use the zero pad algorithm. - * This pads results to an 8-byte boundary and - * suppresses padding verification for inbound (i.e. - * decrypt) operations. - * - * NB: Not sure if the 8-byte pad boundary is a problem. - */ - cmd0 |= SAFE_SA_CMD0_PAD_ZERO; - - /* XXX assert key bufs have the same size */ - for (i = 0; i < nitems(sa->sa_key); i++) - sa->sa_key[i] = ses->ses_key[i]; - } - - if (maccrd) { - if (maccrd->crd_alg == CRYPTO_MD5_HMAC) { - cmd0 |= SAFE_SA_CMD0_MD5; - cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */ - } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) { - cmd0 |= SAFE_SA_CMD0_SHA1; - cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */ - } else { - cmd0 |= SAFE_SA_CMD0_HASH_NULL; - } - /* - * Digest data is loaded from the SA and the hash - * result is saved to the state block where we - * retrieve it for return to the caller. - */ - /* XXX assert digest bufs have the same size */ - for (i = 0; - i < nitems(sa->sa_outdigest); - i++) { - sa->sa_indigest[i] = ses->ses_hminner[i]; - sa->sa_outdigest[i] = ses->ses_hmouter[i]; - } - - cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH; - re->re_flags |= SAFE_QFLAGS_COPYOUTICV; - } - - if (enccrd && maccrd) { - /* - * The offset from hash data to the start of - * crypt data is the difference in the skips. - */ - bypass = maccrd->crd_skip; - coffset = enccrd->crd_skip - maccrd->crd_skip; - if (coffset < 0) { - DPRINTF(("%s: hash does not precede crypt; " - "mac skip %u enc skip %u\n", - __func__, maccrd->crd_skip, enccrd->crd_skip)); - safestats.st_skipmismatch++; - err = EINVAL; - goto errout; - } - oplen = enccrd->crd_skip + enccrd->crd_len; - if (maccrd->crd_skip + maccrd->crd_len != oplen) { - DPRINTF(("%s: hash amount %u != crypt amount %u\n", - __func__, maccrd->crd_skip + maccrd->crd_len, - oplen)); - safestats.st_lenmismatch++; - err = EINVAL; - goto errout; - } -#ifdef SAFE_DEBUG - if (safe_debug) { - printf("mac: skip %d, len %d, inject %d\n", - maccrd->crd_skip, maccrd->crd_len, - maccrd->crd_inject); - printf("enc: skip %d, len %d, inject %d\n", - enccrd->crd_skip, enccrd->crd_len, - enccrd->crd_inject); - printf("bypass %d coffset %d oplen %d\n", - bypass, coffset, oplen); - } -#endif - if (coffset & 3) { /* offset must be 32-bit aligned */ - DPRINTF(("%s: coffset %u misaligned\n", - __func__, coffset)); - safestats.st_coffmisaligned++; - err = EINVAL; - goto errout; - } - coffset >>= 2; - if (coffset > 255) { /* offset must be <256 dwords */ - DPRINTF(("%s: coffset %u too big\n", - __func__, coffset)); - safestats.st_cofftoobig++; - err = EINVAL; - goto errout; - } - /* - * Tell the hardware to copy the header to the output. - * The header is defined as the data from the end of - * the bypass to the start of data to be encrypted. - * Typically this is the inline IV. Note that you need - * to do this even if src+dst are the same; it appears - * that w/o this bit the crypted data is written - * immediately after the bypass data. - */ - cmd1 |= SAFE_SA_CMD1_HDRCOPY; - /* - * Disable IP header mutable bit handling. This is - * needed to get correct HMAC calculations. - */ - cmd1 |= SAFE_SA_CMD1_MUTABLE; - } else { - if (enccrd) { - bypass = enccrd->crd_skip; - oplen = bypass + enccrd->crd_len; - } else { - bypass = maccrd->crd_skip; - oplen = bypass + maccrd->crd_len; - } - coffset = 0; - } - /* XXX verify multiple of 4 when using s/g */ - if (bypass > 96) { /* bypass offset must be <= 96 bytes */ - DPRINTF(("%s: bypass %u too big\n", __func__, bypass)); - safestats.st_bypasstoobig++; - err = EINVAL; - goto errout; - } - - if (bus_dmamap_create(sc->sc_dmat, SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_src_map)) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, re->re_src_map, - re->re_src_m, BUS_DMA_NOWAIT)) { - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - re->re_src_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, re->re_src_map, - re->re_src_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - re->re_src_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - } - nicealign = safe_dmamap_aligned(&re->re_src); - uniform = safe_dmamap_uniform(&re->re_src); - - DPRINTF(("src nicealign %u uniform %u nsegs %u\n", - nicealign, uniform, re->re_src_nsegs)); - if (re->re_src_nsegs > 1) { - re->re_desc.d_src = sc->sc_spalloc.dma_paddr + - ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring); - for (i = 0; i < re->re_src_nsegs; i++) { - /* NB: no need to check if there's space */ - pd = sc->sc_spfree; - if (++(sc->sc_spfree) == sc->sc_springtop) - sc->sc_spfree = sc->sc_spring; - - KASSERT_X((pd->pd_flags&3) == 0 || - (pd->pd_flags&3) == SAFE_PD_DONE, - ("bogus source particle descriptor; flags %x", - pd->pd_flags)); - pd->pd_addr = re->re_src_segs[i].ds_addr; - pd->pd_ctrl = SAFE_PD_READY | - ((re->re_src_segs[i].ds_len << SAFE_PD_LEN_S) - & SAFE_PD_LEN_M); - } - cmd0 |= SAFE_SA_CMD0_IGATHER; - } else { - /* - * No need for gather, reference the operand directly. - */ - re->re_desc.d_src = re->re_src_segs[0].ds_addr; - } - - if (enccrd == NULL && maccrd != NULL) { - /* - * Hash op; no destination needed. - */ - } else { - if (crp->crp_flags & CRYPTO_F_IOV) { - if (!nicealign) { - safestats.st_iovmisaligned++; - err = EINVAL; - goto errout; - } - if (uniform != 1) { - /* - * Source is not suitable for direct use as - * the destination. Create a new scatter/gather - * list based on the destination requirements - * and check if that's ok. - */ - if (bus_dmamap_create(sc->sc_dmat, - SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, - BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_dst_map)) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_uio(sc->sc_dmat, - re->re_dst_map, re->re_dst_io, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - re->re_dst_map); - re->re_dst_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - uniform = safe_dmamap_uniform(&re->re_dst); - if (!uniform) { - /* - * There's no way to handle the DMA - * requirements with this uio. We - * could create a separate DMA area for - * the result and then copy it back, - * but for now we just bail and return - * an error. Note that uio requests - * > SAFE_MAX_DSIZE are handled because - * the DMA map and segment list for the - * destination will result in a - * destination particle list that does - * the necessary scatter DMA. - */ - safestats.st_iovnotuniform++; - err = EINVAL; - goto errout; - } - } else - re->re_dst = re->re_src; - } else if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (nicealign && uniform == 1) { - /* - * Source layout is suitable for direct - * sharing of the DMA map and segment list. - */ - re->re_dst = re->re_src; - } else if (nicealign && uniform == 2) { - /* - * The source is properly aligned but requires a - * different particle list to handle DMA of the - * result. Create a new map and do the load to - * create the segment list. The particle - * descriptor setup code below will handle the - * rest. - */ - if (bus_dmamap_create(sc->sc_dmat, - SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, - BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_dst_map)) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, - re->re_dst_map, re->re_dst_m, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - re->re_dst_map); - re->re_dst_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - } else { /* !(aligned and/or uniform) */ - int totlen, len; - struct mbuf *m, *top, **mp; - - /* - * DMA constraints require that we allocate a - * new mbuf chain for the destination. We - * allocate an entire new set of mbufs of - * optimal/required size and then tell the - * hardware to copy any bits that are not - * created as a byproduct of the operation. - */ - if (!nicealign) - safestats.st_unaligned++; - if (!uniform) - safestats.st_notuniform++; - totlen = re->re_src_mapsize; - if (re->re_src_m->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m, M_DONTWAIT, MT_DATA); - } - if (m == NULL) { - safestats.st_nombuf++; - err = sc->sc_nqchip ? ERESTART : ENOMEM; - goto errout; - } - if (len == MHLEN) { - err = m_dup_pkthdr(m, re->re_src_m, - M_DONTWAIT); - if (err) { - m_free(m); - goto errout; - } - } - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - safestats.st_nomcl++; - err = sc->sc_nqchip ? - ERESTART : ENOMEM; - goto errout; - } - len = MCLBYTES; - } - m->m_len = len; - top = NULL; - mp = ⊤ - - while (totlen > 0) { - if (top) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(top); - safestats.st_nombuf++; - err = sc->sc_nqchip ? - ERESTART : ENOMEM; - goto errout; - } - len = MLEN; - } - if (top && totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - *mp = m; - m_freem(top); - safestats.st_nomcl++; - err = sc->sc_nqchip ? - ERESTART : ENOMEM; - goto errout; - } - len = MCLBYTES; - } - m->m_len = len = min(totlen, len); - totlen -= len; - *mp = m; - mp = &m->m_next; - } - re->re_dst_m = top; - if (bus_dmamap_create(sc->sc_dmat, - SAFE_MAX_DMA, SAFE_MAX_PART, - SAFE_MAX_DSIZE, SAFE_MAX_DSIZE, - BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, - &re->re_dst_map) != 0) { - safestats.st_nomap++; - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, - re->re_dst_map, re->re_dst_m, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - re->re_dst_map); - re->re_dst_map = NULL; - safestats.st_noload++; - err = ENOMEM; - goto errout; - } - if (re->re_src_mapsize > oplen) { - /* - * There's data following what the - * hardware will copy for us. If this - * isn't just the ICV (that's going to - * be written on completion), copy it - * to the new mbufs - */ - if (!(maccrd && - (re->re_src_mapsize-oplen) == 12 && - maccrd->crd_inject == oplen)) - safe_mcopy(re->re_src_m, - re->re_dst_m, - oplen); - else - safestats.st_noicvcopy++; - } - } - } else { - safestats.st_badflags++; - err = EINVAL; - goto errout; - } - - if (re->re_dst_nsegs > 1) { - re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr + - ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring); - for (i = 0; i < re->re_dst_nsegs; i++) { - pd = sc->sc_dpfree; - KASSERT_X((pd->pd_flags&3) == 0 || - (pd->pd_flags&3) == SAFE_PD_DONE, - ("bogus dest particle descriptor; flags %x", - pd->pd_flags)); - if (++(sc->sc_dpfree) == sc->sc_dpringtop) - sc->sc_dpfree = sc->sc_dpring; - pd->pd_addr = re->re_dst_segs[i].ds_addr; - pd->pd_ctrl = SAFE_PD_READY; - } - cmd0 |= SAFE_SA_CMD0_OSCATTER; - } else { - /* - * No need for scatter, reference the operand directly. - */ - re->re_desc.d_dst = re->re_dst_segs[0].ds_addr; - } - } - - /* - * All done with setup; fillin the SA command words - * and the packet engine descriptor. The operation - * is now ready for submission to the hardware. - */ - sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI; - sa->sa_cmd1 = cmd1 - | (coffset << SAFE_SA_CMD1_OFFSET_S) - | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */ - | SAFE_SA_CMD1_SRPCI; - - /* - * NB: the order of writes is important here. In case the - * chip is scanning the ring because of an outstanding request - * it might nab this one too. In that case we need to make - * sure the setup is complete before we write the length - * field of the descriptor as it signals the descriptor is - * ready for processing. - */ - re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI; - if (maccrd) - re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL; - re->re_desc.d_len = oplen - | SAFE_PE_LEN_READY - | (bypass << SAFE_PE_LEN_BYPASS_S) - ; - - safestats.st_ipackets++; - safestats.st_ibytes += oplen; - - if (++(sc->sc_front) == sc->sc_ringtop) - sc->sc_front = sc->sc_ring; - - /* XXX honor batching */ - safe_feed(sc, re); - splx(s); - return (0); - -errout: - if ((re->re_dst_m != NULL) && (re->re_src_m != re->re_dst_m)) - m_freem(re->re_dst_m); - - if (re->re_dst_map != NULL && re->re_dst_map != re->re_src_map) { - bus_dmamap_unload(sc->sc_dmat, re->re_dst_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_dst_map); - } - if (re->re_src_map != NULL) { - bus_dmamap_unload(sc->sc_dmat, re->re_src_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - } - crp->crp_etype = err; - crypto_done(crp); - splx(s); - return (err); -} - -/* - * Resets the board. Values in the regesters are left as is - * from the reset (i.e. initial values are assigned elsewhere). - */ -void -safe_reset_board(struct safe_softc *sc) -{ - u_int32_t v; - - /* - * Reset the device. The manual says no delay - * is needed between marking and clearing reset. - */ - v = READ_REG(sc, SAFE_PE_DMACFG) & - ~(SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET | - SAFE_PE_DMACFG_SGRESET); - WRITE_REG(sc, SAFE_PE_DMACFG, v - | SAFE_PE_DMACFG_PERESET - | SAFE_PE_DMACFG_PDRRESET - | SAFE_PE_DMACFG_SGRESET); - WRITE_REG(sc, SAFE_PE_DMACFG, v); -} - -/* - * Initialize registers we need to touch only once. - */ -void -safe_init_board(struct safe_softc *sc) -{ - u_int32_t v, dwords; - - v = READ_REG(sc, SAFE_PE_DMACFG); - v &= ~(SAFE_PE_DMACFG_PEMODE | SAFE_PE_DMACFG_ESPACKET); - v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */ - | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */ - | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */ - | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */ - | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */ - | SAFE_PE_DMACFG_ESSA /* endian-swap SA data */ - ; - WRITE_REG(sc, SAFE_PE_DMACFG, v); - - WRITE_REG(sc, SAFE_CRYPTO_CTRL, SAFE_CRYPTO_CTRL_PKEY | - SAFE_CRYPTO_CTRL_3DES | SAFE_CRYPTO_CTRL_RNG); - -#if BYTE_ORDER == LITTLE_ENDIAN - WRITE_REG(sc, SAFE_ENDIAN, SAFE_ENDIAN_TGT_PASS|SAFE_ENDIAN_DMA_PASS); -#elif BYTE_ORDER == BIG_ENDIAN - WRITE_REG(sc, SAFE_ENDIAN, SAFE_ENDIAN_TGT_PASS|SAFE_ENDIAN_DMA_SWAB); -#endif - - if (sc->sc_chiprev == SAFE_REV(1,0)) { - /* - * Avoid large PCI DMA transfers. Rev 1.0 has a bug where - * "target mode transfers" done while the chip is DMA'ing - * >1020 bytes cause the hardware to lockup. To avoid this - * we reduce the max PCI transfer size and use small source - * particle descriptors (<= 256 bytes). - */ - WRITE_REG(sc, SAFE_DMA_CFG, 256); - printf("%s: Reduce max DMA size to %u words for rev %u.%u WAR\n", - sc->sc_dev.dv_xname, - (READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff, - SAFE_REV_MAJ(sc->sc_chiprev), - SAFE_REV_MIN(sc->sc_chiprev)); - } - - /* NB: operands+results are overlaid */ - WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr); - WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr); - /* - * Configure ring entry size and number of items in the ring. - */ - KASSERT_X((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0, - ("PE ring entry not 32-bit aligned!")); - dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t); - WRITE_REG(sc, SAFE_PE_RINGCFG, - (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE); - WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */ - - WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr); - WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr); - WRITE_REG(sc, SAFE_PE_PARTSIZE, - (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART); - /* - * NB: destination particles are fixed size. We use - * an mbuf cluster and require all results go to - * clusters or smaller. - */ - WRITE_REG(sc, SAFE_PE_PARTCFG, SAFE_MAX_DSIZE); - - WRITE_REG(sc, SAFE_HI_CLR, SAFE_INT_PE_CDONE | SAFE_INT_PE_DDONE | - SAFE_INT_PE_ERROR | SAFE_INT_PE_ODONE); - - /* it's now safe to enable PE mode, do it */ - WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE); - - /* - * Configure hardware to use level-triggered interrupts and - * to interrupt after each descriptor is processed. - */ - DELAY(1000); - WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL); - DELAY(1000); - WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR); - DELAY(1000); - WRITE_REG(sc, SAFE_HI_DESC_CNT, 1); - DELAY(1000); -} - -/* - * Init PCI registers - */ -void -safe_init_pciregs(struct safe_softc *sc) -{ -} - -int -safe_dma_malloc(struct safe_softc *sc, bus_size_t size, - struct safe_dma_alloc *dma, int mapflags) -{ - int r; - - if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, - &dma->dma_seg, 1, &dma->dma_nseg, BUS_DMA_NOWAIT)) != 0) - goto fail_0; - - if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg, - size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0) - goto fail_1; - - if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_NOWAIT, &dma->dma_map)) != 0) - goto fail_2; - - if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr, - size, NULL, BUS_DMA_NOWAIT)) != 0) - goto fail_3; - - dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr; - dma->dma_size = size; - return (0); - -fail_3: - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -fail_2: - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size); -fail_1: - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); -fail_0: - dma->dma_map = NULL; - return (r); -} - -void -safe_dma_free(struct safe_softc *sc, struct safe_dma_alloc *dma) -{ - bus_dmamap_unload(sc->sc_dmat, dma->dma_map); - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size); - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -} - - -#define SAFE_RNG_MAXWAIT 1000 - -void -safe_rng_init(struct safe_softc *sc) -{ - u_int32_t w, v; - int i; - - WRITE_REG(sc, SAFE_RNG_CTRL, 0); - /* use default value according to the manual */ - WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */ - WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0); - - /* - * There is a bug in rev 1.0 of the 1140 that when the RNG - * is brought out of reset the ready status flag does not - * work until the RNG has finished its internal initialization. - * - * So in order to determine the device is through its - * initialization we must read the data register, using the - * status reg in the read in case it is initialized. Then read - * the data register until it changes from the first read. - * Once it changes read the data register until it changes - * again. At this time the RNG is considered initialized. - * This could take between 750ms - 1000ms in time. - */ - i = 0; - w = READ_REG(sc, SAFE_RNG_OUT); - do { - v = READ_REG(sc, SAFE_RNG_OUT); - if (v != w) { - w = v; - break; - } - DELAY(10); - } while (++i < SAFE_RNG_MAXWAIT); - - /* Wait Until data changes again */ - i = 0; - do { - v = READ_REG(sc, SAFE_RNG_OUT); - if (v != w) - break; - DELAY(10); - } while (++i < SAFE_RNG_MAXWAIT); -} - -static __inline u_int32_t -safe_rng_read(struct safe_softc *sc) -{ - int i; - - i = 0; - while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT) - ; - return (READ_REG(sc, SAFE_RNG_OUT)); -} - -void -safe_rng(void *arg) -{ - struct safe_softc *sc = arg; - u_int32_t buf[SAFE_RNG_MAXBUFSIZ]; /* NB: maybe move to softc */ - u_int maxwords; - int i; - - safestats.st_rng++; - /* - * Fetch the next block of data. - */ - maxwords = safe_rngbufsize; - if (maxwords > SAFE_RNG_MAXBUFSIZ) - maxwords = SAFE_RNG_MAXBUFSIZ; -retry: - for (i = 0; i < maxwords; i++) - buf[i] = safe_rng_read(sc); - /* - * Check the comparator alarm count and reset the h/w if - * it exceeds our threshold. This guards against the - * hardware oscillators resonating with external signals. - */ - if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) { - u_int32_t freq_inc, w; - - DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__, - READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm)); - safestats.st_rngalarm++; - WRITE_REG(sc, SAFE_RNG_CTRL, - READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN); - freq_inc = 18; - for (i = 0; i < 64; i++) { - w = READ_REG(sc, SAFE_RNG_CNFG); - freq_inc = ((w + freq_inc) & 0x3fL); - w = ((w & ~0x3fL) | freq_inc); - WRITE_REG(sc, SAFE_RNG_CNFG, w); - - WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0); - - (void) safe_rng_read(sc); - DELAY(25); - - if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) { - WRITE_REG(sc, SAFE_RNG_CTRL, - READ_REG(sc, SAFE_RNG_CTRL) & - ~SAFE_RNG_CTRL_SHORTEN); - goto retry; - } - freq_inc = 1; - } - WRITE_REG(sc, SAFE_RNG_CTRL, - READ_REG(sc, SAFE_RNG_CTRL) & ~SAFE_RNG_CTRL_SHORTEN); - } else - WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0); - - for (i = 0; i < maxwords; i++) - enqueue_randomness(buf[i]); - - timeout_add_sec(&sc->sc_rngto, safe_rnginterval); -} - -/* - * Allocate a new 'session' and return an encoded session id. 'sidp' - * contains our registration id, and should contain an encoded session - * id on successful allocation. - */ -int -safe_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct cryptoini *c, *encini = NULL, *macini = NULL; - struct safe_softc *sc = NULL; - struct safe_session *ses = NULL; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; - int i, sesn; - - if (sidp == NULL || cri == NULL) - return (EINVAL); - for (i = 0; i < safe_cd.cd_ndevs; i++) { - sc = safe_cd.cd_devs[i]; - if (sc == NULL || sc->sc_cid == (*sidp)) - break; - } - if (sc == NULL) - return (EINVAL); - - for (c = cri; c != NULL; c = c->cri_next) { - if (c->cri_alg == CRYPTO_MD5_HMAC || - c->cri_alg == CRYPTO_SHA1_HMAC) { - if (macini) - return (EINVAL); - macini = c; - } else if (c->cri_alg == CRYPTO_3DES_CBC || - c->cri_alg == CRYPTO_AES_CBC) { - if (encini) - return (EINVAL); - encini = c; - } else - return (EINVAL); - } - if (encini == NULL && macini == NULL) - return (EINVAL); - if (encini) { /* validate key length */ - switch (encini->cri_alg) { - case CRYPTO_3DES_CBC: - if (encini->cri_klen != 192) - return (EINVAL); - break; - case CRYPTO_AES_CBC: - if (encini->cri_klen != 128 && - encini->cri_klen != 192 && - encini->cri_klen != 256) - return (EINVAL); - break; - } - } - - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct safe_session *)malloc( - sizeof(struct safe_session), 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].ses_used == 0) { - ses = &sc->sc_sessions[sesn]; - break; - } - } - - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = mallocarray((sesn + 1), - sizeof(struct safe_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * - sizeof(struct safe_session)); - explicit_bzero(sc->sc_sessions, sesn * - sizeof(struct safe_session)); - free(sc->sc_sessions, M_DEVBUF, 0); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - - bzero(ses, sizeof(struct safe_session)); - ses->ses_used = 1; - - if (encini) { - ses->ses_klen = encini->cri_klen; - bcopy(encini->cri_key, ses->ses_key, ses->ses_klen / 8); - - for (i = 0; i < nitems(ses->ses_key); i++) - ses->ses_key[i] = htole32(ses->ses_key[i]); - } - - if (macini) { - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_IPAD_VAL; - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_ipad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hminner, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_ipad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hminner, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_opad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hmouter, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_opad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hmouter, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_OPAD_VAL; - - /* PE is little-endian, insure proper byte order */ - for (i = 0; - i < sizeof(ses->ses_hminner)/sizeof(ses->ses_hminner[0]); - i++) { - ses->ses_hminner[i] = htole32(ses->ses_hminner[i]); - ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]); - } - } - - *sidp = SAFE_SID(sc->sc_dev.dv_unit, sesn); - return (0); -} - -/* - * Deallocate a session. - */ -int -safe_freesession(u_int64_t tid) -{ - struct safe_softc *sc; - int session, ret, card; - u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; - - card = SAFE_CARD(sid); - if (card >= safe_cd.cd_ndevs || safe_cd.cd_devs[card] == NULL) - return (EINVAL); - sc = safe_cd.cd_devs[card]; - - if (sc == NULL) - return (EINVAL); - - session = SAFE_SESSION(sid); - if (session < sc->sc_nsessions) { - explicit_bzero(&sc->sc_sessions[session], - sizeof(sc->sc_sessions[session])); - ret = 0; - } else - ret = EINVAL; - return (ret); -} - -/* - * Is the operand suitable aligned for direct DMA. Each - * segment must be aligned on a 32-bit boundary and all - * but the last segment must be a multiple of 4 bytes. - */ -int -safe_dmamap_aligned(const struct safe_operand *op) -{ - int i; - - for (i = 0; i < op->map->dm_nsegs; i++) { - if (op->map->dm_segs[i].ds_addr & 3) - return (0); - if (i != (op->map->dm_nsegs - 1) && - (op->map->dm_segs[i].ds_len & 3)) - return (0); - } - return (1); -} - -/* - * Clean up after a chip crash. - * It is assumed that the caller in splnet() - */ -void -safe_cleanchip(struct safe_softc *sc) -{ - - if (sc->sc_nqchip != 0) { - struct safe_ringentry *re = sc->sc_back; - - while (re != sc->sc_front) { - if (re->re_desc.d_csr != 0) - safe_free_entry(sc, re); - if (++re == sc->sc_ringtop) - re = sc->sc_ring; - } - sc->sc_back = re; - sc->sc_nqchip = 0; - } -} - -/* - * free a safe_q - * It is assumed that the caller is within splnet(). - */ -int -safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re) -{ - struct cryptop *crp; - - /* - * Free header MCR - */ - if ((re->re_dst_m != NULL) && (re->re_src_m != re->re_dst_m)) - m_freem(re->re_dst_m); - - crp = (struct cryptop *)re->re_crp; - - re->re_desc.d_csr = 0; - - crp->crp_etype = EFAULT; - crypto_done(crp); - return (0); -} - -/* - * safe_feed() - post a request to chip - */ -void -safe_feed(struct safe_softc *sc, struct safe_ringentry *re) -{ - bus_dmamap_sync(sc->sc_dmat, re->re_src_map, - 0, re->re_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (re->re_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, re->re_dst_map, 0, - re->re_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - /* XXX have no smaller granularity */ - safe_dma_sync(sc, &sc->sc_ringalloc, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - safe_dma_sync(sc, &sc->sc_spalloc, BUS_DMASYNC_PREWRITE); - safe_dma_sync(sc, &sc->sc_dpalloc, BUS_DMASYNC_PREWRITE); - -#ifdef SAFE_DEBUG - if (safe_debug) { - safe_dump_ringstate(sc, __func__); - safe_dump_request(sc, __func__, re); - } -#endif - sc->sc_nqchip++; - if (sc->sc_nqchip > safestats.st_maxqchip) - safestats.st_maxqchip = sc->sc_nqchip; - /* poke h/w to check descriptor ring, any value can be written */ - WRITE_REG(sc, SAFE_HI_RD_DESCR, 0); -} - -/* - * Is the operand suitable for direct DMA as the destination - * of an operation. The hardware requires that each ``particle'' - * but the last in an operation result have the same size. We - * fix that size at SAFE_MAX_DSIZE bytes. This routine returns - * 0 if some segment is not a multiple of this size, 1 if all - * segments are exactly this size, or 2 if segments are at worst - * a multple of this size. - */ -int -safe_dmamap_uniform(const struct safe_operand *op) -{ - int result = 1, i; - - if (op->map->dm_nsegs <= 0) - return (result); - - for (i = 0; i < op->map->dm_nsegs-1; i++) { - if (op->map->dm_segs[i].ds_len % SAFE_MAX_DSIZE) - return (0); - if (op->map->dm_segs[i].ds_len != SAFE_MAX_DSIZE) - result = 2; - } - return (result); -} - -/* - * Copy all data past offset from srcm to dstm. - */ -void -safe_mcopy(struct mbuf *srcm, struct mbuf *dstm, u_int offset) -{ - u_int j, dlen, slen; - caddr_t dptr, sptr; - - /* - * Advance src and dst to offset. - */ - for (j = offset; srcm->m_len <= j;) { - j -= srcm->m_len; - srcm = srcm->m_next; - if (srcm == NULL) - return; - } - sptr = mtod(srcm, caddr_t) + j; - slen = srcm->m_len - j; - - for (j = offset; dstm->m_len <= j;) { - j -= dstm->m_len; - dstm = dstm->m_next; - if (dstm == NULL) - return; - } - dptr = mtod(dstm, caddr_t) + j; - dlen = dstm->m_len - j; - - /* - * Copy everything that remains. - */ - for (;;) { - j = min(slen, dlen); - bcopy(sptr, dptr, j); - if (slen == j) { - srcm = srcm->m_next; - if (srcm == NULL) - return; - sptr = srcm->m_data; - slen = srcm->m_len; - } else - sptr += j, slen -= j; - if (dlen == j) { - dstm = dstm->m_next; - if (dstm == NULL) - return; - dptr = dstm->m_data; - dlen = dstm->m_len; - } else - dptr += j, dlen -= j; - } -} - -void -safe_callback(struct safe_softc *sc, struct safe_ringentry *re) -{ - struct cryptop *crp = (struct cryptop *)re->re_crp; - struct cryptodesc *crd; - int i; - - safestats.st_opackets++; - safestats.st_obytes += (re->re_dst_map == NULL) ? - re->re_src_mapsize : re->re_dst_mapsize; - - safe_dma_sync(sc, &sc->sc_ringalloc, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) { - printf("%s: csr 0x%x cmd0 0x%x cmd1 0x%x\n", - sc->sc_dev.dv_xname, re->re_desc.d_csr, - re->re_sa.sa_cmd0, re->re_sa.sa_cmd1); - safestats.st_peoperr++; - crp->crp_etype = EIO; /* something more meaningful? */ - } - if (re->re_dst_map != NULL && re->re_dst_map != re->re_src_map) { - bus_dmamap_sync(sc->sc_dmat, re->re_dst_map, 0, - re->re_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, re->re_dst_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_dst_map); - } - bus_dmamap_sync(sc->sc_dmat, re->re_src_map, 0, - re->re_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, re->re_src_map); - bus_dmamap_destroy(sc->sc_dmat, re->re_src_map); - - /* - * If result was written to a different mbuf chain, swap - * it in as the return value and reclaim the original. - */ - if ((crp->crp_flags & CRYPTO_F_IMBUF) && re->re_src_m != re->re_dst_m) { - m_freem(re->re_src_m); - crp->crp_buf = (caddr_t)re->re_dst_m; - } - - if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) { - /* copy out ICV result */ - for (i = 0; i < crp->crp_ndesc; i++) { - crd = &crp->crp_desc[i]; - if (!(crd->crd_alg == CRYPTO_MD5_HMAC || - crd->crd_alg == CRYPTO_SHA1_HMAC)) - continue; - if (crd->crd_alg == CRYPTO_SHA1_HMAC) { - /* - * SHA-1 ICV's are byte-swapped; fix 'em up - * before copy them to their destination. - */ - bswap32(re->re_sastate.sa_saved_indigest[0]); - bswap32(re->re_sastate.sa_saved_indigest[1]); - bswap32(re->re_sastate.sa_saved_indigest[2]); - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - crp->crp_etype = - m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, 12, - (caddr_t)re->re_sastate.sa_saved_indigest, - M_NOWAIT); - } else if (crp->crp_flags & CRYPTO_F_IOV && crp->crp_mac) { - bcopy((caddr_t)re->re_sastate.sa_saved_indigest, - crp->crp_mac, 12); - } - break; - } - } - - crypto_done(crp); -} - -/* - * SafeXcel Interrupt routine - */ -int -safe_intr(void *arg) -{ - struct safe_softc *sc = arg; - volatile u_int32_t stat; - - stat = READ_REG(sc, SAFE_HM_STAT); - if (stat == 0) /* shared irq, not for us */ - return (0); - - WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */ - - if ((stat & SAFE_INT_PE_DDONE)) { - /* - * Descriptor(s) done; scan the ring and - * process completed operations. - */ - while (sc->sc_back != sc->sc_front) { - struct safe_ringentry *re = sc->sc_back; -#ifdef SAFE_DEBUG - if (safe_debug) { - safe_dump_ringstate(sc, __func__); - safe_dump_request(sc, __func__, re); - } -#endif - /* - * safe_process marks ring entries that were allocated - * but not used with a csr of zero. This insures the - * ring front pointer never needs to be set backwards - * in the event that an entry is allocated but not used - * because of a setup error. - */ - if (re->re_desc.d_csr != 0) { - if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) - break; - if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) - break; - sc->sc_nqchip--; - safe_callback(sc, re); - } - if (++(sc->sc_back) == sc->sc_ringtop) - sc->sc_back = sc->sc_ring; - } - } - - return (1); -} - -#ifdef SAFE_DEBUG - -void -safe_dump_dmastatus(struct safe_softc *sc, const char *tag) -{ - printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n", tag, - READ_REG(sc, SAFE_DMA_ENDIAN), READ_REG(sc, SAFE_DMA_SRCADDR), - READ_REG(sc, SAFE_DMA_DSTADDR), READ_REG(sc, SAFE_DMA_STAT)); -} - -void -safe_dump_intrstate(struct safe_softc *sc, const char *tag) -{ - printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n", - tag, READ_REG(sc, SAFE_HI_CFG), READ_REG(sc, SAFE_HI_MASK), - READ_REG(sc, SAFE_HI_DESC_CNT), READ_REG(sc, SAFE_HU_STAT), - READ_REG(sc, SAFE_HM_STAT)); -} - -void -safe_dump_ringstate(struct safe_softc *sc, const char *tag) -{ - u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT); - - /* NB: assume caller has lock on ring */ - printf("%s: ERNGSTAT %x (next %u) back %u front %u\n", - tag, estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S), - sc->sc_back - sc->sc_ring, sc->sc_front - sc->sc_ring); -} - -void -safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re) -{ - int ix, nsegs; - - ix = re - sc->sc_ring; - printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n", tag, - re, ix, re->re_desc.d_csr, re->re_desc.d_src, re->re_desc.d_dst, - re->re_desc.d_sa, re->re_desc.d_len); - if (re->re_src_nsegs > 1) { - ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) / - sizeof(struct safe_pdesc); - for (nsegs = re->re_src_nsegs; nsegs; nsegs--) { - printf(" spd[%u] %p: %p", ix, - &sc->sc_spring[ix], - (caddr_t)sc->sc_spring[ix].pd_addr); - printf("\n"); - if (++ix == SAFE_TOTAL_SPART) - ix = 0; - } - } - if (re->re_dst_nsegs > 1) { - ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) / - sizeof(struct safe_pdesc); - for (nsegs = re->re_dst_nsegs; nsegs; nsegs--) { - printf(" dpd[%u] %p: %p\n", ix, - &sc->sc_dpring[ix], - (caddr_t) sc->sc_dpring[ix].pd_addr); - if (++ix == SAFE_TOTAL_DPART) - ix = 0; - } - } - printf("sa: cmd0 %08x cmd1 %08x staterec %x\n", - re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec); - printf("sa: key %x %x %x %x %x %x %x %x\n", re->re_sa.sa_key[0], - re->re_sa.sa_key[1], re->re_sa.sa_key[2], re->re_sa.sa_key[3], - re->re_sa.sa_key[4], re->re_sa.sa_key[5], re->re_sa.sa_key[6], - re->re_sa.sa_key[7]); - printf("sa: indigest %x %x %x %x %x\n", re->re_sa.sa_indigest[0], - re->re_sa.sa_indigest[1], re->re_sa.sa_indigest[2], - re->re_sa.sa_indigest[3], re->re_sa.sa_indigest[4]); - printf("sa: outdigest %x %x %x %x %x\n", re->re_sa.sa_outdigest[0], - re->re_sa.sa_outdigest[1], re->re_sa.sa_outdigest[2], - re->re_sa.sa_outdigest[3], re->re_sa.sa_outdigest[4]); - printf("sr: iv %x %x %x %x\n", - re->re_sastate.sa_saved_iv[0], re->re_sastate.sa_saved_iv[1], - re->re_sastate.sa_saved_iv[2], re->re_sastate.sa_saved_iv[3]); - printf("sr: hashbc %u indigest %x %x %x %x %x\n", - re->re_sastate.sa_saved_hashbc, - re->re_sastate.sa_saved_indigest[0], - re->re_sastate.sa_saved_indigest[1], - re->re_sastate.sa_saved_indigest[2], - re->re_sastate.sa_saved_indigest[3], - re->re_sastate.sa_saved_indigest[4]); -} - -void -safe_dump_ring(struct safe_softc *sc, const char *tag) -{ - printf("\nSafeNet Ring State:\n"); - safe_dump_intrstate(sc, tag); - safe_dump_dmastatus(sc, tag); - safe_dump_ringstate(sc, tag); - if (sc->sc_nqchip) { - struct safe_ringentry *re = sc->sc_back; - do { - safe_dump_request(sc, tag, re); - if (++re == sc->sc_ringtop) - re = sc->sc_ring; - } while (re != sc->sc_front); - } -} - -#endif /* SAFE_DEBUG */ diff --git a/sys/dev/pci/safereg.h b/sys/dev/pci/safereg.h deleted file mode 100644 index 32e38e76f0e..00000000000 --- a/sys/dev/pci/safereg.h +++ /dev/null @@ -1,413 +0,0 @@ -/* $OpenBSD: safereg.h,v 1.5 2009/05/23 15:27:31 jsg Exp $ */ - -/*- - * Copyright (c) 2003 Sam Leffler, Errno Consulting - * Copyright (c) 2003 Global Technology Associates, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $ - */ -#ifndef _SAFE_SAFEREG_H_ -#define _SAFE_SAFEREG_H_ - -/* - * Register definitions for SafeNet SafeXcel-1141 crypto device. - * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual. - */ - -#define SAFE_BAR 0x10 /* DMA base address register */ - -#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */ -#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */ -#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */ -#define SAFE_PE_SA 0x000c /* Packet Engine SA */ -#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */ -#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */ -#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */ -#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */ -#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */ -#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */ -#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */ -#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */ -#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */ -#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */ -#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */ -#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */ -#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */ -#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */ -#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */ -#define SAFE_DEVID 0x0084 /* Device ID */ -#define SAFE_DEVINFO 0x0088 /* Device Info */ -#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */ -#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */ -#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */ -#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */ -#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */ -#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */ -#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */ -#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */ -#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */ -#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */ -#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */ -#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */ -#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */ -#define SAFE_RNG_OUT 0x0100 /* RNG Output */ -#define SAFE_RNG_STAT 0x0104 /* RNG Status */ -#define SAFE_RNG_CTRL 0x0108 /* RNG Control */ -#define SAFE_RNG_A 0x010c /* RNG A */ -#define SAFE_RNG_B 0x0110 /* RNG B */ -#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */ -#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */ -#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */ -#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */ -#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */ -#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */ -#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */ -#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */ -#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */ -#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */ -#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */ -#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */ -#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */ -#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */ -#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */ -#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */ -#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */ -#define SAFE_PK_FUNC 0x081c /* Public Key Function */ -#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */ -#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */ - -#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */ -#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */ -#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */ -#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */ -#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */ -#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */ -#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */ -#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */ -#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */ -#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */ -#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */ -#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */ -#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */ -#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */ -#define SAFE_PE_CSR_XECODE_S 20 -#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */ -#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */ -#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */ -#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */ -#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */ -#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */ -#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */ -#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */ -#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */ -#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */ -#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */ -#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */ -#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */ -#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */ -#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */ - -/* - * Check the CSR to see if the PE has returned ownership to - * the host. Note that before processing a descriptor this - * must be done followed by a check of the SAFE_PE_LEN register - * status bits to avoid premature processing of a descriptor - * on its way back to the host. - */ -#define SAFE_PE_CSR_IS_DONE(_csr) \ - (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE) - -#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */ -#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */ -#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */ -#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */ -#define SAFE_PE_LEN_BYPASS_S 24 - -#define SAFE_PE_LEN_IS_DONE(_len) \ - (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE) - -/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */ -#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */ -#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */ -#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */ -#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */ - -#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */ -#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */ -#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */ - -#define SAFE_ENDIAN_TGT_PASS 0x00e40000 /* target pass-thru */ -#define SAFE_ENDIAN_TGT_SWAB 0x001b0000 /* target swap32 */ -#define SAFE_ENDIAN_DMA_PASS 0x000000e4 /* DMA pass-thru */ -#define SAFE_ENDIAN_DMA_SWAB 0x0000001b /* DMA swap32 */ - -#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */ -#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */ -#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */ -#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */ -#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */ -#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */ -#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */ -#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */ -#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */ -#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */ -#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */ -#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */ -#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */ -#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */ -#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */ -#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */ -#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */ - -#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */ -#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */ -#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */ -#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */ -#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */ -#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */ -#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */ -#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */ -#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */ -#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */ -#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */ -#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */ -#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */ -#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */ - -#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */ -#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */ -#define SAFE_PE_RINGCFG_OFFSET_S 16 - -#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */ -#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */ -#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */ - -#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */ - -#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */ -#define SAFE_PE_ERNGSTAT_NEXT_S 16 - -#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */ -#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */ - -#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */ -#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */ -#define SAFE_PE_PARTCFG_GBURST_2 0x00000000 -#define SAFE_PE_PARTCFG_GBURST_4 0x00010000 -#define SAFE_PE_PARTCFG_GBURST_8 0x00020000 -#define SAFE_PE_PARTCFG_GBURST_16 0x00030000 -#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */ -#define SAFE_PE_PARTCFG_SBURST_2 0x00000000 -#define SAFE_PE_PARTCFG_SBURST_4 0x00040000 -#define SAFE_PE_PARTCFG_SBURST_8 0x00080000 -#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000 - -#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */ -#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */ - -#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */ -#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */ -#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */ - -#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */ -#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */ -#define SAFE_DEVINFO_REV_MAJ_S 4 -#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */ -#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */ -#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */ -#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */ -#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */ -#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */ -#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */ -#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */ -#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */ -#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */ -#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */ - -#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min)) -#define SAFE_REV_MAJ(_chiprev) \ - (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S) -#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN) - -#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */ -#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */ -#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */ -#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */ -#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */ -#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */ -#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */ -#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */ -#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */ -#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */ -#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */ -#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */ - -#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */ - -#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */ -#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */ -#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */ -#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */ -#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */ -#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */ -#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */ -#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */ -#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */ -#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */ - -/* - * Packet engine descriptor. Note that d_csr is a copy of the - * SAFE_PE_CSR register and all definitions apply, and d_len - * is a copy of the SAFE_PE_LEN register and all definitions apply. - * d_src and d_len may point directly to contiguous data or to a - * list of ``particle descriptors'' when using scatter/gather i/o. - */ -struct safe_desc { - volatile u_int32_t d_csr; /* per-packet control/status */ - volatile u_int32_t d_src; /* source address */ - volatile u_int32_t d_dst; /* destination address */ - volatile u_int32_t d_sa; /* SA address */ - volatile u_int32_t d_len; /* length, bypass, status */ -}; - -/* - * Scatter/Gather particle descriptor. - * - * NB: scatter descriptors do not specify a size; this is fixed - * by the setting of the SAFE_PE_PARTCFG register. - */ -struct safe_pdesc { - volatile u_int32_t pd_addr; /* particle address */ - volatile u_int32_t pd_ctrl; /* length/flags */ -}; - -#define SAFE_PD_LEN_M 0xffff0000 /* length mask */ -#define SAFE_PD_LEN_S 16 -#define SAFE_PD_READY 0x00000001 /* ready for processing */ -#define SAFE_PD_DONE 0x00000002 /* h/w completed processing */ - -/* - * Security Association (SA) Record (Rev 1). One of these is - * required for each operation processed by the packet engine. - */ -struct safe_sarec { - volatile u_int32_t sa_cmd0; - volatile u_int32_t sa_cmd1; - volatile u_int32_t sa_resv0; - volatile u_int32_t sa_resv1; - volatile u_int32_t sa_key[8]; /* DES/3DES/AES key */ - volatile u_int32_t sa_indigest[5]; /* inner digest */ - volatile u_int32_t sa_outdigest[5];/* outer digest */ - volatile u_int32_t sa_spi; /* SPI */ - volatile u_int32_t sa_seqnum; /* sequence number */ - volatile u_int32_t sa_seqmask[2]; /* sequence number mask */ - volatile u_int32_t sa_resv2; - volatile u_int32_t sa_staterec; /* address of state record */ - volatile u_int32_t sa_resv3[2]; - volatile u_int32_t sa_samgmt0; /* SA management field 0 */ - volatile u_int32_t sa_samgmt1; /* SA management field 0 */ -}; - -#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */ -#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */ -#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */ -#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */ -#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */ -#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */ -#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */ -#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */ -#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */ -#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */ -#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */ -#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */ -#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */ -#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */ -#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */ -#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */ -#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */ -#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */ -#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */ -#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */ -#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */ -#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */ -#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */ -#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */ -#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */ -#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */ -#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */ -#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */ -#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */ -#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */ -#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */ -#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */ -#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */ -#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */ -#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */ -#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */ -#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */ -#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */ -#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */ -#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */ -#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */ -#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */ -#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */ - -#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */ -#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */ -#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */ -#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */ -#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */ -#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */ -#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */ -#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */ -#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */ -#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */ -#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */ -#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */ -#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */ -#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */ -#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */ -#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */ -#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */ -#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */ -#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */ -#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS -#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */ -#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */ -#define SAFE_SA_CMD1_OFFSET_S 16 -#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */ -#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */ -#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */ -#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */ - -/* - * Security Associate State Record (Rev 1). - */ -struct safe_sastate { - volatile u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */ - volatile u_int32_t sa_saved_hashbc;/* saved hash byte count */ - volatile u_int32_t sa_saved_indigest[5]; /* saved inner digest */ -}; -#endif /* _SAFE_SAFEREG_H_ */ diff --git a/sys/dev/pci/safevar.h b/sys/dev/pci/safevar.h deleted file mode 100644 index 5066a000bdf..00000000000 --- a/sys/dev/pci/safevar.h +++ /dev/null @@ -1,205 +0,0 @@ -/* $OpenBSD: safevar.h,v 1.9 2014/08/15 15:43:27 mikeb Exp $ */ - -/*- - * Copyright (c) 2003 Sam Leffler, Errno Consulting - * Copyright (c) 2003 Global Technology Associates, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/dev/safe/safevar.h,v 1.1 2003/07/21 21:46:07 sam Exp $ - */ -#ifndef _SAFE_SAFEVAR_H_ -#define _SAFE_SAFEVAR_H_ - -/* public key parameter locations */ -#define SAFE_CRK_PARAM_BASE 0 -#define SAFE_CRK_PARAM_EXP 1 -#define SAFE_CRK_PARAM_MOD 2 - -/* Maximum queue length */ -#ifndef SAFE_MAX_NQUEUE -#define SAFE_MAX_NQUEUE 60 -#endif - -#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */ -#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */ -#define SAFE_MAX_DSIZE MCLBYTES /* Fixed scatter particle size */ -#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */ -#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */ -/* total src+dst particle descriptors */ -#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART) -#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART) - -#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */ - -#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28) -#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff) -#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff)) - -#ifdef _KERNEL -/* - * State associated with the allocation of each chunk - * of memory setup for DMA. - */ -struct safe_dma_alloc { - u_int32_t dma_paddr; /* physical address */ - caddr_t dma_vaddr; /* virtual address */ - bus_dmamap_t dma_map; /* associated map */ - bus_dma_segment_t dma_seg; - bus_size_t dma_size; /* mapped memory size (bytes) */ - int dma_nseg; /* number of segments */ -}; - -/* - * Cryptographic operand state. One of these exists for each - * source and destination operand passed in from the crypto - * subsystem. When possible source and destination operands - * refer to the same memory. More often they are distinct. - * We track the virtual address of each operand as well as - * where each is mapped for DMA. - */ -struct safe_operand { - union { - struct mbuf *m; - struct uio *io; - } u; - bus_dmamap_t map; -}; - -/* - * Packet engine ring entry and cryptographic operation state. - * The packet engine requires a ring of descriptors that contain - * pointers to various cryptographic state. However the ring - * configuration register allows you to specify an arbitrary size - * for ring entries. We use this feature to collect most of the - * state for each cryptographic request into one spot. Other than - * ring entries only the ``particle descriptors'' (scatter/gather - * lists) and the actual operand data are kept separate. The - * particle descriptors must also be organized in rings. The - * operand data can be located aribtrarily (modulo alignment constraints). - * - * Note that the descriptor ring is mapped onto the PCI bus so - * the hardware can DMA data. This means the entire ring must be - * contiguous. - */ -struct safe_ringentry { - struct safe_desc re_desc; /* command descriptor */ - struct safe_sarec re_sa; /* SA record */ - struct safe_sastate re_sastate; /* SA state record */ - struct cryptop *re_crp; /* crypto operation */ - - struct safe_operand re_src; /* source operand */ - struct safe_operand re_dst; /* destination operand */ - - int re_sesn; /* crypto session ID */ - int re_flags; -#define SAFE_QFLAGS_COPYOUTICV 0x1 /* copy back on completion */ -}; - -#define re_src_m re_src.u.m -#define re_src_io re_src.u.io -#define re_src_map re_src.map -#define re_src_nsegs re_src.map->dm_nsegs -#define re_src_segs re_src.map->dm_segs -#define re_src_mapsize re_src.map->dm_mapsize - -#define re_dst_m re_dst.u.m -#define re_dst_io re_dst.u.io -#define re_dst_map re_dst.map -#define re_dst_nsegs re_dst.map->dm_nsegs -#define re_dst_segs re_dst.map->dm_segs -#define re_dst_mapsize re_dst.map->dm_mapsize - -struct rndstate_test; - -struct safe_session { - u_int32_t ses_used; - u_int32_t ses_klen; /* key length in bits */ - u_int32_t ses_key[8]; /* DES/3DES/AES key */ - u_int32_t ses_hminner[5]; /* hmac inner state */ - u_int32_t ses_hmouter[5]; /* hmac outer state */ -}; - -struct safe_softc { - struct device sc_dev; /* device backpointer */ - void *sc_ih; /* interrupt handler cookie */ - bus_space_handle_t sc_sh; /* memory handle */ - bus_space_tag_t sc_st; /* memory tag */ - struct resource *sc_sr; /* memory resource */ - bus_dma_tag_t sc_dmat; - u_int sc_chiprev; /* major/minor chip revision */ - int sc_needwakeup; /* notify crypto layer */ - int32_t sc_cid; /* crypto tag */ - struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */ - struct safe_ringentry *sc_ring; /* PE ring */ - struct safe_ringentry *sc_ringtop; /* PE ring top */ - struct safe_ringentry *sc_front; /* next free entry */ - struct safe_ringentry *sc_back; /* next pending entry */ - int sc_nqchip; /* # passed to chip */ - struct safe_pdesc *sc_spring; /* src particle ring */ - struct safe_pdesc *sc_springtop; /* src particle ring top */ - struct safe_pdesc *sc_spfree; /* next free src particle */ - struct safe_dma_alloc sc_spalloc; /* src particle ring state */ - struct safe_pdesc *sc_dpring; /* dest particle ring */ - struct safe_pdesc *sc_dpringtop; /* dest particle ring top */ - struct safe_pdesc *sc_dpfree; /* next free dest particle */ - struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */ - int sc_nsessions; /* # of sessions */ - struct safe_session *sc_sessions; /* sessions */ - - struct timeout sc_rngto; /* rng timeout */ -}; -#endif /* _KERNEL */ - -struct safe_stats { - u_int64_t st_ibytes; - u_int64_t st_obytes; - u_int32_t st_ipackets; - u_int32_t st_opackets; - u_int32_t st_invalid; /* invalid argument */ - u_int32_t st_badsession; /* invalid session id */ - u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */ - u_int32_t st_nodesc; /* op submitted w/o descriptors */ - u_int32_t st_badalg; /* unsupported algorithm */ - u_int32_t st_ringfull; /* PE descriptor ring full */ - u_int32_t st_peoperr; /* PE marked error */ - u_int32_t st_dmaerr; /* PE DMA error */ - u_int32_t st_bypasstoobig; /* bypass > 96 bytes */ - u_int32_t st_skipmismatch; /* enc part begins before auth part */ - u_int32_t st_lenmismatch; /* enc length different auth length */ - u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */ - u_int32_t st_cofftoobig; /* crypto offset > 255 words */ - u_int32_t st_iovmisaligned; /* iov op not aligned */ - u_int32_t st_iovnotuniform; /* iov op not suitable */ - u_int32_t st_unaligned; /* unaligned src caused copy */ - u_int32_t st_notuniform; /* non-uniform src caused copy */ - u_int32_t st_nomap; /* bus_dmamap_create failed */ - u_int32_t st_noload; /* bus_dmamap_load_* failed */ - u_int32_t st_nombuf; /* MGET* failed */ - u_int32_t st_nomcl; /* MCLGET* failed */ - u_int32_t st_maxqchip; /* max mcr1 ops out for processing */ - u_int32_t st_rng; /* RNG requests */ - u_int32_t st_rngalarm; /* RNG alarm requests */ - u_int32_t st_noicvcopy; /* ICV data copies suppressed */ -}; -#endif /* _SAFE_SAFEVAR_H_ */ diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c deleted file mode 100644 index e52cd5911e9..00000000000 --- a/sys/dev/pci/ubsec.c +++ /dev/null @@ -1,1742 +0,0 @@ -/* $OpenBSD: ubsec.c,v 1.168 2021/10/13 13:08:58 bluhm Exp $ */ - -/* - * Copyright (c) 2000 Jason L. Wright (jason@thought.net) - * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org) - * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -#undef UBSEC_DEBUG - -/* - * uBsec 5[56]01, 58xx hardware crypto accelerator - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -/* - * Prototypes and count for the pci_device structure - */ -int ubsec_probe(struct device *, void *, void *); -void ubsec_attach(struct device *, struct device *, void *); -void ubsec_reset_board(struct ubsec_softc *); -void ubsec_init_board(struct ubsec_softc *); -void ubsec_init_pciregs(struct pci_attach_args *pa); -void ubsec_cleanchip(struct ubsec_softc *); -void ubsec_totalreset(struct ubsec_softc *); -int ubsec_free_q(struct ubsec_softc*, struct ubsec_q *); - -struct cfattach ubsec_ca = { - sizeof(struct ubsec_softc), ubsec_probe, ubsec_attach, -}; - -struct cfdriver ubsec_cd = { - 0, "ubsec", DV_DULL -}; - -int ubsec_intr(void *); -int ubsec_newsession(u_int32_t *, struct cryptoini *); -int ubsec_freesession(u_int64_t); -int ubsec_process(struct cryptop *); -void ubsec_callback(struct ubsec_softc *, struct ubsec_q *); -void ubsec_feed(struct ubsec_softc *); -void ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *); -void ubsec_feed2(struct ubsec_softc *); -void ubsec_feed4(struct ubsec_softc *); -void ubsec_rng(void *); -int ubsec_dma_malloc(struct ubsec_softc *, bus_size_t, - struct ubsec_dma_alloc *, int); -void ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *); -int ubsec_dmamap_aligned(bus_dmamap_t); - -#define READ_REG(sc,r) \ - bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r)) - -#define WRITE_REG(sc,reg,val) \ - bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val) - -#define SWAP32(x) (x) = htole32(ntohl((x))) -#define HTOLE32(x) (x) = htole32(x) - - -struct ubsec_stats ubsecstats; - -const struct pci_matchid ubsec_devices[] = { - { PCI_VENDOR_BLUESTEEL, PCI_PRODUCT_BLUESTEEL_5501 }, - { PCI_VENDOR_BLUESTEEL, PCI_PRODUCT_BLUESTEEL_5601 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5801 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5802 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5805 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5820 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5821 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5822 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5823 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5825 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5860 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5861 }, - { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5862 }, - { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_SCA1K }, - { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_5821 }, -}; - -int -ubsec_probe(struct device *parent, void *match, void *aux) -{ - return (pci_matchbyid((struct pci_attach_args *)aux, ubsec_devices, - nitems(ubsec_devices))); -} - -void -ubsec_attach(struct device *parent, struct device *self, void *aux) -{ - struct ubsec_softc *sc = (struct ubsec_softc *)self; - struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; - pcireg_t memtype; - const char *intrstr = NULL; - struct ubsec_dma *dmap; - bus_size_t iosize; - u_int32_t i; - int algs[CRYPTO_ALGORITHM_MAX + 1]; - - SIMPLEQ_INIT(&sc->sc_queue); - SIMPLEQ_INIT(&sc->sc_qchip); - SIMPLEQ_INIT(&sc->sc_queue2); - SIMPLEQ_INIT(&sc->sc_qchip2); - SIMPLEQ_INIT(&sc->sc_queue4); - SIMPLEQ_INIT(&sc->sc_qchip4); - - sc->sc_statmask = BS_STAT_MCR1_DONE | BS_STAT_DMAERR; - sc->sc_maxaggr = UBS_MIN_AGGR; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5601) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5802 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5805)) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5820 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822)) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | - UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY; - - if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5821) || - (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SCA1K || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_5821))) { - sc->sc_statmask |= BS_STAT_MCR1_ALLEMPTY | - BS_STAT_MCR2_ALLEMPTY; - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | - UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY; - } - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5823 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5825)) - sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | - UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY | - UBS_FLAGS_AES; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5860 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5861 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5862)) { - sc->sc_maxaggr = UBS_MAX_AGGR; - sc->sc_statmask |= - BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | - BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY; - sc->sc_flags |= UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | - UBS_FLAGS_LONGCTX | UBS_FLAGS_AES | - UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY; -#if 0 - /* The RNG is not yet supported */ - sc->sc_flags |= UBS_FLAGS_RNG | UBS_FLAGS_RNG4; -#endif - } - - memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BS_BAR); - if (pci_mapreg_map(pa, BS_BAR, memtype, 0, - &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) { - printf(": can't find mem space\n"); - return; - } - sc->sc_dmat = pa->pa_dmat; - - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); - return; - } - intrstr = pci_intr_string(pc, ih); - sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ubsec_intr, sc, - self->dv_xname); - if (sc->sc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); - return; - } - - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) { - pci_intr_disestablish(pc, sc->sc_ih); - bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); - return; - } - - SIMPLEQ_INIT(&sc->sc_freequeue); - dmap = sc->sc_dmaa; - for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) { - struct ubsec_q *q; - - q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q), - M_DEVBUF, M_NOWAIT); - if (q == NULL) { - printf(": can't allocate queue buffers\n"); - break; - } - - if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk), - &dmap->d_alloc, 0)) { - printf(": can't allocate dma buffers\n"); - free(q, M_DEVBUF, 0); - break; - } - dmap->d_dma = (struct ubsec_dmachunk *)dmap->d_alloc.dma_vaddr; - - q->q_dma = dmap; - sc->sc_queuea[i] = q; - - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - } - - bzero(algs, sizeof(algs)); - algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; - if (sc->sc_flags & UBS_FLAGS_AES) - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - crypto_register(sc->sc_cid, algs, ubsec_newsession, - ubsec_freesession, ubsec_process); - - /* - * Reset Broadcom chip - */ - ubsec_reset_board(sc); - - /* - * Init Broadcom specific PCI settings - */ - ubsec_init_pciregs(pa); - - /* - * Init Broadcom chip - */ - ubsec_init_board(sc); - - printf(": 3DES MD5 SHA1"); - if (sc->sc_flags & UBS_FLAGS_AES) - printf(" AES"); - -#ifndef UBSEC_NO_RNG - if (sc->sc_flags & UBS_FLAGS_RNG) { - if (sc->sc_flags & UBS_FLAGS_RNG4) - sc->sc_statmask |= BS_STAT_MCR4_DONE; - else - sc->sc_statmask |= BS_STAT_MCR2_DONE; - - if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), - &sc->sc_rng.rng_q.q_mcr, 0)) - goto skip_rng; - - if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass), - &sc->sc_rng.rng_q.q_ctx, 0)) { - ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); - goto skip_rng; - } - - if (ubsec_dma_malloc(sc, sizeof(u_int32_t) * - UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) { - ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx); - ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); - goto skip_rng; - } - - timeout_set(&sc->sc_rngto, ubsec_rng, sc); - sc->sc_rngms = 10; - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); - printf(" RNG"); -skip_rng: - ; - } -#endif /* UBSEC_NO_RNG */ - - if (sc->sc_flags & UBS_FLAGS_KEY) { - sc->sc_statmask |= BS_STAT_MCR2_DONE; - } - - printf(", %s\n", intrstr); -} - -/* - * UBSEC Interrupt routine - */ -int -ubsec_intr(void *arg) -{ - struct ubsec_softc *sc = arg; - volatile u_int32_t stat; - struct ubsec_q *q; - struct ubsec_dma *dmap; - u_int16_t flags; - int npkts = 0, i; - - stat = READ_REG(sc, BS_STAT); - - if ((stat & (BS_STAT_MCR1_DONE|BS_STAT_MCR2_DONE|BS_STAT_MCR4_DONE| - BS_STAT_DMAERR)) == 0) - return (0); - - stat &= sc->sc_statmask; - WRITE_REG(sc, BS_STAT, stat); /* IACK */ - - /* - * Check to see if we have any packets waiting for us - */ - if ((stat & BS_STAT_MCR1_DONE)) { - while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { - q = SIMPLEQ_FIRST(&sc->sc_qchip); - dmap = q->q_dma; - - if ((dmap->d_dma->d_mcr.mcr_flags & htole16(UBS_MCR_DONE)) == 0) - break; - - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q_next); - - npkts = q->q_nstacked_mcrs; - /* - * search for further sc_qchip ubsec_q's that share - * the same MCR, and complete them too, they must be - * at the top. - */ - for (i = 0; i < npkts; i++) { - if(q->q_stacked_mcr[i]) - ubsec_callback(sc, q->q_stacked_mcr[i]); - else - break; - } - ubsec_callback(sc, q); - } - - /* - * Don't send any more packet to chip if there has been - * a DMAERR. - */ - if (!(stat & BS_STAT_DMAERR)) - ubsec_feed(sc); - } - - /* - * Check to see if we have any key setups/rng's waiting for us - */ - if ((sc->sc_flags & (UBS_FLAGS_KEY|UBS_FLAGS_RNG)) && - (stat & BS_STAT_MCR2_DONE)) { - struct ubsec_q2 *q2; - struct ubsec_mcr *mcr; - - while (!SIMPLEQ_EMPTY(&sc->sc_qchip2)) { - q2 = SIMPLEQ_FIRST(&sc->sc_qchip2); - - bus_dmamap_sync(sc->sc_dmat, q2->q_mcr.dma_map, - 0, q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - - mcr = (struct ubsec_mcr *)q2->q_mcr.dma_vaddr; - - /* A bug in new devices requires to swap this field */ - if (sc->sc_flags & UBS_FLAGS_MULTIMCR) - flags = swap16(mcr->mcr_flags); - else - flags = mcr->mcr_flags; - if ((flags & htole16(UBS_MCR_DONE)) == 0) { - bus_dmamap_sync(sc->sc_dmat, - q2->q_mcr.dma_map, 0, - q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - break; - } - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip2, q_next); - ubsec_callback2(sc, q2); - /* - * Don't send any more packet to chip if there has been - * a DMAERR. - */ - if (!(stat & BS_STAT_DMAERR)) - ubsec_feed2(sc); - } - } - if ((sc->sc_flags & UBS_FLAGS_RNG4) && (stat & BS_STAT_MCR4_DONE)) { - struct ubsec_q2 *q2; - struct ubsec_mcr *mcr; - - while (!SIMPLEQ_EMPTY(&sc->sc_qchip4)) { - q2 = SIMPLEQ_FIRST(&sc->sc_qchip4); - - bus_dmamap_sync(sc->sc_dmat, q2->q_mcr.dma_map, - 0, q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - - mcr = (struct ubsec_mcr *)q2->q_mcr.dma_vaddr; - - /* A bug in new devices requires to swap this field */ - flags = swap16(mcr->mcr_flags); - - if ((flags & htole16(UBS_MCR_DONE)) == 0) { - bus_dmamap_sync(sc->sc_dmat, - q2->q_mcr.dma_map, 0, - q2->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - break; - } - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip4, q_next); - ubsec_callback2(sc, q2); - /* - * Don't send any more packet to chip if there has been - * a DMAERR. - */ - if (!(stat & BS_STAT_DMAERR)) - ubsec_feed4(sc); - } - } - - /* - * Check to see if we got any DMA Error - */ - if (stat & BS_STAT_DMAERR) { -#ifdef UBSEC_DEBUG - volatile u_int32_t a = READ_REG(sc, BS_ERR); - - printf("%s: dmaerr %s@%08x\n", sc->sc_dv.dv_xname, - (a & BS_ERR_READ) ? "read" : "write", a & BS_ERR_ADDR); -#endif /* UBSEC_DEBUG */ - ubsecstats.hst_dmaerr++; - ubsec_totalreset(sc); - ubsec_feed(sc); - } - - return (1); -} - -/* - * ubsec_feed() - aggregate and post requests to chip - * It is assumed that the caller set splnet() - */ -void -ubsec_feed(struct ubsec_softc *sc) -{ -#ifdef UBSEC_DEBUG - static int max; -#endif /* UBSEC_DEBUG */ - struct ubsec_q *q, *q2; - int npkts, i; - void *v; - u_int32_t stat; - - npkts = sc->sc_nqueue; - if (npkts > sc->sc_maxaggr) - npkts = sc->sc_maxaggr; - if (npkts < 2) - goto feed1; - - if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) { - if(stat & BS_STAT_DMAERR) { - ubsec_totalreset(sc); - ubsecstats.hst_dmaerr++; - } - return; - } - -#ifdef UBSEC_DEBUG - printf("merging %d records\n", npkts); - - /* XXX temporary aggregation statistics reporting code */ - if (max < npkts) { - max = npkts; - printf("%s: new max aggregate %d\n", sc->sc_dv.dv_xname, max); - } -#endif /* UBSEC_DEBUG */ - - q = SIMPLEQ_FIRST(&sc->sc_queue); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next); - --sc->sc_nqueue; - - bus_dmamap_sync(sc->sc_dmat, q->q_src_map, - 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (q->q_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, - 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - - q->q_nstacked_mcrs = npkts - 1; /* Number of packets stacked */ - - for (i = 0; i < q->q_nstacked_mcrs; i++) { - q2 = SIMPLEQ_FIRST(&sc->sc_queue); - bus_dmamap_sync(sc->sc_dmat, q2->q_src_map, - 0, q2->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (q2->q_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, q2->q_dst_map, - 0, q2->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next); - --sc->sc_nqueue; - - v = ((char *)&q2->q_dma->d_dma->d_mcr) + sizeof(struct ubsec_mcr) - - sizeof(struct ubsec_mcr_add); - bcopy(v, &q->q_dma->d_dma->d_mcradd[i], sizeof(struct ubsec_mcr_add)); - q->q_stacked_mcr[i] = q2; - } - q->q_dma->d_dma->d_mcr.mcr_pkts = htole16(npkts); - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next); - bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map, - 0, q->q_dma->d_alloc.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_mcr)); - return; - -feed1: - while (!SIMPLEQ_EMPTY(&sc->sc_queue)) { - if ((stat = READ_REG(sc, BS_STAT)) & - (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) { - if(stat & BS_STAT_DMAERR) { - ubsec_totalreset(sc); - ubsecstats.hst_dmaerr++; - } - break; - } - - q = SIMPLEQ_FIRST(&sc->sc_queue); - - bus_dmamap_sync(sc->sc_dmat, q->q_src_map, - 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); - if (q->q_dst_map != NULL) - bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, - 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); - bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map, - 0, q->q_dma->d_alloc.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_mcr)); -#ifdef UBSEC_DEBUG - printf("feed: q->chip %p %08x\n", q, - (u_int32_t)q->q_dma->d_alloc.dma_paddr); -#endif /* UBSEC_DEBUG */ - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next); - --sc->sc_nqueue; - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next); - } -} - -/* - * Allocate a new 'session' and return an encoded session id. 'sidp' - * contains our registration id, and should contain an encoded session - * id on successful allocation. - */ -int -ubsec_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct cryptoini *c, *encini = NULL, *macini = NULL; - struct ubsec_softc *sc = NULL; - struct ubsec_session *ses = NULL; - MD5_CTX md5ctx; - SHA1_CTX sha1ctx; - int i, sesn; - - if (sidp == NULL || cri == NULL) - return (EINVAL); - - for (i = 0; i < ubsec_cd.cd_ndevs; i++) { - sc = ubsec_cd.cd_devs[i]; - if (sc == NULL || sc->sc_cid == (*sidp)) - break; - } - if (sc == NULL) - return (EINVAL); - - for (c = cri; c != NULL; c = c->cri_next) { - if (c->cri_alg == CRYPTO_MD5_HMAC || - c->cri_alg == CRYPTO_SHA1_HMAC) { - if (macini) - return (EINVAL); - macini = c; - } else if (c->cri_alg == CRYPTO_3DES_CBC || - c->cri_alg == CRYPTO_AES_CBC) { - if (encini) - return (EINVAL); - encini = c; - } else - return (EINVAL); - } - if (encini == NULL && macini == NULL) - return (EINVAL); - - if (encini && encini->cri_alg == CRYPTO_AES_CBC) { - switch (encini->cri_klen) { - case 128: - case 192: - case 256: - break; - default: - return (EINVAL); - } - } - - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct ubsec_session *)malloc( - sizeof(struct ubsec_session), 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].ses_used == 0) { - ses = &sc->sc_sessions[sesn]; - break; - } - } - - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = mallocarray((sesn + 1), - sizeof(struct ubsec_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * - sizeof(struct ubsec_session)); - explicit_bzero(sc->sc_sessions, sesn * - sizeof(struct ubsec_session)); - free(sc->sc_sessions, M_DEVBUF, 0); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - - bzero(ses, sizeof(struct ubsec_session)); - ses->ses_used = 1; - if (encini) { - /* Go ahead and compute key in ubsec's byte order */ - if (encini->cri_alg == CRYPTO_AES_CBC) { - bcopy(encini->cri_key, ses->ses_key, - encini->cri_klen / 8); - } else - bcopy(encini->cri_key, ses->ses_key, 24); - - SWAP32(ses->ses_key[0]); - SWAP32(ses->ses_key[1]); - SWAP32(ses->ses_key[2]); - SWAP32(ses->ses_key[3]); - SWAP32(ses->ses_key[4]); - SWAP32(ses->ses_key[5]); - SWAP32(ses->ses_key[6]); - SWAP32(ses->ses_key[7]); - } - - if (macini) { - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_IPAD_VAL; - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_ipad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hminner, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_ipad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hminner, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - if (macini->cri_alg == CRYPTO_MD5_HMAC) { - MD5Init(&md5ctx); - MD5Update(&md5ctx, macini->cri_key, - macini->cri_klen / 8); - MD5Update(&md5ctx, hmac_opad_buffer, - HMAC_MD5_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(md5ctx.state, ses->ses_hmouter, - sizeof(md5ctx.state)); - } else { - SHA1Init(&sha1ctx); - SHA1Update(&sha1ctx, macini->cri_key, - macini->cri_klen / 8); - SHA1Update(&sha1ctx, hmac_opad_buffer, - HMAC_SHA1_BLOCK_LEN - (macini->cri_klen / 8)); - bcopy(sha1ctx.state, ses->ses_hmouter, - sizeof(sha1ctx.state)); - } - - for (i = 0; i < macini->cri_klen / 8; i++) - macini->cri_key[i] ^= HMAC_OPAD_VAL; - } - - *sidp = UBSEC_SID(sc->sc_dv.dv_unit, sesn); - return (0); -} - -/* - * Deallocate a session. - */ -int -ubsec_freesession(u_int64_t tid) -{ - struct ubsec_softc *sc; - int card, session; - u_int32_t sid = ((u_int32_t)tid) & 0xffffffff; - - card = UBSEC_CARD(sid); - if (card >= ubsec_cd.cd_ndevs || ubsec_cd.cd_devs[card] == NULL) - return (EINVAL); - sc = ubsec_cd.cd_devs[card]; - session = UBSEC_SESSION(sid); - explicit_bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session])); - return (0); -} - -int -ubsec_process(struct cryptop *crp) -{ - struct ubsec_q *q = NULL; - int card, err = 0, i, j, s, nicealign; - struct ubsec_softc *sc; - struct cryptodesc *crd1, *crd2 = NULL, *maccrd, *enccrd; - int encoffset = 0, macoffset = 0, cpskip, cpoffset; - int sskip, dskip, stheend, dtheend; - int16_t coffset; - struct ubsec_session *ses, key; - struct ubsec_dma *dmap = NULL; - u_int16_t flags = 0; - int ivlen = 0, keylen = 0; - - card = UBSEC_CARD(crp->crp_sid); - if (card >= ubsec_cd.cd_ndevs || ubsec_cd.cd_devs[card] == NULL) { - ubsecstats.hst_invalid++; - return (EINVAL); - } - - sc = ubsec_cd.cd_devs[card]; - - s = splnet(); - - if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) { - ubsecstats.hst_queuefull++; - splx(s); - err = ENOMEM; - goto errout2; - } - - q = SIMPLEQ_FIRST(&sc->sc_freequeue); - SIMPLEQ_REMOVE_HEAD(&sc->sc_freequeue, q_next); - splx(s); - - dmap = q->q_dma; /* Save dma pointer */ - bzero(q, sizeof(struct ubsec_q)); - bzero(&key, sizeof(key)); - - q->q_sesn = UBSEC_SESSION(crp->crp_sid); - q->q_dma = dmap; - ses = &sc->sc_sessions[q->q_sesn]; - - if (crp->crp_flags & CRYPTO_F_IMBUF) { - q->q_src_m = (struct mbuf *)crp->crp_buf; - q->q_dst_m = (struct mbuf *)crp->crp_buf; - } else if (crp->crp_flags & CRYPTO_F_IOV) { - q->q_src_io = (struct uio *)crp->crp_buf; - q->q_dst_io = (struct uio *)crp->crp_buf; - } else { - err = EINVAL; - goto errout; /* XXX we don't handle contiguous blocks! */ - } - - bzero(&dmap->d_dma->d_mcr, sizeof(struct ubsec_mcr)); - - dmap->d_dma->d_mcr.mcr_pkts = htole16(1); - dmap->d_dma->d_mcr.mcr_flags = 0; - q->q_crp = crp; - - if (crp->crp_ndesc < 1) { - err = EINVAL; - goto errout; - } - crd1 = &crp->crp_desc[0]; - if (crp->crp_ndesc >= 2) - crd2 = &crp->crp_desc[1]; - - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) { - maccrd = crd1; - enccrd = NULL; - } else if (crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) { - maccrd = NULL; - enccrd = crd1; - } else { - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC) && - (crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC) && - ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - /* - * We cannot order the ubsec as requested - */ - err = EINVAL; - goto errout; - } - } - - if (enccrd) { - if (enccrd->crd_alg == CRYPTO_AES_CBC) { - if ((sc->sc_flags & UBS_FLAGS_AES) == 0) { - err = EINVAL; - goto errout; - } - flags |= htole16(UBS_PKTCTX_ENC_AES); - switch (enccrd->crd_klen) { - case 128: - case 192: - case 256: - keylen = enccrd->crd_klen / 8; - break; - default: - err = EINVAL; - goto errout; - } - ivlen = 16; - } else { - flags |= htole16(UBS_PKTCTX_ENC_3DES); - ivlen = 8; - keylen = 24; - } - - encoffset = enccrd->crd_skip; - - if (enccrd->crd_flags & CRD_F_ENCRYPT) { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, key.ses_iv, ivlen); - else - arc4random_buf(key.ses_iv, ivlen); - - if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - err = m_copyback(q->q_src_m, - enccrd->crd_inject, - ivlen, key.ses_iv, M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback(q->q_src_io, - enccrd->crd_inject, - ivlen, key.ses_iv); - if (err) - goto errout; - } - } else { - flags |= htole16(UBS_PKTCTX_INBOUND); - - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, key.ses_iv, ivlen); - else if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata(q->q_src_m, enccrd->crd_inject, - ivlen, key.ses_iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata(q->q_src_io, - enccrd->crd_inject, ivlen, - (caddr_t)key.ses_iv); - } - - for (i = 0; i < (keylen / 4); i++) - key.ses_key[i] = ses->ses_key[i]; - for (i = 0; i < (ivlen / 4); i++) - SWAP32(key.ses_iv[i]); - } - - if (maccrd) { - macoffset = maccrd->crd_skip; - - if (maccrd->crd_alg == CRYPTO_MD5_HMAC) - flags |= htole16(UBS_PKTCTX_AUTH_MD5); - else - flags |= htole16(UBS_PKTCTX_AUTH_SHA1); - - for (i = 0; i < 5; i++) { - key.ses_hminner[i] = ses->ses_hminner[i]; - key.ses_hmouter[i] = ses->ses_hmouter[i]; - - HTOLE32(key.ses_hminner[i]); - HTOLE32(key.ses_hmouter[i]); - } - } - - if (enccrd && maccrd) { - /* - * ubsec cannot handle packets where the end of encryption - * and authentication are not the same, or where the - * encrypted part begins before the authenticated part. - */ - if (((encoffset + enccrd->crd_len) != - (macoffset + maccrd->crd_len)) || - (enccrd->crd_skip < maccrd->crd_skip)) { - err = EINVAL; - goto errout; - } - sskip = maccrd->crd_skip; - cpskip = dskip = enccrd->crd_skip; - stheend = maccrd->crd_len; - dtheend = enccrd->crd_len; - coffset = enccrd->crd_skip - maccrd->crd_skip; - cpoffset = cpskip + dtheend; -#ifdef UBSEC_DEBUG - printf("mac: skip %d, len %d, inject %d\n", - maccrd->crd_skip, maccrd->crd_len, maccrd->crd_inject); - printf("enc: skip %d, len %d, inject %d\n", - enccrd->crd_skip, enccrd->crd_len, enccrd->crd_inject); - printf("src: skip %d, len %d\n", sskip, stheend); - printf("dst: skip %d, len %d\n", dskip, dtheend); - printf("ubs: coffset %d, pktlen %d, cpskip %d, cpoffset %d\n", - coffset, stheend, cpskip, cpoffset); -#endif - } else { - cpskip = dskip = sskip = macoffset + encoffset; - dtheend = stheend = (enccrd)?enccrd->crd_len:maccrd->crd_len; - cpoffset = cpskip + dtheend; - coffset = 0; - } - - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER, - 0xfff0, 0, BUS_DMA_NOWAIT, &q->q_src_map) != 0) { - err = ENOMEM; - goto errout; - } - if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (bus_dmamap_load_mbuf(sc->sc_dmat, q->q_src_map, - q->q_src_m, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - q->q_src_map = NULL; - err = ENOMEM; - goto errout; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - if (bus_dmamap_load_uio(sc->sc_dmat, q->q_src_map, - q->q_src_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - q->q_src_map = NULL; - err = ENOMEM; - goto errout; - } - } - nicealign = ubsec_dmamap_aligned(q->q_src_map); - - dmap->d_dma->d_mcr.mcr_pktlen = htole16(stheend); - -#ifdef UBSEC_DEBUG - printf("src skip: %d\n", sskip); -#endif - for (i = j = 0; i < q->q_src_map->dm_nsegs; i++) { - struct ubsec_pktbuf *pb; - bus_size_t packl = q->q_src_map->dm_segs[i].ds_len; - bus_addr_t packp = q->q_src_map->dm_segs[i].ds_addr; - - if (sskip >= packl) { - sskip -= packl; - continue; - } - - packl -= sskip; - packp += sskip; - sskip = 0; - - if (packl > 0xfffc) { - err = EIO; - goto errout; - } - - if (j == 0) - pb = &dmap->d_dma->d_mcr.mcr_ipktbuf; - else - pb = &dmap->d_dma->d_sbuf[j - 1]; - - pb->pb_addr = htole32(packp); - - if (stheend) { - if (packl > stheend) { - pb->pb_len = htole32(stheend); - stheend = 0; - } else { - pb->pb_len = htole32(packl); - stheend -= packl; - } - } else - pb->pb_len = htole32(packl); - - if ((i + 1) == q->q_src_map->dm_nsegs) - pb->pb_next = 0; - else - pb->pb_next = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_sbuf[j])); - j++; - } - - if (enccrd == NULL && maccrd != NULL) { - dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr = 0; - dmap->d_dma->d_mcr.mcr_opktbuf.pb_len = 0; - dmap->d_dma->d_mcr.mcr_opktbuf.pb_next = - htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_macbuf[0])); -#ifdef UBSEC_DEBUG - printf("opkt: %x %x %x\n", - dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr, - dmap->d_dma->d_mcr.mcr_opktbuf.pb_len, - dmap->d_dma->d_mcr.mcr_opktbuf.pb_next); -#endif - } else { - if (crp->crp_flags & CRYPTO_F_IOV) { - if (!nicealign) { - err = EINVAL; - goto errout; - } - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, - UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, - &q->q_dst_map) != 0) { - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_uio(sc->sc_dmat, q->q_dst_map, - q->q_dst_io, BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - q->q_dst_map = NULL; - goto errout; - } - } else if (crp->crp_flags & CRYPTO_F_IMBUF) { - if (nicealign) { - q->q_dst_m = q->q_src_m; - q->q_dst_map = q->q_src_map; - } else { - q->q_dst_m = m_dup_pkt(q->q_src_m, 0, - M_NOWAIT); - if (q->q_dst_m == NULL) { - err = ENOMEM; - goto errout; - } - if (bus_dmamap_create(sc->sc_dmat, 0xfff0, - UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, - &q->q_dst_map) != 0) { - err = ENOMEM; - goto errout; - } - if (bus_dmamap_load_mbuf(sc->sc_dmat, - q->q_dst_map, q->q_dst_m, - BUS_DMA_NOWAIT) != 0) { - bus_dmamap_destroy(sc->sc_dmat, - q->q_dst_map); - q->q_dst_map = NULL; - err = ENOMEM; - goto errout; - } - } - } else { - err = EINVAL; - goto errout; - } - -#ifdef UBSEC_DEBUG - printf("dst skip: %d\n", dskip); -#endif - for (i = j = 0; i < q->q_dst_map->dm_nsegs; i++) { - struct ubsec_pktbuf *pb; - bus_size_t packl = q->q_dst_map->dm_segs[i].ds_len; - bus_addr_t packp = q->q_dst_map->dm_segs[i].ds_addr; - - if (dskip >= packl) { - dskip -= packl; - continue; - } - - packl -= dskip; - packp += dskip; - dskip = 0; - - if (packl > 0xfffc) { - err = EIO; - goto errout; - } - - if (j == 0) - pb = &dmap->d_dma->d_mcr.mcr_opktbuf; - else - pb = &dmap->d_dma->d_dbuf[j - 1]; - - pb->pb_addr = htole32(packp); - - if (dtheend) { - if (packl > dtheend) { - pb->pb_len = htole32(dtheend); - dtheend = 0; - } else { - pb->pb_len = htole32(packl); - dtheend -= packl; - } - } else - pb->pb_len = htole32(packl); - - if ((i + 1) == q->q_dst_map->dm_nsegs) { - if (maccrd) - pb->pb_next = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_macbuf[0])); - else - pb->pb_next = 0; - } else - pb->pb_next = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_dbuf[j])); - j++; - } - } - - dmap->d_dma->d_mcr.mcr_cmdctxp = htole32(dmap->d_alloc.dma_paddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - if (enccrd && enccrd->crd_alg == CRYPTO_AES_CBC) { - struct ubsec_pktctx_aes128 *aes128; - struct ubsec_pktctx_aes192 *aes192; - struct ubsec_pktctx_aes256 *aes256; - struct ubsec_pktctx_hdr *ph; - u_int8_t *ctx; - - ctx = (u_int8_t *)(dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - ph = (struct ubsec_pktctx_hdr *)ctx; - ph->ph_type = htole16(UBS_PKTCTX_TYPE_IPSEC_AES); - ph->ph_flags = flags; - ph->ph_offset = htole16(coffset >> 2); - - switch (enccrd->crd_klen) { - case 128: - aes128 = (struct ubsec_pktctx_aes128 *)ctx; - ph->ph_len = htole16(sizeof(*aes128)); - ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_128); - for (i = 0; i < 4; i++) - aes128->pc_aeskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - aes128->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - aes128->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 4; i++) - aes128->pc_iv[i] = key.ses_iv[i]; - break; - case 192: - aes192 = (struct ubsec_pktctx_aes192 *)ctx; - ph->ph_len = htole16(sizeof(*aes192)); - ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_192); - for (i = 0; i < 6; i++) - aes192->pc_aeskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - aes192->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - aes192->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 4; i++) - aes192->pc_iv[i] = key.ses_iv[i]; - break; - case 256: - aes256 = (struct ubsec_pktctx_aes256 *)ctx; - ph->ph_len = htole16(sizeof(*aes256)); - ph->ph_flags |= htole16(UBS_PKTCTX_KEYSIZE_256); - for (i = 0; i < 8; i++) - aes256->pc_aeskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - aes256->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - aes256->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 4; i++) - aes256->pc_iv[i] = key.ses_iv[i]; - break; - } - } else if (sc->sc_flags & UBS_FLAGS_LONGCTX) { - struct ubsec_pktctx_3des *ctx; - struct ubsec_pktctx_hdr *ph; - - ctx = (struct ubsec_pktctx_3des *) - (dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - ph = (struct ubsec_pktctx_hdr *)ctx; - ph->ph_len = htole16(sizeof(*ctx)); - ph->ph_type = htole16(UBS_PKTCTX_TYPE_IPSEC_3DES); - ph->ph_flags = flags; - ph->ph_offset = htole16(coffset >> 2); - - for (i = 0; i < 6; i++) - ctx->pc_deskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - ctx->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - ctx->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 2; i++) - ctx->pc_iv[i] = key.ses_iv[i]; - } else { - struct ubsec_pktctx *ctx = (struct ubsec_pktctx *) - (dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - - ctx->pc_flags = flags; - ctx->pc_offset = htole16(coffset >> 2); - for (i = 0; i < 6; i++) - ctx->pc_deskey[i] = key.ses_key[i]; - for (i = 0; i < 5; i++) - ctx->pc_hminner[i] = key.ses_hminner[i]; - for (i = 0; i < 5; i++) - ctx->pc_hmouter[i] = key.ses_hmouter[i]; - for (i = 0; i < 2; i++) - ctx->pc_iv[i] = key.ses_iv[i]; - } - - s = splnet(); - SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next); - sc->sc_nqueue++; - ubsecstats.hst_ipackets++; - ubsecstats.hst_ibytes += dmap->d_alloc.dma_map->dm_mapsize; - ubsec_feed(sc); - splx(s); - explicit_bzero(&key, sizeof(key)); - return (0); - -errout: - if (q != NULL) { - if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) - m_freem(q->q_dst_m); - - if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { - bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - } - if (q->q_src_map != NULL) { - bus_dmamap_unload(sc->sc_dmat, q->q_src_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - } - - s = splnet(); - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - splx(s); - } - if (err == EINVAL) - ubsecstats.hst_invalid++; - else - ubsecstats.hst_nomem++; -errout2: - crp->crp_etype = err; - crypto_done(crp); - explicit_bzero(&key, sizeof(key)); - return (0); -} - -void -ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q) -{ - struct cryptop *crp = (struct cryptop *)q->q_crp; - struct cryptodesc *crd; - struct ubsec_dma *dmap = q->q_dma; - u_int8_t *ctx = (u_int8_t *)(dmap->d_alloc.dma_vaddr + - offsetof(struct ubsec_dmachunk, d_ctx)); - struct ubsec_pktctx_hdr *ph = (struct ubsec_pktctx_hdr *)ctx; - int i; - - ubsecstats.hst_opackets++; - ubsecstats.hst_obytes += dmap->d_alloc.dma_size; - - bus_dmamap_sync(sc->sc_dmat, dmap->d_alloc.dma_map, 0, - dmap->d_alloc.dma_map->dm_mapsize, - BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { - bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, - 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); - } - bus_dmamap_sync(sc->sc_dmat, q->q_src_map, - 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, q->q_src_map); - bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); - - explicit_bzero(ctx, ph->ph_len); - - if ((crp->crp_flags & CRYPTO_F_IMBUF) && (q->q_src_m != q->q_dst_m)) { - m_freem(q->q_src_m); - crp->crp_buf = (caddr_t)q->q_dst_m; - } - - for (i = 0; i < crp->crp_ndesc; i++) { - crd = &crp->crp_desc[i]; - if (crd->crd_alg != CRYPTO_MD5_HMAC && - crd->crd_alg != CRYPTO_SHA1_HMAC) - continue; - if (crp->crp_flags & CRYPTO_F_IMBUF) - crp->crp_etype = m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, 12, - dmap->d_dma->d_macbuf, M_NOWAIT); - else if (crp->crp_flags & CRYPTO_F_IOV && crp->crp_mac) - bcopy((caddr_t)dmap->d_dma->d_macbuf, - crp->crp_mac, 12); - break; - } - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - crypto_done(crp); -} - -/* - * feed the key generator, must be called at splnet() or higher. - */ -void -ubsec_feed2(struct ubsec_softc *sc) -{ - struct ubsec_q2 *q; - - while (!SIMPLEQ_EMPTY(&sc->sc_queue2)) { - if (READ_REG(sc, BS_STAT) & BS_STAT_MCR2_FULL) - break; - q = SIMPLEQ_FIRST(&sc->sc_queue2); - - bus_dmamap_sync(sc->sc_dmat, q->q_mcr.dma_map, 0, - q->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, - q->q_ctx.dma_map->dm_mapsize, - BUS_DMASYNC_PREWRITE); - - WRITE_REG(sc, BS_MCR2, q->q_mcr.dma_paddr); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue2, q_next); - --sc->sc_nqueue2; - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip2, q, q_next); - } -} - -/* - * feed the RNG (used instead of ubsec_feed2() on 5827+ devices) - */ -void -ubsec_feed4(struct ubsec_softc *sc) -{ - struct ubsec_q2 *q; - - while (!SIMPLEQ_EMPTY(&sc->sc_queue4)) { - if (READ_REG(sc, BS_STAT) & BS_STAT_MCR4_FULL) - break; - q = SIMPLEQ_FIRST(&sc->sc_queue4); - - bus_dmamap_sync(sc->sc_dmat, q->q_mcr.dma_map, 0, - q->q_mcr.dma_map->dm_mapsize, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, - q->q_ctx.dma_map->dm_mapsize, - BUS_DMASYNC_PREWRITE); - - WRITE_REG(sc, BS_MCR4, q->q_mcr.dma_paddr); - SIMPLEQ_REMOVE_HEAD(&sc->sc_queue4, q_next); - --sc->sc_nqueue4; - SIMPLEQ_INSERT_TAIL(&sc->sc_qchip4, q, q_next); - } -} - -/* - * Callback for handling random numbers - */ -void -ubsec_callback2(struct ubsec_softc *sc, struct ubsec_q2 *q) -{ - struct ubsec_ctx_keyop *ctx; - - ctx = (struct ubsec_ctx_keyop *)q->q_ctx.dma_vaddr; - bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, - q->q_ctx.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - - switch (q->q_type) { -#ifndef UBSEC_NO_RNG - case UBS_CTXOP_RNGSHA1: - case UBS_CTXOP_RNGBYPASS: { - struct ubsec_q2_rng *rng = (struct ubsec_q2_rng *)q; - u_int32_t *p; - int i; - - bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, - rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - p = (u_int32_t *)rng->rng_buf.dma_vaddr; - for (i = 0; i < UBSEC_RNG_BUFSIZ; p++, i++) - enqueue_randomness(*p); - rng->rng_used = 0; - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); - break; - } -#endif - default: - printf("%s: unknown ctx op: %x\n", sc->sc_dv.dv_xname, - letoh16(ctx->ctx_op)); - break; - } -} - -#ifndef UBSEC_NO_RNG -void -ubsec_rng(void *vsc) -{ - struct ubsec_softc *sc = vsc; - struct ubsec_q2_rng *rng = &sc->sc_rng; - struct ubsec_mcr *mcr; - struct ubsec_ctx_rngbypass *ctx; - int s, *nqueue; - - s = splnet(); - if (rng->rng_used) { - splx(s); - return; - } - if (sc->sc_flags & UBS_FLAGS_RNG4) - nqueue = &sc->sc_nqueue4; - else - nqueue = &sc->sc_nqueue2; - - (*nqueue)++; - if (*nqueue >= UBS_MAX_NQUEUE) - goto out; - - mcr = (struct ubsec_mcr *)rng->rng_q.q_mcr.dma_vaddr; - ctx = (struct ubsec_ctx_rngbypass *)rng->rng_q.q_ctx.dma_vaddr; - - mcr->mcr_pkts = htole16(1); - mcr->mcr_flags = 0; - mcr->mcr_cmdctxp = htole32(rng->rng_q.q_ctx.dma_paddr); - mcr->mcr_ipktbuf.pb_addr = mcr->mcr_ipktbuf.pb_next = 0; - mcr->mcr_ipktbuf.pb_len = 0; - mcr->mcr_reserved = mcr->mcr_pktlen = 0; - mcr->mcr_opktbuf.pb_addr = htole32(rng->rng_buf.dma_paddr); - mcr->mcr_opktbuf.pb_len = htole32(((sizeof(u_int32_t) * UBSEC_RNG_BUFSIZ)) & - UBS_PKTBUF_LEN); - mcr->mcr_opktbuf.pb_next = 0; - - ctx->rbp_len = htole16(sizeof(struct ubsec_ctx_rngbypass)); - ctx->rbp_op = htole16(UBS_CTXOP_RNGSHA1); - rng->rng_q.q_type = UBS_CTXOP_RNGSHA1; - - bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, - rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); - - if (sc->sc_flags & UBS_FLAGS_RNG4) { - SIMPLEQ_INSERT_TAIL(&sc->sc_queue4, &rng->rng_q, q_next); - rng->rng_used = 1; - ubsec_feed4(sc); - } else { - SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rng->rng_q, q_next); - rng->rng_used = 1; - ubsec_feed2(sc); - } - splx(s); - - return; - -out: - /* - * Something weird happened, generate our own call back. - */ - (*nqueue)--; - splx(s); - timeout_add_msec(&sc->sc_rngto, sc->sc_rngms); -} -#endif /* UBSEC_NO_RNG */ - -int -ubsec_dma_malloc(struct ubsec_softc *sc, bus_size_t size, - struct ubsec_dma_alloc *dma, int mapflags) -{ - int r; - - if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, - &dma->dma_seg, 1, &dma->dma_nseg, BUS_DMA_NOWAIT)) != 0) - goto fail_0; - - if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg, - size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0) - goto fail_1; - - if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_NOWAIT, &dma->dma_map)) != 0) - goto fail_2; - - if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr, - size, NULL, BUS_DMA_NOWAIT)) != 0) - goto fail_3; - - dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr; - dma->dma_size = size; - return (0); - -fail_3: - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -fail_2: - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size); -fail_1: - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); -fail_0: - dma->dma_map = NULL; - return (r); -} - -void -ubsec_dma_free(struct ubsec_softc *sc, struct ubsec_dma_alloc *dma) -{ - bus_dmamap_unload(sc->sc_dmat, dma->dma_map); - bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size); - bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); - bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); -} - -/* - * Resets the board. Values in the regesters are left as is - * from the reset (i.e. initial values are assigned elsewhere). - */ -void -ubsec_reset_board(struct ubsec_softc *sc) -{ - volatile u_int32_t ctrl; - - /* Reset the device */ - ctrl = READ_REG(sc, BS_CTRL); - ctrl |= BS_CTRL_RESET; - WRITE_REG(sc, BS_CTRL, ctrl); - - /* - * Wait aprox. 30 PCI clocks = 900 ns = 0.9 us - */ - DELAY(10); - - /* Enable RNG and interrupts on newer devices */ - if (sc->sc_flags & UBS_FLAGS_MULTIMCR) { - WRITE_REG(sc, BS_CFG, BS_CFG_RNG); - WRITE_REG(sc, BS_INT, BS_INT_DMAINT); - } -} - -/* - * Init Broadcom registers - */ -void -ubsec_init_board(struct ubsec_softc *sc) -{ - u_int32_t ctrl; - - ctrl = READ_REG(sc, BS_CTRL); - ctrl &= ~(BS_CTRL_BE32 | BS_CTRL_BE64); - ctrl |= BS_CTRL_LITTLE_ENDIAN | BS_CTRL_MCR1INT; - - if (sc->sc_flags & UBS_FLAGS_KEY) - ctrl |= BS_CTRL_MCR2INT; - else - ctrl &= ~BS_CTRL_MCR2INT; - - if (sc->sc_flags & UBS_FLAGS_HWNORM) - ctrl &= ~BS_CTRL_SWNORM; - - if (sc->sc_flags & UBS_FLAGS_MULTIMCR) { - ctrl |= BS_CTRL_BSIZE240; - ctrl &= ~BS_CTRL_MCR3INT; /* MCR3 is reserved for SSL */ - - if (sc->sc_flags & UBS_FLAGS_RNG4) - ctrl |= BS_CTRL_MCR4INT; - else - ctrl &= ~BS_CTRL_MCR4INT; - } - - WRITE_REG(sc, BS_CTRL, ctrl); -} - -/* - * Init Broadcom PCI registers - */ -void -ubsec_init_pciregs(struct pci_attach_args *pa) -{ - pci_chipset_tag_t pc = pa->pa_pc; - u_int32_t misc; - - /* - * This will set the cache line size to 1, this will - * force the BCM58xx chip just to do burst read/writes. - * Cache line read/writes are to slow - */ - misc = pci_conf_read(pc, pa->pa_tag, PCI_BHLC_REG); - misc = (misc & ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT)) - | ((UBS_DEF_CACHELINE & 0xff) << PCI_CACHELINE_SHIFT); - pci_conf_write(pc, pa->pa_tag, PCI_BHLC_REG, misc); -} - -/* - * Clean up after a chip crash. - * It is assumed that the caller is in splnet() - */ -void -ubsec_cleanchip(struct ubsec_softc *sc) -{ - struct ubsec_q *q; - - while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { - q = SIMPLEQ_FIRST(&sc->sc_qchip); - SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q_next); - ubsec_free_q(sc, q); - } -} - -/* - * free a ubsec_q - * It is assumed that the caller is within splnet() - */ -int -ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q) -{ - struct ubsec_q *q2; - struct cryptop *crp; - int npkts; - int i; - - npkts = q->q_nstacked_mcrs; - - for (i = 0; i < npkts; i++) { - if(q->q_stacked_mcr[i]) { - q2 = q->q_stacked_mcr[i]; - - if ((q2->q_dst_m != NULL) && (q2->q_src_m != q2->q_dst_m)) - m_freem(q2->q_dst_m); - - crp = (struct cryptop *)q2->q_crp; - - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q2, q_next); - - crp->crp_etype = EFAULT; - crypto_done(crp); - } else { - break; - } - } - - /* - * Free header MCR - */ - if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) - m_freem(q->q_dst_m); - - crp = (struct cryptop *)q->q_crp; - - SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); - - crp->crp_etype = EFAULT; - crypto_done(crp); - return(0); -} - -/* - * Routine to reset the chip and clean up. - * It is assumed that the caller is in splnet() - */ -void -ubsec_totalreset(struct ubsec_softc *sc) -{ - ubsec_reset_board(sc); - ubsec_init_board(sc); - ubsec_cleanchip(sc); -} - -int -ubsec_dmamap_aligned(bus_dmamap_t map) -{ - int i; - - for (i = 0; i < map->dm_nsegs; i++) { - if (map->dm_segs[i].ds_addr & 3) - return (0); - if ((i != (map->dm_nsegs - 1)) && - (map->dm_segs[i].ds_len & 3)) - return (0); - } - return (1); -} diff --git a/sys/dev/pci/ubsecreg.h b/sys/dev/pci/ubsecreg.h deleted file mode 100644 index 9e881f6b877..00000000000 --- a/sys/dev/pci/ubsecreg.h +++ /dev/null @@ -1,252 +0,0 @@ -/* $OpenBSD: ubsecreg.h,v 1.30 2009/03/27 13:31:30 reyk Exp $ */ - -/* - * Copyright (c) 2000 Theo de Raadt - * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -/* - * Register definitions for 5601 BlueSteel Networks Ubiquitous Broadband - * Security "uBSec" chip. Definitions from revision 2.8 of the product - * datasheet. - */ - -#define BS_BAR 0x10 /* DMA base address register */ -#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */ -#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */ - -#define UBS_PCI_RTY_SHIFT 8 -#define UBS_PCI_RTY_MASK 0xff -#define UBS_PCI_RTY(misc) \ - (((misc) >> UBS_PCI_RTY_SHIFT) & UBS_PCI_RTY_MASK) - -#define UBS_PCI_TOUT_SHIFT 0 -#define UBS_PCI_TOUT_MASK 0xff -#define UBS_PCI_TOUT(misc) \ - (((misc) >> PCI_TOUT_SHIFT) & PCI_TOUT_MASK) - -/* - * DMA Control & Status Registers (offset from BS_BAR) - */ -#define BS_MCR1 0x0000 /* DMA Master Command Record 1 */ -#define BS_CTRL 0x0004 /* DMA Control */ -#define BS_STAT 0x0008 /* DMA Status */ -#define BS_ERR 0x000c /* DMA Error Address */ -#define BS_MCR2 0x0010 /* DMA Master Command Record 2 */ -#define BS_MCR3 0x0014 /* 5827+, DMA Master Command Record 3 */ -#define BS_MCR4 0x001c /* 5827+, DMA Master Command Record 4 */ -#define BS_CFG 0x0700 /* 5827+, Configuration Register */ -#define BS_INT 0x0f00 /* 5827+, Interrupt Register */ - -/* BS_CTRL - DMA Control */ -#define BS_CTRL_RESET 0x80000000 /* hardware reset, 5805/5820 */ -#define BS_CTRL_MCR2INT 0x40000000 /* enable intr MCR for MCR2 */ -#define BS_CTRL_MCR1INT 0x20000000 /* enable intr MCR for MCR1 */ -#define BS_CTRL_OFM 0x10000000 /* Output fragment mode */ -#define BS_CTRL_BE32 0x08000000 /* big-endian, 32bit bytes */ -#define BS_CTRL_BE64 0x04000000 /* big-endian, 64bit bytes */ -#define BS_CTRL_DMAERR 0x02000000 /* enable intr DMA error */ -#define BS_CTRL_RNG_M 0x01800000 /* RNG mode */ -#define BS_CTRL_RNG_1 0x00000000 /* 1bit rn/one slow clock */ -#define BS_CTRL_RNG_4 0x00800000 /* 1bit rn/four slow clocks */ -#define BS_CTRL_RNG_8 0x01000000 /* 1bit rn/eight slow clocks */ -#define BS_CTRL_RNG_16 0x01800000 /* 1bit rn/16 slow clocks */ -#define BS_CTRL_SWNORM 0x00400000 /* 582[01], sw normalization */ -#define BS_CTRL_MCR3INT 0x00400000 /* 5827+, intr for MCR3 */ -#define BS_CTRL_MCR4INT 0x00200000 /* 5827+, intr for MCR4 */ -#define BS_CTRL_BSIZE240 0x000f0000 /* 5827+, burst size 240 */ -#define BS_CTRL_FRAG_M 0x0000ffff /* output fragment size mask */ -#define BS_CTRL_LITTLE_ENDIAN (BS_CTRL_BE32 | BS_CTRL_BE64) - -/* BS_STAT - DMA Status */ -#define BS_STAT_MCR_BUSY 0x80000000 /* MCR is busy */ -#define BS_STAT_MCR1_FULL 0x40000000 /* MCR1 is full */ -#define BS_STAT_MCR1_DONE 0x20000000 /* MCR1 is done */ -#define BS_STAT_DMAERR 0x10000000 /* DMA error */ -#define BS_STAT_MCR2_FULL 0x08000000 /* MCR2 is full */ -#define BS_STAT_MCR2_DONE 0x04000000 /* MCR2 is done */ -#define BS_STAT_MCR1_ALLEMPTY 0x02000000 /* 5821, MCR1 is empty */ -#define BS_STAT_MCR2_ALLEMPTY 0x01000000 /* 5821, MCR2 is empty */ -#define BS_STAT_MCR3_ALLEMPTY 0x00800000 /* 5827+, MCR3 is empty */ -#define BS_STAT_MCR4_ALLEMPTY 0x00400000 /* 5827+, MCR4 is empty */ -#define BS_STAT_MCR3_FULL 0x00080000 /* 5827+, MCR3 is full */ -#define BS_STAT_MCR3_DONE 0x00040000 /* 5827+, MCR3 is done */ -#define BS_STAT_MCR4_FULL 0x00020000 /* 5827+, MCR4 is full */ -#define BS_STAT_MCR4_DONE 0x00010000 /* 5827+, MCR4 is done */ - -/* BS_ERR - DMA Error Address */ -#define BS_ERR_ADDR 0xfffffffc /* error address mask */ -#define BS_ERR_READ 0x00000002 /* fault was on read */ - -/* BS_CFG */ -#define BS_CFG_RNG 0x00000001 /* 5827+, enable RNG */ - -/* BS_INT */ -#define BS_INT_DMAINT 0x80000000 /* 5827+, enable DMA intr */ - -/* DES/3DES */ -struct ubsec_pktctx { - u_int32_t pc_deskey[6]; /* 3DES key */ - u_int32_t pc_hminner[5]; /* hmac inner state */ - u_int32_t pc_hmouter[5]; /* hmac outer state */ - u_int32_t pc_iv[2]; /* [3]DES iv */ - u_int16_t pc_flags; /* flags, below */ - u_int16_t pc_offset; /* crypto offset */ -}; -#define UBS_PKTCTX_ENC_3DES 0x8000 /* use 3des */ -#define UBS_PKTCTX_ENC_NONE 0x0000 /* no encryption */ -#define UBS_PKTCTX_INBOUND 0x4000 /* inbound packet */ -#define UBS_PKTCTX_AUTH 0x3000 /* authentication mask */ -#define UBS_PKTCTX_AUTH_NONE 0x0000 /* no authentication */ -#define UBS_PKTCTX_AUTH_MD5 0x1000 /* use hmac-md5 */ -#define UBS_PKTCTX_AUTH_SHA1 0x2000 /* use hmac-sha1 */ - -/* "Long" cryptographic operations on newer chipsets */ -#define UBS_PKTCTX_TYPE_IPSEC_3DES 0x0000 -#define UBS_PKTCTX_TYPE_IPSEC_AES 0x0040 - -struct ubsec_pktctx_hdr { - volatile u_int16_t ph_len; /* length of ctx struct */ - volatile u_int16_t ph_type; /* context type, 0 */ - volatile u_int16_t ph_flags; /* flags, same as above */ - volatile u_int16_t ph_offset; /* crypto/auth offset */ -}; - -/* Long version of DES/3DES */ -struct ubsec_pktctx_3des { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_deskey[6]; /* 3DES key */ - volatile u_int32_t pc_iv[2]; /* [3]DES iv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; - -/* AES uses different structures for each supported key size */ -struct ubsec_pktctx_aes128 { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_aeskey[4]; /* AES128 key */ - volatile u_int32_t pc_iv[4]; /* AES iv/ucv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; - -struct ubsec_pktctx_aes192 { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_aeskey[6]; /* AES192 key */ - volatile u_int32_t pc_iv[4]; /* AES iv/icv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; - -struct ubsec_pktctx_aes256 { - struct ubsec_pktctx_hdr pc_hdr; /* Common header */ - volatile u_int32_t pc_aeskey[8]; /* AES256 key */ - volatile u_int32_t pc_iv[4]; /* AES iv/icv */ - volatile u_int32_t pc_hminner[5]; /* hmac inner state */ - volatile u_int32_t pc_hmouter[5]; /* hmac outer state */ -}; -#define UBS_PKTCTX_ENC_AES 0x8000 /* use aes */ -#define UBS_PKTCTX_MODE_CBC 0x0000 /* Cipher Block Chaining mode */ -#define UBS_PKTCTX_MODE_CTR 0x0400 /* Counter mode */ -#define UBS_PKTCTX_KEYSIZE_128 0x0000 /* AES128 */ -#define UBS_PKTCTX_KEYSIZE_192 0x0100 /* AES192 */ -#define UBS_PKTCTX_KEYSIZE_256 0x0200 /* AES256 */ - -struct ubsec_pktbuf { - volatile u_int32_t pb_addr; /* address of buffer start */ - volatile u_int32_t pb_next; /* pointer to next pktbuf */ - volatile u_int32_t pb_len; /* packet length */ -}; -#define UBS_PKTBUF_LEN 0x0000ffff /* length mask */ - -struct ubsec_mcr { - volatile u_int16_t mcr_pkts; /* #pkts in this mcr */ - volatile u_int16_t mcr_flags; /* mcr flags (below) */ - volatile u_int32_t mcr_cmdctxp; /* command ctx pointer */ - struct ubsec_pktbuf mcr_ipktbuf; /* input chain header */ - volatile u_int16_t mcr_reserved; - volatile u_int16_t mcr_pktlen; - struct ubsec_pktbuf mcr_opktbuf; /* output chain header */ -}; - -struct ubsec_mcr_add { - volatile u_int32_t mcr_cmdctxp; /* command ctx pointer */ - struct ubsec_pktbuf mcr_ipktbuf; /* input chain header */ - volatile u_int16_t mcr_reserved; - volatile u_int16_t mcr_pktlen; - struct ubsec_pktbuf mcr_opktbuf; /* output chain header */ -}; - -#define UBS_MCR_DONE 0x0001 /* mcr has been processed */ -#define UBS_MCR_ERROR 0x0002 /* error in processing */ -#define UBS_MCR_ERRORCODE 0xff00 /* error type */ - -struct ubsec_ctx_keyop { - volatile u_int16_t ctx_len; /* command length */ - volatile u_int16_t ctx_op; /* operation code */ - volatile u_int8_t ctx_pad[60]; /* padding */ -}; -#define UBS_CTXOP_DHPKGEN 0x01 /* dh public key generation */ -#define UBS_CTXOP_DHSSGEN 0x02 /* dh shared secret gen. */ -#define UBS_CTXOP_RSAPUB 0x03 /* rsa public key op */ -#define UBS_CTXOP_RSAPRIV 0x04 /* rsa private key op */ -#define UBS_CTXOP_DSASIGN 0x05 /* dsa signing op */ -#define UBS_CTXOP_DSAVRFY 0x06 /* dsa verification */ -#define UBS_CTXOP_RNGBYPASS 0x41 /* rng direct test mode */ -#define UBS_CTXOP_RNGSHA1 0x42 /* rng sha1 test mode */ -#define UBS_CTXOP_MODADD 0x43 /* modular addition */ -#define UBS_CTXOP_MODSUB 0x44 /* modular subtraction */ -#define UBS_CTXOP_MODMUL 0x45 /* modular multiplication */ -#define UBS_CTXOP_MODRED 0x46 /* modular reduction */ -#define UBS_CTXOP_MODEXP 0x47 /* modular exponentiation */ -#define UBS_CTXOP_MODINV 0x48 /* modular inverse */ - -struct ubsec_ctx_rngbypass { - volatile u_int16_t rbp_len; /* command length, 64 */ - volatile u_int16_t rbp_op; /* rng bypass, 0x41 */ - volatile u_int8_t rbp_pad[60]; /* padding */ -}; - -/* modexp: C = (M ^ E) mod N */ -struct ubsec_ctx_modexp { - volatile u_int16_t me_len; /* command length */ - volatile u_int16_t me_op; /* modexp, 0x47 */ - volatile u_int16_t me_E_len; /* E (bits) */ - volatile u_int16_t me_N_len; /* N (bits) */ - u_int8_t me_N[2048/8]; /* N */ -}; - -struct ubsec_ctx_rsapriv { - volatile u_int16_t rpr_len; /* command length */ - volatile u_int16_t rpr_op; /* rsaprivate, 0x04 */ - volatile u_int16_t rpr_q_len; /* q (bits) */ - volatile u_int16_t rpr_p_len; /* p (bits) */ - u_int8_t rpr_buf[5 * 1024 / 8]; /* parameters: */ - /* p, q, dp, dq, pinv */ -}; diff --git a/sys/dev/pci/ubsecvar.h b/sys/dev/pci/ubsecvar.h deleted file mode 100644 index cb5cd9b3773..00000000000 --- a/sys/dev/pci/ubsecvar.h +++ /dev/null @@ -1,175 +0,0 @@ -/* $OpenBSD: ubsecvar.h,v 1.41 2020/01/10 23:09:23 cheloha Exp $ */ - -/* - * Copyright (c) 2000 Theo de Raadt - * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - * - */ - -/* Maximum queue length */ -#ifndef UBS_MAX_NQUEUE -#define UBS_MAX_NQUEUE 60 -#endif - -#define UBS_MAX_SCATTER 64 /* Maximum scatter/gather depth */ - -#ifndef UBS_MAX_AGGR -#define UBS_MAX_AGGR 17 /* Maximum aggregation count */ -#endif - -#ifndef UBS_MIN_AGGR -#define UBS_MIN_AGGR 5 /* < 5827, Maximum aggregation count */ -#endif - -#define UBSEC_CARD(sid) (((sid) & 0xf0000000) >> 28) -#define UBSEC_SESSION(sid) ( (sid) & 0x0fffffff) -#define UBSEC_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff)) - -#define UBS_DEF_RTY 0xff /* PCI Retry Timeout */ -#define UBS_DEF_TOUT 0xff /* PCI TRDY Timeout */ -#define UBS_DEF_CACHELINE 0x01 /* Cache Line setting */ - -struct ubsec_dma_alloc { - u_int32_t dma_paddr; - caddr_t dma_vaddr; - bus_dmamap_t dma_map; - bus_dma_segment_t dma_seg; - bus_size_t dma_size; - int dma_nseg; -}; - -struct ubsec_q2 { - SIMPLEQ_ENTRY(ubsec_q2) q_next; - struct ubsec_dma_alloc q_mcr; - struct ubsec_dma_alloc q_ctx; - u_int q_type; -}; - -struct ubsec_q2_rng { - struct ubsec_q2 rng_q; - struct ubsec_dma_alloc rng_buf; - int rng_used; -}; - -#define UBSEC_RNG_BUFSIZ 16 /* measured in 32bit words */ - -struct ubsec_dmachunk { - struct ubsec_mcr d_mcr; - struct ubsec_mcr_add d_mcradd[UBS_MAX_AGGR-1]; - struct ubsec_pktbuf d_sbuf[UBS_MAX_SCATTER-1]; - struct ubsec_pktbuf d_dbuf[UBS_MAX_SCATTER-1]; - u_int32_t d_macbuf[5]; - union { - struct ubsec_pktctx_aes256 ctx_aes256; - struct ubsec_pktctx_aes192 ctx_aes192; - struct ubsec_pktctx_aes128 ctx_aes128; - struct ubsec_pktctx_3des ctx_3des; - struct ubsec_pktctx ctx; - } d_ctx; -}; - -struct ubsec_dma { - SIMPLEQ_ENTRY(ubsec_dma) d_next; - struct ubsec_dmachunk *d_dma; - struct ubsec_dma_alloc d_alloc; -}; - -#define UBS_FLAGS_KEY 0x01 /* has key accelerator */ -#define UBS_FLAGS_LONGCTX 0x02 /* uses long ipsec ctx */ -#define UBS_FLAGS_BIGKEY 0x04 /* 2048bit keys */ -#define UBS_FLAGS_HWNORM 0x08 /* hardware normalization */ -#define UBS_FLAGS_RNG 0x10 /* hardware rng */ -#define UBS_FLAGS_AES 0x20 /* supports aes */ -#define UBS_FLAGS_MULTIMCR 0x40 /* 5827+ with 4 MCRs */ -#define UBS_FLAGS_RNG4 0x80 /* 5827+ RNG on MCR4 */ - -struct ubsec_q { - SIMPLEQ_ENTRY(ubsec_q) q_next; - int q_nstacked_mcrs; - struct ubsec_q *q_stacked_mcr[UBS_MAX_AGGR-1]; - struct cryptop *q_crp; - struct ubsec_dma *q_dma; - - struct mbuf *q_src_m, *q_dst_m; - struct uio *q_src_io, *q_dst_io; - - bus_dmamap_t q_src_map; - bus_dmamap_t q_dst_map; - - int q_sesn; -}; - -struct ubsec_softc { - struct device sc_dv; /* generic device */ - void *sc_ih; /* interrupt handler cookie */ - bus_space_handle_t sc_sh; /* memory handle */ - bus_space_tag_t sc_st; /* memory tag */ - bus_dma_tag_t sc_dmat; /* dma tag */ - int sc_flags; /* device specific flags */ - u_int32_t sc_statmask; /* interrupt status mask */ - int32_t sc_cid; /* crypto tag */ - int sc_maxaggr; /* max pkt aggregation */ - SIMPLEQ_HEAD(,ubsec_q) sc_queue; /* packet queue, mcr1 */ - int sc_nqueue; /* count enqueued, mcr1 */ - SIMPLEQ_HEAD(,ubsec_q) sc_qchip; /* on chip, mcr1 */ - SIMPLEQ_HEAD(,ubsec_q) sc_freequeue; /* list of free queue elements */ - SIMPLEQ_HEAD(,ubsec_q2) sc_queue2; /* packet queue, mcr2 */ - int sc_nqueue2; /* count enqueued, mcr2 */ - SIMPLEQ_HEAD(,ubsec_q2) sc_qchip2; /* on chip, mcr2 */ - SIMPLEQ_HEAD(,ubsec_q2) sc_queue4; /* packet queue, mcr4 */ - int sc_nqueue4; /* count enqueued, mcr4 */ - SIMPLEQ_HEAD(,ubsec_q2) sc_qchip4; /* on chip, mcr4 */ - int sc_nsessions; /* # of sessions */ - struct ubsec_session *sc_sessions; /* sessions */ - struct timeout sc_rngto; /* rng timeout */ - int sc_rngms; /* rng poll time (msecs) */ - struct ubsec_q2_rng sc_rng; - struct ubsec_dma sc_dmaa[UBS_MAX_NQUEUE]; - struct ubsec_q *sc_queuea[UBS_MAX_NQUEUE]; -}; - -struct ubsec_session { - u_int32_t ses_used; - u_int32_t ses_key[8]; /* 3DES/AES key */ - u_int32_t ses_hminner[5]; /* hmac inner state */ - u_int32_t ses_hmouter[5]; /* hmac outer state */ - u_int32_t ses_iv[4]; /* [3]DES iv or AES iv/icv */ -}; - -struct ubsec_stats { - u_int64_t hst_ibytes; - u_int64_t hst_obytes; - u_int32_t hst_ipackets; - u_int32_t hst_opackets; - u_int32_t hst_invalid; - u_int32_t hst_nomem; - u_int32_t hst_queuefull; - u_int32_t hst_dmaerr; - u_int32_t hst_mcrerr; - u_int32_t hst_nodmafree; -}; -- 2.20.1