svn commit: r188359 - in stable/7/sys: . contrib/pf dev/ath/ath_hal
dev/cxgb dev/re pci
Pyun YongHyeon
yongari at FreeBSD.org
Sun Feb 8 17:38:03 PST 2009
Author: yongari
Date: Mon Feb 9 01:38:01 2009
New Revision: 188359
URL: http://svn.freebsd.org/changeset/base/188359
Log:
MFC r186214,186389,187417
r186214:
It seems that RealTek PCIe controllers require an explicit Tx poll
command whenever Tx completion interrupt is raised. The Tx poll
bit is cleared when all packets waiting to be transferred have been
processed. This means the second Tx poll command can be silently
ignored as the Tx poll bit could be still active while processing
of previous Tx poll command is in progress.
To address the issue re(4) used to invoke the Tx poll command in Tx
completion handler whenever it detects there are pending packets in
TxQ. However that still does not seem to completely eliminate
watchdog timeouts seen on RealTek PCIe controllers. To fix the
issue kick Tx poll command only after Tx completion interrupt is
raised as this would indicate Tx is now idle state such that it can
accept new Tx poll command again. While here apply this workaround
for PCIe based controllers as other controllers does not seem to
have this limitation.
r186389:
Since we don't request reset for rlphy(4), the link state 'UP'
event from mii(4) may not be delivered if valid link was already
established. To address the issue, check current link state after
driving MII_TICK. This should fix a regression introduced in
r185753 on fast ethernet controllers.
r187417:
Sometimes RTL8168B seems to take long time to access GMII registers
in device attach phase. Double GMII register access timeout value
to fix the issue.
Modified:
stable/7/sys/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/ath/ath_hal/ (props changed)
stable/7/sys/dev/cxgb/ (props changed)
stable/7/sys/dev/re/if_re.c
stable/7/sys/pci/if_rlreg.h
Modified: stable/7/sys/dev/re/if_re.c
==============================================================================
--- stable/7/sys/dev/re/if_re.c Mon Feb 9 01:30:14 2009 (r188358)
+++ stable/7/sys/dev/re/if_re.c Mon Feb 9 01:38:01 2009 (r188359)
@@ -418,14 +418,14 @@ re_gmii_readreg(device_t dev, int phy, i
CSR_WRITE_4(sc, RL_PHYAR, reg << 16);
- for (i = 0; i < RL_TIMEOUT; i++) {
+ for (i = 0; i < RL_PHY_TIMEOUT; i++) {
rval = CSR_READ_4(sc, RL_PHYAR);
if (rval & RL_PHYAR_BUSY)
break;
DELAY(100);
}
- if (i == RL_TIMEOUT) {
+ if (i == RL_PHY_TIMEOUT) {
device_printf(sc->rl_dev, "PHY read failed\n");
return (0);
}
@@ -445,14 +445,14 @@ re_gmii_writereg(device_t dev, int phy,
CSR_WRITE_4(sc, RL_PHYAR, (reg << 16) |
(data & RL_PHYAR_PHYDATA) | RL_PHYAR_BUSY);
- for (i = 0; i < RL_TIMEOUT; i++) {
+ for (i = 0; i < RL_PHY_TIMEOUT; i++) {
rval = CSR_READ_4(sc, RL_PHYAR);
if (!(rval & RL_PHYAR_BUSY))
break;
DELAY(100);
}
- if (i == RL_TIMEOUT) {
+ if (i == RL_PHY_TIMEOUT) {
device_printf(sc->rl_dev, "PHY write failed\n");
return (0);
}
@@ -1157,6 +1157,7 @@ re_attach(device_t dev)
msic = 0;
if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
+ sc->rl_flags |= RL_FLAG_PCIE;
msic = pci_msi_count(dev);
if (bootverbose)
device_printf(dev, "MSI count : %d\n", msic);
@@ -2042,16 +2043,6 @@ re_txeof(struct rl_softc *sc)
/* No changes made to the TX ring, so no flush needed */
if (sc->rl_ldata.rl_tx_free != sc->rl_ldata.rl_tx_desc_cnt) {
- /*
- * Some chips will ignore a second TX request issued
- * while an existing transmission is in progress. If
- * the transmitter goes idle but there are still
- * packets waiting to be sent, we need to restart the
- * channel here to flush them out. This only seems to
- * be required with the PCIe devices.
- */
- CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
-
#ifdef RE_TX_MODERATION
/*
* If not all descriptors have been reaped yet, reload
@@ -2077,6 +2068,8 @@ re_tick(void *xsc)
mii = device_get_softc(sc->rl_miibus);
mii_tick(mii);
+ if ((sc->rl_flags & RL_FLAG_LINK) == 0)
+ re_miibus_statchg(sc->rl_dev);
re_watchdog(sc);
callout_reset(&sc->rl_stat_callout, hz, re_tick, sc);
}
@@ -2115,6 +2108,9 @@ re_poll_locked(struct ifnet *ifp, enum p
return;
if (status)
CSR_WRITE_2(sc, RL_ISR, status);
+ if ((status & (RL_ISR_TX_OK | RL_ISR_TX_DESC_UNAVAIL)) &&
+ (sc->rl_flags & RL_FLAG_PCIE))
+ CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
/*
* XXX check behaviour on receiver stalls.
@@ -2176,6 +2172,17 @@ re_int_task(void *arg, int npending)
if (status & (RL_ISR_RX_OK|RL_ISR_RX_ERR|RL_ISR_FIFO_OFLOW))
rval = re_rxeof(sc);
+ /*
+ * Some chips will ignore a second TX request issued
+ * while an existing transmission is in progress. If
+ * the transmitter goes idle but there are still
+ * packets waiting to be sent, we need to restart the
+ * channel here to flush them out. This only seems to
+ * be required with the PCIe devices.
+ */
+ if ((status & (RL_ISR_TX_OK | RL_ISR_TX_DESC_UNAVAIL)) &&
+ (sc->rl_flags & RL_FLAG_PCIE))
+ CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
if (status & (
#ifdef RE_TX_MODERATION
RL_ISR_TIMEOUT_EXPIRED|
Modified: stable/7/sys/pci/if_rlreg.h
==============================================================================
--- stable/7/sys/pci/if_rlreg.h Mon Feb 9 01:30:14 2009 (r188358)
+++ stable/7/sys/pci/if_rlreg.h Mon Feb 9 01:38:01 2009 (r188359)
@@ -864,6 +864,7 @@ struct rl_softc {
#define RL_FLAG_PHY8110S 0x0800
#define RL_FLAG_WOLRXENB 0x1000
#define RL_FLAG_MACSLEEP 0x2000
+#define RL_FLAG_PCIE 0x4000
#define RL_FLAG_LINK 0x8000
};
@@ -909,6 +910,7 @@ struct rl_softc {
CSR_WRITE_4(sc, offset, CSR_READ_4(sc, offset) & ~(val))
#define RL_TIMEOUT 1000
+#define RL_PHY_TIMEOUT 2000
/*
* General constants that are fun to know.
More information about the svn-src-stable-7
mailing list