Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 09 Nov 2004 17:49:42 +0100
From:      Christian Brueffer <chris@unixpages.org>
To:        net@freebsd.org
Subject:   sf(4) device polling
Message-ID:  <20041109164942.GC555@unixpages.org>

next in thread | raw e-mail | index | archive | help

--W5WqUoFLvi1M7tJE
Content-Type: multipart/mixed; boundary="XWOWbaMNXpFDWE00"
Content-Disposition: inline


--XWOWbaMNXpFDWE00
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi,

the attached patch implements device polling for the sf(4) driver.  It
has been running on my home gateway for almost two weeks now, without any
ill effects.

I'd appreciate it, when someone could review/commit this.

- Christian

--=20
Christian Brueffer	chris@unixpages.org	brueffer@FreeBSD.org
GPG Key:	 http://people.freebsd.org/~brueffer/brueffer.key.asc
GPG Fingerprint: A5C8 2099 19FF AACA F41B  B29B 6C76 178C A0ED 982D

--XWOWbaMNXpFDWE00
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sf_polling.diff"
Content-Transfer-Encoding: quoted-printable

Index: pci/if_sf.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /data/ncvs/freebsd/src/sys/pci/if_sf.c,v
retrieving revision 1.72.2.1
diff -u -r1.72.2.1 if_sf.c
--- pci/if_sf.c	2 Sep 2004 20:57:40 -0000	1.72.2.1
+++ pci/if_sf.c	9 Nov 2004 16:45:24 -0000
@@ -164,6 +164,12 @@
 static int sf_miibus_readreg	(device_t, int, int);
 static int sf_miibus_writereg	(device_t, int, int, int);
 static void sf_miibus_statchg	(device_t);
+#ifdef DEVICE_POLLING
+static void sf_poll		(struct ifnet *ifp, enum poll_cmd cmd,
+				 int count);
+static void sf_poll_locked	(struct ifnet *ifp, enum poll_cmd cmd,
+				 int count);
+#endif
=20
 static u_int32_t csr_read_4	(struct sf_softc *, int);
 static void csr_write_4		(struct sf_softc *, int, u_int32_t);
@@ -534,6 +540,10 @@
 		mii =3D device_get_softc(sc->sf_miibus);
 		error =3D ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
+	case SIOCSIFCAP:
+		ifp->if_capenable &=3D ~IFCAP_POLLING;
+		ifp->if_capenable |=3D ifr->ifr_reqcap & IFCAP_POLLING;
+		break;
 	default:
 		error =3D ether_ioctl(ifp, command, data);
 		break;
@@ -714,6 +724,10 @@
 	ifp->if_init =3D sf_init;
 	ifp->if_baudrate =3D 10000000;
 	ifp->if_snd.ifq_maxlen =3D SF_TX_DLIST_CNT - 1;
+#ifdef DEVICE_POLLING
+	ifp->if_capabilities |=3D IFCAP_POLLING;
+#endif
+	ifp->if_capenable =3D ifp->if_capabilities;
=20
 	/*
 	 * Call MI attach routine.
@@ -903,6 +917,14 @@
 	while (cmpconsidx !=3D cmpprodidx) {
 		struct mbuf		*m0;
=20
+#ifdef DEVICE_POLLING
+		if (ifp->if_flags & IFF_POLLING) {
+			if (sc->rxcycles <=3D 0)
+				break;
+			sc->rxcycles--;
+		}
+#endif
+
 		cur_rx =3D &sc->sf_ldata->sf_rx_clist[cmpconsidx];
 		desc =3D &sc->sf_ldata->sf_rx_dlist_big[cur_rx->sf_endidx];
 		m =3D desc->sf_mbuf;
@@ -1010,6 +1032,58 @@
 	}
 }
=20
+#ifdef DEVICE_POLLING
+static void
+sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+	struct sf_softc *sc =3D ifp->if_softc;
+
+	SF_LOCK(sc);
+	sf_poll_locked(ifp, cmd, count);
+	SF_UNLOCK(sc);
+}
+
+static void
+sf_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+	struct sf_softc *sc =3D ifp->if_softc;
+
+	SF_LOCK_ASSERT(sc);
+
+	if (!(ifp->if_capenable & IFCAP_POLLING)) {
+		ether_poll_deregister(ifp);
+		cmd =3D POLL_DEREGISTER;
+	}
+
+	if (cmd =3D=3D POLL_DEREGISTER) {
+		/* Final call, enable interrupts. */
+		csr_write_4(sc, SF_IMR, SF_INTRS);
+		return;
+	}
+
+	sc->rxcycles =3D count;
+	sf_rxeof(sc);
+	sf_txeof(sc);
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd));
+		sf_start(ifp);
+
+	if (cmd =3D=3D POLL_AND_CHECK_STATUS) {
+		uint16_t status;
+	=09
+		status =3D csr_read_4(sc, SF_ISR);
+
+		if (!status)
+			return;
+	=09
+		/* ACK what we have. */
+		csr_write_4(sc, SF_ISR, status);
+
+		if ((status & SF_INTRS) =3D=3D 0)
+			return;
+	}
+}
+#endif
+
 static void
 sf_intr(arg)
 	void			*arg;
