From owner-freebsd-sparc64@FreeBSD.ORG Mon Apr 17 06:28:09 2006 Return-Path: X-Original-To: sparc64@freebsd.org Delivered-To: freebsd-sparc64@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E9AC916A413 for ; Mon, 17 Apr 2006 06:28:09 +0000 (UTC) (envelope-from bel@orel.ru) Received: from mail.orel.ru (relay.orel.ru [213.59.64.76]) by mx1.FreeBSD.org (Postfix) with ESMTP id 275F643D46 for ; Mon, 17 Apr 2006 06:28:08 +0000 (GMT) (envelope-from bel@orel.ru) Received: from [192.168.99.99] (pf1.net.orel.ru [213.59.64.75]) by mail.orel.ru (8.13.4/8.13.4) with ESMTP id k3H6S3BY026602 for ; Mon, 17 Apr 2006 10:28:04 +0400 (MSD) (envelope-from bel@orel.ru) Message-ID: <44433573.70702@orel.ru> Date: Mon, 17 Apr 2006 10:28:03 +0400 From: Andrew Belashov Organization: ORIS User-Agent: Thunderbird 1.5 (X11/20060123) MIME-Version: 1.0 To: sparc64@freebsd.org Content-Type: multipart/mixed; boundary="------------070306050507010000060006" X-Antivirus: Dr.Web (R) for Mail Servers on mail.orel.ru host X-Antivirus-Code: 100000 X-Zombi-Check: on netra2.orel.ru Cc: Subject: Call for testers, hme(4) device polling patch X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Apr 2006 06:28:10 -0000 This is a multi-part message in MIME format. --------------070306050507010000060006 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit There is a patch that needs extensive testing which adds device polling support in hme(4) driver. The patch was tested on U60(two CPUs) and had no problems. If you encounter a panic related with the patch, please let me know.(Don't forget to send your 'backtrace' output.) -- With Best Regards, Andrew Belashov. --------------070306050507010000060006 Content-Type: text/plain; name="hme_polling.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="hme_polling.patch" --- sys/dev/hme/if_hme.c.orig Wed Mar 29 21:09:12 2006 +++ sys/dev/hme/if_hme.c Fri Apr 14 08:36:49 2006 @@ -61,9 +61,21 @@ __FBSDID("$FreeBSD: src/sys/dev/hme/if_h * can be reactivated by setting special link option link0 with ifconfig(8). */ #define HME_CSUM_FEATURES (CSUM_TCP) +#define HME_SEB_STAT_IMASK ( \ + ~(/*HME_SEB_STAT_GOTFRAME | HME_SEB_STAT_SENTFRAME |*/ \ + HME_SEB_STAT_HOSTTOTX | \ + HME_SEB_STAT_RXTOHOST | \ + HME_SEB_STAT_TXALL | \ + HME_SEB_STAT_TXPERR | \ + HME_SEB_STAT_RCNTEXP | \ + HME_SEB_STAT_ALL_ERRORS )) #define HMEDEBUG #define KTR_HME KTR_CT2 /* XXX */ +#ifdef HAVE_KERNEL_OPTION_HEADERS +#include "opt_device_polling.h" +#endif + #include #include #include @@ -113,6 +125,10 @@ static int hme_mac_bitflip(struct hme_so u_int32_t, u_int32_t); static void hme_mifinit(struct hme_softc *); static void hme_setladrf(struct hme_softc *, int); +#ifdef DEVICE_POLLING +static void hme_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); +static void hme_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); +#endif static int hme_mediachange(struct ifnet *); static void hme_mediastatus(struct ifnet *, struct ifmediareq *); @@ -341,8 +357,11 @@ hme_config(struct hme_softc *sc) */ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; + ifp->if_capenable |= ifp->if_capabilities; +#ifdef DEVICE_POLLING + ifp->if_capabilities |= IFCAP_POLLING; +#endif ifp->if_hwassist |= sc->sc_csum_features; - ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; return (0); fail_txdesc: @@ -378,6 +397,10 @@ hme_detach(struct hme_softc *sc) struct ifnet *ifp = sc->sc_ifp; int i; +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) + ether_poll_deregister(ifp); +#endif HME_LOCK(sc); hme_stop(sc); HME_UNLOCK(sc); @@ -756,14 +779,13 @@ hme_init_locked(struct hme_softc *sc) HME_MAC_WRITE_4(sc, HME_MACI_RXSIZE, HME_MAX_FRAMESIZE); /* step 8. Global Configuration & Interrupt Mask */ - HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, - ~(/*HME_SEB_STAT_GOTFRAME | HME_SEB_STAT_SENTFRAME |*/ - HME_SEB_STAT_HOSTTOTX | - HME_SEB_STAT_RXTOHOST | - HME_SEB_STAT_TXALL | - HME_SEB_STAT_TXPERR | - HME_SEB_STAT_RCNTEXP | - HME_SEB_STAT_ALL_ERRORS )); +#ifdef DEVICE_POLLING + /* Disable interrupts if we are polling. */ + if (ifp->if_capenable & IFCAP_POLLING) + HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, 0xffffffff); + else +#endif + HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, HME_SEB_STAT_IMASK); switch (sc->sc_burst) { default: @@ -1267,6 +1289,14 @@ hme_rint(struct hme_softc *sc) if ((flags & HME_XD_OWN) != 0) break; +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) { + if (sc->rxcycles <= 0) + break; + sc->rxcycles--; + } +#endif + progress++; if ((flags & HME_XD_OFL) != 0) { device_printf(sc->sc_dev, "buffer overflow, ri=%d; " @@ -1301,6 +1331,46 @@ hme_eint(struct hme_softc *sc, u_int sta } } +#ifdef DEVICE_POLLING +static void +hme_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct hme_softc *sc = ifp->if_softc; + + HME_LOCK(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + hme_poll_locked(ifp, cmd, count); + HME_UNLOCK(sc); +} + +static void +hme_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct hme_softc *sc = ifp->if_softc; + u_int32_t status; + + HME_LOCK_ASSERT(sc, MA_OWNED); + + sc->rxcycles = count; + + status = HME_SEB_READ_4(sc, HME_SEBI_STAT); + CTR1(KTR_HME, "hme_poll: status %#x", (u_int)status); + + if (cmd == POLL_AND_CHECK_STATUS && + (status & HME_SEB_STAT_ALL_ERRORS) != 0) + hme_eint(sc, status); + + if ((status & HME_SEB_STAT_RXTOHOST) != 0) + hme_rint(sc); + + if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0) + hme_tint(sc); + + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + hme_start_locked(ifp); +} +#endif /* DEVICE_POLLING */ + void hme_intr(void *v) { @@ -1308,6 +1378,12 @@ hme_intr(void *v) u_int32_t status; HME_LOCK(sc); + +#ifdef DEVICE_POLLING + if (sc->sc_ifp->if_capenable & IFCAP_POLLING) + goto done_locked; +#endif + status = HME_SEB_READ_4(sc, HME_SEBI_STAT); CTR1(KTR_HME, "hme_intr: status %#x", (u_int)status); @@ -1319,6 +1395,10 @@ hme_intr(void *v) if ((status & HME_SEB_STAT_RXTOHOST) != 0) hme_rint(sc); + +#ifdef DEVICE_POLLING +done_locked: +#endif HME_UNLOCK(sc); } @@ -1555,12 +1635,39 @@ hme_ioctl(struct ifnet *ifp, u_long cmd, break; case SIOCSIFCAP: HME_LOCK(sc); - ifp->if_capenable = ifr->ifr_reqcap; - if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) + if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) { ifp->if_hwassist = sc->sc_csum_features; - else + ifp->if_capenable |= IFCAP_TXCSUM; + } else { ifp->if_hwassist = 0; + ifp->if_capenable &= ~IFCAP_TXCSUM; + } HME_UNLOCK(sc); +#ifdef DEVICE_POLLING + if (ifr->ifr_reqcap & IFCAP_POLLING && + !(ifp->if_capenable & IFCAP_POLLING)) { + error = ether_poll_register(hme_poll, ifp); + if (error) + return(error); + HME_LOCK(sc); + /* Disable interrupts */ + HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, 0xffffffff); + ifp->if_capenable |= IFCAP_POLLING; + HME_UNLOCK(sc); + return (error); + + } + if (!(ifr->ifr_reqcap & IFCAP_POLLING) && + ifp->if_capenable & IFCAP_POLLING) { + error = ether_poll_deregister(ifp); + /* Enable interrupts. */ + HME_LOCK(sc); + HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, HME_SEB_STAT_IMASK); + ifp->if_capenable &= ~IFCAP_POLLING; + HME_UNLOCK(sc); + return (error); + } +#endif /* DEVICE_POLLING */ break; default: error = ether_ioctl(ifp, cmd, data); --- sys/dev/hme/if_hmevar.h.orig Wed Mar 29 21:09:12 2006 +++ sys/dev/hme/if_hmevar.h Thu Apr 13 08:46:19 2006 @@ -144,6 +144,9 @@ struct hme_softc { int sc_debug; struct mtx sc_lock; +#ifdef DEVICE_POLLING + int rxcycles; +#endif }; #define HME_LOCK(_sc) mtx_lock(&(_sc)->sc_lock) --------------070306050507010000060006--