From owner-svn-src-all@FreeBSD.ORG Mon Feb 1 19:28:44 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 45256106568F; Mon, 1 Feb 2010 19:28:44 +0000 (UTC) (envelope-from jfv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 348DC8FC13; Mon, 1 Feb 2010 19:28:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o11JSiAb050726; Mon, 1 Feb 2010 19:28:44 GMT (envelope-from jfv@svn.freebsd.org) Received: (from jfv@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o11JSihs050723; Mon, 1 Feb 2010 19:28:44 GMT (envelope-from jfv@svn.freebsd.org) Message-Id: <201002011928.o11JSihs050723@svn.freebsd.org> From: Jack F Vogel Date: Mon, 1 Feb 2010 19:28:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r203354 - head/sys/dev/e1000 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Feb 2010 19:28:44 -0000 Author: jfv Date: Mon Feb 1 19:28:43 2010 New Revision: 203354 URL: http://svn.freebsd.org/changeset/base/203354 Log: A few minor changes: add altq option header, add missing conditional around a buf_ring call that will break 7.3, and thanks to Fabien Thomas add POLLING support for igb and a minor related fix in the em driver. Modified: head/sys/dev/e1000/if_em.c head/sys/dev/e1000/if_igb.c Modified: head/sys/dev/e1000/if_em.c ============================================================================== --- head/sys/dev/e1000/if_em.c Mon Feb 1 18:27:19 2010 (r203353) +++ head/sys/dev/e1000/if_em.c Mon Feb 1 19:28:43 2010 (r203354) @@ -35,6 +35,7 @@ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" #include "opt_inet.h" +#include "opt_altq.h" #endif #include @@ -1545,13 +1546,13 @@ em_poll(struct ifnet *ifp, enum poll_cmd if (cmd == POLL_AND_CHECK_STATUS) { reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + /* Link status change */ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - callout_stop(&adapter->timer); adapter->hw.mac.get_link_status = 1; em_update_link_status(adapter); - callout_reset(&adapter->timer, hz, - em_local_timer, adapter); } + if (reg_icr & E1000_ICR_RXO) + adapter->rx_overruns++; } EM_CORE_UNLOCK(adapter); Modified: head/sys/dev/e1000/if_igb.c ============================================================================== --- head/sys/dev/e1000/if_igb.c Mon Feb 1 18:27:19 2010 (r203353) +++ head/sys/dev/e1000/if_igb.c Mon Feb 1 19:28:43 2010 (r203354) @@ -36,6 +36,7 @@ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" #include "opt_inet.h" +#include "opt_altq.h" #endif #include @@ -250,6 +251,10 @@ static void igb_handle_link(void *contex static void igb_msix_que(void *); static void igb_msix_link(void *); +#ifdef DEVICE_POLLING +static poll_handler_t igb_poll; +#endif /* POLLING */ + /********************************************************************* * FreeBSD Device Interface Entry Points *********************************************************************/ @@ -624,6 +629,11 @@ igb_detach(device_t dev) return (EBUSY); } +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) + ether_poll_deregister(ifp); +#endif + IGB_CORE_LOCK(adapter); adapter->in_detach = 1; igb_stop(adapter); @@ -974,6 +984,9 @@ igb_ioctl(struct ifnet *ifp, u_long comm IGB_CORE_LOCK(adapter); igb_disable_intr(adapter); igb_set_multi(adapter); +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif igb_enable_intr(adapter); IGB_CORE_UNLOCK(adapter); } @@ -1000,6 +1013,26 @@ igb_ioctl(struct ifnet *ifp, u_long comm IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)"); reinit = 0; mask = ifr->ifr_reqcap ^ ifp->if_capenable; +#ifdef DEVICE_POLLING + if (mask & IFCAP_POLLING) { + if (ifr->ifr_reqcap & IFCAP_POLLING) { + error = ether_poll_register(igb_poll, ifp); + if (error) + return (error); + IGB_CORE_LOCK(adapter); + igb_disable_intr(adapter); + ifp->if_capenable |= IFCAP_POLLING; + IGB_CORE_UNLOCK(adapter); + } else { + error = ether_poll_deregister(ifp); + /* Enable interrupt even in error case */ + IGB_CORE_LOCK(adapter); + igb_enable_intr(adapter); + ifp->if_capenable &= ~IFCAP_POLLING; + IGB_CORE_UNLOCK(adapter); + } + } +#endif if (mask & IFCAP_HWCSUM) { ifp->if_capenable ^= IFCAP_HWCSUM; reinit = 1; @@ -1123,8 +1156,19 @@ igb_init_locked(struct adapter *adapter) /* this clears any pending interrupts */ E1000_READ_REG(&adapter->hw, E1000_ICR); +#ifdef DEVICE_POLLING + /* + * Only enable interrupts if we are not polling, make sure + * they are off otherwise. + */ + if (ifp->if_capenable & IFCAP_POLLING) + igb_disable_intr(adapter); + else +#endif /* DEVICE_POLLING */ + { igb_enable_intr(adapter); E1000_WRITE_REG(&adapter->hw, E1000_ICS, E1000_ICS_LSC); + } /* Don't reset the phy next time init gets called */ adapter->hw.phy.reset_disable = TRUE; @@ -1201,6 +1245,9 @@ igb_handle_que(void *context, int pendin } /* Reenable this interrupt */ +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims); } @@ -1257,6 +1304,63 @@ igb_irq_fast(void *arg) return FILTER_HANDLED; } +#ifdef DEVICE_POLLING +/********************************************************************* + * + * Legacy polling routine + * + *********************************************************************/ +#if __FreeBSD_version >= 800000 +#define POLL_RETURN_COUNT(a) (a) +static int +#else +#define POLL_RETURN_COUNT(a) +static void +#endif +igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct adapter *adapter = ifp->if_softc; + struct rx_ring *rxr = adapter->rx_rings; + struct tx_ring *txr = adapter->tx_rings; + u32 reg_icr, rx_done = 0; + u32 loop = IGB_MAX_LOOP; + bool more; + + IGB_CORE_LOCK(adapter); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + IGB_CORE_UNLOCK(adapter); + return POLL_RETURN_COUNT(rx_done); + } + + if (cmd == POLL_AND_CHECK_STATUS) { + reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + /* Link status change */ + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) + taskqueue_enqueue(adapter->tq, &adapter->link_task); + + if (reg_icr & E1000_ICR_RXO) + adapter->rx_overruns++; + } + IGB_CORE_UNLOCK(adapter); + + /* TODO: rx_count */ + rx_done = igb_rxeof(rxr, count) ? 1 : 0; + + IGB_TX_LOCK(txr); + do { + more = igb_txeof(txr); + } while (loop-- && more); +#if __FreeBSD_version >= 800000 + if (!drbr_empty(ifp, txr->br)) + igb_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); +#endif + IGB_TX_UNLOCK(txr); + return POLL_RETURN_COUNT(rx_done); +} +#endif /* DEVICE_POLLING */ /********************************************************************* * @@ -1783,6 +1887,9 @@ igb_local_timer(void *arg) } /* Trigger an RX interrupt on all queues */ +#ifdef DEVICE_POLLING + if (!(ifp->if_capenable & IFCAP_POLLING)) +#endif E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->rx_mask); callout_reset(&adapter->timer, hz, igb_local_timer, adapter); return; @@ -2544,6 +2651,9 @@ igb_setup_interface(device_t dev, struct ifp->if_capabilities |= IFCAP_LRO; ifp->if_capenable = ifp->if_capabilities; +#ifdef DEVICE_POLLING + ifp->if_capabilities |= IFCAP_POLLING; +#endif /* * Tell the upper layer(s) we support long frames. @@ -2808,7 +2918,9 @@ err_tx_desc: igb_dma_free(adapter, &txr->txdma); free(adapter->rx_rings, M_DEVBUF); rx_fail: +#if __FreeBSD_version >= 800000 buf_ring_free(txr->br, M_DEVBUF); +#endif free(adapter->tx_rings, M_DEVBUF); tx_fail: free(adapter->queues, M_DEVBUF);