@@ -1023,6 +1097,19 @@
=20
 	ifp =3D &sc->arpcom.ac_if;
=20
+#ifdef DEVICE_POLLING
+	if (ifp->if_flags & IFF_POLLING)
+		goto done_locked;
+
+	if ((ifp->if_capenable & IFCAP_POLLING) &&
+	    ether_poll_register(sf_poll, ifp)) {
+		/* OK, disable interrupts. */
+		csr_write_4(sc, SF_IMR, 0x00000000);
+		sf_poll_locked(ifp, 0, 1);
+		goto done_locked;
+	}
+#endif
+
 	if (!(csr_read_4(sc, SF_ISR_SHADOW) & SF_ISR_PCIINT_ASSERTED)) {
 		SF_UNLOCK(sc);
 		return;
@@ -1066,6 +1153,7 @@
 	if (ifp->if_snd.ifq_head !=3D NULL)
 		sf_start(ifp);
=20
+done_locked:
 	SF_UNLOCK(sc);
 }
=20
@@ -1163,6 +1251,13 @@
 	/* Enable autopadding of short TX frames. */
 	SF_SETBIT(sc, SF_MACCFG_1, SF_MACCFG1_AUTOPAD);
=20
+#ifdef DEVICE_POLLING
+	/* Disable interrupts if we are polling */
+	if (ifp->if_flags & IFF_POLLING)
+		csr_write_4(sc, SF_IMR, 0x00000000);
+	else
+#endif
+
 	/* Enable interrupts. */
 	csr_write_4(sc, SF_IMR, SF_INTRS);
 	SF_SETBIT(sc, SF_PCI_DEVCFG, SF_PCIDEVCFG_INTR_ENB);
@@ -1339,6 +1434,10 @@
=20
 	untimeout(sf_stats_update, sc, sc->sf_stat_ch);
=20
+#ifdef DEVICE_POLLING
+	ether_poll_deregister(ifp);
+#endif
+=09
 	csr_write_4(sc, SF_GEN_ETH_CTL, 0);
 	csr_write_4(sc, SF_CQ_CONSIDX, 0);
 	csr_write_4(sc, SF_CQ_PRODIDX, 0);
Index: pci/if_sfreg.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /data/ncvs/freebsd/src/sys/pci/if_sfreg.h,v
retrieving revision 1.10
diff -u -r1.10 if_sfreg.h
--- pci/if_sfreg.h	14 Nov 2003 19:00:31 -0000	1.10
+++ pci/if_sfreg.h	9 Nov 2004 16:45:33 -0000
@@ -1046,6 +1046,9 @@
 	int			sf_if_flags;
 	struct callout_handle	sf_stat_ch;
 	struct mtx		sf_mtx;
+#ifdef DEVICE_POLLING
+	int			rxcycles;
+#endif
 };
=20
=20

--XWOWbaMNXpFDWE00--

--W5WqUoFLvi1M7tJE
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (FreeBSD)

iD8DBQFBkPUmbHYXjKDtmC0RAnkkAKD81hFQlJXBM8I4niXDPY6m/UXIgQCg8iyb
j7Jteuu4X6qmFHCNZEHEHnU=
=oh88
-----END PGP SIGNATURE-----

--W5WqUoFLvi1M7tJE--



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