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.
2000-01-04 11:12:42 +00:00
|
|
|
/*
|
|
|
|
* 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 */
|
2000-01-23 01:39:13 +00:00
|
|
|
#define WX_CACHELINE_SIZE 0x20
|
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.
2000-01-04 11:12:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
2000-01-25 04:11:33 +00:00
|
|
|
#define WX_MAX_PKT_SIZE_JUMBO 9014
|