summaryrefslogtreecommitdiff
path: root/sys/dev/ic/re.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/re.c')
-rw-r--r--sys/dev/ic/re.c110
1 files changed, 84 insertions, 26 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c
index 10bafe10af3..e12b06ba394 100644
--- a/sys/dev/ic/re.c
+++ b/sys/dev/ic/re.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: re.c,v 1.83 2008/07/13 05:24:05 jsg Exp $ */
+/* $OpenBSD: re.c,v 1.84 2008/07/15 13:21:17 jsg Exp $ */
/* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -568,16 +568,10 @@ re_setmulti(struct rl_softc *sc)
* parts. This means we have to write the hash pattern in reverse
* order for those devices.
*/
- switch (sc->sc_hwrev) {
- case RL_HWREV_8100E_SPIN1:
- case RL_HWREV_8100E_SPIN2:
- case RL_HWREV_8101E:
- case RL_HWREV_8168_SPIN1:
- case RL_HWREV_8168_SPIN2:
+ if (sc->rl_flags & RL_FLAG_INVMAR) {
CSR_WRITE_4(sc, RL_MAR0, swap32(hashes[1]));
CSR_WRITE_4(sc, RL_MAR4, swap32(hashes[0]));
- break;
- default:
+ } else {
CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
}
@@ -867,6 +861,53 @@ re_attach(struct rl_softc *sc, const char *intrstr)
sc->sc_hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV;
+ switch (sc->sc_hwrev) {
+ case RL_HWREV_8139CPLUS:
+ sc->rl_flags |= RL_FLAG_NOJUMBO;
+ break;
+ case RL_HWREV_8100E_SPIN1:
+ case RL_HWREV_8100E_SPIN2:
+ case RL_HWREV_8101E:
+ sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR |
+ RL_FLAG_PHYWAKE;
+ break;
+ case RL_HWREV_8102E:
+ case RL_HWREV_8102EL:
+ sc->rl_flags |= RL_FLAG_NOJUMBO | RL_FLAG_INVMAR |
+ RL_FLAG_PHYWAKE | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT;
+ break;
+ case RL_HWREV_8168_SPIN1:
+ case RL_HWREV_8168_SPIN2:
+ case RL_HWREV_8168_SPIN3:
+ sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE |
+ RL_FLAG_MACSTAT;
+ break;
+ case RL_HWREV_8168C:
+ case RL_HWREV_8168C_SPIN2:
+ case RL_HWREV_8168CP:
+ sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE |
+ RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT;
+ /*
+ * These controllers support jumbo frame but it seems
+ * that enabling it requires touching additional magic
+ * registers. Depending on MAC revisions some
+ * controllers need to disable checksum offload. So
+ * disable jumbo frame until I have better idea what
+ * it really requires to make it support.
+ * RTL8168C/CP : supports up to 6KB jumbo frame.
+ * RTL8111C/CP : supports up to 9KB jumbo frame.
+ */
+ sc->rl_flags |= RL_FLAG_NOJUMBO;
+ break;
+ case RL_HWREV_8169_8110SB:
+ case RL_HWREV_8169_8110SCd:
+ case RL_HWREV_8169_8110SBL:
+ sc->rl_flags |= RL_FLAG_PHYWAKE;
+ break;
+ default:
+ break;
+ }
+
/*
* Set RX length mask, TX poll request register
* and TX descriptor count.
@@ -1007,13 +1048,16 @@ re_attach(struct rl_softc *sc, const char *intrstr)
ifp->if_start = re_start;
ifp->if_watchdog = re_watchdog;
ifp->if_init = re_init;
- if (sc->sc_hwrev != RL_HWREV_8139CPLUS)
+ if ((sc->rl_flags & RL_FLAG_NOJUMBO) == 0)
ifp->if_hardmtu = RL_JUMBO_MTU;
IFQ_SET_MAXLEN(&ifp->if_snd, RL_TX_QLEN);
IFQ_SET_READY(&ifp->if_snd);
- ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
- IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
+
+ ifp->if_capabilities = IFCAP_VLAN_MTU;
+ if ((sc->rl_flags & RL_FLAG_DESCV2) == 0)
+ ifp->if_capabilities |= IFCAP_CSUM_IPv4 |
+ IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
#if NVLAN > 0
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
@@ -1354,17 +1398,22 @@ re_rxeof(struct rl_softc *sc)
/* Do RX checksumming */
- /* Check IP header checksum */
- if ((rxstat & RL_RDESC_STAT_PROTOID) &&
- !(rxstat & RL_RDESC_STAT_IPSUMBAD))
- m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
-
- /* 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 |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
+ if (sc->rl_flags & RL_FLAG_DESCV2) {
+ /* XXX V2 CSUM */
+ } else {
+ /* Check IP header checksum */
+ if ((rxstat & RL_RDESC_STAT_PROTOID) &&
+ !(rxstat & RL_RDESC_STAT_IPSUMBAD))
+ m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
+
+ /* 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 |= M_TCP_CSUM_IN_OK |
+ M_UDP_CSUM_IN_OK;
+ }
#if NBPFILTER > 0
if (ifp->if_bpf)
@@ -1796,6 +1845,7 @@ re_init(struct ifnet *ifp)
{
struct rl_softc *sc = ifp->if_softc;
u_int32_t rxcfg = 0;
+ u_int16_t cfg;
int s;
union {
u_int32_t align_dummy;
@@ -1813,9 +1863,17 @@ re_init(struct ifnet *ifp)
* Enable C+ RX and TX mode, as well as RX checksum offload.
* We must configure the C+ register before all others.
*/
- CSR_WRITE_2(sc, RL_CPLUS_CMD, RL_CPLUSCMD_RXENB|
- RL_CPLUSCMD_TXENB|RL_CPLUSCMD_PCI_MRW|
- RL_CPLUSCMD_RXCSUM_ENB);
+ cfg = RL_CPLUSCMD_PCI_MRW;
+ if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
+ cfg |= RL_CPLUSCMD_RXCSUM_ENB;
+ if (sc->rl_flags & RL_FLAG_MACSTAT) {
+ cfg |= RL_CPLUSCMD_MACSTAT_DIS;
+ /* XXX magic. */
+ cfg |= 0x0001;
+ } else {
+ cfg |= RL_CPLUSCMD_RXENB | RL_CPLUSCMD_TXENB;
+ }
+ CSR_WRITE_2(sc, RL_CPLUS_CMD, cfg);
/*
* Init our MAC address. Even though the chipset