summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/re/if_re.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/re/if_re.c')
-rw-r--r--freebsd/sys/dev/re/if_re.c114
1 files changed, 68 insertions, 46 deletions
diff --git a/freebsd/sys/dev/re/if_re.c b/freebsd/sys/dev/re/if_re.c
index b574f9a2..554af66a 100644
--- a/freebsd/sys/dev/re/if_re.c
+++ b/freebsd/sys/dev/re/if_re.c
@@ -129,6 +129,7 @@ __FBSDID("$FreeBSD$");
#include <sys/taskqueue.h>
#include <net/if.h>
+#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
@@ -149,7 +150,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
MODULE_DEPEND(re, pci, 1, 1, 1);
MODULE_DEPEND(re, ether, 1, 1, 1);
@@ -239,6 +240,7 @@ static const struct rl_hwrev re_hwrevs[] = {
{ RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168G, RL_8169, "8168G/8111G", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168GU, RL_8169, "8168GU/8111GU", RL_JUMBO_MTU_9K},
+ { RL_HWREV_8168H, RL_8169, "8168H/8111H", RL_JUMBO_MTU_9K},
{ RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K},
{ RL_HWREV_8411B, RL_8169, "8411B", RL_JUMBO_MTU_9K},
{ 0, 0, NULL, 0 }
@@ -305,6 +307,7 @@ static void re_set_linkspeed (struct rl_softc *);
#ifdef DEV_NETMAP /* see ixgbe.c for details */
#include <dev/netmap/if_re_netmap.h>
+MODULE_DEPEND(re, netmap, 1, 1, 1);
#endif /* !DEV_NETMAP */
#ifdef RE_DIAG
@@ -635,9 +638,8 @@ re_miibus_statchg(device_t dev)
}
}
/*
- * RealTek controllers does not provide any interface to
- * Tx/Rx MACs for resolved speed, duplex and flow-control
- * parameters.
+ * RealTek controllers do not provide any interface to the RX/TX
+ * MACs for resolved speed, duplex and flow-control parameters.
*/
}
@@ -659,7 +661,7 @@ re_set_rxmode(struct rl_softc *sc)
rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
if ((sc->rl_flags & RL_FLAG_EARLYOFF) != 0)
rxfilt |= RL_RXCFG_EARLYOFF;
- else if ((sc->rl_flags & RL_FLAG_EARLYOFFV2) != 0)
+ else if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
rxfilt |= RL_RXCFG_EARLYOFFV2;
if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
@@ -953,7 +955,7 @@ re_probe(device_t dev)
}
t = re_devs;
- for (i = 0; i < sizeof(re_devs) / sizeof(re_devs[0]); i++, t++) {
+ for (i = 0; i < nitems(re_devs); i++, t++) {
if (vendor == t->rl_vid && devid == t->rl_did) {
device_set_desc(dev, t->rl_name);
return (BUS_PROBE_DEFAULT);
@@ -1206,11 +1208,10 @@ re_attach(device_t dev)
struct rl_softc *sc;
struct ifnet *ifp;
const struct rl_hwrev *hw_rev;
+ int capmask, error = 0, hwrev, i, msic, msixc,
+ phy, reg, rid;
u_int32_t cap, ctl;
- int hwrev;
u_int16_t devid, re_did = 0;
- int error = 0, i, phy, rid;
- int msic, msixc, reg;
uint8_t cfg;
sc = device_get_softc(dev);
@@ -1338,7 +1339,7 @@ re_attach(device_t dev)
SYS_RES_IRQ, &rid, RF_ACTIVE);
if (sc->rl_irq[i] == NULL) {
device_printf(dev,
- "couldn't llocate IRQ resources for "
+ "couldn't allocate IRQ resources for "
"message %d\n", rid);
error = ENXIO;
goto fail;
@@ -1364,8 +1365,8 @@ re_attach(device_t dev)
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
ctl = pci_read_config(dev, sc->rl_expcap +
PCIER_LINK_CTL, 2);
- if ((ctl & 0x0003) != 0) {
- ctl &= ~0x0003;
+ if ((ctl & PCIEM_LINK_CTL_ASPMC) != 0) {
+ ctl &= ~PCIEM_LINK_CTL_ASPMC;
pci_write_config(dev, sc->rl_expcap +
PCIER_LINK_CTL, ctl, 2);
device_printf(dev, "ASPM disabled\n");
@@ -1490,11 +1491,12 @@ re_attach(device_t dev)
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK |
- RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+ RL_FLAG_8168G_PLUS;
break;
case RL_HWREV_8168GU:
+ case RL_HWREV_8168H:
if (pci_get_device(dev) == RT_DEVICEID_8101E) {
- /* RTL8106EUS */
+ /* RTL8106E(US), RTL8107E */
sc->rl_flags |= RL_FLAG_FASTETHER;
} else
sc->rl_flags |= RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK;
@@ -1502,7 +1504,7 @@ re_attach(device_t dev)
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ |
- RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+ RL_FLAG_8168G_PLUS;
break;
case RL_HWREV_8169_8110SB:
case RL_HWREV_8169_8110SBL:
@@ -1652,8 +1654,11 @@ re_attach(device_t dev)
phy = RE_PHYAD_INTERNAL;
if (sc->rl_type == RL_8169)
phy = 1;
+ capmask = BMSR_DEFCAPMASK;
+ if ((sc->rl_flags & RL_FLAG_FASTETHER) != 0)
+ capmask &= ~BMSR_EXTSTAT;
error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd,
- re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
+ re_ifmedia_sts, capmask, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto fail;
@@ -1676,7 +1681,7 @@ re_attach(device_t dev)
/*
* Don't enable TSO by default. It is known to generate
* corrupted TCP segments(bad TCP options) under certain
- * circumtances.
+ * circumstances.
*/
ifp->if_hwassist &= ~CSUM_TSO;
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO);
@@ -1688,18 +1693,18 @@ re_attach(device_t dev)
* Must appear after the call to ether_ifattach() because
* ether_ifattach() sets ifi_hdrlen to the default value.
*/
- ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+ ifp->if_hdrlen = sizeof(struct ether_vlan_header);
#ifdef DEV_NETMAP
re_netmap_attach(sc);
#endif /* DEV_NETMAP */
+
#ifdef RE_DIAG
/*
* Perform hardware diagnostic on the original RTL8169.
* Some 32-bit cards were incorrectly wired and would
* malfunction if plugged into a 64-bit slot.
*/
-
if (hwrev == RL_HWREV_8169) {
error = re_diag(sc);
if (error) {
@@ -1731,7 +1736,6 @@ re_attach(device_t dev)
}
fail:
-
if (error)
re_detach(dev);
@@ -1825,10 +1829,10 @@ re_detach(device_t dev)
/* Unload and free the RX DMA ring memory and map */
if (sc->rl_ldata.rl_rx_list_tag) {
- if (sc->rl_ldata.rl_rx_list_map)
+ if (sc->rl_ldata.rl_rx_list_addr)
bus_dmamap_unload(sc->rl_ldata.rl_rx_list_tag,
sc->rl_ldata.rl_rx_list_map);
- if (sc->rl_ldata.rl_rx_list_map && sc->rl_ldata.rl_rx_list)
+ if (sc->rl_ldata.rl_rx_list)
bus_dmamem_free(sc->rl_ldata.rl_rx_list_tag,
sc->rl_ldata.rl_rx_list,
sc->rl_ldata.rl_rx_list_map);
@@ -1838,10 +1842,10 @@ re_detach(device_t dev)
/* Unload and free the TX DMA ring memory and map */
if (sc->rl_ldata.rl_tx_list_tag) {
- if (sc->rl_ldata.rl_tx_list_map)
+ if (sc->rl_ldata.rl_tx_list_addr)
bus_dmamap_unload(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list_map);
- if (sc->rl_ldata.rl_tx_list_map && sc->rl_ldata.rl_tx_list)
+ if (sc->rl_ldata.rl_tx_list)
bus_dmamem_free(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list,
sc->rl_ldata.rl_tx_list_map);
@@ -1883,10 +1887,10 @@ re_detach(device_t dev)
/* Unload and free the stats buffer and map */
if (sc->rl_ldata.rl_stag) {
- if (sc->rl_ldata.rl_smap)
+ if (sc->rl_ldata.rl_stats_addr)
bus_dmamap_unload(sc->rl_ldata.rl_stag,
sc->rl_ldata.rl_smap);
- if (sc->rl_ldata.rl_smap && sc->rl_ldata.rl_stats)
+ if (sc->rl_ldata.rl_stats)
bus_dmamem_free(sc->rl_ldata.rl_stag,
sc->rl_ldata.rl_stats, sc->rl_ldata.rl_smap);
bus_dma_tag_destroy(sc->rl_ldata.rl_stag);
@@ -2248,7 +2252,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
(rxstat & RL_RDESC_STAT_ERRS) == RL_RDESC_STAT_GIANT)
rxerr = 0;
if (rxerr != 0) {
- ifp->if_ierrors++;
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
/*
* If this is part of a multi-fragment packet,
* discard all the pieces.
@@ -2271,7 +2275,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
else
rxerr = re_newbuf(sc, i);
if (rxerr != 0) {
- ifp->if_iqdrops++;
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
if (sc->rl_head != NULL) {
m_freem(sc->rl_head);
sc->rl_head = sc->rl_tail = NULL;
@@ -2313,7 +2317,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
#ifdef RE_FIXUP_RX
re_fixup_rx(m);
#endif
- ifp->if_ipackets++;
+ if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
m->m_pkthdr.rcvif = ifp;
/* Do RX checksumming if enabled */
@@ -2432,11 +2436,11 @@ re_txeof(struct rl_softc *sc)
txd->tx_m = NULL;
if (txstat & (RL_TDESC_STAT_EXCESSCOL|
RL_TDESC_STAT_COLCNT))
- ifp->if_collisions++;
+ if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
if (txstat & RL_TDESC_STAT_TXERRSUM)
- ifp->if_oerrors++;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
else
- ifp->if_opackets++;
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
sc->rl_ldata.rl_tx_free++;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
@@ -2551,7 +2555,7 @@ re_intr(void *arg)
return (FILTER_STRAY);
CSR_WRITE_2(sc, RL_IMR, 0);
- taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_inttask);
+ taskqueue_enqueue(taskqueue_fast, &sc->rl_inttask);
return (FILTER_HANDLED);
}
@@ -2619,7 +2623,7 @@ re_int_task(void *arg, int npending)
RL_UNLOCK(sc);
if ((CSR_READ_2(sc, RL_ISR) & RL_INTRS_CPLUS) || rval) {
- taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_inttask);
+ taskqueue_enqueue(taskqueue_fast, &sc->rl_inttask);
return;
}
@@ -2827,7 +2831,7 @@ re_encap(struct rl_softc *sc, struct mbuf **m_head)
/*
* Unconditionally enable IP checksum if TCP or UDP
* checksum is required. Otherwise, TCP/UDP checksum
- * does't make effects.
+ * doesn't make effects.
*/
if (((*m_head)->m_pkthdr.csum_flags & RE_CSUM_FEATURES) != 0) {
if ((sc->rl_flags & RL_FLAG_DESCV2) == 0) {
@@ -2937,6 +2941,7 @@ re_start_locked(struct ifnet *ifp)
return;
}
#endif /* DEV_NETMAP */
+
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
return;
@@ -3192,14 +3197,18 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr));
- if ((sc->rl_flags & RL_FLAG_RXDV_GATED) != 0)
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+ /* Disable RXDV gate. */
CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
~0x00080000);
+ }
/*
- * Enable transmit and receive.
+ * Enable transmit and receive for pre-RTL8168G controllers.
+ * RX/TX MACs should be enabled before RX/TX configuration.
*/
- CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) == 0)
+ CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
/*
* Set the initial TX configuration.
@@ -3227,6 +3236,13 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_2(sc, RL_INTRMOD, 0x5100);
}
+ /*
+ * Enable transmit and receive for RTL8168G and later controllers.
+ * RX/TX MACs should be enabled after RX/TX configuration.
+ */
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
+ CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
+
#ifdef DEVICE_POLLING
/*
* Disable interrupts if we are polling.
@@ -3250,10 +3266,6 @@ re_init_locked(struct rl_softc *sc)
/* Start RX/TX process. */
CSR_WRITE_4(sc, RL_MISSEDPKT, 0);
-#ifdef notdef
- /* Enable receiver and transmitter. */
- CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
-#endif
/*
* Initialize the timer interrupt register so that
@@ -3294,7 +3306,7 @@ re_init_locked(struct rl_softc *sc)
if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0) {
/*
* For controllers that use new jumbo frame scheme,
- * set maximum size of jumbo frame depedning on
+ * set maximum size of jumbo frame depending on
* controller revisions.
*/
if (ifp->if_mtu > RL_MTU)
@@ -3546,7 +3558,7 @@ re_watchdog(struct rl_softc *sc)
}
if_printf(ifp, "watchdog timeout\n");
- ifp->if_oerrors++;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
re_rxeof(sc, NULL);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
@@ -3585,6 +3597,12 @@ re_stop(struct rl_softc *sc)
~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI |
RL_RXCFG_RX_BROAD));
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+ /* Enable RXDV gate. */
+ CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) |
+ 0x00080000);
+ }
+
if ((sc->rl_flags & RL_FLAG_WAIT_TXPOLL) != 0) {
for (i = RL_TIMEOUT; i > 0; i--) {
if ((CSR_READ_1(sc, sc->rl_txstart) &
@@ -3836,6 +3854,11 @@ re_setwol(struct rl_softc *sc)
CSR_READ_1(sc, RL_GPIO) & ~0x01);
}
if ((ifp->if_capenable & IFCAP_WOL) != 0) {
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+ /* Disable RXDV gate. */
+ CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
+ ~0x00080000);
+ }
re_set_rxmode(sc);
if ((sc->rl_flags & RL_FLAG_WOL_MANLINK) != 0)
re_set_linkspeed(sc);
@@ -3948,7 +3971,6 @@ re_add_sysctls(struct rl_softc *sc)
sc->rl_int_rx_mod = RL_TIMER_DEFAULT;
}
}
-
}
static int
@@ -3990,7 +4012,7 @@ re_sysctl_stats(SYSCTL_HANDLER_ARGS)
RL_UNLOCK(sc);
if (i == 0) {
device_printf(sc->rl_dev,
- "DUMP statistics request timedout\n");
+ "DUMP statistics request timed out\n");
return (ETIMEDOUT);
}
done: