📄 safe.c
字号:
* 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 + -