| 103 |
103 |
static void hifn_intr(void *);
|
| 104 |
104 |
static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
|
| 105 |
105 |
static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
|
| 106 |
|
static int hifn_newsession(void *, u_int32_t *, struct cryptoini *);
|
| 107 |
|
static int hifn_freesession(void *, u_int64_t);
|
| 108 |
|
static int hifn_process(void *, struct cryptop *, int);
|
|
106 |
static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
|
|
107 |
static int hifn_freesession(device_t, u_int64_t);
|
|
108 |
static int hifn_process(device_t, struct cryptop *, int);
|
| 109 |
109 |
static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
|
| 110 |
110 |
static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
|
| 111 |
111 |
static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
|
| ... | ... | |
| 293 |
293 |
* always will allow the card to work. If a card is using the PCI
|
| 294 |
294 |
* bus clock and in a 33MHz slot then it will be operating at half
|
| 295 |
295 |
* speed until the correct information is provided.
|
|
296 |
*
|
|
297 |
* We use a default setting of "ext66" because according to Mike Ham
|
|
298 |
* of HiFn, almost every board in existence has an external crystal
|
|
299 |
* populated at 66Mhz. Using PCI can be a problem on modern motherboards,
|
|
300 |
* because PCI33 can have clocks from 0 to 33Mhz, and some have
|
|
301 |
* non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
|
| 296 |
302 |
*/
|
| 297 |
303 |
static void
|
| 298 |
304 |
hifn_getpllconfig(device_t dev, u_int *pll)
|
| ... | ... | |
| 303 |
309 |
char *nxt;
|
| 304 |
310 |
|
| 305 |
311 |
if (resource_string_value("hifn", device_get_unit(dev),
|
| 306 |
|
"pllconfig", &pllspec))
|
| 307 |
|
pllspec = "pci66";
|
|
312 |
"pllconfig", &pllspec))
|
|
313 |
pllspec = "ext66";
|
| 308 |
314 |
fl = 33, fh = 66;
|
| 309 |
315 |
pllconfig = 0;
|
| 310 |
316 |
if (strncmp(pllspec, "ext", 3) == 0) {
|
| ... | ... | |
| 357 |
363 |
bzero(sc, sizeof (*sc));
|
| 358 |
364 |
sc->sc_dev = dev;
|
| 359 |
365 |
|
|
366 |
lockinit(&sc->sc_lock, device_get_nameunit(dev), 0, LK_CANRECURSE);
|
|
367 |
|
| 360 |
368 |
/* XXX handle power management */
|
| 361 |
369 |
|
| 362 |
370 |
/*
|
| ... | ... | |
| 539 |
547 |
* NB: Network code assumes we are blocked with splimp()
|
| 540 |
548 |
* so make sure the IRQ is marked appropriately.
|
| 541 |
549 |
*/
|
| 542 |
|
if (bus_setup_intr(dev, sc->sc_irq, INTR_FAST,
|
|
550 |
if (bus_setup_intr(dev, sc->sc_irq, INTR_MPSAFE,
|
| 543 |
551 |
hifn_intr, sc,
|
| 544 |
552 |
&sc->sc_intrhand, NULL)) {
|
| 545 |
553 |
device_printf(dev, "could not setup interrupt\n");
|
| ... | ... | |
| 605 |
613 |
hifn_init_pubrng(sc);
|
| 606 |
614 |
|
| 607 |
615 |
/* NB: 1 means the callout runs w/o Giant locked */
|
| 608 |
|
callout_init(&sc->sc_tickto);
|
|
616 |
callout_init_mp(&sc->sc_tickto);
|
| 609 |
617 |
callout_reset(&sc->sc_tickto, hz, hifn_tick, sc);
|
| 610 |
618 |
|
| 611 |
619 |
return (0);
|
| ... | ... | |
| 629 |
637 |
fail_io0:
|
| 630 |
638 |
bus_release_resource(dev, SYS_RES_MEMORY, HIFN_BAR0, sc->sc_bar0res);
|
| 631 |
639 |
fail_pci:
|
|
640 |
lockuninit(&sc->sc_lock);
|
| 632 |
641 |
return (ENXIO);
|
| 633 |
642 |
}
|
| 634 |
643 |
|
| ... | ... | |
| 645 |
654 |
/* disable interrupts */
|
| 646 |
655 |
WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
|
| 647 |
656 |
|
| 648 |
|
crit_enter();
|
| 649 |
657 |
/*XXX other resources */
|
| 650 |
658 |
callout_stop(&sc->sc_tickto);
|
| 651 |
659 |
callout_stop(&sc->sc_rngto);
|
| ... | ... | |
| 673 |
681 |
|
| 674 |
682 |
bus_release_resource(dev, SYS_RES_MEMORY, HIFN_BAR1, sc->sc_bar1res);
|
| 675 |
683 |
bus_release_resource(dev, SYS_RES_MEMORY, HIFN_BAR0, sc->sc_bar0res);
|
| 676 |
|
crit_exit();
|
|
684 |
|
|
685 |
lockuninit(&sc->sc_lock);
|
| 677 |
686 |
|
| 678 |
687 |
return (0);
|
| 679 |
688 |
}
|
| ... | ... | |
| 805 |
814 |
else
|
| 806 |
815 |
sc->sc_rnghz = 1;
|
| 807 |
816 |
/* NB: 1 means the callout runs w/o Giant locked */
|
| 808 |
|
callout_init(&sc->sc_rngto);
|
|
817 |
callout_init_mp(&sc->sc_rngto);
|
| 809 |
818 |
callout_reset(&sc->sc_rngto, sc->sc_rnghz, hifn_rng, sc);
|
| 810 |
819 |
}
|
| 811 |
820 |
#endif
|
| ... | ... | |
| 873 |
882 |
hifn_puc_wait(struct hifn_softc *sc)
|
| 874 |
883 |
{
|
| 875 |
884 |
int i;
|
|
885 |
int reg = HIFN_0_PUCTRL;
|
|
886 |
|
|
887 |
if (sc->sc_flags & HIFN_IS_7956) {
|
|
888 |
reg = HIFN_0_PUCTRL2;
|
|
889 |
}
|
| 876 |
890 |
|
| 877 |
891 |
for (i = 5000; i > 0; i--) {
|
| 878 |
892 |
DELAY(1);
|
| 879 |
|
if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET))
|
|
893 |
if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
|
| 880 |
894 |
break;
|
| 881 |
895 |
}
|
| 882 |
896 |
if (!i)
|
| ... | ... | |
| 889 |
903 |
static void
|
| 890 |
904 |
hifn_reset_puc(struct hifn_softc *sc)
|
| 891 |
905 |
{
|
|
906 |
int reg = HIFN_0_PUCTRL;
|
|
907 |
|
|
908 |
if (sc->sc_flags & HIFN_IS_7956) {
|
|
909 |
reg = HIFN_0_PUCTRL2;
|
|
910 |
}
|
|
911 |
|
| 892 |
912 |
/* Reset processing unit */
|
| 893 |
|
WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
|
|
913 |
WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
|
| 894 |
914 |
hifn_puc_wait(sc);
|
| 895 |
915 |
}
|
| 896 |
916 |
|
| ... | ... | |
| 959 |
979 |
}
|
| 960 |
980 |
if (reg == 1000)
|
| 961 |
981 |
kprintf(": cram init timeout\n");
|
|
982 |
} else {
|
|
983 |
/* set up DMA configuration register #2 */
|
|
984 |
/* turn off all PK and BAR0 swaps */
|
|
985 |
WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
|
|
986 |
(3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
|
|
987 |
(3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
|
|
988 |
(2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
|
|
989 |
(2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
|
| 962 |
990 |
}
|
| 963 |
991 |
}
|
| 964 |
992 |
|
| ... | ... | |
| 1196 |
1224 |
/* turn off the clocks and insure bypass is set */
|
| 1197 |
1225 |
pll = READ_REG_1(sc, HIFN_1_PLL);
|
| 1198 |
1226 |
pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
|
| 1199 |
|
| HIFN_PLL_BP;
|
|
1227 |
| HIFN_PLL_BP | HIFN_PLL_MBSET;
|
| 1200 |
1228 |
WRITE_REG_1(sc, HIFN_1_PLL, pll);
|
| 1201 |
1229 |
DELAY(10*1000); /* 10ms */
|
| 1202 |
1230 |
/* change configuration */
|
| ... | ... | |
| 1580 |
1608 |
base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
|
| 1581 |
1609 |
dlen >>= 16;
|
| 1582 |
1610 |
slen >>= 16;
|
| 1583 |
|
#if 0
|
| 1584 |
|
base_cmd->session_num = htole16(cmd->session_num |
|
| 1585 |
|
#else
|
|
1611 |
|
| 1586 |
1612 |
base_cmd->session_num = htole16(
|
| 1587 |
|
#endif
|
| 1588 |
1613 |
((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
|
| 1589 |
1614 |
((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
|
| 1590 |
1615 |
buf_pos += sizeof(hifn_base_command_t);
|
| ... | ... | |
| 1688 |
1713 |
return (1);
|
| 1689 |
1714 |
}
|
| 1690 |
1715 |
|
|
1716 |
static __inline int
|
|
1717 |
hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
|
|
1718 |
{
|
|
1719 |
struct hifn_dma *dma = sc->sc_dma;
|
|
1720 |
|
|
1721 |
if (++idx == HIFN_D_DST_RSIZE) {
|
|
1722 |
dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
|
|
1723 |
HIFN_D_MASKDONEIRQ);
|
|
1724 |
HIFN_DSTR_SYNC(sc, idx,
|
|
1725 |
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
|
1726 |
idx = 0;
|
|
1727 |
}
|
|
1728 |
return (idx);
|
|
1729 |
}
|
|
1730 |
|
| 1691 |
1731 |
static int
|
| 1692 |
1732 |
hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
|
| 1693 |
1733 |
{
|
| ... | ... | |
| 1705 |
1745 |
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 1706 |
1746 |
used++;
|
| 1707 |
1747 |
|
| 1708 |
|
if (++idx == HIFN_D_DST_RSIZE) {
|
| 1709 |
|
dma->dstr[idx].l = htole32(HIFN_D_VALID |
|
| 1710 |
|
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
| 1711 |
|
HIFN_DSTR_SYNC(sc, idx,
|
| 1712 |
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 1713 |
|
idx = 0;
|
| 1714 |
|
}
|
|
1748 |
idx = hifn_dmamap_dstwrap(sc, idx);
|
| 1715 |
1749 |
}
|
| 1716 |
1750 |
|
| 1717 |
1751 |
if (cmd->sloplen == 0) {
|
| ... | ... | |
| 1733 |
1767 |
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 1734 |
1768 |
used++;
|
| 1735 |
1769 |
|
| 1736 |
|
if (++idx == HIFN_D_DST_RSIZE) {
|
| 1737 |
|
dma->dstr[idx].l = htole32(HIFN_D_VALID |
|
| 1738 |
|
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
| 1739 |
|
HIFN_DSTR_SYNC(sc, idx,
|
| 1740 |
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 1741 |
|
idx = 0;
|
| 1742 |
|
}
|
|
1770 |
idx = hifn_dmamap_dstwrap(sc, idx);
|
| 1743 |
1771 |
}
|
| 1744 |
1772 |
}
|
| 1745 |
1773 |
dma->dstr[idx].p = htole32(p);
|
| ... | ... | |
| 1747 |
1775 |
HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 1748 |
1776 |
used++;
|
| 1749 |
1777 |
|
| 1750 |
|
if (++idx == HIFN_D_DST_RSIZE) {
|
| 1751 |
|
dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
|
| 1752 |
|
HIFN_D_MASKDONEIRQ);
|
| 1753 |
|
HIFN_DSTR_SYNC(sc, idx,
|
| 1754 |
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 1755 |
|
idx = 0;
|
| 1756 |
|
}
|
|
1778 |
idx = hifn_dmamap_dstwrap(sc, idx);
|
| 1757 |
1779 |
|
| 1758 |
1780 |
dma->dsti = idx;
|
| 1759 |
1781 |
dma->dstu += used;
|
| 1760 |
1782 |
return (idx);
|
| 1761 |
1783 |
}
|
| 1762 |
1784 |
|
|
1785 |
static __inline int
|
|
1786 |
hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
|
|
1787 |
{
|
|
1788 |
struct hifn_dma *dma = sc->sc_dma;
|
|
1789 |
|
|
1790 |
if (++idx == HIFN_D_SRC_RSIZE) {
|
|
1791 |
dma->srcr[idx].l = htole32(HIFN_D_VALID |
|
|
1792 |
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
|
1793 |
HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
|
|
1794 |
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
|
1795 |
idx = 0;
|
|
1796 |
}
|
|
1797 |
return (idx);
|
|
1798 |
}
|
|
1799 |
|
| 1763 |
1800 |
static int
|
| 1764 |
1801 |
hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
|
| 1765 |
1802 |
{
|
| ... | ... | |
| 1779 |
1816 |
HIFN_SRCR_SYNC(sc, idx,
|
| 1780 |
1817 |
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
| 1781 |
1818 |
|
| 1782 |
|
if (++idx == HIFN_D_SRC_RSIZE) {
|
| 1783 |
|
dma->srcr[idx].l = htole32(HIFN_D_VALID |
|
| 1784 |
|
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
| 1785 |
|
HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
|
| 1786 |
|
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
| 1787 |
|
idx = 0;
|
| 1788 |
|
}
|
|
1819 |
idx = hifn_dmamap_srcwrap(sc, idx);
|
| 1789 |
1820 |
}
|
| 1790 |
1821 |
dma->srci = idx;
|
| 1791 |
1822 |
dma->srcu += src->nsegs;
|
| ... | ... | |
| 1813 |
1844 |
int hint)
|
| 1814 |
1845 |
{
|
| 1815 |
1846 |
struct hifn_dma *dma = sc->sc_dma;
|
| 1816 |
|
u_int32_t cmdlen;
|
|
1847 |
u_int32_t cmdlen, csr;
|
| 1817 |
1848 |
int cmdi, resi, err = 0;
|
| 1818 |
1849 |
|
| 1819 |
1850 |
/*
|
| ... | ... | |
| 1821 |
1852 |
*
|
| 1822 |
1853 |
* NB: check this first since it's easy.
|
| 1823 |
1854 |
*/
|
|
1855 |
HIFN_LOCK(sc);
|
| 1824 |
1856 |
if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
|
| 1825 |
1857 |
(dma->resu + 1) > HIFN_D_RES_RSIZE) {
|
| 1826 |
1858 |
#ifdef HIFN_DEBUG
|
| ... | ... | |
| 1831 |
1863 |
}
|
| 1832 |
1864 |
#endif
|
| 1833 |
1865 |
hifnstats.hst_nomem_cr++;
|
|
1866 |
HIFN_UNLOCK(sc);
|
| 1834 |
1867 |
return (ERESTART);
|
| 1835 |
1868 |
}
|
| 1836 |
1869 |
|
| 1837 |
1870 |
if (bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT, &cmd->src_map)) {
|
| 1838 |
1871 |
hifnstats.hst_nomem_map++;
|
|
1872 |
HIFN_UNLOCK(sc);
|
| 1839 |
1873 |
return (ENOMEM);
|
| 1840 |
1874 |
}
|
| 1841 |
1875 |
|
| ... | ... | |
| 1847 |
1881 |
goto err_srcmap1;
|
| 1848 |
1882 |
}
|
| 1849 |
1883 |
} else if (crp->crp_flags & CRYPTO_F_IOV) {
|
|
1884 |
#if 0
|
| 1850 |
1885 |
cmd->src_io->uio_segflg = UIO_USERSPACE;
|
|
1886 |
#endif
|
| 1851 |
1887 |
if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map,
|
| 1852 |
1888 |
cmd->src_io, hifn_op_cb, &cmd->src, BUS_DMA_NOWAIT)) {
|
| 1853 |
1889 |
hifnstats.hst_nomem_load++;
|
| ... | ... | |
| 1959 |
1995 |
goto err_dstmap1;
|
| 1960 |
1996 |
}
|
| 1961 |
1997 |
} else if (crp->crp_flags & CRYPTO_F_IOV) {
|
|
1998 |
#if 0
|
| 1962 |
1999 |
cmd->dst_io->uio_segflg |= UIO_USERSPACE;
|
|
2000 |
#endif
|
| 1963 |
2001 |
if (bus_dmamap_load_uio(sc->sc_dmat, cmd->dst_map,
|
| 1964 |
2002 |
cmd->dst_io, hifn_op_cb, &cmd->dst, BUS_DMA_NOWAIT)) {
|
| 1965 |
2003 |
hifnstats.hst_nomem_load++;
|
| ... | ... | |
| 2025 |
2063 |
HIFN_CMDR_SYNC(sc, cmdi,
|
| 2026 |
2064 |
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
| 2027 |
2065 |
dma->cmdu++;
|
| 2028 |
|
if (sc->sc_c_busy == 0) {
|
| 2029 |
|
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA);
|
| 2030 |
|
sc->sc_c_busy = 1;
|
| 2031 |
|
}
|
| 2032 |
2066 |
|
| 2033 |
2067 |
/*
|
| 2034 |
2068 |
* We don't worry about missing an interrupt (which a "command wait"
|
| ... | ... | |
| 2044 |
2078 |
hifnstats.hst_ibytes += cmd->src_mapsize;
|
| 2045 |
2079 |
|
| 2046 |
2080 |
hifn_dmamap_load_src(sc, cmd);
|
| 2047 |
|
if (sc->sc_s_busy == 0) {
|
| 2048 |
|
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA);
|
| 2049 |
|
sc->sc_s_busy = 1;
|
| 2050 |
|
}
|
| 2051 |
2081 |
|
| 2052 |
2082 |
/*
|
| 2053 |
2083 |
* Unlike other descriptors, we don't mask done interrupt from
|
| ... | ... | |
| 2084 |
2114 |
HIFN_RESR_SYNC(sc, resi,
|
| 2085 |
2115 |
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
| 2086 |
2116 |
dma->resu++;
|
| 2087 |
|
if (sc->sc_r_busy == 0) {
|
| 2088 |
|
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA);
|
| 2089 |
|
sc->sc_r_busy = 1;
|
| 2090 |
|
}
|
| 2091 |
2117 |
|
| 2092 |
2118 |
if (cmd->sloplen)
|
| 2093 |
2119 |
cmd->slopidx = resi;
|
| 2094 |
2120 |
|
| 2095 |
2121 |
hifn_dmamap_load_dst(sc, cmd);
|
| 2096 |
2122 |
|
|
2123 |
csr = 0;
|
|
2124 |
if (sc->sc_c_busy == 0) {
|
|
2125 |
csr |= HIFN_DMACSR_C_CTRL_ENA;
|
|
2126 |
sc->sc_c_busy = 1;
|
|
2127 |
}
|
|
2128 |
if (sc->sc_s_busy == 0) {
|
|
2129 |
csr |= HIFN_DMACSR_S_CTRL_ENA;
|
|
2130 |
sc->sc_s_busy = 1;
|
|
2131 |
}
|
|
2132 |
if (sc->sc_r_busy == 0) {
|
|
2133 |
csr |= HIFN_DMACSR_R_CTRL_ENA;
|
|
2134 |
sc->sc_r_busy = 1;
|
|
2135 |
}
|
| 2097 |
2136 |
if (sc->sc_d_busy == 0) {
|
| 2098 |
|
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA);
|
|
2137 |
csr |= HIFN_DMACSR_D_CTRL_ENA;
|
| 2099 |
2138 |
sc->sc_d_busy = 1;
|
| 2100 |
2139 |
}
|
|
2140 |
if (csr)
|
|
2141 |
WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
|
| 2101 |
2142 |
|
| 2102 |
2143 |
#ifdef HIFN_DEBUG
|
| 2103 |
2144 |
if (hifn_debug) {
|
| ... | ... | |
| 2108 |
2149 |
#endif
|
| 2109 |
2150 |
|
| 2110 |
2151 |
sc->sc_active = 5;
|
|
2152 |
HIFN_UNLOCK(sc);
|
| 2111 |
2153 |
KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
|
| 2112 |
2154 |
return (err); /* success */
|
| 2113 |
2155 |
|
| ... | ... | |
| 2125 |
2167 |
bus_dmamap_unload(sc->sc_dmat, cmd->src_map);
|
| 2126 |
2168 |
err_srcmap1:
|
| 2127 |
2169 |
bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
|
|
2170 |
HIFN_UNLOCK(sc);
|
| 2128 |
2171 |
return (err);
|
| 2129 |
2172 |
}
|
| 2130 |
2173 |
|
| ... | ... | |
| 2133 |
2176 |
{
|
| 2134 |
2177 |
struct hifn_softc *sc = vsc;
|
| 2135 |
2178 |
|
| 2136 |
|
crit_enter();
|
|
2179 |
HIFN_LOCK(sc);
|
| 2137 |
2180 |
if (sc->sc_active == 0) {
|
| 2138 |
2181 |
struct hifn_dma *dma = sc->sc_dma;
|
| 2139 |
2182 |
u_int32_t r = 0;
|
| ... | ... | |
| 2158 |
2201 |
WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
|
| 2159 |
2202 |
} else
|
| 2160 |
2203 |
sc->sc_active--;
|
| 2161 |
|
crit_exit();
|
|
2204 |
HIFN_UNLOCK(sc);
|
| 2162 |
2205 |
callout_reset(&sc->sc_tickto, hz, hifn_tick, sc);
|
| 2163 |
2206 |
}
|
| 2164 |
2207 |
|
| ... | ... | |
| 2178 |
2221 |
return;
|
| 2179 |
2222 |
}
|
| 2180 |
2223 |
|
|
2224 |
HIFN_LOCK(sc);
|
|
2225 |
|
| 2181 |
2226 |
dma = sc->sc_dma;
|
| 2182 |
2227 |
|
| 2183 |
2228 |
#ifdef HIFN_DEBUG
|
| ... | ... | |
| 2215 |
2260 |
device_printf(sc->sc_dev, "abort, resetting.\n");
|
| 2216 |
2261 |
hifnstats.hst_abort++;
|
| 2217 |
2262 |
hifn_abort(sc);
|
|
2263 |
HIFN_UNLOCK(sc);
|
| 2218 |
2264 |
return;
|
| 2219 |
2265 |
}
|
| 2220 |
2266 |
|
| ... | ... | |
| 2297 |
2343 |
}
|
| 2298 |
2344 |
dma->cmdk = i; dma->cmdu = u;
|
| 2299 |
2345 |
|
|
2346 |
HIFN_UNLOCK(sc);
|
|
2347 |
|
| 2300 |
2348 |
if (sc->sc_needwakeup) { /* XXX check high watermark */
|
| 2301 |
2349 |
int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
|
| 2302 |
2350 |
#ifdef HIFN_DEBUG
|
| ... | ... | |
| 2317 |
2365 |
* id on successful allocation.
|
| 2318 |
2366 |
*/
|
| 2319 |
2367 |
static int
|
| 2320 |
|
hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
|
2368 |
hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
|
| 2321 |
2369 |
{
|
| 2322 |
2370 |
struct cryptoini *c;
|
| 2323 |
|
struct hifn_softc *sc = arg;
|
|
2371 |
struct hifn_softc *sc = device_get_softc(dev);
|
| 2324 |
2372 |
int mac = 0, cry = 0, sesn;
|
| 2325 |
2373 |
struct hifn_session *ses = NULL;
|
| 2326 |
2374 |
|
| ... | ... | |
| 2328 |
2376 |
if (sidp == NULL || cri == NULL || sc == NULL)
|
| 2329 |
2377 |
return (EINVAL);
|
| 2330 |
2378 |
|
|
2379 |
HIFN_LOCK(sc);
|
| 2331 |
2380 |
if (sc->sc_sessions == NULL) {
|
| 2332 |
2381 |
ses = sc->sc_sessions = (struct hifn_session *)kmalloc(
|
| 2333 |
2382 |
sizeof(*ses), M_DEVBUF, M_NOWAIT);
|
| 2334 |
|
if (ses == NULL)
|
|
2383 |
if (ses == NULL) {
|
|
2384 |
HIFN_UNLOCK(sc);
|
| 2335 |
2385 |
return (ENOMEM);
|
|
2386 |
}
|
| 2336 |
2387 |
sesn = 0;
|
| 2337 |
2388 |
sc->sc_nsessions = 1;
|
| 2338 |
2389 |
} else {
|
| ... | ... | |
| 2347 |
2398 |
sesn = sc->sc_nsessions;
|
| 2348 |
2399 |
ses = (struct hifn_session *)kmalloc((sesn + 1) *
|
| 2349 |
2400 |
sizeof(*ses), M_DEVBUF, M_NOWAIT);
|
| 2350 |
|
if (ses == NULL)
|
|
2401 |
if (ses == NULL) {
|
|
2402 |
HIFN_UNLOCK(sc);
|
| 2351 |
2403 |
return (ENOMEM);
|
|
2404 |
}
|
| 2352 |
2405 |
bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
|
| 2353 |
2406 |
bzero(sc->sc_sessions, sesn * sizeof(*ses));
|
| 2354 |
2407 |
kfree(sc->sc_sessions, M_DEVBUF);
|
| ... | ... | |
| 2357 |
2410 |
sc->sc_nsessions++;
|
| 2358 |
2411 |
}
|
| 2359 |
2412 |
}
|
|
2413 |
HIFN_UNLOCK(sc);
|
|
2414 |
|
| 2360 |
2415 |
bzero(ses, sizeof(*ses));
|
| 2361 |
2416 |
ses->hs_used = 1;
|
| 2362 |
2417 |
|
| ... | ... | |
| 2382 |
2437 |
break;
|
| 2383 |
2438 |
}
|
| 2384 |
2439 |
}
|
|
2440 |
break;
|
| 2385 |
2441 |
case CRYPTO_DES_CBC:
|
| 2386 |
2442 |
case CRYPTO_3DES_CBC:
|
| 2387 |
2443 |
case CRYPTO_AES_CBC:
|
| ... | ... | |
| 2415 |
2471 |
#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
|
| 2416 |
2472 |
|
| 2417 |
2473 |
static int
|
| 2418 |
|
hifn_freesession(void *arg, u_int64_t tid)
|
|
2474 |
hifn_freesession(device_t dev, u_int64_t tid)
|
| 2419 |
2475 |
{
|
| 2420 |
|
struct hifn_softc *sc = arg;
|
| 2421 |
|
int session;
|
|
2476 |
struct hifn_softc *sc = device_get_softc(dev);
|
|
2477 |
int session, error;
|
| 2422 |
2478 |
u_int32_t sid = CRYPTO_SESID2LID(tid);
|
| 2423 |
2479 |
|
| 2424 |
2480 |
KASSERT(sc != NULL, ("hifn_freesession: null softc"));
|
| 2425 |
2481 |
if (sc == NULL)
|
| 2426 |
2482 |
return (EINVAL);
|
| 2427 |
2483 |
|
|
2484 |
HIFN_LOCK(sc);
|
| 2428 |
2485 |
session = HIFN_SESSION(sid);
|
| 2429 |
|
if (session >= sc->sc_nsessions)
|
| 2430 |
|
return (EINVAL);
|
|
2486 |
if (session < sc->sc_nsessions) {
|
|
2487 |
bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
|
|
2488 |
error = 0;
|
|
2489 |
} else
|
|
2490 |
error = EINVAL;
|
|
2491 |
HIFN_UNLOCK(sc);
|
| 2431 |
2492 |
|
| 2432 |
|
bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
|
| 2433 |
|
return (0);
|
|
2493 |
return (error);
|
| 2434 |
2494 |
}
|
| 2435 |
2495 |
|
| 2436 |
2496 |
static int
|
| 2437 |
|
hifn_process(void *arg, struct cryptop *crp, int hint)
|
|
2497 |
hifn_process(device_t dev, struct cryptop *crp, int hint)
|
| 2438 |
2498 |
{
|
| 2439 |
|
struct hifn_softc *sc = arg;
|
|
2499 |
struct hifn_softc *sc = device_get_softc(dev);
|
| 2440 |
2500 |
struct hifn_command *cmd = NULL;
|
| 2441 |
2501 |
int session, err, ivlen;
|
| 2442 |
2502 |
struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
|
| ... | ... | |
| 2567 |
2627 |
|
| 2568 |
2628 |
if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
|
| 2569 |
2629 |
== 0) {
|
| 2570 |
|
if (crp->crp_flags & CRYPTO_F_IMBUF)
|
| 2571 |
|
m_copyback(cmd->src_m,
|
| 2572 |
|
enccrd->crd_inject,
|
| 2573 |
|
ivlen, cmd->iv);
|
| 2574 |
|
else if (crp->crp_flags & CRYPTO_F_IOV)
|
| 2575 |
|
cuio_copyback(cmd->src_io,
|
| 2576 |
|
enccrd->crd_inject,
|
| 2577 |
|
ivlen, cmd->iv);
|
|
2630 |
crypto_copyback(crp->crp_flags,
|
|
2631 |
crp->crp_buf, enccrd->crd_inject,
|
|
2632 |
ivlen, cmd->iv);
|
| 2578 |
2633 |
}
|
| 2579 |
2634 |
} else {
|
| 2580 |
2635 |
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
|
| 2581 |
2636 |
bcopy(enccrd->crd_iv, cmd->iv, ivlen);
|
| 2582 |
|
else if (crp->crp_flags & CRYPTO_F_IMBUF)
|
| 2583 |
|
m_copydata(cmd->src_m,
|
| 2584 |
|
enccrd->crd_inject, ivlen, cmd->iv);
|
| 2585 |
|
else if (crp->crp_flags & CRYPTO_F_IOV)
|
| 2586 |
|
cuio_copydata(cmd->src_io,
|
| 2587 |
|
enccrd->crd_inject, ivlen, cmd->iv);
|
|
2637 |
else {
|
|
2638 |
crypto_copydata(crp->crp_flags,
|
|
2639 |
crp->crp_buf, enccrd->crd_inject,
|
|
2640 |
ivlen, cmd->iv);
|
|
2641 |
}
|
| 2588 |
2642 |
}
|
| 2589 |
2643 |
}
|
| 2590 |
2644 |
|
| ... | ... | |
| 2593 |
2647 |
cmd->ck = enccrd->crd_key;
|
| 2594 |
2648 |
cmd->cklen = enccrd->crd_klen >> 3;
|
| 2595 |
2649 |
cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
|
|
2650 |
|
| 2596 |
2651 |
/*
|
| 2597 |
2652 |
* Need to specify the size for the AES key in the masks.
|
| 2598 |
2653 |
*/
|
| ... | ... | |
| 2794 |
2849 |
}
|
| 2795 |
2850 |
|
| 2796 |
2851 |
if (cmd->sloplen != 0) {
|
| 2797 |
|
if (crp->crp_flags & CRYPTO_F_IMBUF)
|
| 2798 |
|
m_copyback((struct mbuf *)crp->crp_buf,
|
| 2799 |
|
cmd->src_mapsize - cmd->sloplen,
|
| 2800 |
|
cmd->sloplen, (caddr_t)&dma->slop[cmd->slopidx]);
|
| 2801 |
|
else if (crp->crp_flags & CRYPTO_F_IOV)
|
| 2802 |
|
cuio_copyback((struct uio *)crp->crp_buf,
|
| 2803 |
|
cmd->src_mapsize - cmd->sloplen,
|
| 2804 |
|
cmd->sloplen, (caddr_t)&dma->slop[cmd->slopidx]);
|
|
2852 |
crypto_copyback(crp->crp_flags, crp->crp_buf,
|
|
2853 |
cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
|
|
2854 |
(caddr_t)&dma->slop[cmd->slopidx]);
|
| 2805 |
2855 |
}
|
| 2806 |
2856 |
|
| 2807 |
2857 |
i = dma->dstk; u = dma->dstu;
|
| ... | ... | |
| 2830 |
2880 |
continue;
|
| 2831 |
2881 |
ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
|
| 2832 |
2882 |
HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
|
| 2833 |
|
if (crp->crp_flags & CRYPTO_F_IMBUF)
|
| 2834 |
|
m_copydata((struct mbuf *)crp->crp_buf,
|
| 2835 |
|
crd->crd_skip + crd->crd_len - ivlen, ivlen,
|
| 2836 |
|
cmd->softc->sc_sessions[cmd->session_num].hs_iv);
|
| 2837 |
|
else if (crp->crp_flags & CRYPTO_F_IOV) {
|
| 2838 |
|
cuio_copydata((struct uio *)crp->crp_buf,
|
| 2839 |
|
crd->crd_skip + crd->crd_len - ivlen, ivlen,
|
| 2840 |
|
cmd->softc->sc_sessions[cmd->session_num].hs_iv);
|
| 2841 |
|
}
|
|
2883 |
crypto_copydata(crp->crp_flags, crp->crp_buf,
|
|
2884 |
crd->crd_skip + crd->crd_len - ivlen, ivlen,
|
|
2885 |
cmd->softc->sc_sessions[cmd->session_num].hs_iv);
|
| 2842 |
2886 |
break;
|
| 2843 |
2887 |
}
|
| 2844 |
2888 |
}
|
| ... | ... | |
| 2857 |
2901 |
crypto_copyback(crp->crp_flags, crp->crp_buf,
|
| 2858 |
2902 |
crd->crd_inject, len, macbuf);
|
| 2859 |
2903 |
break;
|
| 2860 |
|
#if 0
|
| 2861 |
|
if (crd->crd_alg == CRYPTO_MD5)
|
| 2862 |
|
len = 16;
|
| 2863 |
|
else if (crd->crd_alg == CRYPTO_SHA1)
|
| 2864 |
|
len = 20;
|
| 2865 |
|
else if (crd->crd_alg == CRYPTO_MD5_HMAC ||
|
| 2866 |
|
crd->crd_alg == CRYPTO_SHA1_HMAC)
|
| 2867 |
|
len = 12;
|
| 2868 |
|
else
|
| 2869 |
|
continue;
|
| 2870 |
|
|
| 2871 |
|
if (crp->crp_flags & CRYPTO_F_IMBUF)
|
| 2872 |
|
m_copyback((struct mbuf *)crp->crp_buf,
|
| 2873 |
|
crd->crd_inject, len, macbuf);
|
| 2874 |
|
else if ((crp->crp_flags & CRYPTO_F_IOV) && crp->crp_mac)
|
| 2875 |
|
bcopy((caddr_t)macbuf, crp->crp_mac, len);
|
| 2876 |
|
break;
|
| 2877 |
|
#endif
|
| 2878 |
2904 |
}
|
| 2879 |
2905 |
}
|
| 2880 |
2906 |
|