Wed Jan 29 05:54:29 2020 UTC ()
Adopt <net/if_stats.h>.


(thorpej)
diff -r1.21 -r1.22 src/sys/dev/cadence/if_cemac.c

cvs diff -r1.21 -r1.22 src/sys/dev/cadence/if_cemac.c (expand / switch to unified diff)

--- src/sys/dev/cadence/if_cemac.c 2019/05/28 07:41:48 1.21
+++ src/sys/dev/cadence/if_cemac.c 2020/01/29 05:54:29 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_cemac.c,v 1.21 2019/05/28 07:41:48 msaitoh Exp $ */ 1/* $NetBSD: if_cemac.c,v 1.22 2020/01/29 05:54:29 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2015 Genetec Corporation. All rights reserved. 4 * Copyright (c) 2015 Genetec Corporation. All rights reserved.
5 * Written by Hashimoto Kenichi for Genetec Corporation. 5 * Written by Hashimoto Kenichi for Genetec Corporation.
6 * 6 *
7 * Based on arch/arm/at91/at91emac.c 7 * Based on arch/arm/at91/at91emac.c
8 * 8 *
9 * Copyright (c) 2007 Embedtronics Oy 9 * Copyright (c) 2007 Embedtronics Oy
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Copyright (c) 2004 Jesse Off 12 * Copyright (c) 2004 Jesse Off
13 * All rights reserved. 13 * All rights reserved.
14 * 14 *
@@ -30,27 +30,27 @@ @@ -30,27 +30,27 @@
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37/* 37/*
38 * Cadence EMAC/GEM ethernet controller IP driver 38 * Cadence EMAC/GEM ethernet controller IP driver
39 * used by arm/at91, arm/zynq SoC 39 * used by arm/at91, arm/zynq SoC
40 */ 40 */
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.21 2019/05/28 07:41:48 msaitoh Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.22 2020/01/29 05:54:29 thorpej Exp $");
44 44
45#include <sys/types.h> 45#include <sys/types.h>
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/ioctl.h> 48#include <sys/ioctl.h>
49#include <sys/kernel.h> 49#include <sys/kernel.h>
50#include <sys/proc.h> 50#include <sys/proc.h>
51#include <sys/malloc.h> 51#include <sys/malloc.h>
52#include <sys/time.h> 52#include <sys/time.h>
53#include <sys/device.h> 53#include <sys/device.h>
54#include <uvm/uvm_extern.h> 54#include <uvm/uvm_extern.h>
55 55
56#include <sys/bus.h> 56#include <sys/bus.h>
@@ -286,40 +286,41 @@ cemac_intr(void *arg) @@ -286,40 +286,41 @@ cemac_intr(void *arg)
286 ETH_ISR_RBNA | ETH_ISR_ROVR | ETH_ISR_TCOM))) { 286 ETH_ISR_RBNA | ETH_ISR_ROVR | ETH_ISR_TCOM))) {
287 // interrupt not enabled, can't be us 287 // interrupt not enabled, can't be us
288 return 0; 288 return 0;
289 } 289 }
290 290
291 isr = CEMAC_READ(ETH_ISR); 291 isr = CEMAC_READ(ETH_ISR);
292 CEMAC_WRITE(ETH_ISR, isr); 292 CEMAC_WRITE(ETH_ISR, isr);
293 isr &= imr; 293 isr &= imr;
294#ifdef CEMAC_DEBUG 294#ifdef CEMAC_DEBUG
295 rsr = CEMAC_READ(ETH_RSR); // get receive status register 295 rsr = CEMAC_READ(ETH_RSR); // get receive status register
296#endif 296#endif
297 DPRINTFN(2, ("%s: isr=0x%08X rsr=0x%08X imr=0x%08X\n", __FUNCTION__, isr, rsr, imr)); 297 DPRINTFN(2, ("%s: isr=0x%08X rsr=0x%08X imr=0x%08X\n", __FUNCTION__, isr, rsr, imr));
298 298
 299 net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
