Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Oct 2009 02:35:57 GMT
From:      Yohanes Nugroho <yohanes@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 169170 for review
Message-ID:  <200910030235.n932ZvIp026096@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910030235.n932ZvIp026096>