/drivers/crypto/hifn_795x.c
C | 2800 lines | 2182 code | 455 blank | 163 comment | 234 complexity | 4fedb8f2c231bee5c77cc311a41d5cdf MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*
- * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/mod_devicetable.h>
- #include <linux/interrupt.h>
- #include <linux/pci.h>
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/mm.h>
- #include <linux/dma-mapping.h>
- #include <linux/scatterlist.h>
- #include <linux/highmem.h>
- #include <linux/crypto.h>
- #include <linux/hw_random.h>
- #include <linux/ktime.h>
- #include <crypto/algapi.h>
- #include <crypto/des.h>
- #include <asm/kmap_types.h>
- //#define HIFN_DEBUG
- #ifdef HIFN_DEBUG
- #define dprintk(f, a...) printk(f, ##a)
- #else
- #define dprintk(f, a...) do {} while (0)
- #endif
- static char hifn_pll_ref[sizeof("extNNN")] = "ext";
- module_param_string(hifn_pll_ref, hifn_pll_ref, sizeof(hifn_pll_ref), 0444);
- MODULE_PARM_DESC(hifn_pll_ref,
- "PLL reference clock (pci[freq] or ext[freq], default ext)");
- static atomic_t hifn_dev_number;
- #define ACRYPTO_OP_DECRYPT 0
- #define ACRYPTO_OP_ENCRYPT 1
- #define ACRYPTO_OP_HMAC 2
- #define ACRYPTO_OP_RNG 3
- #define ACRYPTO_MODE_ECB 0
- #define ACRYPTO_MODE_CBC 1
- #define ACRYPTO_MODE_CFB 2
- #define ACRYPTO_MODE_OFB 3
- #define ACRYPTO_TYPE_AES_128 0
- #define ACRYPTO_TYPE_AES_192 1
- #define ACRYPTO_TYPE_AES_256 2
- #define ACRYPTO_TYPE_3DES 3
- #define ACRYPTO_TYPE_DES 4
- #define PCI_VENDOR_ID_HIFN 0x13A3
- #define PCI_DEVICE_ID_HIFN_7955 0x0020
- #define PCI_DEVICE_ID_HIFN_7956 0x001d
- /* I/O region sizes */
- #define HIFN_BAR0_SIZE 0x1000
- #define HIFN_BAR1_SIZE 0x2000
- #define HIFN_BAR2_SIZE 0x8000
- /* DMA registres */
- #define HIFN_DMA_CRA 0x0C /* DMA Command Ring Address */
- #define HIFN_DMA_SDRA 0x1C /* DMA Source Data Ring Address */
- #define HIFN_DMA_RRA 0x2C /* DMA Result Ring Address */
- #define HIFN_DMA_DDRA 0x3C /* DMA Destination Data Ring Address */
- #define HIFN_DMA_STCTL 0x40 /* DMA Status and Control */
- #define HIFN_DMA_INTREN 0x44 /* DMA Interrupt Enable */
- #define HIFN_DMA_CFG1 0x48 /* DMA Configuration #1 */
- #define HIFN_DMA_CFG2 0x6C /* DMA Configuration #2 */
- #define HIFN_CHIP_ID 0x98 /* Chip ID */
- /*
- * 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) */