summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2003-08-10 01:41:35 +0000
committerwpaul <wpaul@FreeBSD.org>2003-08-10 01:41:35 +0000
commit38b3b484f3cb63d58a043bca4e4900b96a6f92ec (patch)
treec5fdd0e79f40e6cc9abc2e511cc98854cfb23702 /sys/pci
parentfdf2badf9d65545e87e752ecaba5ce0ce9109c04 (diff)
downloadFreeBSD-src-38b3b484f3cb63d58a043bca4e4900b96a6f92ec.zip
FreeBSD-src-38b3b484f3cb63d58a043bca4e4900b96a6f92ec.tar.gz
- 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.
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_rl.c91
-rw-r--r--sys/pci/if_rlreg.h9
2 files changed, 60 insertions, 40 deletions
diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c
index 520759e..e0ab4c4 100644
--- a/sys/pci/if_rl.c
+++ b/sys/pci/if_rl.c
@@ -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;
-
- /* 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;
+ /* Do RX checksumming if enabled */
+
+ 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);
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index 086b61b..4a32aef 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -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 {
OpenPOWER on IntegriCloud