From owner-freebsd-bugs Fri Jun 28 18:51:25 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AAFEE37B401 for ; Fri, 28 Jun 2002 18:50:08 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7F45543E06 for ; Fri, 28 Jun 2002 18:50:07 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.4/8.12.4) with ESMTP id g5T1o7JU066025 for ; Fri, 28 Jun 2002 18:50:07 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g5T1o7n4066024; Fri, 28 Jun 2002 18:50:07 -0700 (PDT) Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5DFD637B400 for ; Fri, 28 Jun 2002 18:48:41 -0700 (PDT) Received: from atropos.snu.ac.kr (atropos.snu.ac.kr [147.46.106.37]) by mx1.FreeBSD.org (Postfix) with ESMTP id 762CE43E06 for ; Fri, 28 Jun 2002 18:48:40 -0700 (PDT) (envelope-from redjade@atropos.snu.ac.kr) Received: (from redjade@localhost) by atropos.snu.ac.kr (8.11.6/8.11.6) id g5T1mc006475; Sat, 29 Jun 2002 10:48:38 +0900 (KST) Message-Id: <20020629104838.A6435@atropos.snu.ac.kr> Date: Sat, 29 Jun 2002 10:48:38 +0900 From: Kyunghwan Kim Reply-To: Kyunghwan Kim To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/39977: Device polling support for em(4) driver Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 39977 >Category: kern >Synopsis: Device polling support for em(4) driver >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Jun 28 18:50:06 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Kyunghwan Kim >Release: FreeBSD 5.0-CURRENT i386 >Organization: Web Data Bank, Inc. >Environment: System: FreeBSD genomy.wdb.co.kr 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Tue Apr 9 15:40:58 KST 2002 root@genomy.wdb.co.kr:/usr/src/sys/i386/compile/GENOMY i386 >Description: Device polling support for em(4) driver. >How-To-Repeat: nothing >Fix: Don't mind the revision numbers, these are in local cvs. patch against -CURRENT today(20020629): Index: if_em.c =================================================================== RCS file: /data/cvs/em/if_em.c,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -u -r1.11 -r1.11.2.1 --- if_em.c 2002/06/21 09:13:34 1.11 +++ if_em.c 2002/06/28 09:49:27 1.11.2.1 @@ -143,6 +143,9 @@ static int em_get_buf(struct em_rx_buffer *, struct adapter *, struct mbuf *); static void em_enable_vlans(struct adapter *adapter); +#ifdef DEVICE_POLLING +static poll_handler_t em_poll; +#endif /* DEVICE_POLLING */ /********************************************************************* * FreeBSD Device Interface Entry Points @@ -631,6 +634,11 @@ em_set_multi(adapter); if (adapter->hw.mac_type == em_82542_rev2_0) em_initialize_receive_unit(adapter); +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + break; + else +#endif /* DEVICE_POLLING */ em_enable_intr(adapter); } break; @@ -919,6 +927,11 @@ adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz); em_clear_hw_cntrs(&adapter->hw); +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + em_disable_intr(adapter); + else +#endif /* DEVICE_POLLING */ em_enable_intr(adapter); splx(s); @@ -951,6 +964,9 @@ /* Tell the stack that the interface is no longer active */ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); +#ifdef DEVICE_POLLING + ether_poll_deregister(ifp); +#endif /* DEVICE_POLLING */ return; } @@ -970,6 +986,17 @@ ifp = &adapter->interface_data.ac_if; +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + return; + + if (ether_poll_register(em_poll, ifp)) { + em_disable_intr(adapter); + em_poll(ifp, 0, 1); + return; + } +#endif /* DEVICE_POLLING */ + em_disable_intr(adapter); while (loop_cnt > 0 && (reg_icr = E1000_READ_REG(&adapter->hw, ICR)) != 0) { @@ -1892,6 +1919,13 @@ } while (current_desc->status & E1000_RXD_STAT_DD) { +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) { + if (adapter->rxcycles <= 0) + break; + adapter->rxcycles--; + } +#endif /* DEVICE_POLLING */ /* Get a pointer to the actual receive buffer */ rx_buffer = STAILQ_FIRST(&adapter->rx_buffer_list); @@ -2366,3 +2400,45 @@ return; } +#ifdef DEVICE_POLLING +static void +em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct adapter *adapter = ifp->if_softc; + u_int32_t loop_cnt = EM_MAX_INTR; + u_int32_t reg_icr; + + if (cmd == POLL_DEREGISTER) { + em_enable_intr(adapter); + return; + } + + adapter->rxcycles = count; + em_process_receive_interrupts(adapter); + em_clean_transmit_interrupts(adapter); + if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + em_start(ifp); + + if (cmd == POLL_AND_CHECK_STATUS) { + while (loop_cnt > 0 && (reg_icr = E1000_READ_REG(&adapter->hw, + ICR)) != 0) { + /* Link status change */ + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + untimeout(em_local_timer, adapter, + adapter->timer_handle); + adapter->hw.get_link_status = 1; + em_check_for_link(&adapter->hw); + em_print_link_status(adapter); + adapter->timer_handle = timeout(em_local_timer, + adapter, 2*hz); + } + + if (ifp->if_flags & IFF_RUNNING) { + em_process_receive_interrupts(adapter); + em_clean_transmit_interrupts(adapter); + } + loop_cnt--; + } + } +} +#endif /* DEVICE_POLLING */ Index: if_em.h =================================================================== RCS file: /data/cvs/em/if_em.h,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -r1.3 -r1.3.2.1 --- if_em.h 2002/06/21 09:13:35 1.3 +++ if_em.h 2002/06/28 09:49:28 1.3.2.1 @@ -245,6 +245,9 @@ #endif struct em_hw_stats stats; +#ifdef DEVICE_POLLING + int rxcycles; +#endif /* DEVICE_POLLING */ }; #endif /* _EM_H_DEFINED_ */ and patch against -STABLE today(20020629): Index: if_em.c =================================================================== RCS file: /data/cvs/em/if_em.c,v retrieving revision 1.1.1.1.2.1 retrieving revision 1.1.1.1.2.1.2.1 diff -u -r1.1.1.1.2.1 -r1.1.1.1.2.1.2.1 --- if_em.c 2002/06/19 08:28:59 1.1.1.1.2.1 +++ if_em.c 2002/06/28 09:16:36 1.1.1.1.2.1.2.1 @@ -143,6 +143,9 @@ static int em_get_buf __P((struct em_rx_buffer *, struct adapter *, struct mbuf *)); static void em_enable_vlans __P((struct adapter *adapter)); +#ifdef DEVICE_POLLING +static poll_handler_t em_poll; +#endif /* DEVICE_POLLING */ /********************************************************************* * FreeBSD Device Interface Entry Points @@ -631,6 +634,11 @@ em_set_multi(adapter); if (adapter->hw.mac_type == em_82542_rev2_0) em_initialize_receive_unit(adapter); +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + break; + else +#endif /* DEVICE_POLLING */ em_enable_intr(adapter); } break; @@ -919,6 +927,11 @@ adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz); em_clear_hw_cntrs(&adapter->hw); +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + em_disable_intr(adapter); + else +#endif /* DEVICE_POLLING */ em_enable_intr(adapter); splx(s); @@ -951,6 +964,10 @@ /* Tell the stack that the interface is no longer active */ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); +#ifdef DEVICE_POLLING + ether_poll_deregister(ifp); +#endif /* DEVICE_POLLING */ + return; } @@ -970,6 +987,17 @@ ifp = &adapter->interface_data.ac_if; +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + return; + + if (ether_poll_register(em_poll, ifp)) { + em_disable_intr(adapter); + em_poll(ifp, 0, 1); + return; + } +#endif /* DEVICE_POLLING */ + em_disable_intr(adapter); while (loop_cnt > 0 && (reg_icr = E1000_READ_REG(&adapter->hw, ICR)) != 0) { @@ -1892,6 +1920,13 @@ } while (current_desc->status & E1000_RXD_STAT_DD) { +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) { + if (adapter->rxcycles <= 0) + break; + adapter->rxcycles--; + } +#endif /* DEVICE_POLLING */ /* Get a pointer to the actual receive buffer */ rx_buffer = STAILQ_FIRST(&adapter->rx_buffer_list); @@ -2366,3 +2401,45 @@ return; } +#ifdef DEVICE_POLLING +static void +em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct adapter *adapter = ifp->if_softc; + u_int32_t loop_cnt = EM_MAX_INTR; + u_int32_t reg_icr; + + if (cmd == POLL_DEREGISTER) { + em_enable_intr(adapter); + return; + } + + adapter->rxcycles = count; + em_process_receive_interrupts(adapter); + em_clean_transmit_interrupts(adapter); + if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + em_start(ifp); + + if (cmd == POLL_AND_CHECK_STATUS) { + while (loop_cnt > 0 && (reg_icr = E1000_READ_REG(&adapter->hw, + ICR)) != 0) { + /* Link status change */ + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + untimeout(em_local_timer, adapter, + adapter->timer_handle); + adapter->hw.get_link_status = 1; + em_check_for_link(&adapter->hw); + em_print_link_status(adapter); + adapter->timer_handle = timeout(em_local_timer, + adapter, 2*hz); + } + + if (ifp->if_flags & IFF_RUNNING) { + em_process_receive_interrupts(adapter); + em_clean_transmit_interrupts(adapter); + } + loop_cnt--; + } + } +} +#endif /* DEVICE_POLLING */ Index: if_em.h =================================================================== RCS file: /data/cvs/em/if_em.h,v retrieving revision 1.1.1.1.2.1 retrieving revision 1.1.1.1.2.1.2.1 diff -u -r1.1.1.1.2.1 -r1.1.1.1.2.1.2.1 --- if_em.h 2002/06/19 08:29:00 1.1.1.1.2.1 +++ if_em.h 2002/06/28 09:16:37 1.1.1.1.2.1.2.1 @@ -245,6 +245,10 @@ #endif struct em_hw_stats stats; + +#ifdef DEVICE_POLLING + int rxcycles; +#endif /* DEVICE_POLLING */ }; #endif /* _EM_H_DEFINED_ */ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message