Add first pass of the Intel Gigabit Ethernet (wiseman) driver. This

driver seems relatively functional, but could use some souping up,
particularly in the performance area. This has both NetBSD and FreeBSD
attachment code and a fair amount of effort has been put into making
it easy to port to different *BSD platforms.

The basic design is a one tfd per mbuf transmit (with no transmit
related interrupts- tfds are gc'd as needed). The receive ring
uses a 2K buffer per rfd with a +2 byte adjust for the ethernet
header (so the payload is aligned). There's support that *almost*
works for doing large packets- the rfd chaining code works, but there's
some problem with getting good checksums at the IP reassembly level
(ditto for doing short tfd's too).

The chip has support for TCP checksums insertion for transmit and
TCP checksum calculation on receive (for both you have to do some
appropriate backoff && twiddling), but this isn't in place.

This is nearly entirely reverse engineered from the released Intel
driver, so there's a lot of "We have to do this but do not know why"
stuff. There is somebody who has the chip specs who works in FreeBSD
but they're being a bit standoffish about even sharing hints which
is somewhat annoying. It's also apparent that all I had to work with
were the first rev boards.

This driver has been lightly tested on intel && alpha, but only
point-to-point. There may be some issues with switches- use of
boot time environment variables that override EEPROM settings
(e.g., 'set wx_ilos=1' which inverts the sense of optical signal
loss) may help with this.

I had this out for review for three weeks, and nobody said anything
negative or positive, ergo, this checkin has no 'reviewed by' field
which I would have preferred.
This commit is contained in:
Matt Jacob 2000-01-04 11:12:42 +00:00
parent 677202cac3
commit 78dda2ae0c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55410
3 changed files with 2551 additions and 0 deletions

1922
sys/pci/if_wx.c Normal file

File diff suppressed because it is too large Load Diff

313
sys/pci/if_wxreg.h Normal file
View File

@ -0,0 +1,313 @@
/*
* Copyright (c) 1999, Traakan Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#define WX_VENDOR_INTEL 0x8086
#define WX_PRODUCT_82452 0x1000
#define WX_MMBA 0x10
#define MWI 0x10 /* Memory Write Invalidate */
/*
* Information about this chipset gathered from a released Intel Linux driver,
* which was clearly a port of an NT driver.
*/
/*
* Various Descriptor Structures.
* These are all in little endian format (for now).
*/
typedef struct {
u_int32_t lowpart;
u_int32_t highpart;
} wxpa_t, wxrp_t;
/*
* Receive Descriptor.
* The base address of a receive descriptor ring must be on a 4KB boundary,
* and they must be allocated in multiples of 8.
*/
typedef struct {
wxpa_t address; /* physical address of buffer */
u_int16_t length;
u_int16_t csum;
u_int8_t status;
u_int8_t errors;
u_int16_t special;
} wxrd_t;
#define RDSTAT_DD 0x1 /* descriptor done */
#define RDSTAT_EOP 0x2 /* end of packet */
#define RDSTAT_RSVD 0x74 /* reserved bits */
#define RDERR_CRC 0x1 /* CRC Error */
#define RDERR_SE 0x2 /* Symbol Error */
#define RDERR_SEQ 0x4 /* Sequence Error */
/*
* Transmit Descriptor
* The base address of a transmit descriptor ring must be on a 4KB boundary,
* and they must be allocated in multiples of 8.
*/
typedef struct {
wxpa_t address;
u_int16_t length;
u_int8_t cso; /* checksum offset */
u_int8_t cmd; /* cmd */
u_int8_t status; /* status */
u_int8_t css; /* checksum start */
u_int16_t special;
} wxtd_t;
#define TXCMD_EOP 0x1 /* last packet */
#define TXCMD_IFCS 0x2 /* insert FCS */
#define TXCMD_IC 0x4 /* insert checksum */
#define TXCMD_RS 0x8 /* report status */
#define TXCMD_RPS 0x10 /* report packet sent */
#define TXCMD_SM 0x20 /* symbol mode */
#define TXCMD_IDE 0x80 /* interrupt delay enable */
#define TXSTS_DD 0x1 /* descriptor done */
#define TXSTS_EC 0x2 /* excess collisions */
#define TXSTS_LC 0x4 /* late collision */
/*
* This device can only be accessed via memory space.
*/
/*
* Register access via offsets.
*/
#define WXREG_DCR 0x00000000
#define WXREG_DSR 0x00000008
#define WXREG_EECDR 0x00000010
#define WXREG_FCAL 0x00000028
#define WXREG_FCAH 0x0000002C
#define WXREG_FCT 0x00000030
#define WXREG_VET 0x00000038
#define WXREG_RAL_BASE 0x00000040
#define WXREG_RAL_LO(x) (WXREG_RAL_BASE + ((x) << 3))
#define WXREG_RAL_HI(x) (WXREG_RAL_LO(x) + 4)
#define WXREG_ICR 0x000000c0
#define WXREG_ICS 0x000000c8
#define WXREG_IMASK 0x000000d0
#define WXREG_IMCLR 0x000000d8
#define WXREG_RCTL 0x00000100
#define WXREG_RDTR0 0x00000108
#define WXREG_RDBA0_LO 0x00000110
#define WXREG_RDBA0_HI 0x00000114
#define WXREG_RDLEN0 0x00000118
#define WXREG_RDH0 0x00000120
#define WXREG_RDT0 0x00000128
#define WXREG_RDTR1 0x00000130
#define WXREG_RDBA1_LO 0x00000138
#define WXREG_RDBA1_HI 0x0000013C
#define WXREG_RDLEN1 0x00000140
#define WXREG_RDH1 0x00000148
#define WXREG_RDT1 0x00000150
#define WXREG_FLOW_RCV_HI 0x00000160
#define WXREG_FLOW_RCV_LO 0x00000168
#define WXREG_FLOW_XTIMER 0x00000170
#define WXREG_XMIT_CFGW 0x00000178
#define WXREG_RECV_CFGW 0x00000180
#define WXREG_MTA 0x00000200
#define WXREG_TCTL 0x00000400
#define WXREG_TQSA_LO 0x00000408
#define WXREG_TQSA_HI 0x0000040C
#define WXREG_TIPG 0x00000410
#define WXREG_TQC 0x00000418
#define WXREG_TDBA_LO 0x00000420
#define WXREG_TDBA_HI 0x00000424
#define WXREG_TDLEN 0x00000428
#define WXREG_TDH 0x00000430
#define WXREG_TDT 0x00000438
#define WXREG_TIDV 0x00000440
#define WXREG_VFTA 0x00000600
#define WX_RAL_TAB_SIZE 16
#define WX_RAL_AV 0x80000000
#define WX_MC_TAB_SIZE 128
#define WX_VLAN_TAB_SIZE 128
/*
* Device Control Register Defines
*/
#define WXDCR_FD 0x1 /* full duplex */
#define WXDCR_BEM 0x2 /* big endian mode */
#define WXDCR_FAIR 0x4 /* 1->Fairness, 0->Receive Priority */
#define WXDCR_LRST 0x8 /* Link Reset */
#define WXDCR_SLU 0x40 /* Set Link Up */
#define WXDCR_ILOS 0x80 /* Invert Loss-of-Signal */
#define WXDCR_SWDPINS_SHIFT 18
#define WXDCR_SWDPINS_MASK 0xf
#define WXDCR_SWDPIN0 (1 << 18)
#define WXDCR_SWDPIN1 (1 << 19)
#define WXDCR_SWDPIN2 (1 << 20)
#define WXDCR_SWDPIN3 (1 << 21)
#define WXDCR_SWDPIO_SHIFT 22
#define WXDCR_SWDPIO_MASK 0xf
#define WXDCR_SWDPIO0 (1 << 22)
#define WXDCR_SWDPIO1 (1 << 23)
#define WXDCR_SWDPIO2 (1 << 24)
#define WXDCR_SWDPIO3 (1 << 25)
#define WXDCR_RST 0x04000000 /* Device Reset (self clearing) */
#define WXDCR_RFCE 0x08000000 /* Receive Flow Control Enable */
#define WXDCR_TFCE 0x10000000 /* Transmit Flow Control Enable */
#define WXDCR_RTE 0x20000000 /* Routing Tag Enable */
#define WXDCR_VME 0x40000000 /* VLAN Mode Enable */
/*
* Device Status Register Defines
*/
#define WXDSR_FD 0x1 /* full duplex */
#define WXDSR_LU 0x2 /* link up */
#define WXDSR_TXCLK 0x4 /* transmit clock running */
#define WXDSR_RBCLK 0x8 /* receive clock running */
#define WXDSR_TXOFF 0x10 /* transmit paused */
/*
* EEPROM Register Defines
*/
#define WXEECD_SK 0x1 /* enable clock */
#define WXEECD_CS 0x2 /* chip select */
#define WXEECD_DI 0x4 /* data input */
#define WXEECD_DO 0x8 /* data output */
#define EEPROM_READ_OPCODE 0x6
/*
* Constant Flow Control Frame MAC Address and Type values.
*/
#define FC_FRM_CONST_LO 0x00C28001
#define FC_FRM_CONST_HI 0x0100
#define FC_TYP_CONST 0x8808
/*
* Bits pertinent for the Receive Address register pairs. The low address
* is the low 32 bits of a 48 bit MAC address. The high address contains
* bits 32-47 of the 48 bit MAC address. The top bit in the high address
* is a 'valid' bit.
*/
#define WXRAH_RDR1 0x40000000 /* second receive descriptor ring */
#define WXRAH_VALID 0x80000000
/*
* Interrupt Cause Bits
*/
#define WXISR_TXDW 0x1 /* transmit descriptor written back */
#define WXISR_TXQE 0x2 /* transmit queue empty */
#define WXISR_LSC 0x4 /* link status change */
#define WXISR_RXSEQ 0x8 /* receive sequence error */
#define WXISR_RXDMT0 0x10 /* receiver ring 0 getting empty */
#define WXISR_RXO 0x40 /* receiver overrun */
#define WXISR_RXT0 0x80 /* ring 0 receiver timer interrupt */
#define WXISR_PCIE 0x200 /* ?? Probably PCI interface error... */
#define WXIENABLE_DEFAULT \
(WXISR_RXO|WXISR_RXT0|WXISR_RXDMT0|WXISR_RXSEQ|WXISR_LSC|WXISR_PCIE)
#define WXDISABLE 0xffffffff
/*
* Receive Control Register bits.
*/
#define WXRCTL_RST 0x1 /* receiver reset */
#define WXRCTL_EN 0x2 /* receiver enable */
#define WXRCTL_SBP 0x4 /* store bad packets */
#define WXRCTL_UPE 0x8 /* unicast promiscuos mode */
#define WXRCTL_MPE 0x10 /* multicast promiscuous mode */
#define WXRCTL_LPE 0x20 /* large packet enable */
#define WXRCTL_BAM 0x8000 /* broadcast accept mode */
#define WXRCTL_2KRBUF (0 << 16) /* 2-Kbyte Receive Buffers */
#define WXRCTL_1KRBUF (1 << 16) /* 1-Kbyte Receive Buffers */
#define WXRCTL_512BRBUF (2 << 16) /* 512 Byte Receive Buffers */
#define WXRCTL_256BRBUF (3 << 16) /* 256 Byte Receive Buffers */
/*
* Receive Delay Timer Register bits.
*/
#define WXRDTR_FPD 0x80000000 /* flush partial descriptor */
/*
* Transmit Configuration Word defines
*/
#define WXTXCW_FD 0x00000020 /* Full Duplex */
#define WXTXCW_PMASK 0x00000180 /* pause mask */
#define WXTXCW_ANE 0x80000000 /* AutoNegotiate */
#define WXTXCW_DEFAULT 0x800001A0
/*
* Transmit Control Register defines.
*/
#define WXTCTL_RST 0x1 /* transmitter reset */
#define WXTCTL_EN 0x2 /* transmitter enable */
#define WXTCTL_PSP 0x8 /* pad short packets */
#define WXTCTL_CT(x) (((x) & 0xff) << 4) /* 4:11 - Collision Threshold */
#define WXTCTL_COLD(x) (((x) & 0x3ff) << 12) /* 12:21 - Collision Distance */
#define WXTCTL_SWXOFF (1 << 22) /* Software XOFF */
#define WX_COLLISION_THRESHOLD 15
#define WX_FDX_COLLISION_DX 64
#define WX_HDX_COLLISION_DX 512
/*
* Miscellaneous
*/
#define WX_EEPROM_MAC_OFF 0
/*
* Offset for Initialization Control Word #1
*/
#define WX_EEPROM_CTLR1_OFF 0xA
#define WX_EEPROM_CTLR1_FD (1 << 10)
#define WX_EEPROM_CTLR1_SWDPIO_SHIFT 5
#define WX_EEPROM_CTLR1_ILOS (1 << 4)
#define WX_XTIMER_DFLT 0x100
#define WX_RCV_FLOW_HI_DFLT 0x8000
#define WX_RCV_FLOW_LO_DFLT 0x4000
#define WX_TIPG_DFLT (10 | (2 << 10) | (10 << 20))
#define WX_CRC_LENGTH 4
/*
* Hardware cannot transmit less than 16 bytes. It also cannot
* successfully receive less than 60 bytes.
*/
#define WX_MIN_XPKT_SIZE 16
#define WX_MIN_RPKT_SIZE 60
#define WX_MAX_PKT_SIZE 1514

316
sys/pci/if_wxvar.h Normal file
View File

@ -0,0 +1,316 @@
/*
* Copyright (c) 1999, Traakan Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* Softc definitions for the Intel Gigabit Ethernet driver.
*
* Guidance and inspiration from David Greenman's
* if_fxp driver gratefully acknowledged here.
*/
/*
* Platform specific defines and inline functions go here.
* Look further below for more generic structures.
*/
#if defined(__NetBSD__)
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/device.h>
#include <net/if.h>
#if defined(SIOCSIFMEDIA)
#include <net/if_media.h>
#endif
#include <net/if_types.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <net/netisr.h>
#include "bpfilter.h"
#if NBPFILTER > 0
#include <net/bpf.h>
#include <net/bpfdesc.h>
#endif
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#endif
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_kern.h>
#include <net/if_ether.h>
#if defined(INET)
#include <netinet/if_inarp.h>
#endif
#include <machine/bus.h>
#include <machine/intr.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/if_wxreg.h>
struct wxmdvar {
struct device dev; /* generic device structures */
void * ih; /* interrupt handler cookie */
struct ethercom ethercom; /* ethernet common part */
pci_chipset_tag_t pci_pc;
pcitag_t pci_tag;
u_int8_t enaddr[6]; /* our mac address */
u_int32_t cmdw;
bus_space_tag_t st; /* bus space tag */
bus_space_handle_t sh; /* bus space handle */
struct ifmedia ifm;
struct wx_softc * next;
};
#define wx_dev w.dev
#define wx_enaddr w.enaddr
#define wx_cmdw w.cmdw
#define wx_media w.ifm
#define wx_next w.next
#define wx_if w.ethercom.ec_if
#define wx_name w.dev.dv_xname
#define IOCTL_CMD_TYPE u_long
#define WXMALLOC(len) malloc(len, M_DEVBUF, M_NOWAIT)
#define WXFREE(ptr) free(ptr, M_DEVBUF)
#define SOFTC_IFP(ifp) ifp->if_softc
#define WX_BPFTAP_ARG(ifp) (ifp)->if_bpf
#define TIMEOUT(sc, func, arg, time) timeout(func, arg, time)
#define VTIMEOUT(sc, func, arg, time) timeout(func, arg, time)
#define UNTIMEOUT(f, arg, sc) untimeout(f, arg)
#define INLINE inline
#define vm_offset_t vaddr_t
#ifndef IFM_1000_SX
#define IFM_1000_SX IFM_1000_FX
#endif
#define READ_CSR _read_csr
#define WRITE_CSR _write_csr
#elif defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
#endif
#include <net/bpf.h>
#include <sys/sockio.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/clock.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#include <pci/if_wxreg.h>
#include "opt_bdg.h"
#ifdef BRIDGE
#include <net/if_types.h>
#include <net/bridge.h>
#endif
struct wxmdvar {
struct device * dev; /* backpointer to device */
struct arpcom arpcom; /* per-interface network data */
struct resource * mem; /* resource descriptor for registers */
struct resource * irq; /* resource descriptor for interrupt */
void * ih; /* interrupt handler cookie */
u_int16_t cmdw;
struct callout_handle sch; /* handle for timeouts */
char name[8];
bus_space_tag_t st; /* bus space tag */
bus_space_handle_t sh; /* bus space handle */
struct ifmedia ifm;
struct wx_softc * next;
};
#define wx_dev w.dev
#define wx_enaddr w.arpcom.ac_enaddr
#define wx_cmdw w.cmdw
#define wx_media w.ifm
#define wx_next w.next
#define wx_if w.arpcom.ac_if
#define wx_name w.name
#define IOCTL_CMD_TYPE u_long
#define WXMALLOC(len) malloc(len, M_DEVBUF, M_NOWAIT)
#define WXFREE(ptr) free(ptr, M_DEVBUF)
#define SOFTC_IFP(ifp) ifp->if_softc
#define WX_BPFTAP_ARG(ifp) ifp
#define VTIMEOUT(sc, func, arg, time) (void) timeout(func, arg, time)
#define TIMEOUT(sc, func, arg, time) (sc)->w.sch = timeout(func, arg, time)
#define UNTIMEOUT(f, arg, sc) untimeout(f, arg, (sc)->w.sch)
#define INLINE __inline
#define READ_CSR(sc, reg) \
bus_space_read_4((sc)->w.st, (sc)->w.sh, (reg))
#define WRITE_CSR(sc, reg, val) \
bus_space_write_4((sc)->w.st, (sc)->w.sh, (reg), (val))
#endif
/*
* Transmit soft descriptor, used to manage packets as they come in.
*/
typedef struct rxpkt {
struct mbuf *dptr; /* pointer to receive frame */
u_int32_t dma_addr; /* dma address */
} rxpkt_t;
/*
* Transmit soft descriptor, used to manage packets as they are transmitted.
*/
typedef struct txpkt {
struct txpkt *next; /* next in a chain */
struct mbuf *dptr; /* pointer to mbuf being sent */
u_int32_t sidx; /* start index */
u_int32_t eidx; /* end index */
} txpkt_t;
typedef struct wx_softc {
/*
* OS dependent storage... must be first...
*/
struct wxmdvar w;
/*
* misc goodies
*/
u_int32_t : 18,
wx_no_flow : 1,
wx_ilos : 1,
wx_no_ilos : 1,
wx_debug : 1,
linkup : 1,
all_mcasts : 1,
revision : 8; /* chip revision */
u_int16_t wx_cfg1;
u_int16_t wx_txint_delay;
u_int32_t wx_ienable; /* current ienable to use */
u_int32_t wx_dcr; /* dcr used */
u_int32_t wx_icr; /* last icr */
/*
* Statistics, soft && hard
*/
u_int32_t wx_intr;
u_int32_t wx_linkintr;
u_int32_t wx_rxintr;
u_int32_t wx_xmitgc;
u_int32_t wx_xmitpullup;
u_int32_t wx_xmitcluster;
u_int32_t wx_xmitputback;
u_int32_t wx_xmitwanted;
u_int32_t wx_xmitblocked;
u_int32_t wx_xmitblocked1;
u_int32_t wx_xmitrunt;
u_int32_t wx_rxnobuf;
/*
* Soft copies of multicast addresses. We're only
* using (right now) the rest of the receive address
* registers- not the hashed multicast table.
*/
u_int8_t wx_mcaddr[WX_RAL_TAB_SIZE-1][6];
u_int8_t wx_nmca; /* # active multicast addrs */
/*
* Receive Management
* We have software and shared memory rings in a buddy store format.
*/
wxrd_t *rdescriptors; /* receive descriptor ring */
rxpkt_t *rbase; /* base of soft rdesc list */
u_int16_t rnxt; /* next descriptor to check */
u_int16_t _pad;
/*
* Transmit Management
* We have software and shared memory rings in a buddy store format.
*/
txpkt_t *tbase; /* base of soft soft management */
txpkt_t *tbsyf, *tbsyl; /* linked busy list */
wxtd_t *tdescriptors; /* transmit descriptor ring */
u_int16_t tnxtfree; /* next free index (circular) */
u_int16_t tactive; /* # active */
} wx_softc_t;
/*
* We offset the the receive frame header by two bytes so that the actual
* payload is 32 bit aligned. On platforms that require strict structure
* alignment, this means that the ethernet frame header may have to be shifted
* to align it at interrupt time, but because it's such a small amount
* (fourteen bytes) and processors have gotten pretty fast, that's okay.
* It may even turn out on some platforms that this doesn't have to happen.
*/
#define WX_RX_OFFSET_VALUE 2
/*
* Tunable Parameters.
*
* Descriptor lengths must be in multiples of 8.
*/
#define WX_MAX_TDESC 256 /* number of transmit descriptors */
#define T_NXT_IDX(x) ((x + 1) & (WX_MAX_TDESC - 1))
#define WX_MAX_RDESC 64 /* number of receive descriptors */
#define R_NXT_IDX(x) ((x + 1) & (WX_MAX_RDESC - 1))