⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 safe.c

📁 linux下基于加密芯片的加密设备
💻 C
📖 第 1 页 / 共 4 页
字号:
 * 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 of this size, 1 if all * segments are exactly this size, or 2 if segments are at worst * a multple of this size. */static intsafe_dmamap_uniform(const struct safe_operand *op){	int result = 1;	DPRINTF("%s()\n", __FUNCTION__);	if (op->nsegs > 0) {		int i;		for (i = 0; i < op->nsegs-1; i++) {			if (op->segs[i].ds_len % SAFE_MAX_DSIZE)				return (0);			if (op->segs[i].ds_len != SAFE_MAX_DSIZE)				result = 2;		}	}	return (result);}#ifdef SAFE_DEBUGstatic voidsafe_dump_dmastatus(struct safe_softc *sc, const char *tag){	DPRINTF("%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)	);}static voidsafe_dump_intrstate(struct safe_softc *sc, const char *tag){	DPRINTF("%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)	);}static voidsafe_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 */	DPRINTF("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",		tag,		estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),		(unsigned long)(sc->sc_back - sc->sc_ring),		(unsigned long)(sc->sc_front - sc->sc_ring));}static voidsafe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re){	int ix, nsegs;	ix = re - sc->sc_ring;	DPRINTF("%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_sp_dma) /			sizeof(struct safe_pdesc);		for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {			printk(" spd[%u] %p: %p size %u flags %x"				, ix, &sc->sc_spring[ix]				, (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr				, sc->sc_spring[ix].pd_size				, sc->sc_spring[ix].pd_flags			);			if (sc->sc_spring[ix].pd_size == 0)				printk(" (zero!)");			printk("\n");			if (++ix == SAFE_TOTAL_SPART)				ix = 0;		}	}	if (re->re_dst.nsegs > 1) {		ix = (re->re_desc.d_dst - sc->sc_dp_dma) /			sizeof(struct safe_pdesc);		for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {			printk(" dpd[%u] %p: %p flags %x\n"				, ix, &sc->sc_dpring[ix]				, (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr				, sc->sc_dpring[ix].pd_flags			);			if (++ix == SAFE_TOTAL_DPART)				ix = 0;		}	}	printk("sa: cmd0 %08x cmd1 %08x staterec %x\n",		re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);	printk("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]	);	printk("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]	);	printk("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]	);	printk("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]	);	printk("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]	);}static voidsafe_dump_ring(struct safe_softc *sc, const char *tag){	DPRINTF("%s()\n", __FUNCTION__);	spin_lock_irqsave(&sc->sc_ringmtx, flags);	printk("\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);	}	spin_unlock_irqrestore(&sc->sc_ringmtx, flags);}#endif /* SAFE_DEBUG */static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent){	struct safe_softc *sc = NULL;	u32 mem_start, mem_len, cmd;	int i, rc, devinfo;	dma_addr_t raddr;	static int num_chips = 0;	DPRINTF("%s()\n", __FUNCTION__);	if (pci_enable_device(dev) < 0)		return(-ENODEV);	if (!dev->irq) {		printk("safe: found device with no IRQ assigned. check BIOS settings!");		pci_disable_device(dev);		return(-ENODEV);	}	sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);	if (!sc)		return(-ENOMEM);	memset(sc, 0, sizeof(*sc));	sc->sc_irq = -1;	sc->sc_cid = -1;	sc->sc_dev = dev;	sc->sc_num = num_chips++;	pci_set_drvdata(sc->sc_dev, sc);	/* we read its hardware registers as memory */	mem_start = pci_resource_start(sc->sc_dev, 0);	mem_len   = pci_resource_len(sc->sc_dev, 0);	sc->sc_base_addr = (u32) ioremap(mem_start, mem_len);	if (!sc->sc_base_addr) {		printk("safe: failed to ioremap 0x%x-0x%x\n",				mem_start, mem_start + mem_len - 1);		goto out;	}	pci_set_master(sc->sc_dev);	pci_read_config_dword(sc->sc_dev, PCI_COMMAND, &cmd);	if (!(cmd & PCI_COMMAND_MEMORY)) {		printk("safe: failed to enable memory mapping\n");		goto out;	}	if (!(cmd & PCI_COMMAND_MASTER)) {		printk("safe: failed to enable bus mastering\n");		goto out;	}	rc = request_irq(dev->irq, safe_intr, SA_SHIRQ, "safe", sc);	if (rc) {		printk("safe: failed to hook irq %d\n", sc->sc_irq);		goto out;	}	sc->sc_irq = dev->irq;	sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &			(SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);	/*	 * Allocate packet engine descriptors.	 */	sc->sc_ring_vma = pci_alloc_consistent(sc->sc_dev,			SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),			&sc->sc_ring_dma);	if (!sc->sc_ring_vma) {		printk("safe: cannot allocate PE descriptor ring\n");		goto out;	}	/*	 * Hookup the static portion of all our data structures.	 */	sc->sc_ring = (struct safe_ringentry *) sc->sc_ring_vma;	sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;	sc->sc_front = sc->sc_ring;	sc->sc_back = sc->sc_ring;	raddr = sc->sc_ring_dma;	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);	}	spin_lock_init(&sc->sc_ringmtx);	/*	 * Allocate scatter and gather particle descriptors.	 */	sc->sc_sp_vma = pci_alloc_consistent(sc->sc_dev,			SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),			&sc->sc_sp_dma);	if (!sc->sc_sp_vma) {		printk("safe: cannot allocate source particle descriptor ring\n");		goto out;	}	sc->sc_spring = (struct safe_pdesc *) sc->sc_sp_vma;	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));	sc->sc_dp_vma = pci_alloc_consistent(sc->sc_dev,			SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),			&sc->sc_dp_dma);	if (!sc->sc_dp_vma) {		printk("safe: cannot allocate destination particle descriptor ring\n");		goto out;	}	sc->sc_dpring = (struct safe_pdesc *) sc->sc_dp_vma;	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));	sc->sc_cid = crypto_get_driverid(0);	if (sc->sc_cid < 0) {		printk("safe: could not get crypto driver id\n");		goto out;	}	printk("safe:");	devinfo = READ_REG(sc, SAFE_DEVINFO);	if (devinfo & SAFE_DEVINFO_RNG) {		sc->sc_flags |= SAFE_FLAGS_RNG;		printk(" rng");	}	if (devinfo & SAFE_DEVINFO_PKEY) {#ifdef NOTYET		printk(" key");		sc->sc_flags |= SAFE_FLAGS_KEY;		crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0,			safe_kprocess, sc);		crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0,			safe_kprocess, sc);#endif	}	if (devinfo & SAFE_DEVINFO_DES) {		printk(" des/3des");		crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0,			safe_newsession, safe_freesession, safe_process, sc);		crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0,			safe_newsession, safe_freesession, safe_process, sc);	}	if (devinfo & SAFE_DEVINFO_AES) {		printk(" aes");		crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0,			safe_newsession, safe_freesession, safe_process, sc);	}	if (devinfo & SAFE_DEVINFO_MD5) {		printk(" md5");		crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0,			safe_newsession, safe_freesession, safe_process, sc);	}	if (devinfo & SAFE_DEVINFO_SHA1) {		printk(" sha1");		crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0,			safe_newsession, safe_freesession, safe_process, sc);	}	printk(" null");	crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0,		safe_newsession, safe_freesession, safe_process, sc);	crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0,		safe_newsession, safe_freesession, safe_process, sc);	/* XXX other supported algorithms */	printk("\n");	safe_reset_board(sc);		/* reset h/w */	safe_init_board(sc);		/* init h/w */#ifndef SAFE_NO_RNG	if (sc->sc_flags & SAFE_FLAGS_RNG) {		safe_rng_init(sc);		init_timer(&sc->sc_rngto);		sc->sc_rngto.function = safe_rng;		sc->sc_rngto.data = (unsigned long) sc;		mod_timer(&sc->sc_rngto, jiffies + HZ * safe_rnginterval);	}#endif /* SAFE_NO_RNG */	return (0);out:	if (sc->sc_cid >= 0)		crypto_unregister_all(sc->sc_cid);	if (sc->sc_irq != -1)		free_irq(sc->sc_irq, sc);	if (sc->sc_ring_vma)		pci_free_consistent(sc->sc_dev,				SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),				sc->sc_ring_vma, sc->sc_ring_dma);	if (sc->sc_sp_vma)		pci_free_consistent(sc->sc_dev,				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),				sc->sc_sp_vma, sc->sc_sp_dma);	if (sc->sc_dp_vma)		pci_free_consistent(sc->sc_dev,				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),				sc->sc_dp_vma, sc->sc_dp_dma);	kfree(sc);	return(-ENODEV);}static void safe_remove(struct pci_dev *dev){	struct safe_softc *sc = pci_get_drvdata(dev);	DPRINTF("%s()\n", __FUNCTION__);	/* XXX wait/abort active ops */	WRITE_REG(sc, SAFE_HI_MASK, 0);		/* disable interrupts */	del_timer(&sc->sc_rngto);	crypto_unregister_all(sc->sc_cid);	safe_cleanchip(sc);	if (sc->sc_irq != -1)		free_irq(sc->sc_irq, sc);	if (sc->sc_ring_vma)		pci_free_consistent(sc->sc_dev,				SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),				sc->sc_ring_vma, sc->sc_ring_dma);	if (sc->sc_sp_vma)		pci_free_consistent(sc->sc_dev,				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),				sc->sc_sp_vma, sc->sc_sp_dma);	if (sc->sc_dp_vma)		pci_free_consistent(sc->sc_dev,				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),				sc->sc_dp_vma, sc->sc_dp_dma);	sc->sc_irq = -1;	sc->sc_ring_vma = NULL;	sc->sc_sp_vma = NULL;	sc->sc_dp_vma = NULL;}static struct pci_device_id safe_pci_tbl[] = {	{ PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{ },};MODULE_DEVICE_TABLE(pci, safe_pci_tbl);static struct pci_driver safe_driver = {	.name         = "safe",	.id_table     = safe_pci_tbl,	.probe        =	safe_probe,	.remove       = safe_remove,	/* add PM stuff here one day */};static int __init safe_init (void){	DPRINTF("%s(%p)\n", __FUNCTION__, safe_init);	return pci_module_init(&safe_driver);}static void __exit safe_exit (void){	pci_unregister_driver(&safe_driver);}module_init(safe_init);module_exit(safe_exit);MODULE_LICENSE("BSD");MODULE_AUTHOR("davidm@snapgear.com");MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -