mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Take the support for the 8139C+/8169/8169S/8110S chips out of the
rl(4) driver and put it in a new re(4) driver. The re(4) driver shares the if_rlreg.h file with rl(4) but is a separate module. (Ultimately I may change this. For now, it's convenient.) rl(4) has been modified so that it will never attach to an 8139C+ chip, leaving it to re(4) instead. Only re(4) has the PCI IDs to match the 8169/8169S/8110S gigE chips. if_re.c contains the same basic code that was originally bolted onto if_rl.c, with the following updates: - Added support for jumbo frames. Currently, there seems to be a limit of approximately 6200 bytes for jumbo frames on transmit. (This was determined via experimentation.) The 8169S/8110S chips apparently are limited to 7.5K frames on transmit. This may require some more work, though the framework to handle jumbo frames on RX is in place: the re_rxeof() routine will gather up frames than span multiple 2K clusters into a single mbuf list. - Fixed bug in re_txeof(): if we reap some of the TX buffers, but there are still some pending, re-arm the timer before exiting re_txeof() so that another timeout interrupt will be generated, just in case re_start() doesn't do it for us. - Handle the 'link state changed' interrupt - Fix a detach bug. If re(4) is loaded as a module, and you do tcpdump -i re0, then you do 'kldunload if_re,' the system will panic after a few seconds. This happens because ether_ifdetach() ends up calling the BPF detach code, which notices the interface is in promiscuous mode and tries to switch promisc mode off while detaching the BPF listner. This ultimately results in a call to re_ioctl() (due to SIOCSIFFLAGS), which in turn calls re_init() to handle the IFF_PROMISC flag change. Unfortunately, calling re_init() here turns the chip back on and restarts the 1-second timeout loop that drives re_tick(). By the time the timeout fires, if_re.ko has been unloaded, which results in a call to invalid code and blows up the system. To fix this, I cleared the IFF_UP flag before calling ether_ifdetach(), which stops the ioctl routine from trying to reset the chip. - Modified comments in re_rxeof() relating to the difference in RX descriptor status bit layout between the 8139C+ and the gigE chips. The layout is different because the frame length field was expanded from 12 bits to 13, and they got rid of one of the status bits to make room. - Add diagnostic code (re_diag()) to test for the case where a user has installed a broken 32-bit 8169 PCI NIC in a 64-bit slot. Some NICs have the REQ64# and ACK64# lines connected even though the board is 32-bit only (in this case, they should be pulled high). This fools the chip into doing 64-bit DMA transfers even though there is no 64-bit data path. To detect this, re_diag() puts the chip into digital loopback mode and sets the receiver to promiscuous mode, then initiates a single 64-byte packet transmission. The frame is echoed back to the host, and if the frame contents are intact, we know DMA is working correctly, otherwise we complain loudly on the console and abort the device attach. (At the moment, I don't know of any way to work around the problem other than physically modifying the board, so until/unless I can think of a software workaround, this will have do to.) - Created re(4) man page - Modified rlphy.c to allow re(4) to attach as well as rl(4). Note that this code works for the sample 8169/Marvell 88E1000 NIC that I have, but probably won't work for the 8169S/8110S chips. RealTek has sent me some sample NICs, but they haven't arrived yet. I will probably need to add an rlgphy driver to handle the on-board PHY in the 8169S/8110S (it needs special DSP initialization).
This commit is contained in:
parent
5e3cb29a6b
commit
a94100fa9b
16 changed files with 2589 additions and 1242 deletions
|
|
@ -197,6 +197,7 @@ MAN= aac.4 \
|
|||
puc.4 \
|
||||
raid.4 \
|
||||
random.4 \
|
||||
re.4 \
|
||||
rl.4 \
|
||||
rndtest.4 \
|
||||
route.4 \
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
.Os
|
||||
.Sh NAME
|
||||
.Nm rl
|
||||
.Nd RealTek 8129/8139/8139C+ fast ethernet device driver
|
||||
.Nd RealTek 8129/8139 fast ethernet device driver
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device miibus"
|
||||
.Cd "device rl"
|
||||
|
|
@ -120,20 +120,9 @@ supports both 10 and 100Mbps speeds in either full or half duplex.
|
|||
The 8129 can support the same speeds and modes given an appropriate
|
||||
PHY chip.
|
||||
.Pp
|
||||
Support is also provided for the special C+ mode of the 8139C+ chip.
|
||||
By default, the 8139C+ is back backwards compatible with the 8139, but
|
||||
in C+ mode it supports advanced features such as descriptor-based DMA,
|
||||
64-bit addressing, TCP/IP checksum offload on both receive and transmit,
|
||||
hardware VLAN tag insertion and extraction, and TCP large send.
|
||||
When used with an 8139C+ chip, the
|
||||
.Nm
|
||||
driver makes use of all of these features, except for TCP large send,
|
||||
since there is currently no OS support for it. Transmit interrupt
|
||||
moderation is also used to improve performance at high frame rates.
|
||||
The receive and transmit checksum offload capabilities are on by default
|
||||
but can be toggled off using the
|
||||
.Xr ifconfig 8
|
||||
command.
|
||||
Note: support for the 8139C+ chip is provided by the
|
||||
.Xr re 4
|
||||
driver.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ device miibus # MII bus support
|
|||
device dc # DEC/Intel 21143 and various workalikes
|
||||
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
|
||||
device pcn # AMD Am79C97x PCI 10/100 (precedence over 'lnc')
|
||||
device re # RealTek 8139C+/8169/8169S/8110S
|
||||
device rl # RealTek 8129/8139
|
||||
device sf # Adaptec AIC-6915 (``Starfire'')
|
||||
device sis # Silicon Integrated Systems SiS 900/SiS 7016
|
||||
|
|
|
|||
|
|
@ -662,6 +662,7 @@ crypto/sha2/sha2.c optional random
|
|||
dev/ray/if_ray.c optional ray card
|
||||
dev/ray/if_ray.c optional ray pccard
|
||||
dev/rc/rc.c optional rc
|
||||
dev/re/if_re.c optional re
|
||||
dev/rndtest/rndtest.c optional rndtest
|
||||
dev/rp/rp.c optional rp
|
||||
dev/rp/rp_isa.c optional rp isa
|
||||
|
|
|
|||
|
|
@ -110,9 +110,10 @@ rlphy_probe(dev)
|
|||
return (ENXIO);
|
||||
|
||||
/*
|
||||
* Make sure the parent is an `rl'.
|
||||
* Make sure the parent is an `rl' or an `re'.
|
||||
*/
|
||||
if (strcmp(device_get_name(parent), "rl") != 0)
|
||||
if (strcmp(device_get_name(parent), "rl") != 0 &&
|
||||
strcmp(device_get_name(parent), "re") != 0)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "RealTek internal media interface");
|
||||
|
|
|
|||
2430
sys/dev/re/if_re.c
Normal file
2430
sys/dev/re/if_re.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -190,6 +190,7 @@ device miibus # MII bus support
|
|||
device dc # DEC/Intel 21143 and various workalikes
|
||||
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
|
||||
device pcn # AMD Am79C97x PCI 10/100 (precedence over 'lnc')
|
||||
device re # RealTek 8139C+/8169/8169S/8110S
|
||||
device rl # RealTek 8129/8139
|
||||
device sf # Adaptec AIC-6915 (``Starfire'')
|
||||
device sis # Silicon Integrated Systems SiS 900/SiS 7016
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ device bge # Broadcom BCM570xx Gigabit Ethernet
|
|||
device dc # DEC/Intel 21143 and various workalikes
|
||||
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
|
||||
device pcn # AMD Am79C97x PCI 10/100 NICs
|
||||
device re # RealTek 8139C+/8169/8169S/8110S
|
||||
device rl # RealTek 8129/8139
|
||||
device sf # Adaptec AIC-6915 (``Starfire'')
|
||||
device sis # Silicon Integrated Systems SiS 900/SiS 7016
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ SUBDIR= accf_data \
|
|||
${_random} \
|
||||
rc \
|
||||
rc4 \
|
||||
re \
|
||||
rl \
|
||||
rp \
|
||||
rue \
|
||||
|
|
|
|||
9
sys/modules/re/Makefile
Normal file
9
sys/modules/re/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../pci
|
||||
|
||||
KMOD= if_re
|
||||
SRCS= if_re.c opt_bdg.h device_if.h bus_if.h pci_if.h
|
||||
SRCS+= miibus_if.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
|
@ -177,6 +177,7 @@ device miibus # MII bus support
|
|||
device dc # DEC/Intel 21143 and various workalikes
|
||||
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
|
||||
device pcn # AMD Am79C97x PCI 10/100 NICs
|
||||
device re # RealTek 8139C+/8169/8169S/8110S
|
||||
device rl # RealTek 8129/8139
|
||||
device sf # Adaptec AIC-6915 (``Starfire'')
|
||||
device sis # Silicon Integrated Systems SiS 900/SiS 7016
|
||||
|
|
|
|||
1322
sys/pci/if_rl.c
1322
sys/pci/if_rl.c
File diff suppressed because it is too large
Load diff
|
|
@ -136,9 +136,13 @@
|
|||
#define RL_TXCFG_MAXDMA 0x00000700 /* max DMA burst size */
|
||||
#define RL_TXCFG_CRCAPPEND 0x00010000 /* CRC append (0 = yes) */
|
||||
#define RL_TXCFG_LOOPBKTST 0x00060000 /* loopback test */
|
||||
#define RL_TXCFG_IFG2 0x00080000 /* 8169 only */
|
||||
#define RL_TXCFG_IFG 0x03000000 /* interframe gap */
|
||||
#define RL_TXCFG_HWREV 0x7CC00000
|
||||
|
||||
#define RL_LOOPTEST_OFF 0x00000000
|
||||
#define RL_LOOPTEST_ON 0x00020000
|
||||
|
||||
#define RL_HWREV_8169 0x00000000
|
||||
#define RL_HWREV_8110 0x00800000
|
||||
#define RL_HWREV_8139 0x60000000
|
||||
|
|
@ -184,6 +188,7 @@
|
|||
#define RL_ISR_TX_ERR 0x0008
|
||||
#define RL_ISR_RX_OVERRUN 0x0010
|
||||
#define RL_ISR_PKT_UNDERRUN 0x0020
|
||||
#define RL_ISR_LINKCHG 0x0020 /* 8169 only */
|
||||
#define RL_ISR_FIFO_OFLOW 0x0040 /* 8139 only */
|
||||
#define RL_ISR_TX_DESC_UNAVAIL 0x0080 /* C+ only */
|
||||
#define RL_ISR_SWI 0x0100 /* C+ only */
|
||||
|
|
@ -198,7 +203,7 @@
|
|||
RL_ISR_PCS_TIMEOUT|RL_ISR_SYSTEM_ERR)
|
||||
|
||||
#define RL_INTRS_CPLUS \
|
||||
(RL_ISR_RX_OK|RL_ISR_RX_ERR|RL_ISR_TX_ERR| \
|
||||
(RL_ISR_RX_OK|RL_ISR_RX_ERR|RL_ISR_TX_ERR| \
|
||||
RL_ISR_RX_OVERRUN|RL_ISR_PKT_UNDERRUN|RL_ISR_FIFO_OFLOW| \
|
||||
RL_ISR_PCS_TIMEOUT|RL_ISR_SYSTEM_ERR|RL_ISR_TIMEOUT_EXPIRED)
|
||||
|
||||
|
|
@ -401,8 +406,8 @@
|
|||
#define RL_MIN_FRAMELEN 60
|
||||
#define RL_TXTHRESH(x) ((x) << 11)
|
||||
#define RL_TX_THRESH_INIT 96
|
||||
#define RL_RX_FIFOTHRESH RL_RXFIFO_256BYTES
|
||||
#define RL_RX_MAXDMA RL_RXDMA_1024BYTES /*RL_RXDMA_UNLIMITED*/
|
||||
#define RL_RX_FIFOTHRESH RL_RXFIFO_NOTHRESH
|
||||
#define RL_RX_MAXDMA RL_RXDMA_UNLIMITED
|
||||
#define RL_TX_MAXDMA RL_TXDMA_2048BYTES
|
||||
|
||||
#define RL_RXCFG_CONFIG (RL_RX_FIFOTHRESH|RL_RX_MAXDMA|RL_RX_BUF_SZ)
|
||||
|
|
@ -524,7 +529,7 @@ struct rl_desc {
|
|||
|
||||
#define RL_RDESC_CMD_EOR 0x40000000
|
||||
#define RL_RDESC_CMD_OWN 0x80000000
|
||||
#define RL_RDESC_CMD_BUFLEN 0x00001FFF
|
||||
#define RL_RDESC_CMD_BUFLEN 0x00003FFF
|
||||
|
||||
#define RL_RDESC_STAT_OWN 0x80000000
|
||||
#define RL_RDESC_STAT_EOR 0x40000000
|
||||
|
|
@ -544,7 +549,7 @@ struct rl_desc {
|
|||
#define RL_RDESC_STAT_IPSUMBAD 0x00008000 /* IP header checksum bad */
|
||||
#define RL_RDESC_STAT_UDPSUMBAD 0x00004000 /* UDP checksum bad */
|
||||
#define RL_RDESC_STAT_TCPSUMBAD 0x00002000 /* TCP checksum bad */
|
||||
#define RL_RDESC_STAT_FRAGLEN 0x00001FFF /* RX'ed frame/frag len */
|
||||
#define RL_RDESC_STAT_FRAGLEN 0x00003FFF /* RX'ed frame/frag len */
|
||||
|
||||
#define RL_RDESC_VLANCTL_TAG 0x00010000 /* VLAN tag available
|
||||
(rl_vlandata valid)*/
|
||||
|
|
@ -591,11 +596,22 @@ struct rl_stats {
|
|||
#define RL_OWN(x) (le32toh((x)->rl_cmdstat) & RL_RDESC_STAT_OWN)
|
||||
#define RL_RXBYTES(x) (le32toh((x)->rl_cmdstat) & \
|
||||
RL_RDESC_STAT_FRAGLEN)
|
||||
#define RL_PKTSZ(x) ((x) >> 3)
|
||||
#define RL_PKTSZ(x) ((x)/* >> 3*/)
|
||||
|
||||
#define RL_ADDR_LO(y) ((u_int64_t) (y) & 0xFFFFFFFF)
|
||||
#define RL_ADDR_HI(y) ((u_int64_t) (y) >> 32)
|
||||
|
||||
#define RL_JUMBO_FRAMELEN 9018
|
||||
#define RL_JUMBO_MTU (RL_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
|
||||
#define RL_JSLOTS 128
|
||||
|
||||
#define RL_JRAWLEN (RL_JUMBO_FRAMELEN + ETHER_ALIGN + sizeof(u_int64_t))
|
||||
#define RL_JLEN (RL_JRAWLEN + (sizeof(u_int64_t) - \
|
||||
(RL_JRAWLEN % sizeof(u_int64_t))))
|
||||
#define RL_JPAGESZ PAGE_SIZE
|
||||
#define RL_RESID (RL_JPAGESZ - (RL_JLEN * RL_JSLOTS) % RL_JPAGESZ)
|
||||
#define RL_JMEM ((RL_JLEN * RL_JSLOTS) + RL_RESID)
|
||||
|
||||
struct rl_softc;
|
||||
|
||||
struct rl_dmaload_arg {
|
||||
|
|
@ -649,6 +665,10 @@ struct rl_softc {
|
|||
struct rl_list_data rl_ldata;
|
||||
struct callout_handle rl_stat_ch;
|
||||
struct mtx rl_mtx;
|
||||
struct mbuf *rl_head;
|
||||
struct mbuf *rl_tail;
|
||||
u_int32_t rl_hwrev;
|
||||
int rl_testmode;
|
||||
int suspended; /* 0 = normal 1 = suspended */
|
||||
#ifdef DEVICE_POLLING
|
||||
int rxcycles;
|
||||
|
|
@ -667,7 +687,7 @@ struct rl_softc {
|
|||
/*
|
||||
* register space access macros
|
||||
*/
|
||||
#define CSR_WRITE_STREAM_4(sc, reg, val) \
|
||||
#define CSR_WRITE_STREAM_4(sc, reg, val) \
|
||||
bus_space_write_stream_4(sc->rl_btag, sc->rl_bhandle, reg, val)
|
||||
#define CSR_WRITE_4(sc, reg, val) \
|
||||
bus_space_write_4(sc->rl_btag, sc->rl_bhandle, reg, val)
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ device fxp # Intel EtherExpress PRO/100B (82557, 82558)
|
|||
device gem # Sun GEM/Sun ERI/Apple GMAC
|
||||
device hme # Sun HME (Happy Meal Ethernet)
|
||||
#device pcn # AMD Am79C97x PCI 10/100 NICs
|
||||
device re # RealTek 8139C+/8169/8169S/8110S
|
||||
device rl # RealTek 8129/8139
|
||||
#device sf # Adaptec AIC-6915 (``Starfire'')
|
||||
#device sis # Silicon Integrated Systems SiS 900/SiS 7016
|
||||
|
|
|
|||
|
|
@ -109,7 +109,9 @@ static struct _devname {
|
|||
{ DEVICE_TYPE_NETWORK, "nge", "NatSemi PCI gigabit ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "pcn", "AMD Am79c79x PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "ray", "Raytheon Raylink 802.11 wireless adaptor" },
|
||||
{ DEVICE_TYPE_NETWORK, "re", "RealTek 8139C+/8169/8169S/8110S PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "rl", "RealTek 8129/8139 PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "rue", "RealTek USB ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "sf", "Adaptec AIC-6915 PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "sis", "SiS 900/SiS 7016 PCI ethernet card" },
|
||||
#ifdef PC98
|
||||
|
|
|
|||
|
|
@ -109,7 +109,9 @@ static struct _devname {
|
|||
{ DEVICE_TYPE_NETWORK, "nge", "NatSemi PCI gigabit ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "pcn", "AMD Am79c79x PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "ray", "Raytheon Raylink 802.11 wireless adaptor" },
|
||||
{ DEVICE_TYPE_NETWORK, "re", "RealTek 8139C+/8169/8169S/8110S PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "rl", "RealTek 8129/8139 PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "rue", "RealTek USB ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "sf", "Adaptec AIC-6915 PCI ethernet card" },
|
||||
{ DEVICE_TYPE_NETWORK, "sis", "SiS 900/SiS 7016 PCI ethernet card" },
|
||||
#ifdef PC98
|
||||
|
|
|
|||
Loading…
Reference in a new issue