mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-04 09:09:56 +00:00
- Update some comments regarding hardware details of the 8169 and
note the existence of the 8169S and 8110S components. (The 8169 is just a MAC, the 8169S and 8110S contain both a MAC and PHY.) - Properly handle list and buffer addresses as 64-bit. The RX and TX DMA list addresses should be bus_addr_t's. Added RL_ADDR_HI() and RL_ADDR_LO() macros to obtain values for writing into chip registers. - Set a slightly different TIMERINT value for 8169 NICs for improved performance. - Change left out of previous commit log: added some additional hardware rev codes for other 10/100 chips and for the 8169S/8110S 'rev C' gigE MACs.
This commit is contained in:
parent
96e934df56
commit
f6bb113e42
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=118712
@ -80,9 +80,9 @@
|
||||
* the 8139 lets you directly access the on-board PHY registers. We need
|
||||
* to select which interface to use depending on the chip type.
|
||||
*
|
||||
* Fast forward a few years. RealTek how has a new chip called the
|
||||
* Fast forward a few years. RealTek now has a new chip called the
|
||||
* 8139C+ which at long last implements descriptor-based DMA. Not
|
||||
* only that, in supports RX and TX TCP/IP checksum offload, VLAN
|
||||
* only that, it supports RX and TX TCP/IP checksum offload, VLAN
|
||||
* tagging and insertion, TCP large send and 64-bit addressing.
|
||||
* Better still, it allows arbitrary byte alignments for RX and
|
||||
* TX buffers, meaning no copying is necessary on any architecture.
|
||||
@ -96,26 +96,36 @@
|
||||
* mode has to be enabled by setting the appropriate bits in the C+
|
||||
* command register. The PHY access mechanism appears to be unchanged.
|
||||
*
|
||||
* The 8169 is a 10/100/1000 ethernet MAC with built-in tri-speed
|
||||
* copper PHY. It has almost the same programming API as the C+ mode
|
||||
* of the 8139C+, with a couple of minor changes and additions: the
|
||||
* TX start register is located at a different offset, and there are
|
||||
* additional registers for GMII PHY status and control, as well as
|
||||
* TBI-mode status and control. There is also a maximum RX packet
|
||||
* size register to allow the chip to receive jumbo frames. The
|
||||
* 8169 can only be programmed in C+ mode: the old 8139 programming
|
||||
* The 8169 is a 10/100/1000 ethernet MAC. It has almost the same
|
||||
* programming API as the C+ mode of the 8139C+, with a couple of
|
||||
* minor changes and additions: TX start register and timer interrupt
|
||||
* register are located at different offsets, and there are additional
|
||||
* registers for GMII PHY status and control, as well as TBI-mode
|
||||
* status and control. There is also a maximum RX packet size
|
||||
* register to allow the chip to receive jumbo frames. The 8169
|
||||
* can only be programmed in C+ mode: the old 8139 programming
|
||||
* method isn't supported with this chip. Also, RealTek has a LOM
|
||||
* (LAN On Motherboard) gigabit MAC chip called the RTL8110S which
|
||||
* I believe to be register compatible with the 8169.
|
||||
* I believe to be register compatible with the 8169. Unlike the
|
||||
* 8139C+, the 8169 can have up to 1024 descriptors per DMA ring.
|
||||
* The reference 8169 board design uses a Marvell 88E1000 'Alaska'
|
||||
* copper PHY.
|
||||
*
|
||||
* Unfortunately, RealTek has not released a programming manual for
|
||||
* the 8169 or 8110 yet. The datasheet for the 8139C+ provides most
|
||||
* The 8169S and 8110S are newer versions of the 8169. Available
|
||||
* in both 32-bit and 64-bit forms, these devices have built-in
|
||||
* copper 10/100/1000 PHYs. The 8110S is a lan-on-motherboard chip
|
||||
* that is pin-for-pin compatible with the 8100. Unfortunately,
|
||||
* RealTek has not released programming manuals for the 8169S and
|
||||
* 8110S yet. The datasheet for the original 8169 provides most
|
||||
* of the information, but you must refer to RealTek's 8169 Linux
|
||||
* driver to fill in the gaps.
|
||||
* driver to fill in the gaps. Mostly, it appears that the built-in
|
||||
* PHY requires some special initialization. The original 8169
|
||||
* datasheet and the 8139C+ datasheet can be obtained from
|
||||
* http://www.freebsd.org/~wpaul/RealTek.
|
||||
*
|
||||
* This driver now supports both the old 8139 and new 8139C+
|
||||
* programming models. We detect the 8139C+ by looking for a PCI
|
||||
* revision ID of 0x20 or higher, and we detect the 8169 by its
|
||||
* programming models. We detect the 8139C+ by looking for the
|
||||
* corresponding hardware rev bits, and we detect the 8169 by its
|
||||
* PCI ID. Two new NIC type codes, RL_8139CPLUS and RL_8169 have
|
||||
* been added to distinguish the chips at runtime. Separate RX and
|
||||
* TX handling routines have been added to handle C+ mode, which
|
||||
@ -1122,8 +1132,8 @@ rl_dma_map_desc(arg, segs, nseg, mapsize, error)
|
||||
return;
|
||||
}
|
||||
cmdstat = segs[i].ds_len;
|
||||
d->rl_bufaddr_lo = htole32(segs[i].ds_addr);
|
||||
d->rl_bufaddr_hi = 0;
|
||||
d->rl_bufaddr_lo = htole32(RL_ADDR_LO(segs[i].ds_addr));
|
||||
d->rl_bufaddr_hi = htole32(RL_ADDR_HI(segs[i].ds_addr));
|
||||
if (i == 0)
|
||||
cmdstat |= RL_TDESC_CMD_SOF;
|
||||
else
|
||||
@ -1834,20 +1844,25 @@ rl_rxeofcplus(sc)
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
/* Check IP header checksum */
|
||||
if (rxstat & RL_RDESC_STAT_PROTOID)
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
|
||||
if (!(rxstat & RL_RDESC_STAT_IPSUMBAD))
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
|
||||
/* Do RX checksumming if enabled */
|
||||
|
||||
/* Check TCP/UDP checksum */
|
||||
if ((RL_TCPPKT(rxstat) &&
|
||||
!(rxstat & RL_RDESC_STAT_TCPSUMBAD)) ||
|
||||
(RL_UDPPKT(rxstat) &&
|
||||
!(rxstat & RL_RDESC_STAT_UDPSUMBAD))) {
|
||||
m->m_pkthdr.csum_flags |=
|
||||
CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
|
||||
m->m_pkthdr.csum_data = 0xffff;
|
||||
if (ifp->if_capenable & IFCAP_RXCSUM) {
|
||||
|
||||
/* Check IP header checksum */
|
||||
if (rxstat & RL_RDESC_STAT_PROTOID)
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
|
||||
if (!(rxstat & RL_RDESC_STAT_IPSUMBAD))
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
|
||||
|
||||
/* Check TCP/UDP checksum */
|
||||
if ((RL_TCPPKT(rxstat) &&
|
||||
!(rxstat & RL_RDESC_STAT_TCPSUMBAD)) ||
|
||||
(RL_UDPPKT(rxstat) &&
|
||||
!(rxstat & RL_RDESC_STAT_UDPSUMBAD))) {
|
||||
m->m_pkthdr.csum_flags |=
|
||||
CSUM_DATA_VALID|CSUM_PSEUDO_HDR;
|
||||
m->m_pkthdr.csum_data = 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
if (rxvlan & RL_RDESC_VLANCTL_TAG)
|
||||
@ -2734,13 +2749,15 @@ rl_init(xsc)
|
||||
(ifp->if_capenable & IFCAP_RXCSUM ?
|
||||
RL_CPLUSCMD_RXCSUM_ENB : 0));
|
||||
|
||||
CSR_WRITE_4(sc, RL_RXLIST_ADDR_HI, 0);
|
||||
CSR_WRITE_4(sc, RL_RXLIST_ADDR_HI,
|
||||
RL_ADDR_HI(sc->rl_ldata.rl_rx_list_addr));
|
||||
CSR_WRITE_4(sc, RL_RXLIST_ADDR_LO,
|
||||
sc->rl_ldata.rl_rx_list_addr);
|
||||
RL_ADDR_LO(sc->rl_ldata.rl_rx_list_addr));
|
||||
|
||||
CSR_WRITE_4(sc, RL_TXLIST_ADDR_HI, 0);
|
||||
CSR_WRITE_4(sc, RL_TXLIST_ADDR_HI,
|
||||
RL_ADDR_HI(sc->rl_ldata.rl_tx_list_addr));
|
||||
CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
|
||||
sc->rl_ldata.rl_tx_list_addr);
|
||||
RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr));
|
||||
|
||||
CSR_WRITE_1(sc, RL_EARLY_TX_THRESH, RL_EARLYTXTHRESH_CNT);
|
||||
|
||||
@ -2753,7 +2770,7 @@ rl_init(xsc)
|
||||
*/
|
||||
|
||||
if (sc->rl_type == RL_8169)
|
||||
CSR_WRITE_4(sc, RL_TIMERINT_8169, 0x400);
|
||||
CSR_WRITE_4(sc, RL_TIMERINT_8169, 0x800);
|
||||
else
|
||||
CSR_WRITE_4(sc, RL_TIMERINT, 0x400);
|
||||
|
||||
|
@ -593,6 +593,9 @@ struct rl_stats {
|
||||
RL_RDESC_STAT_FRAGLEN)
|
||||
#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)
|
||||
|
||||
struct rl_softc;
|
||||
|
||||
struct rl_dmaload_arg {
|
||||
@ -615,15 +618,15 @@ struct rl_list_data {
|
||||
bus_dma_tag_t rl_stag; /* stats mapping tag */
|
||||
bus_dmamap_t rl_smap; /* stats map */
|
||||
struct rl_stats *rl_stats;
|
||||
u_int32_t rl_stats_addr;
|
||||
bus_addr_t rl_stats_addr;
|
||||
bus_dma_tag_t rl_rx_list_tag;
|
||||
bus_dmamap_t rl_rx_list_map;
|
||||
struct rl_desc *rl_rx_list;
|
||||
u_int32_t rl_rx_list_addr;
|
||||
bus_addr_t rl_rx_list_addr;
|
||||
bus_dma_tag_t rl_tx_list_tag;
|
||||
bus_dmamap_t rl_tx_list_map;
|
||||
struct rl_desc *rl_tx_list;
|
||||
u_int32_t rl_tx_list_addr;
|
||||
bus_addr_t rl_tx_list_addr;
|
||||
};
|
||||
|
||||
struct rl_softc {
|
||||
|
Loading…
Reference in New Issue
Block a user