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

📄 hifn7751.c

📁 linux下基于加密芯片的加密设备
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidhifn_remove(struct pci_dev *dev){	struct hifn_softc *sc = pci_get_drvdata(dev);	DPRINTF("%s()\n", __FUNCTION__);	KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));	/* disable interrupts */	WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);	/*XXX other resources */	del_timer(&sc->sc_tickto);	del_timer(&sc->sc_rngto);	/* Turn off DMA polling */	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |	    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);	crypto_unregister_all(sc->sc_cid);	free_irq(sc->sc_irq, sc);	pci_free_consistent(sc->sc_dev, sizeof(*sc->sc_dma),                sc->sc_dma, sc->sc_dma_physaddr);}static inthifn_init_pubrng(struct hifn_softc *sc){	u_int32_t r;	int i;	DPRINTF("%s()\n", __FUNCTION__);	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) {			device_printf(sc->sc_dev, "public key init failed\n");			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;		if (HZ >= 100)			sc->sc_rnghz = HZ / 100;		else			sc->sc_rnghz = 1;		init_timer(&sc->sc_rngto);		sc->sc_rngto.function = hifn_rng;		sc->sc_rngto.data = (unsigned long) sc;		mod_timer(&sc->sc_rngto, jiffies + sc->sc_rnghz);	}	/* 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);}static voidhifn_rng(unsigned long vsc){#define	RANDOM_BITS(n)	(n)*sizeof (u_int32_t), (n)*sizeof (u_int32_t)*NBBY, 0	struct hifn_softc *sc = (struct hifn_softc *) vsc;	u_int32_t sts, num[2];	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) {				device_printf(sc->sc_dev,					      "RNG underflow: disabling\n");				return;			}			if ((sts & HIFN_7811_RNGSTS_RDY) == 0)				break;			/*			 * There are at least two words in the RNG FIFO			 * at this point.			 */			num[0] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);			num[1] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);#if 0			/* NB: discard first data read */			if (sc->sc_rngfirst)				sc->sc_rngfirst = 0;			else				(*sc->sc_harvest)(sc->sc_rndtest,					num, sizeof (num));#endif		}	} else {		num[0] = READ_REG_1(sc, HIFN_1_RNG_DATA);		/* NB: discard first data read */#if 0		if (sc->sc_rngfirst)			sc->sc_rngfirst = 0;		else			(*sc->sc_harvest)(sc->sc_rndtest,				num, sizeof (num[0]));#endif	}	mod_timer(&sc->sc_rngto, jiffies + sc->sc_rnghz);#undef RANDOM_BITS}static voidhifn_puc_wait(struct hifn_softc *sc){	int i;	DPRINTF("%s()\n", __FUNCTION__);	for (i = 5000; i > 0; i--) {		DELAY(1);		if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET))			break;	}	if (!i)		device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",				READ_REG_0(sc, HIFN_0_PUCTRL));}/* * Reset the processing unit. */static voidhifn_reset_puc(struct hifn_softc *sc){	/* Reset processing unit */	WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);	hifn_puc_wait(sc);}/* * Set the Retry and TRDY registers; note that we set them to * zero because the 7811 locks up when forced to retry (section * 3.6 of "Specification Update SU-0014-04".  Not clear if we * should do this for all Hifn parts, but it doesn't seem to hurt. */static voidhifn_set_retry(struct hifn_softc *sc){	DPRINTF("%s()\n", __FUNCTION__);	/* NB: RETRY only responds to 8-bit reads/writes */	pci_write_config_byte(sc->sc_dev, HIFN_RETRY_TIMEOUT, 0);	pci_write_config_dword(sc->sc_dev, HIFN_TRDY_TIMEOUT, 0);}/* * Resets the board.  Values in the regesters are left as is * from the reset (i.e. initial values are assigned elsewhere). */static voidhifn_reset_board(struct hifn_softc *sc, int full){	u_int32_t reg;	DPRINTF("%s()\n", __FUNCTION__);	/*	 * 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);	}	KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));	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)			device_printf(sc->sc_dev, ": cram init timeout\n");	}}static u_int32_thifn_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;}/* * 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. */static int hifn_enable_crypto(struct hifn_softc *sc){	u_int32_t dmacfg, ramcfg, encl, addr, i;	char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,					  0x00, 0x00, 0x00, 0x00 };	DPRINTF("%s()\n", __FUNCTION__);	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		if (hifn_debug)			device_printf(sc->sc_dev,			    "Strong crypto already enabled!\n");#endif		goto report;	}	if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {#ifdef HIFN_DEBUG		if (hifn_debug)			device_printf(sc->sc_dev,			      "Unknown encryption level 0x%x\n", encl);#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_UNLOCK_SECRET1);	DELAY(1000);	WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);	DELAY(1000);	for (i = 0; i <= 12; i++) {		addr = hifn_next_signature(addr, offtbl[i] + 0x101);		WRITE_REG_1(sc, HIFN_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 (hifn_debug) {		if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)			device_printf(sc->sc_dev, "Engine is permanently "				"locked until next system reset!\n");		else			device_printf(sc->sc_dev, "Engine enabled "				"successfully!\n");	}#endifreport:	WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);	switch (encl) {	case HIFN_PUSTAT_ENA_1:	case HIFN_PUSTAT_ENA_2:		break;	case HIFN_PUSTAT_ENA_0:	default:		device_printf(sc->sc_dev, "disabled\n");		break;	}	return 0;}/* * Give initial values to the registers listed in the "Register Space" * section of the HIFN Software Development reference manual. */static void hifn_init_pci_registers(struct hifn_softc *sc){	DPRINTF("%s()\n", __FUNCTION__);	/* 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_dma_physaddr +	    offsetof(struct hifn_dma, cmdr[0]));	WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +	    offsetof(struct hifn_dma, srcr[0]));	WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +	    offsetof(struct hifn_dma, dstr[0]));	WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +	    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 |	    ((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);	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. */static voidhifn_sessions(struct hifn_softc *sc){	u_int32_t pucnfg;	int ctxsize;	DPRINTF("%s()\n", __FUNCTION__);	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. */static inthifn_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);	}

⌨️ 快捷键说明

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