Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Jul 2006 16:16:31 GMT
From:      Paolo Pisati <piso@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 101480 for review
Message-ID:  <200607131616.k6DGGVeg043616@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=101480

Change 101480 by piso@piso_newluxor on 2006/07/13 16:16:08

	Please welcome the first driver converted to use a filter+ithread 
	handler.

Affected files ...

.. //depot/projects/soc2006/intr_filter/dev/bfe/if_bfe.c#3 edit
.. //depot/projects/soc2006/intr_filter/dev/bfe/if_bfereg.h#2 edit

Differences ...

==== //depot/projects/soc2006/intr_filter/dev/bfe/if_bfe.c#3 (text+ko) ====

@@ -88,7 +88,11 @@
 static int  bfe_attach				(device_t);
 static int  bfe_detach				(device_t);
 static void bfe_release_resources	(struct bfe_softc *);
+#if 0
 static void bfe_intr				(void *);
+#endif
+static int  bfe_filter				(void *);
+static void bfe_handler				(void *);
 static void bfe_start				(struct ifnet *);
 static void bfe_start_locked			(struct ifnet *);
 static int  bfe_ioctl				(struct ifnet *, u_long, caddr_t);
@@ -418,8 +422,12 @@
 	/*
 	 * Hook interrupt last to avoid having to lock softc
 	 */
+#if 0
 	error = bus_setup_intr(dev, sc->bfe_irq, INTR_TYPE_NET | INTR_MPSAFE,
 			NULL, bfe_intr, sc, &sc->bfe_intrhand);
+#endif
+	error = bus_setup_intr(dev, sc->bfe_irq, INTR_TYPE_NET | INTR_MPSAFE,
+			bfe_filter, bfe_handler, sc, &sc->bfe_intrhand);
 
 	if (error) {
 		printf("bfe%d: couldn't set up irq\n", unit);
@@ -1182,6 +1190,95 @@
 	sc->bfe_rx_cons = cons;
 }
 
+static int
+bfe_filter(void *xsc)
+{
+	struct bfe_softc *sc = xsc;
+	u_int32_t imask;
+
+	sc->bfe_istat = CSR_READ_4(sc, BFE_ISTAT);
+	imask = CSR_READ_4(sc, BFE_IMASK);
+
+	/*
+	 * Defer unsolicited interrupts - This is necessary because setting the
+	 * chips interrupt mask register to 0 doesn't actually stop the
+	 * interrupts
+	 */
+	sc->bfe_istat &= imask;
+	CSR_WRITE_4(sc, BFE_ISTAT, sc->bfe_istat);
+	CSR_READ_4(sc, BFE_ISTAT);
+
+	/* not expecting this interrupt, disregard it */
+	if(sc->bfe_istat == 0)
+		return (FILTER_STRAY);
+
+	/* disable interrupts - not that it actually does..*/
+	CSR_WRITE_4(sc, BFE_IMASK, 0);
+	CSR_READ_4(sc, BFE_IMASK);
+
+	return (FILTER_SCHEDULE_THREAD);
+}
+
+static void
+bfe_handler(void *xsc)
+{
+	struct bfe_softc *sc = xsc;
+	struct ifnet *ifp;
+	u_int32_t istat, flag;
+
+	ifp = sc->bfe_ifp;
+
+	BFE_LOCK(sc);
+
+	istat = sc->bfe_istat;
+	if(istat & BFE_ISTAT_ERRORS) {
+
+		if (istat & BFE_ISTAT_DSCE) {
+			printf("if_bfe Descriptor Error\n");
+			bfe_stop(sc);
+			BFE_UNLOCK(sc);
+			return;
+		}
+
+		if (istat & BFE_ISTAT_DPE) {
+			printf("if_bfe Descriptor Protocol Error\n");
+			bfe_stop(sc);
+			BFE_UNLOCK(sc);
+			return;
+		}
+		
+		flag = CSR_READ_4(sc, BFE_DMATX_STAT);
+		if(flag & BFE_STAT_EMASK)
+			ifp->if_oerrors++;
+
+		flag = CSR_READ_4(sc, BFE_DMARX_STAT);
+		if(flag & BFE_RX_FLAG_ERRORS)
+			ifp->if_ierrors++;
+
+		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+		bfe_init_locked(sc);
+	}
+
+	/* A packet was received */
+	if(istat & BFE_ISTAT_RX)
+		bfe_rxeof(sc);
+
+	/* A packet was sent */
+	if(istat & BFE_ISTAT_TX)
+		bfe_txeof(sc);
+
+	/* We have packets pending, fire them out */
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		bfe_start_locked(ifp);
+
+	BFE_UNLOCK(sc);	
+
+	/* Enable interrupts */
+	CSR_WRITE_4(sc, BFE_IMASK, BFE_IMASK_DEF);
+}
+
+#if 0
 static void
 bfe_intr(void *xsc)
 {
@@ -1254,6 +1351,7 @@
 
 	BFE_UNLOCK(sc);
 }
+#endif
 
 static int
 bfe_encap(struct bfe_softc *sc, struct mbuf **m_head, u_int32_t *txidx)

==== //depot/projects/soc2006/intr_filter/dev/bfe/if_bfereg.h#2 (text+ko) ====

@@ -510,6 +510,7 @@
     struct bfe_data         bfe_tx_ring[BFE_TX_LIST_CNT]; /* XXX */
     struct bfe_data         bfe_rx_ring[BFE_RX_LIST_CNT]; /* XXX */
     struct mtx              bfe_mtx;
+    u_int32_t               bfe_istat;
     u_int32_t               bfe_flags;
     u_int32_t               bfe_imask;
     u_int32_t               bfe_dma_offset;



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