Module Name: src Committed By: matt Date: Thu Feb 7 06:51:50 UTC 2013
Modified Files: src/sys/arch/arm/broadcom [matt-nb6-plus]: bcm53xx_board.c bcm53xx_eth.c bcm53xx_idm.c bcm53xx_reg.h bcm53xx_rng.c Log Message: Sync bcm53xx support to HEAD. To generate a diff of this commit: cvs rdiff -u -r1.8.4.2 -r1.8.4.3 src/sys/arch/arm/broadcom/bcm53xx_board.c cvs rdiff -u -r1.17.2.3 -r1.17.2.4 src/sys/arch/arm/broadcom/bcm53xx_eth.c cvs rdiff -u -r1.2.4.2 -r1.2.4.3 src/sys/arch/arm/broadcom/bcm53xx_idm.c cvs rdiff -u -r1.10.2.3 -r1.10.2.4 src/sys/arch/arm/broadcom/bcm53xx_reg.h cvs rdiff -u -r1.3.4.2 -r1.3.4.3 src/sys/arch/arm/broadcom/bcm53xx_rng.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/broadcom/bcm53xx_board.c diff -u src/sys/arch/arm/broadcom/bcm53xx_board.c:1.8.4.2 src/sys/arch/arm/broadcom/bcm53xx_board.c:1.8.4.3 --- src/sys/arch/arm/broadcom/bcm53xx_board.c:1.8.4.2 Wed Nov 28 22:40:21 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_board.c Thu Feb 7 06:51:48 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm53xx_board.c,v 1.8.4.2 2012/11/28 22:40:21 matt Exp $ */ +/* $NetBSD: bcm53xx_board.c,v 1.8.4.3 2013/02/07 06:51:48 matt Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -34,7 +34,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: bcm53xx_board.c,v 1.8.4.2 2012/11/28 22:40:21 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: bcm53xx_board.c,v 1.8.4.3 2013/02/07 06:51:48 matt Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -65,7 +65,6 @@ bus_space_tag_t bcm53xx_armcore_bst = &b bus_space_handle_t bcm53xx_armcore_bsh; static struct cpu_softc cpu_softc; -static struct bcm53xx_clock_info clk_info; struct arm32_dma_range bcm53xx_dma_ranges[2] = { [0] = { @@ -450,23 +449,24 @@ void bcm53xx_print_clocks(void) { #if defined(VERBOSE_ARM_INIT) - printf("ref clk = %u (%#x)\n", clk_info.clk_ref, clk_info.clk_ref); - printf("sys clk = %u (%#x)\n", clk_info.clk_sys, clk_info.clk_sys); - printf("lcpll clk = %u (%#x)\n", clk_info.clk_lcpll, clk_info.clk_lcpll); - printf("pcie ref clk = %u (%#x) [CH0]\n", clk_info.clk_pcie_ref, clk_info.clk_pcie_ref); - printf("sdio clk = %u (%#x) [CH1]\n", clk_info.clk_sdio, clk_info.clk_sdio); - printf("ddr ref clk = %u (%#x) [CH2]\n", clk_info.clk_ddr_ref, clk_info.clk_ddr_ref); - printf("axi clk = %u (%#x) [CH3]\n", clk_info.clk_axi, clk_info.clk_axi); - printf("genpll clk = %u (%#x)\n", clk_info.clk_genpll, clk_info.clk_genpll); - printf("mac clk = %u (%#x) [CH0]\n", clk_info.clk_mac, clk_info.clk_mac); - printf("robo clk = %u (%#x) [CH1]\n", clk_info.clk_robo, clk_info.clk_robo); - printf("usb2 clk = %u (%#x) [CH2]\n", clk_info.clk_usb2, clk_info.clk_usb2); - printf("iproc clk = %u (%#x) [CH3]\n", clk_info.clk_iproc, clk_info.clk_iproc); - printf("ddr clk = %u (%#x)\n", clk_info.clk_ddr, clk_info.clk_ddr); - printf("ddr mhz = %u (%#x)\n", clk_info.clk_ddr_mhz, clk_info.clk_ddr_mhz); - printf("cpu clk = %u (%#x)\n", clk_info.clk_cpu, clk_info.clk_cpu); - printf("apb clk = %u (%#x)\n", clk_info.clk_apb, clk_info.clk_apb); - printf("usb ref clk = %u (%#x)\n", clk_info.clk_usb_ref, clk_info.clk_usb_ref); + const struct bcm53xx_clock_info * const clk = &cpu_softc.cpu_clk; + printf("ref clk = %u (%#x)\n", clk->clk_ref, clk->clk_ref); + printf("sys clk = %u (%#x)\n", clk->clk_sys, clk->clk_sys); + printf("lcpll clk = %u (%#x)\n", clk->clk_lcpll, clk->clk_lcpll); + printf("pcie ref clk = %u (%#x) [CH0]\n", clk->clk_pcie_ref, clk->clk_pcie_ref); + printf("sdio clk = %u (%#x) [CH1]\n", clk->clk_sdio, clk->clk_sdio); + printf("ddr ref clk = %u (%#x) [CH2]\n", clk->clk_ddr_ref, clk->clk_ddr_ref); + printf("axi clk = %u (%#x) [CH3]\n", clk->clk_axi, clk->clk_axi); + printf("genpll clk = %u (%#x)\n", clk->clk_genpll, clk->clk_genpll); + printf("mac clk = %u (%#x) [CH0]\n", clk->clk_mac, clk->clk_mac); + printf("robo clk = %u (%#x) [CH1]\n", clk->clk_robo, clk->clk_robo); + printf("usb2 clk = %u (%#x) [CH2]\n", clk->clk_usb2, clk->clk_usb2); + printf("iproc clk = %u (%#x) [CH3]\n", clk->clk_iproc, clk->clk_iproc); + printf("ddr clk = %u (%#x)\n", clk->clk_ddr, clk->clk_ddr); + printf("ddr mhz = %u (%#x)\n", clk->clk_ddr_mhz, clk->clk_ddr_mhz); + printf("cpu clk = %u (%#x)\n", clk->clk_cpu, clk->clk_cpu); + printf("apb clk = %u (%#x)\n", clk->clk_apb, clk->clk_apb); + printf("usb ref clk = %u (%#x)\n", clk->clk_usb_ref, clk->clk_usb_ref); #endif } @@ -500,7 +500,7 @@ bcm53xx_bootstrap(vaddr_t iobase) bcm53xx_get_chip_ioreg_state(&bcs, bcm53xx_ioreg_bst, bcm53xx_ioreg_bsh); bcm53xx_get_chip_armcore_state(&bcs, bcm53xx_armcore_bst, bcm53xx_armcore_bsh); - struct bcm53xx_clock_info * const clk = &clk_info; + struct bcm53xx_clock_info * const clk = &cpu_softc.cpu_clk; bcm53xx_clock_init(clk); bcm53xx_lcpll_clock_init(clk, bcs.bcs_lcpll_control1, @@ -575,7 +575,7 @@ bcm53xx_device_register(device_t self, v * to timers that are part of the A9 MP core subsystem. */ prop_dictionary_set_uint32(dict, "frequency", - clk_info.clk_cpu / 2); + cpu_softc.cpu_clk.clk_cpu / 2); return; } Index: src/sys/arch/arm/broadcom/bcm53xx_eth.c diff -u src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.17.2.3 src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.17.2.4 --- src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.17.2.3 Fri Dec 7 22:47:13 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_eth.c Thu Feb 7 06:51:49 2013 @@ -35,7 +35,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth.c,v 1.17.2.3 2012/12/07 22:47:13 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth.c,v 1.17.2.4 2013/02/07 06:51:49 matt Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -71,7 +71,6 @@ __KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth. #endif #define BCMETH_EVCNT_INCR(a) BCMETH_EVCNT_ADD((a), 1) -#define BCMETH_RCVOFFSET 10 #define BCMETH_MAXTXMBUFS 128 #define BCMETH_NTXSEGS 30 #define BCMETH_MAXRXMBUFS 255 @@ -79,7 +78,7 @@ __KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth. #define BCMETH_NRXSEGS 1 #define BCMETH_RINGSIZE PAGE_SIZE -#if 0 +#if 1 #define BCMETH_RCVMAGIC 0xfeedface #endif @@ -148,6 +147,8 @@ struct bcmeth_softc { struct bcmeth_rxqueue sc_rxq; struct bcmeth_txqueue sc_txq; + size_t sc_rcvoffset; + uint32_t sc_macaddr[2]; uint32_t sc_maxfrm; uint32_t sc_cmdcfg; uint32_t sc_intmask; @@ -434,7 +435,7 @@ bcmeth_macaddr_create(const uint8_t *ena return (enaddr[3] << 0) // UNIMAC_MAC_0 | (enaddr[2] << 8) // UNIMAC_MAC_0 | (enaddr[1] << 16) // UNIMAC_MAC_0 - | (enaddr[0] << 24) // UNIMAC_MAC_0 + | ((uint64_t)enaddr[0] << 24) // UNIMAC_MAC_0 | ((uint64_t)enaddr[5] << 32) // UNIMAC_MAC_1 | ((uint64_t)enaddr[4] << 40); // UNIMAC_MAC_1 } @@ -457,6 +458,21 @@ bcmeth_ifinit(struct ifnet *ifp) bcmeth_ifstop(ifp, 0); /* + * Reserve enough space at the front so that we can insert a maxsized + * link header and a VLAN tag. Also make sure we have enough room for + * the rcvsts field as well. + */ + KASSERT(ALIGN(max_linkhdr) == max_linkhdr); + KASSERTMSG(max_linkhdr > sizeof(struct ether_header), "%u > %zu", + max_linkhdr, sizeof(struct ether_header)); + sc->sc_rcvoffset = max_linkhdr + 4 - sizeof(struct ether_header); + if (sc->sc_rcvoffset <= 4) + sc->sc_rcvoffset += 4; + KASSERT((sc->sc_rcvoffset & 3) == 2); + KASSERT(sc->sc_rcvoffset <= __SHIFTOUT(RCVCTL_RCVOFFSET, RCVCTL_RCVOFFSET)); + KASSERT(sc->sc_rcvoffset >= 6); + + /* * If our frame size has changed (or it's our first time through) * destroy the existing transmit mapcache. */ @@ -483,8 +499,24 @@ bcmeth_ifinit(struct ifnet *ifp) sc->sc_cmdcfg &= ~PROMISC_EN; } - const uint64_t macstnaddr = - bcmeth_macaddr_create(CLLADDR(ifp->if_sadl)); + const uint8_t * const lladdr = CLLADDR(ifp->if_sadl); + const uint64_t macstnaddr = bcmeth_macaddr_create(lladdr); + + /* + * We make sure that a received Ethernet packet start on a non-word + * boundary so that the packet payload will be on a word boundary. + * So to check the destination address we keep around two words to + * quickly compare with. + */ +#if __ARMEL__ + sc->sc_macaddr[0] = lladdr[0] | (lladdr[1] << 8); + sc->sc_macaddr[1] = lladdr[2] | (lladdr[3] << 8) + | (lladdr[4] << 16) | (lladdr[5] << 24); +#else + sc->sc_macaddr[0] = lladdr[1] | (lladdr[0] << 8); + sc->sc_macaddr[1] = lladdr[5] | (lladdr[4] << 8) + | (lladdr[1] << 16) | (lladdr[2] << 24); +#endif sc->sc_intmask = DESCPROTOERR|DATAERR|DESCERR; @@ -492,7 +524,7 @@ bcmeth_ifinit(struct ifnet *ifp) bcmeth_rxq_reset(sc, &sc->sc_rxq); bcmeth_write_4(sc, sc->sc_rxq.rxq_reg_rcvctl, - __SHIFTIN(BCMETH_RCVOFFSET, RCVCTL_RCVOFFSET) + __SHIFTIN(sc->sc_rcvoffset, RCVCTL_RCVOFFSET) | RCVCTL_PARITY_DIS | RCVCTL_OFLOW_CONTINUE | __SHIFTIN(3, RCVCTL_BURSTLEN)); @@ -519,8 +551,9 @@ bcmeth_ifinit(struct ifnet *ifp) bcmeth_write_4(sc, GMAC_DEVCONTROL, devctl); /* Setup lazy receive (at most 1ms). */ + const struct cpu_softc * const cpu = curcpu()->ci_softc; sc->sc_rcvlazy = __SHIFTIN(4, INTRCVLAZY_FRAMECOUNT) - | __SHIFTIN(125000000 / 1000, INTRCVLAZY_TIMEOUT); + | __SHIFTIN(cpu->cpu_clk.clk_apb / 1000, INTRCVLAZY_TIMEOUT); bcmeth_write_4(sc, GMAC_INTRCVLAZY, sc->sc_rcvlazy); /* 11. Enable transmit queues in TQUEUE, and ensure that the transmit scheduling mode is correctly set in TCTRL. */ @@ -863,7 +896,6 @@ bcmeth_rx_buf_alloc( bcmeth_mapcache_put(sc, sc->sc_rx_mapcache, map); return NULL; } - KASSERT(((map->_dm_flags ^ sc->sc_dmat->_ranges[0].dr_flags) & _BUS_DMAMAP_COHERENT) == 0); KASSERT(map->dm_mapsize == MCLBYTES); #ifdef BCMETH_RCVMAGIC *mtod(m, uint32_t *) = BCMETH_RCVMAGIC; @@ -872,7 +904,7 @@ bcmeth_rx_buf_alloc( bus_dmamap_sync(sc->sc_dmat, map, sizeof(uint32_t), map->dm_mapsize - sizeof(uint32_t), BUS_DMASYNC_PREREAD); #else - bus_dmamap_sync(sc->sc_dmat, map, 0, sizeof(uint32_t), + bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREREAD); #endif @@ -958,21 +990,18 @@ bcmeth_rx_input( bcmeth_rx_map_unload(sc, m); - m_adj(m, BCMETH_RCVOFFSET); + m_adj(m, sc->sc_rcvoffset); - switch (__SHIFTOUT(rxdb_flags, RXSTS_PKTTYPE)) { - case RXSTS_PKTTYPE_UC: - break; - case RXSTS_PKTTYPE_MC: - m->m_flags |= M_MCAST; - break; - case RXSTS_PKTTYPE_BC: - m->m_flags |= M_BCAST|M_MCAST; - break; - default: - if (sc->sc_cmdcfg & PROMISC_EN) - m->m_flags |= M_PROMISC; - break; + /* + * If we are in promiscuous mode and this isn't a multicast, check the + * destination address to make sure it matches our own. If it doesn't, + * mark the packet as being received promiscuously. + */ + if ((sc->sc_cmdcfg & PROMISC_EN) + && (m->m_data[0] & 1) == 0 + && (*(uint16_t *)&m->m_data[0] != sc->sc_macaddr[0] + || *(uint32_t *)&m->m_data[2] != sc->sc_macaddr[1])) { + m->m_flags |= M_PROMISC; } m->m_pkthdr.rcvif = ifp; @@ -994,29 +1023,27 @@ bcmeth_rx_input( #endif } -static void +static bool bcmeth_rxq_consume( struct bcmeth_softc *sc, - struct bcmeth_rxqueue *rxq) + struct bcmeth_rxqueue *rxq, + size_t atmost) { struct ifnet * const ifp = &sc->sc_if; struct gmac_rxdb *consumer = rxq->rxq_consumer; size_t rxconsumed = 0; + bool didconsume = false; - for (;;) { + while (atmost-- > 0) { if (consumer == rxq->rxq_producer) { - rxq->rxq_consumer = consumer; - rxq->rxq_inuse -= rxconsumed; KASSERT(rxq->rxq_inuse == 0); - return; + break; } uint32_t rcvsts0 = bcmeth_read_4(sc, rxq->rxq_reg_rcvsts0); uint32_t currdscr = __SHIFTOUT(rcvsts0, RCV_CURRDSCR); if (consumer == rxq->rxq_first + currdscr) { - rxq->rxq_consumer = consumer; - rxq->rxq_inuse -= rxconsumed; - return; + break; } bcmeth_rxq_desc_postsync(sc, rxq, consumer, 1); @@ -1024,6 +1051,7 @@ bcmeth_rxq_consume( * We own this packet again. Copy the rxsts word from it. */ rxconsumed++; + didconsume = true; uint32_t rxsts; KASSERT(rxq->rxq_mhead != NULL); bus_dmamap_t map = M_GETCTX(rxq->rxq_mhead, bus_dmamap_t); @@ -1091,7 +1119,7 @@ bcmeth_rxq_consume( } while (m); } else { uint32_t framelen = __SHIFTOUT(rxsts, RXSTS_FRAMELEN); - framelen += BCMETH_RCVOFFSET; + framelen += sc->sc_rcvoffset; m->m_pkthdr.len = framelen; if (desc_count == 1) { KASSERT(framelen <= MCLBYTES); @@ -1137,6 +1165,17 @@ bcmeth_rxq_consume( consumer = rxq->rxq_first; } } + + /* + * Update queue info. + */ + rxq->rxq_consumer = consumer; + rxq->rxq_inuse -= rxconsumed; + + /* + * Did we consume anything? + */ + return didconsume; } static void @@ -1881,7 +1920,14 @@ bcmeth_soft_intr(void *arg) /* * Let's consume */ - bcmeth_rxq_consume(sc, &sc->sc_rxq); + while (bcmeth_rxq_consume(sc, &sc->sc_rxq, + sc->sc_rxq.rxq_threshold / 4)) { + /* + * We've consumed a quarter of the ring and still have + * more to do. Refill the ring. + */ + bcmeth_rxq_produce(sc, &sc->sc_rxq); + } intmask |= RCVINT; } @@ -1934,7 +1980,14 @@ bcmeth_worker(struct work *wk, void *arg /* * Let's consume */ - bcmeth_rxq_consume(sc, &sc->sc_rxq); + while (bcmeth_rxq_consume(sc, &sc->sc_rxq, + sc->sc_rxq.rxq_threshold / 4)) { + /* + * We've consumed a quarter of the ring and still have + * more to do. Refill the ring. + */ + bcmeth_rxq_produce(sc, &sc->sc_rxq); + } intmask |= RCVINT; } Index: src/sys/arch/arm/broadcom/bcm53xx_idm.c diff -u src/sys/arch/arm/broadcom/bcm53xx_idm.c:1.2.4.2 src/sys/arch/arm/broadcom/bcm53xx_idm.c:1.2.4.3 --- src/sys/arch/arm/broadcom/bcm53xx_idm.c:1.2.4.2 Wed Nov 28 22:40:22 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_idm.c Thu Feb 7 06:51:49 2013 @@ -35,7 +35,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: bcm53xx_idm.c,v 1.2.4.2 2012/11/28 22:40:22 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: bcm53xx_idm.c,v 1.2.4.3 2013/02/07 06:51:49 matt Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -78,12 +78,28 @@ bcmeth_unreset(bus_space_tag_t bst, bus_ off + IDM_IO_CONTROL_DIRECT); /* * Clear read-allocate and write-allocate bits from - * ACP cache access so we don't pollute the caches. + * ACP cache access so we don't pollute the caches with + * DMA traffic. */ v &= ~IO_CONTROL_DIRECT_ARCACHE; v &= ~IO_CONTROL_DIRECT_AWCACHE; +#if 0 + v |= __SHIFTIN(AXCACHE_WA, IO_CONTROL_DIRECT_ARCACHE); + v |= __SHIFTIN(AXCACHE_RA, IO_CONTROL_DIRECT_AWCACHE); +#endif v |= __SHIFTIN(AXCACHE_C|AXCACHE_B, IO_CONTROL_DIRECT_ARCACHE); v |= __SHIFTIN(AXCACHE_C|AXCACHE_B, IO_CONTROL_DIRECT_AWCACHE); + /* + * These are the default but make sure they are + * properly set. + */ + v |= __SHIFTIN(0x1F, IO_CONTROL_DIRECT_ARUSER); + v |= __SHIFTIN(0x1F, IO_CONTROL_DIRECT_AWUSER); + v |= IO_CONTROL_DIRECT_CLK_250_SEL; + v |= IO_CONTROL_DIRECT_DIRECT_GMII_MODE; + v |= IO_CONTROL_DIRECT_SOURCE_SYNC_MODE_EN; + v |= IO_CONTROL_DIRECT_CLK_GATING_EN; + bus_space_write_4(bst, bsh, off + IDM_IO_CONTROL_DIRECT, v); } Index: src/sys/arch/arm/broadcom/bcm53xx_reg.h diff -u src/sys/arch/arm/broadcom/bcm53xx_reg.h:1.10.2.3 src/sys/arch/arm/broadcom/bcm53xx_reg.h:1.10.2.4 --- src/sys/arch/arm/broadcom/bcm53xx_reg.h:1.10.2.3 Thu Nov 29 18:42:05 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_reg.h Thu Feb 7 06:51:49 2013 @@ -237,14 +237,14 @@ #define MIIMGT_MDCDIV __BITS(6,0) #define MIICMD 0x004 #define MIICMD_SB __BITS(31,30) -#define MIICMD_SB_DEF __SHIFTIN(1, MIICMD_OP) +#define MIICMD_SB_DEF __SHIFTIN(1, MIICMD_SB) #define MIICMD_OP __BITS(29,28) #define MIICMD_OP_RD __SHIFTIN(2, MIICMD_OP) #define MIICMD_OP_WR __SHIFTIN(1, MIICMD_OP) #define MIICMD_PHY __BITS(27,23) #define MIICMD_REG __BITS(22,18) #define MIICMD_TA __BITS(17,16) -#define MIICMD_TA_DEF __SHIFTIN(2, MIICMD_OP) +#define MIICMD_TA_DEF __SHIFTIN(2, MIICMD_TA) #define MIICMD_DATA __BITS(15,0) #define MIICMD_RD_DEF (MIICMD_SB_DEF|MIICMD_OP_RD|MIICMD_TA_DEF) @@ -646,6 +646,8 @@ #define IDM_RESET_STATUS 0x0804 #define IDM_INTERRUPT_STATUS 0x0a00 +#define IO_CONTROL_DIRECT_ARUSER __BITS(29,25) +#define IO_CONTROL_DIRECT_AWUSER __BITS(24,20) #define IO_CONTROL_DIRECT_ARCACHE __BITS(19,16) #define IO_CONTROL_DIRECT_AWCACHE __BITS(10,7) #define AXCACHE_WA __BIT(3) @@ -653,6 +655,12 @@ #define AXCACHE_C __BIT(1) #define AXCACHE_B __BIT(0) #define IO_CONTROL_DIRECT_UARTCLKSEL __BIT(17) +#define IO_CONTROL_DIRECT_CLK_250_SEL __BIT(6) +#define IO_CONTROL_DIRECT_DIRECT_GMII_MODE __BIT(5) +#define IO_CONTROL_DIRECT_TX_CLK_OUT_INVERT_EN __BIT(4) +#define IO_CONTROL_DIRECT_DEST_SYNC_MODE_EN __BIT(3) +#define IO_CONTROL_DIRECT_SOURCE_SYNC_MODE_EN __BIT(2) +#define IO_CONTROL_DIRECT_CLK_GATING_EN __BIT(0) #define RESET_CONTROL_RESET __BIT(0) Index: src/sys/arch/arm/broadcom/bcm53xx_rng.c diff -u src/sys/arch/arm/broadcom/bcm53xx_rng.c:1.3.4.2 src/sys/arch/arm/broadcom/bcm53xx_rng.c:1.3.4.3 --- src/sys/arch/arm/broadcom/bcm53xx_rng.c:1.3.4.2 Wed Nov 28 22:40:23 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_rng.c Thu Feb 7 06:51:49 2013 @@ -33,7 +33,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: bcm53xx_rng.c,v 1.3.4.2 2012/11/28 22:40:23 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: bcm53xx_rng.c,v 1.3.4.3 2013/02/07 06:51:49 matt Exp $"); #include <sys/bus.h> #include <sys/callout.h> @@ -91,6 +91,13 @@ bcmrng_read_4(struct bcmrng_softc *sc, b } static inline void +bcmrng_read_multi_4(struct bcmrng_softc *sc, bus_size_t o, uint32_t *p, + size_t c) +{ + return bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, o, p, c); +} + +static inline void bcmrng_write_4(struct bcmrng_softc *sc, bus_size_t o, uint32_t v) { bus_space_write_4(sc->sc_bst, sc->sc_bsh, o, v); @@ -162,16 +169,13 @@ bcmrng_empty(struct bcmrng_softc *sc) } uint32_t data[nwords]; - while (nwords-- > 0) { - /* - * It's random data, who cares what order we load it in? - */ - data[nwords] = bcmrng_read_4(sc, RNG_DATA); - } + + bcmrng_read_multi_4(sc, RNG_DATA, data, nwords); + rnd_add_data(&sc->sc_rnd_source, data, sizeof(data), sizeof(data) * 8); mutex_exit(sc->sc_lock); - //aprint_debug_dev(sc->sc_dev, "added %zu words\n", __arraycount(data)); - return __arraycount(data); + //aprint_debug_dev(sc->sc_dev, "added %zu words\n", nwords); + return nwords; } void