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().
This commit is contained in:
tsutsui 2003-11-08 16:08:13 +00:00
parent addcf5d254
commit 1fafd3e354
3 changed files with 51 additions and 60 deletions

View File

@ -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 <sys/cdefs.h>
__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);
}

View File

@ -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

View File

@ -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 *));