From owner-p4-projects@FreeBSD.ORG Thu Jan 12 16:01:03 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id ED55A16A422; Thu, 12 Jan 2006 16:01:02 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B613116A41F for ; Thu, 12 Jan 2006 16:01:02 +0000 (GMT) (envelope-from cognet@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6D42643D45 for ; Thu, 12 Jan 2006 16:01:02 +0000 (GMT) (envelope-from cognet@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k0CG127t014181 for ; Thu, 12 Jan 2006 16:01:02 GMT (envelope-from cognet@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k0CG12lc014178 for perforce@freebsd.org; Thu, 12 Jan 2006 16:01:02 GMT (envelope-from cognet@freebsd.org) Date: Thu, 12 Jan 2006 16:01:02 GMT Message-Id: <200601121601.k0CG12lc014178@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to cognet@freebsd.org using -f From: Olivier Houchard To: Perforce Change Reviews Cc: Subject: PERFORCE change 89554 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Jan 2006 16:01:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=89554 Change 89554 by cognet@cognet on 2006/01/12 16:00:13 - Setup the RX descriptors. - Start an interrupt handler. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/if_ate.c#20 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/if_ate.c#20 (text+ko) ==== @@ -62,6 +62,12 @@ #include "miibus_if.h" #define ATE_MAX_TX_BUFFERS 2 /* We have ping-pong tx buffers */ +#define ATE_MAX_RX_BUFFERS 8 + +typedef struct { + bus_addr_t addr; + int status; +} rx_desc_t; struct ate_softc { @@ -75,7 +81,15 @@ struct callout tick_ch; /* Tick callout */ bus_dma_tag_t mtag; /* bus dma tag for mbufs */ bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS]; + bus_dma_tag_t rxtag; + bus_dmamap_t rx_map[ATE_MAX_RX_BUFFERS]; + bus_dma_tag_t rx_desc_tag; + bus_dmamap_t rx_desc_map; int txcur; /* current tx map pointer */ + struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */ + struct mbuf *rx_mbuf[ATE_MAX_RX_BUFFERS]; /* RX mbufs */ + bus_addr_t rx_desc_phys; + rx_desc_t *rx_descs; // XXX bogus int intr; @@ -212,6 +226,17 @@ return EBUSY; /* XXX */ } +static void +ate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) +{ + struct ate_softc *sc; + + if (error != 0) + return; + sc = (struct ate_softc *)arg; + sc->rx_desc_phys = segs[0].ds_addr; +} + static int ate_activate(device_t dev) { @@ -243,14 +268,65 @@ if (err != 0) goto errout; } - + /* + * Allocate our Rx buffers. This chip has a rx structure that's filled + * in + */ + /* - * Allocate our Rx buffers. This chip has a rx structure that's filled - * in -- later XXX + * Allocate DMA tags and maps for RX. */ + err = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, + BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, MCLBYTES, 0, + busdma_lock_mutex, &sc->sc_mtx, &sc->rxtag); + if (err != 0) + goto errout; + for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) { + err = bus_dmamap_create(sc->rxtag, 0, &sc->rx_map[i]); + if (err != 0) + goto errout; + } + /* Dma TAG and MAP for the rx descriptors. */ + err = bus_dma_tag_create(NULL, sizeof(rx_desc_t), 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + ATE_MAX_RX_BUFFERS * sizeof(rx_desc_t), 1, + ATE_MAX_RX_BUFFERS * sizeof(rx_desc_t), 0, busdma_lock_mutex, + &sc->sc_mtx, &sc->rx_desc_tag); + if (err != 0) + goto errout; + if (bus_dmamem_alloc(sc->rx_desc_tag, (void **)&sc->rx_descs, M_WAITOK, + &sc->rx_desc_map) != 0) + goto errout; + if (bus_dmamap_load(sc->rx_desc_tag, sc->rx_desc_map, + sc->rx_descs, ATE_MAX_RX_BUFFERS * sizeof(rx_desc_t), ate_getaddr, + sc, 0) != 0) + goto errout; + for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) { + bus_dma_segment_t seg; + int nsegs; + + sc->rx_mbuf[i] = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); + sc->rx_mbuf[i]->m_len = sc->rx_mbuf[i]->m_pkthdr.len = + MCLBYTES; + if (bus_dmamap_load_mbuf_sg(sc->rxtag, sc->rx_map[i], + sc->rx_mbuf[i], &seg, &nsegs, 0) != 0) + goto errout; + /* + * For the last buffer, set the wrap bit so the controller + * restarts from the first descriptor. + */ + if (i == ATE_MAX_RX_BUFFERS - 1) + seg.ds_addr |= 1 << 1; + sc->rx_descs[i].addr = seg.ds_addr; + sc->rx_descs[i].status = 0; + bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREWRITE); + } + bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE); + /* Write the descriptor queue address. */ + WR4(sc, ETH_RBQP, sc->rx_desc_phys); return (0); -errout:; +errout: ate_deactivate(dev); return (ENOMEM); } @@ -442,8 +518,86 @@ ate_intr(void *xsc) { struct ate_softc *sc = xsc; + int status; + int i; + + sc->intr++; + status = RD4(sc, ETH_ISR); + if (status == 0) + return; + if (status & ETH_ISR_RCOM) { + bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, + BUS_DMASYNC_POSTREAD); + for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) { + if (sc->rx_descs[i].addr & 1) { + struct mbuf *mb = sc->rx_mbuf[i]; + bus_dma_segment_t seg; + int rx_stat = sc->rx_descs[i].status; + int nsegs; + + bus_dmamap_sync(sc->rxtag, + sc->rx_map[i], BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->rxtag, + sc->rx_map[i]); + /* + * Clear the corresponding bits in RSR. + */ + WR4(sc, ETH_RSR, RD4(sc, ETH_RSR)); + sc->rx_mbuf[i] = m_getcl(M_DONTWAIT, MT_DATA, + M_PKTHDR); + if (!sc->rx_mbuf[i]) { + sc->rx_mbuf[i] = mb; + sc->rx_descs[i].addr &= ~1; + bus_dmamap_sync(sc->rx_desc_tag, + sc->rx_desc_map, + BUS_DMASYNC_PREWRITE); + break; + } + if (bus_dmamap_load_mbuf_sg(sc->rxtag, + sc->rx_map[i], + sc->rx_mbuf[i], &seg, &nsegs, 0) != 0) { + sc->rx_mbuf[i] = mb; + sc->rx_descs[i].addr &= ~1; + bus_dmamap_sync(sc->rx_desc_tag, + sc->rx_desc_map, + BUS_DMASYNC_PREWRITE); + break; + } + /* + * For the last buffer, set the wrap bit so the controller + * restarts from the first descriptor. + */ + if (i == ATE_MAX_RX_BUFFERS - 1) + seg.ds_addr |= 1 << 1; + sc->rx_descs[i].addr = seg.ds_addr; + sc->rx_descs[i].status = 0; + /* Bits 0-10 of the status file == length. */ + mb->m_len = rx_stat & 0x7ff; + (*sc->ifp->if_input)(sc->ifp, mb); + break; - sc->intr++; + + } + } + } + if (status & ETH_ISR_TCOM) { + if (sc->sent_mbuf[0]) + m_freem(sc->sent_mbuf[0]); + if (sc->sent_mbuf[1]) { + if (RD4(sc, ETH_TSR) & ETH_TSR_IDLE) { + m_freem(sc->sent_mbuf[1]); + sc->txcur = 0; + sc->sent_mbuf[0] = sc->sent_mbuf[1] = NULL; + } else { + sc->sent_mbuf[0] = sc->sent_mbuf[1]; + sc->sent_mbuf[1] = NULL; + sc->txcur = 1; + } + } else { + sc->sent_mbuf[0] = NULL; + sc->txcur = 0; + } + } } /* @@ -477,7 +631,7 @@ WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_RMII); #endif - WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE); + WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); /* * Boot loader fills in MAC address. If that's not the case, then @@ -516,7 +670,7 @@ if (ifp->if_drv_flags & IFF_DRV_OACTIVE) return; -outloop:; +outloop: /* XXX ed checks to see if there are buffered packets and an idle * transmitter and kicks something if so. This shouldn't happen * for this device, and I note it here only in passing @@ -545,6 +699,7 @@ goto outloop; } bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txcur], BUS_DMASYNC_PREWRITE); + sc->sent_mbuf[sc->txcur] = m; sc->txcur++; if (sc->txcur >= ATE_MAX_TX_BUFFERS) sc->txcur = 0;