From owner-p4-projects@FreeBSD.ORG Sat Oct 3 02:35:59 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 69DC910656A5; Sat, 3 Oct 2009 02:35:59 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 047941065693 for ; Sat, 3 Oct 2009 02:35:59 +0000 (UTC) (envelope-from yohanes@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id E5F828FC1B for ; Sat, 3 Oct 2009 02:35:58 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n932Zvo4026098 for ; Sat, 3 Oct 2009 02:35:57 GMT (envelope-from yohanes@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n932ZvIp026096 for perforce@freebsd.org; Sat, 3 Oct 2009 02:35:57 GMT (envelope-from yohanes@FreeBSD.org) Date: Sat, 3 Oct 2009 02:35:57 GMT Message-Id: <200910030235.n932ZvIp026096@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to yohanes@FreeBSD.org using -f From: Yohanes Nugroho To: Perforce Change Reviews Cc: Subject: PERFORCE change 169170 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: Sat, 03 Oct 2009 02:35:59 -0000 http://perforce.freebsd.org/chv.cgi?CH=169170 Change 169170 by yohanes@econa on 2009/10/03 02:35:46 not stopping DMA, using interrupt for cleanup Affected files ... .. //depot/projects/str91xx/src/sys/arm/conf/CNS11XXNAS#4 edit .. //depot/projects/str91xx/src/sys/arm/econa/econa_machdep.c#4 edit .. //depot/projects/str91xx/src/sys/arm/econa/if_ece.c#5 edit .. //depot/projects/str91xx/src/sys/arm/econa/timer.c#4 edit Differences ... ==== //depot/projects/str91xx/src/sys/arm/conf/CNS11XXNAS#4 (text+ko) ==== @@ -52,7 +52,8 @@ #options COMPAT_FREEBSD7 -options SCHED_ULE #ULE scheduler +#options SCHED_ULE #ULE scheduler +options SCHED_4BSD #4BSD scheduler options GEOM_PART_GPT # GUID Partition Tables. #options GEOM_PART_EBR #options GEOM_PART_EBR_COMPAT @@ -106,7 +107,7 @@ #options ARM_USE_SMALL_ALLOC device usb -options USB_DEBUG +#options USB_DEBUG device ohci device ehci device umass ==== //depot/projects/str91xx/src/sys/arm/econa/econa_machdep.c#4 (text+ko) ==== @@ -201,7 +201,7 @@ boot_arg1 = arg; boot_arg2 = arg2; boothowto = RB_VERBOSE; - //boothowto |= RB_SINGLE; + boothowto |= RB_SINGLE; set_cpufuncs(); lastaddr = fake_preload_metadata(); ==== //depot/projects/str91xx/src/sys/arm/econa/if_ece.c#5 (text+ko) ==== @@ -79,6 +79,7 @@ struct mtx sc_mtx; /* global mutex */ struct mtx sc_mtx_tx; /* tx mutex */ struct mtx sc_mtx_rx; /* rx mutex */ + struct mtx sc_mtx_cleanup; /* rx mutex */ bus_dma_tag_t sc_parent_tag; /* parent bus DMA tag */ @@ -86,11 +87,13 @@ device_t miibus; /* My child miibus */ void *intrhand; /* Interrupt handle */ void *intrhand_qf; /* Interrupt handle: queue full */ + void *intrhand_tx; /* Interrupt handle: queue full */ void *intrhand_status; /* Interrupt handle */ - struct resource *irq_res_rec; /* IRQ resource */ - struct resource *irq_res_qf; /* IRQ resource */ - struct resource *irq_res_status; /* IRQ resource */ + struct resource *irq_res_tx; /* transmit */ + struct resource *irq_res_rec; /* receive */ + struct resource *irq_res_qf; /* queue full */ + struct resource *irq_res_status; /* status */ struct resource *mem_res; /* Memory resource */ @@ -131,6 +134,7 @@ struct taskqueue *sc_tq; struct task sc_intr_task; + struct task sc_cleanup_task; struct task sc_tx_task; }; @@ -212,6 +216,14 @@ mtx_init(&_sc->sc_mtx_tx, device_get_nameunit(_sc->dev), \ "ECE TX Lock", MTX_DEF) + +#define ECE_CLEANUPLOCK(_sc) mtx_lock(&(_sc)->sc_mtx_cleanup) +#define ECE_CLEANUPUNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx_cleanup) +#define ECE_CLEANUPLOCK_INIT(_sc) \ + mtx_init(&_sc->sc_mtx_cleanup, device_get_nameunit(_sc->dev), \ + "ECE cleanup Lock", MTX_DEF) + + #define ECE_RXLOCK(_sc) mtx_lock(&(_sc)->sc_mtx_rx) #define ECE_RXUNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx_rx) #define ECE_RXLOCK_INIT(_sc) \ @@ -221,6 +233,7 @@ #define ECE_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); #define ECE_TXLOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx_tx); #define ECE_RXLOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx_rx); +#define ECE_CLEANUPLOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx_cleanup); #define ECE_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); #define ECE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); @@ -271,9 +284,13 @@ static void ece_intr_task(void *arg, int pending __unused); static void ece_tx_task(void *arg, int pending __unused); +static void ece_cleanup_task(void *arg, int pending __unused); static int ece_allocate_dma(struct ece_softc *sc); +static void ece_intr_tx(void *xsc); + + static inline int phy_read(struct ece_softc *sc, int phy, int reg) { @@ -289,6 +306,7 @@ for (ii = 0; ii < 0x1000; ii++) { status = RD4(sc, PHY_CONTROL); + DELAY(1); if (status & (0x1 << 15)) { /* clear the rw_ok status, and clear other bits value */ WR4(sc, PHY_CONTROL, (0x1 << 15)); @@ -393,6 +411,13 @@ if (sc->irq_res_rec == NULL) goto out; + // + rid = 1; /*TSTC: Fm-Switch-Tx-Complete*/ + sc->irq_res_tx = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->irq_res_tx == NULL) + goto out; + rid = 0; sc->irq_res_status = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); @@ -488,6 +513,7 @@ TASK_INIT(&sc->sc_intr_task, 0, ece_intr_task, sc); TASK_INIT(&sc->sc_tx_task, 1, ece_tx_task, ifp); + TASK_INIT(&sc->sc_cleanup_task, 2, ece_cleanup_task, sc); sc->sc_tq = taskqueue_create_fast("ece_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->sc_tq); if (sc->sc_tq == NULL) { @@ -517,6 +543,7 @@ ECE_LOCK_DESTROY(sc); goto out; } + err = bus_setup_intr(dev, sc->irq_res_qf, INTR_TYPE_NET | INTR_MPSAFE, NULL,ece_intr_qf, sc, &sc->intrhand_qf); @@ -525,8 +552,21 @@ ECE_LOCK_DESTROY(sc); goto out; } + + + err = bus_setup_intr(dev, sc->irq_res_tx, INTR_TYPE_NET | INTR_MPSAFE, + NULL,ece_intr_tx, sc, &sc->intrhand_tx); + + if (err) { + ether_ifdetach(ifp); + ECE_LOCK_DESTROY(sc); + goto out; + } + + ECE_TXLOCK_INIT(sc); ECE_RXLOCK_INIT(sc); + ECE_CLEANUPLOCK_INIT(sc); DEBUG_TRACE; @@ -1652,9 +1692,69 @@ taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task); } +static void +ece_cleanup_locked(struct ece_softc *sc) +{ + //printf("cleaning up\n"); + int desc_idx; + eth_tx_desc_t *desc; + int start = sc->curr_tx_mbuf - 1; + if (start<0) start = ECE_MAX_TX_BUFFERS-1; + + desc_idx = sc->sent_position[start]; + while (desc_idx!=-1) { + //bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_idx], BUS_DMASYNC_PREREAD); + desc = (eth_tx_desc_t *)&(sc->desc_tx[desc_idx]); + if (desc->cown != 0) { + if (sc->buffer_tx[start]) { + //printf("freeing\n"); + m_freem(sc->buffer_tx[start]); + sc->buffer_tx[start] = 0; + } + sc->sent_position[start] = -1; + start--; + if (start<0) start = ECE_MAX_TX_BUFFERS-1; + desc_idx = sc->sent_position[start]; + } else { + break; + } + } + +} + +static void +ece_cleanup_task(void *arg, int pending __unused) +{ +// printf("ECE INTR TASK"); + struct ece_softc *sc = arg; + //struct ifnet *ifp = sc->ifp; + //printf("cleanup task called\n"); + ECE_CLEANUPLOCK(sc); + //printf("inside lock\n"); + ece_cleanup_locked(sc); + ECE_CLEANUPUNLOCK(sc); +} + static void +ece_intr_tx(void *xsc) +{ + struct ece_softc *sc = xsc; + struct ifnet *ifp = sc->ifp; + //printf("data sent"); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + printf("should not happen, stopping dma"); + /*this should not happen, stop DMA*/ + WR4(sc, FS_DMA_CONTROL, 0); + return; + } + taskqueue_enqueue(sc->sc_tq, &sc->sc_cleanup_task); +} + + + +static void ece_intr_qf(void *xsc) { struct ece_softc *sc = xsc; @@ -1706,7 +1806,7 @@ int seg; int nsegs; int desc_no; - int desc_idx; + //int desc_idx; int start; eth_tx_desc_t *desc = 0; @@ -1767,6 +1867,7 @@ desc->ico = 0; desc->tco = 0; desc->uco = 0; + desc->interrupt = 1; #if 0 if (csum_flags) { @@ -1783,7 +1884,7 @@ } //desc->cown = 0; - desc->interrupt = 0; + //sc->interrupt = 0; desc++; sc->desc_curr_tx = (sc->desc_curr_tx+1) % ECE_MAX_TX_BUFFERS; @@ -1796,7 +1897,7 @@ for (seg = 0; seg < nsegs; seg++) { desc->cown = 0; desc++; - bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_no], BUS_DMASYNC_PREWRITE); + //bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_no], BUS_DMASYNC_PREWRITE); desc_no = (desc_no+1) % ECE_MAX_TX_BUFFERS; if (desc_no==0) { desc = (eth_tx_desc_t *)&(sc->desc_tx[0]); @@ -1806,24 +1907,6 @@ bus_dmamap_sync(sc->dmatag_ring_tx, mapp, BUS_DMASYNC_PREWRITE); - if (start<0) start = ECE_MAX_TX_BUFFERS-1; - - desc_idx = sc->sent_position[start]; - while (desc_idx!=-1) { - //bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_idx], BUS_DMASYNC_PREREAD); - desc = (eth_tx_desc_t *)&(sc->desc_tx[desc_idx]); - if (desc->cown != 0) { - if (sc->buffer_tx[start]) { - m_freem(sc->buffer_tx[start]); - sc->buffer_tx[start] = 0; - - } - sc->sent_position[start] = -1; - start--; - if (start<0) start = ECE_MAX_TX_BUFFERS-1; - desc_idx = sc->sent_position[start]; - } - } return (0); } @@ -1845,7 +1928,7 @@ IFF_DRV_RUNNING) return; - WR4(sc, TS_DMA_CONTROL, 0); + //WR4(sc, TS_DMA_CONTROL, 0); for (;;) { /* Get packet from the queue */ IF_DEQUEUE(&ifp->if_snd, m0); @@ -2032,7 +2115,7 @@ if (phy>0) return 0; //printf("read reg %d phy %d\n", reg, phy); sc = device_get_softc(dev); - + return phy_read(sc, phy, reg); } ==== //depot/projects/str91xx/src/sys/arm/econa/timer.c#4 (text+ko) ==== @@ -51,7 +51,7 @@ unsigned int AHB_clock; unsigned int APB_clock; -unsigned long gettimeoffset(void); + void timer_enable(void); unsigned int str9100_timer_disable(void); unsigned int read_timer_counter(void); @@ -358,50 +358,6 @@ -unsigned long -gettimeoffset(void) -{ - unsigned int ticks1, ticks2; - unsigned int interrupt_status; - u_int savedints; - savedints = disable_interrupts(I32_bit); - - - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks2 = read_timer_counter(); - do { - ticks1 = ticks2; - interrupt_status = read_timer_interrupt_status(); - ticks2 = read_timer_counter(); - } while (ticks2 > ticks1); - - /* - * Number of ticks since last interrupt. - */ - ticks1 = timer_counter - ticks2; - - /* - * Interrupt pending? If so, we've reloaded once already. - */ - if (interrupt_status & - ((1 << TIMER1_MATCH1_INTR_BIT_INDEX) || - (1 << TIMER1_MATCH2_INTR_BIT_INDEX) || - (1 << TIMER1_OVERFLOW_INTR_BIT_INDEX))) { - ticks1 += timer_counter; - } - restore_interrupts(savedints); - /* - * Convert the ticks to usecs - */ - return TICKS2USECS(ticks1); -} - - static unsigned ec_timer_get_timecount(struct timecounter *a) @@ -427,9 +383,9 @@ { sys_clock = 100000000; - printf("System clock %08x", (*(unsigned int *)(0x77000008))); + printf("System clock %08x\n", (*(unsigned int *)(0x77000008))); - printf("Reset conf %08x", (*(unsigned int *)(0x77000014))); + printf("Reset conf %08x\n", (*(unsigned int *)(0x77000014))); switch (((*(unsigned int *)(0x77000014)) >> 6) & 0x3) {