299 if (isr & ETH_ISR_RBNA) { // out of receive buffers 300 if (isr & ETH_ISR_RBNA) { // out of receive buffers
300 CEMAC_WRITE(ETH_RSR, ETH_RSR_BNA); // clear interrupt 301 CEMAC_WRITE(ETH_RSR, ETH_RSR_BNA); // clear interrupt
301 ctl = CEMAC_READ(ETH_CTL); // get current control register value 302 ctl = CEMAC_READ(ETH_CTL); // get current control register value
302 CEMAC_WRITE(ETH_CTL, ctl & ~ETH_CTL_RE); // disable receiver 303 CEMAC_WRITE(ETH_CTL, ctl & ~ETH_CTL_RE); // disable receiver
303 CEMAC_WRITE(ETH_RSR, ETH_RSR_BNA); // clear BNA bit 304 CEMAC_WRITE(ETH_RSR, ETH_RSR_BNA); // clear BNA bit
304 CEMAC_WRITE(ETH_CTL, ctl | ETH_CTL_RE); // re-enable receiver 305 CEMAC_WRITE(ETH_CTL, ctl | ETH_CTL_RE); // re-enable receiver
305 ifp->if_ierrors++; 306 if_statinc_ref(nsr, if_ierrors);
306 ifp->if_ipackets++; 307 if_statinc_ref(nsr, if_ipackets);
307 DPRINTFN(1,("%s: out of receive buffers\n", __FUNCTION__)); 308 DPRINTFN(1,("%s: out of receive buffers\n", __FUNCTION__));
308 } 309 }
309 if (isr & ETH_ISR_ROVR) { 310 if (isr & ETH_ISR_ROVR) {
310 CEMAC_WRITE(ETH_RSR, ETH_RSR_OVR); // clear interrupt 311 CEMAC_WRITE(ETH_RSR, ETH_RSR_OVR); // clear interrupt
311 ifp->if_ierrors++; 312 if_statinc_ref(nsr, if_ierrors);
312 ifp->if_ipackets++; 313 if_statinc_ref(nsr, if_ipackets);
313 DPRINTFN(1,("%s: receive overrun\n", __FUNCTION__)); 314 DPRINTFN(1,("%s: receive overrun\n", __FUNCTION__));
314 } 315 }
315 316
316 if (isr & ETH_ISR_RCOM) { // packet has been received! 317 if (isr & ETH_ISR_RCOM) { // packet has been received!
317 uint32_t nfo; 318 uint32_t nfo;
318 DPRINTFN(2,("#2 RDSC[%i].INFO=0x%08X\n", sc->rxqi % RX_QLEN, sc->RDSC[sc->rxqi % RX_QLEN].Info)); 319 DPRINTFN(2,("#2 RDSC[%i].INFO=0x%08X\n", sc->rxqi % RX_QLEN, sc->RDSC[sc->rxqi % RX_QLEN].Info));
319 while (sc->RDSC[(bi = sc->rxqi % RX_QLEN)].Addr & ETH_RDSC_F_USED) { 320 while (sc->RDSC[(bi = sc->rxqi % RX_QLEN)].Addr & ETH_RDSC_F_USED) {
320 int fl, csum; 321 int fl, csum;
321 struct mbuf *m; 322 struct mbuf *m;
322 323
323 nfo = sc->RDSC[bi].Info; 324 nfo = sc->RDSC[bi].Info;
324 fl = (nfo & ETH_RDSC_I_LEN) - 4; 325 fl = (nfo & ETH_RDSC_I_LEN) - 4;
325 DPRINTFN(2,("## nfo=0x%08X\n", nfo)); 326 DPRINTFN(2,("## nfo=0x%08X\n", nfo));
@@ -363,32 +364,34 @@ cemac_intr(void *arg) @@ -363,32 +364,34 @@ cemac_intr(void *arg)
363 NULL, BUS_DMA_NOWAIT); 364 NULL, BUS_DMA_NOWAIT);
364 bus_dmamap_sync(sc->sc_dmat, sc->rxq[bi].m_dmamap, 0, 365 bus_dmamap_sync(sc->sc_dmat, sc->rxq[bi].m_dmamap, 0,
365 MCLBYTES, BUS_DMASYNC_PREREAD); 366 MCLBYTES, BUS_DMASYNC_PREREAD);
366 sc->RDSC[bi].Info = 0; 367 sc->RDSC[bi].Info = 0;
367 sc->RDSC[bi].Addr = 368 sc->RDSC[bi].Addr =
368 sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr 369 sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr
369 | (bi == (RX_QLEN-1) ? ETH_RDSC_F_WRAP : 0); 370 | (bi == (RX_QLEN-1) ? ETH_RDSC_F_WRAP : 0);
370 } else { 371 } else {
371 /* Drop packets until we can get replacement 372 /* Drop packets until we can get replacement
372 * empty mbufs for the RXDQ. 373 * empty mbufs for the RXDQ.
373 */ 374 */
374 if (m != NULL) 375 if (m != NULL)
375 m_freem(m); 376 m_freem(m);
376 ifp->if_ierrors++; 377 if_statinc_ref(nsr, if_ierrors);
377 } 378 }
378 sc->rxqi++; 379 sc->rxqi++;
379 } 380 }
380 } 381 }
381 382
 383 IF_STAT_PUTREF(ifp);
 384
382 if (cemac_gctx(sc) > 0) 385 if (cemac_gctx(sc) > 0)
383 if_schedule_deferred_start(ifp); 386 if_schedule_deferred_start(ifp);
384#if 0 // reloop 387#if 0 // reloop
385 irq = CEMAC_READ(IntStsC); 388 irq = CEMAC_READ(IntStsC);
386 if ((irq & (IntSts_RxSQ | IntSts_ECI)) != 0) 389 if ((irq & (IntSts_RxSQ | IntSts_ECI)) != 0)
387 goto begin; 390 goto begin;
388#endif 391#endif
389 392
390 return (1); 393 return (1);
391} 394}
392 395
393 396
394static void 397static void
@@ -709,29 +712,31 @@ cemac_statchg(struct ifnet *ifp) @@ -709,29 +712,31 @@ cemac_statchg(struct ifnet *ifp)
709 break; 712 break;
710 } 713 }
711 CEMAC_WRITE(ETH_CFG, reg); 714 CEMAC_WRITE(ETH_CFG, reg);
712} 715}
713 716
714static void 717static void
715cemac_tick(void *arg) 718cemac_tick(void *arg)
716{ 719{
717 struct cemac_softc* sc = (struct cemac_softc *)arg; 720 struct cemac_softc* sc = (struct cemac_softc *)arg;
718 struct ifnet * ifp = &sc->sc_ethercom.ec_if; 721 struct ifnet * ifp = &sc->sc_ethercom.ec_if;
719 int s; 722 int s;
720 723
721 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 724 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM))
722 ifp->if_collisions += CEMAC_READ(GEM_SCOL) + CEMAC_READ(GEM_MCOL); 725 if_statadd(ifp, if_collisions,
 726 CEMAC_READ(GEM_SCOL) + CEMAC_READ(GEM_MCOL));
723 else 727 else
724 ifp->if_collisions += CEMAC_READ(ETH_SCOL) + CEMAC_READ(ETH_MCOL); 728 if_statadd(ifp, if_collisions,
 729 CEMAC_READ(ETH_SCOL) + CEMAC_READ(ETH_MCOL));
725 730
726 /* These misses are ok, they will happen if the RAM/CPU can't keep up */ 731 /* These misses are ok, they will happen if the RAM/CPU can't keep up */
727 if (!ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) { 732 if (!ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) {
728 uint32_t misses = CEMAC_READ(ETH_DRFC); 733 uint32_t misses = CEMAC_READ(ETH_DRFC);
729 if (misses > 0) 734 if (misses > 0)
730 aprint_normal_ifnet(ifp, "%d rx misses\n", misses); 735 aprint_normal_ifnet(ifp, "%d rx misses\n", misses);
731 } 736 }
732 737
733 s = splnet(); 738 s = splnet();
734 if (cemac_gctx(sc) > 0 && IFQ_IS_EMPTY(&ifp->if_snd) == 0) 739 if (cemac_gctx(sc) > 0 && IFQ_IS_EMPTY(&ifp->if_snd) == 0)
735 cemac_ifstart(ifp); 740 cemac_ifstart(ifp);
736 splx(s); 741 splx(s);
737 742