Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/matt-nb6-plus]: src/sys/arch/arm/broadcom Sync bcm53xx support to HEAD.



details:   https://anonhg.NetBSD.org/src/rev/96de45cb34e2
branches:  matt-nb6-plus
changeset: 774545:96de45cb34e2
user:      matt <matt%NetBSD.org@localhost>
date:      Thu Feb 07 06:51:48 2013 +0000

description:
Sync bcm53xx support to HEAD.

diffstat:

 sys/arch/arm/broadcom/bcm53xx_board.c |   44 +++++-----
 sys/arch/arm/broadcom/bcm53xx_eth.c   |  125 ++++++++++++++++++++++++---------
 sys/arch/arm/broadcom/bcm53xx_idm.c   |   20 ++++-
 sys/arch/arm/broadcom/bcm53xx_reg.h   |   12 ++-
 sys/arch/arm/broadcom/bcm53xx_rng.c   |   22 +++--
 5 files changed, 152 insertions(+), 71 deletions(-)

diffs (truncated from 488 to 300 lines):

diff -r 1471b181ce7d -r 96de45cb34e2 sys/arch/arm/broadcom/bcm53xx_board.c
--- a/sys/arch/arm/broadcom/bcm53xx_board.c     Thu Feb 07 01:42:08 2013 +0000
+++ b/sys/arch/arm/broadcom/bcm53xx_board.c     Thu Feb 07 06:51:48 2013 +0000
@@ -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_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 @@
 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_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 @@
                 * 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;
        }
 
diff -r 1471b181ce7d -r 96de45cb34e2 sys/arch/arm/broadcom/bcm53xx_eth.c
--- a/sys/arch/arm/broadcom/bcm53xx_eth.c       Thu Feb 07 01:42:08 2013 +0000
+++ b/sys/arch/arm/broadcom/bcm53xx_eth.c       Thu Feb 07 06:51:48 2013 +0000
@@ -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 @@
 #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 @@
 #define        BCMETH_NRXSEGS          1
 #define        BCMETH_RINGSIZE         PAGE_SIZE
 
-#if 0
+#if 1
 #define        BCMETH_RCVMAGIC         0xfeedface
 #endif
 
@@ -148,6 +147,8 @@
        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 @@
        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_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 @@
                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_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_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_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 @@
        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_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 @@
 #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 @@
                 * 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 @@
                        } while (m);
                } else {



Home | Main Index | Thread Index | Old Index