From 1fafd3e354ac3709934073e5bdb7b5fce72b5797 Mon Sep 17 00:00:00 2001 From: tsutsui Date: Sat, 8 Nov 2003 16:08:13 +0000 Subject: [PATCH] Define all members in TX/RX DMA descriptors as u_int32_t and use proper shift and mask ops since smc83c170 chips access them in 32bit width with proper byteswap mechanism, so that all #if BYTE_ORDER in descriptors can be removed. While here, do some slight optimizations in epic_start() and epic_intr(). --- sys/dev/ic/smc83c170.c | 42 ++++++++++++++------------ sys/dev/ic/smc83c170reg.h | 62 ++++++++++++++++----------------------- sys/dev/ic/smc83c170var.h | 7 ++--- 3 files changed, 51 insertions(+), 60 deletions(-) diff --git a/sys/dev/ic/smc83c170.c b/sys/dev/ic/smc83c170.c index 60b794779888..c8223f0fc17a 100644 --- a/sys/dev/ic/smc83c170.c +++ b/sys/dev/ic/smc83c170.c @@ -1,4 +1,4 @@ -/* $NetBSD: smc83c170.c,v 1.54 2003/11/02 11:07:46 wiz Exp $ */ +/* $NetBSD: smc83c170.c,v 1.55 2003/11/08 16:08:13 tsutsui Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -43,7 +43,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.54 2003/11/02 11:07:46 wiz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.55 2003/11/08 16:08:13 tsutsui Exp $"); #include "bpfilter.h" @@ -371,6 +371,7 @@ epic_start(ifp) struct epic_fraglist *fr; bus_dmamap_t dmamap; int error, firsttx, nexttx, opending, seg; + u_int len; /* * Remember the previous txpending and the first transmit @@ -453,10 +454,11 @@ epic_start(ifp) fr->ef_frags[seg].ef_length = dmamap->dm_segs[seg].ds_len; } - if (m0->m_pkthdr.len < ETHER_PAD_LEN) { + len = m0->m_pkthdr.len; + if (len < ETHER_PAD_LEN) { fr->ef_frags[seg].ef_addr = sc->sc_nulldma; - fr->ef_frags[seg].ef_length = - ETHER_PAD_LEN - m0->m_pkthdr.len; + fr->ef_frags[seg].ef_length = ETHER_PAD_LEN - len; + len = ETHER_PAD_LEN; seg++; } fr->ef_nfrags = seg; @@ -476,7 +478,6 @@ epic_start(ifp) * Fill in the transmit descriptor. */ txd->et_control = ET_TXCTL_LASTDESC | ET_TXCTL_FRAGLIST; - txd->et_txlength = max(m0->m_pkthdr.len, ETHER_PAD_LEN); /* * If this is the first descriptor we're enqueueing, @@ -484,9 +485,10 @@ epic_start(ifp) * a race condition. We'll do it below. */ if (nexttx == firsttx) - txd->et_txstatus = 0; + txd->et_txstatus = TXSTAT_TXLENGTH(len); else - txd->et_txstatus = ET_TXSTAT_OWNER; + txd->et_txstatus = + TXSTAT_TXLENGTH(len) | ET_TXSTAT_OWNER; EPIC_CDTXSYNC(sc, nexttx, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); @@ -529,7 +531,7 @@ epic_start(ifp) * The entire packet chain is set up. Give the * first descriptor to the EPIC now. */ - EPIC_CDTX(sc, firsttx)->et_txstatus = ET_TXSTAT_OWNER; + EPIC_CDTX(sc, firsttx)->et_txstatus |= ET_TXSTAT_OWNER; EPIC_CDTXSYNC(sc, firsttx, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); @@ -612,7 +614,7 @@ epic_intr(arg) struct epic_txdesc *txd; struct epic_descsoft *ds; struct mbuf *m; - u_int32_t intstat; + u_int32_t intstat, rxstatus, txstatus; int i, claimed = 0; u_int len; @@ -643,7 +645,8 @@ epic_intr(arg) EPIC_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - if (rxd->er_rxstatus & ER_RXSTAT_OWNER) { + rxstatus = rxd->er_rxstatus; + if (rxstatus & ER_RXSTAT_OWNER) { /* * We have processed all of the * receive buffers. @@ -657,11 +660,11 @@ epic_intr(arg) * The buffer will be reused the next time the * descriptor comes up in the ring. */ - if ((rxd->er_rxstatus & ER_RXSTAT_PKTINTACT) == 0) { - if (rxd->er_rxstatus & ER_RXSTAT_CRCERROR) + if ((rxstatus & ER_RXSTAT_PKTINTACT) == 0) { + if (rxstatus & ER_RXSTAT_CRCERROR) printf("%s: CRC error\n", sc->sc_dev.dv_xname); - if (rxd->er_rxstatus & ER_RXSTAT_ALIGNERROR) + if (rxstatus & ER_RXSTAT_ALIGNERROR) printf("%s: alignment error\n", sc->sc_dev.dv_xname); ifp->if_ierrors++; @@ -675,7 +678,7 @@ epic_intr(arg) /* * The EPIC includes the CRC with every packet. */ - len = rxd->er_rxlength; + len = RXSTAT_RXLENGTH(rxstatus); if (len < sizeof(struct ether_header)) { /* @@ -775,7 +778,8 @@ epic_intr(arg) EPIC_CDTXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); - if (txd->et_txstatus & ET_TXSTAT_OWNER) + txstatus = txd->et_txstatus; + if (txstatus & ET_TXSTAT_OWNER) break; EPIC_CDFLSYNC(sc, i, BUS_DMASYNC_POSTWRITE); @@ -790,13 +794,13 @@ epic_intr(arg) /* * Check for errors and collisions. */ - if ((txd->et_txstatus & ET_TXSTAT_PACKETTX) == 0) + if ((txstatus & ET_TXSTAT_PACKETTX) == 0) ifp->if_oerrors++; else ifp->if_opackets++; ifp->if_collisions += - TXSTAT_COLLISIONS(txd->et_txstatus); - if (txd->et_txstatus & ET_TXSTAT_CARSENSELOST) + TXSTAT_COLLISIONS(txstatus); + if (txstatus & ET_TXSTAT_CARSENSELOST) printf("%s: lost carrier\n", sc->sc_dev.dv_xname); } diff --git a/sys/dev/ic/smc83c170reg.h b/sys/dev/ic/smc83c170reg.h index a63233d5888b..7f74847b62a3 100644 --- a/sys/dev/ic/smc83c170reg.h +++ b/sys/dev/ic/smc83c170reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: smc83c170reg.h,v 1.8 2003/11/02 11:07:46 wiz Exp $ */ +/* $NetBSD: smc83c170reg.h,v 1.9 2003/11/08 16:08:13 tsutsui Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -49,25 +49,16 @@ * EPIC transmit descriptor. Must be 4-byte aligned. */ struct epic_txdesc { -#if BYTE_ORDER == BIG_ENDIAN - u_int16_t et_txlength; /* transmit length */ - u_int16_t et_txstatus; /* transmit status; see below */ -#else - u_int16_t et_txstatus; /* transmit status; see below */ - u_int16_t et_txlength; /* transmit length */ -#endif + u_int32_t et_txstatus; /* transmit status; see below */ u_int32_t et_bufaddr; /* buffer address */ -#if BYTE_ORDER == BIG_ENDIAN - u_int16_t et_control; /* control word; see below */ - u_int16_t et_buflength; /* buffer length */ -#else - u_int16_t et_buflength; /* buffer length */ - u_int16_t et_control; /* control word; see below */ -#endif + u_int32_t et_control; /* control word; see below */ u_int32_t et_nextdesc; /* next descriptor pointer */ }; /* et_txstatus */ +#define TXSTAT_TXLENGTH_SHIFT 16 /* TX length in higher 16bits */ +#define TXSTAT_TXLENGTH(x) ((x) << TXSTAT_TXLENGTH_SHIFT) + #define ET_TXSTAT_OWNER 0x8000 /* NIC owns descriptor */ #define ET_TXSTAT_COLLMASK 0x1f00 /* collisions */ #define ET_TXSTAT_DEFERRING 0x0080 /* deferring due to jabber */ @@ -82,35 +73,29 @@ struct epic_txdesc { #define TXSTAT_COLLISIONS(x) (((x) & ET_TXSTAT_COLLMASK) >> 8) /* et_control */ -#define ET_TXCTL_LASTDESC 0x0010 /* last descriptor in frame */ -#define ET_TXCTL_NOCRC 0x0008 /* disable CRC generation */ -#define ET_TXCTL_IAF 0x0004 /* interrupt after frame */ -#define ET_TXCTL_LFFORM 0x0002 /* alternate fraglist format */ -#define ET_TXCTL_FRAGLIST 0x0001 /* descriptor points to fraglist */ +#define TXCTL_BUFLENGTH_MASK 0x0000ffff /* buf length in lower 16bits */ +#define TXCTL_BUFLENGTH(x) ((x) & TXCTL_BUFLENGTH_MASK) + +#define ET_TXCTL_LASTDESC 0x00100000 /* last descriptor in frame */ +#define ET_TXCTL_NOCRC 0x00080000 /* disable CRC generation */ +#define ET_TXCTL_IAF 0x00040000 /* interrupt after frame */ +#define ET_TXCTL_LFFORM 0x00020000 /* alternate fraglist format */ +#define ET_TXCTL_FRAGLIST 0x00010000 /* descriptor points to fraglist */ /* * EPIC receive descriptor. Must be 4-byte aligned. */ struct epic_rxdesc { -#if BYTE_ORDER == BIG_ENDIAN - u_int16_t er_rxlength; /* receive frame length */ - u_int16_t er_rxstatus; /* receive status; see below */ -#else - u_int16_t er_rxstatus; /* receive status; see below */ - u_int16_t er_rxlength; /* receive frame length */ -#endif + u_int32_t er_rxstatus; /* receive status; see below */ u_int32_t er_bufaddr; /* buffer address */ -#if BYTE_ORDER == BIG_ENDIAN - u_int16_t er_control; /* control word; see below */ - u_int16_t er_buflength; /* buffer length */ -#else - u_int16_t er_buflength; /* buffer length */ - u_int16_t er_control; /* control word; see below */ -#endif + u_int32_t er_control; /* control word; see below */ u_int32_t er_nextdesc; /* next descriptor pointer */ }; /* er_rxstatus */ +#define RXSTAT_RXLENGTH_SHIFT 16 /* TX length in higher 16bits */ +#define RXSTAT_RXLENGTH(x) ((x) >> RXSTAT_RXLENGTH_SHIFT) + #define ER_RXSTAT_OWNER 0x8000 /* NIC owns descriptor */ #define ER_RXSTAT_HDRCOPIED 0x4000 /* rx status posted after hdr copy */ #define ER_RXSTAT_FRAGLISTERR 0x2000 /* ran out of frags to copy frame */ @@ -124,9 +109,12 @@ struct epic_rxdesc { #define ER_RXSTAT_PKTINTACT 0x0001 /* packet received without error */ /* er_control */ -#define ER_RXCTL_HEADER 0x0004 /* descriptor is for hdr copy */ -#define ER_RXCTL_LFFORM 0x0002 /* alternate fraglist format */ -#define ER_RXCTL_FRAGLIST 0x0001 /* descriptor points to fraglist */ +#define RXCTL_BUFLENGTH_MASK 0x0000ffff /* buf length in lower 16bits */ +#define RXCTL_BUFLENGTH(x) ((x) & RXCTL_BUFLENGTH_MASK) + +#define ER_RXCTL_HEADER 0x00040000 /* descriptor is for hdr copy */ +#define ER_RXCTL_LFFORM 0x00020000 /* alternate fraglist format */ +#define ER_RXCTL_FRAGLIST 0x00010000 /* descriptor points to fraglist */ /* * This is not really part of the register description, but we need diff --git a/sys/dev/ic/smc83c170var.h b/sys/dev/ic/smc83c170var.h index 5695a65ecf98..ac4a3993c1eb 100644 --- a/sys/dev/ic/smc83c170var.h +++ b/sys/dev/ic/smc83c170var.h @@ -1,4 +1,4 @@ -/* $NetBSD: smc83c170var.h,v 1.7 2003/01/13 17:00:18 bouyer Exp $ */ +/* $NetBSD: smc83c170var.h,v 1.8 2003/11/08 16:08:13 tsutsui Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -176,12 +176,11 @@ do { \ */ \ __m->m_data = __m->m_ext.ext_buf + 2; \ __rxd->er_bufaddr = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \ - __rxd->er_buflength = __m->m_ext.ext_size - 2; \ - __rxd->er_control = 0; \ + __rxd->er_control = RXCTL_BUFLENGTH(__m->m_ext.ext_size - 2); \ __rxd->er_rxstatus = ER_RXSTAT_OWNER; \ __rxd->er_nextdesc = EPIC_CDRXADDR((sc), EPIC_NEXTRX((x))); \ EPIC_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ -} while (0) +} while (/* CONSTCOND */ 0) #ifdef _KERNEL void epic_attach __P((struct epic_softc *));