diff options
author | yongari <yongari@FreeBSD.org> | 2007-01-08 00:58:00 +0000 |
---|---|---|
committer | yongari <yongari@FreeBSD.org> | 2007-01-08 00:58:00 +0000 |
commit | c72796ebf4aa19ba0e60e6f8b0fc87e78ceded28 (patch) | |
tree | 67a674b11bc3121ac2536e235bf804f058194f58 /sys/dev/msk/if_msk.c | |
parent | 8825eb7340fd7c42a8c7eb5c3789dede0e9de8da (diff) | |
download | FreeBSD-src-c72796ebf4aa19ba0e60e6f8b0fc87e78ceded28.zip FreeBSD-src-c72796ebf4aa19ba0e60e6f8b0fc87e78ceded28.tar.gz |
Don't rely on GM_GP_CTRL register contents when mii(4) layer reports
link state changes. Instead, build new speed/duplex/flow-control
settings from the values reported from PHY.
This should fix speed/duplex/flow-control mismatches between GMAC and
PHY which resulted in very poor Rx performance due to lots of
out-of-order packet delivery.
Reported by: Arno J. Klaassen <arno AT heho DOT snv DOT jussieu DOT fr>
Tested by: Arno J. Klaassen <arno AT heho DOT snv DOT jussieu DOT fr>
Diffstat (limited to 'sys/dev/msk/if_msk.c')
-rw-r--r-- | sys/dev/msk/if_msk.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index def6df8..ea2bd01 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -445,7 +445,7 @@ msk_link_task(void *arg, int pending) struct msk_if_softc *sc_if; struct mii_data *mii; struct ifnet *ifp; - uint32_t gmac, ane; + uint32_t gmac; sc_if = (struct msk_if_softc *)arg; sc = sc_if->msk_softc; @@ -465,42 +465,36 @@ msk_link_task(void *arg, int pending) } else sc_if->msk_link = 0; - gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); - ane = 0; if (sc_if->msk_link != 0) { /* Enable Tx FIFO Underrun. */ CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_MSK), GM_IS_TX_FF_UR | GM_IS_RX_FF_OR); + /* + * Because mii(4) notify msk(4) that it detected link status + * change, there is no need to enable automatic + * speed/flow-control/duplex updates. + */ + gmac = GM_GPCR_AU_ALL_DIS; switch (IFM_SUBTYPE(mii->mii_media_active)) { - case IFM_AUTO: - ane = 1; - break; case IFM_1000_SX: case IFM_1000_T: - gmac &= ~GM_GPCR_SPEED_100; gmac |= GM_GPCR_SPEED_1000; break; case IFM_100_TX: gmac |= GM_GPCR_SPEED_100; - gmac &= ~GM_GPCR_SPEED_1000; break; case IFM_10_T: - gmac &= ~(GM_GPCR_SPEED_100 | GM_GPCR_SPEED_1000); break; } - if (ane == 0) - gmac |= GM_GPCR_AU_ALL_DIS; - else - gmac &= ~GM_GPCR_AU_ALL_DIS; if (((mii->mii_media_active & IFM_GMASK) & IFM_FDX) != 0) gmac |= GM_GPCR_DUP_FULL; - /* Enable Rx flow control. */ - if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG0) != 0) - gmac &= ~GM_GPCR_FC_RX_DIS; - /* Enable Tx flow control. */ - if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG1) != 0) - gmac &= ~GM_GPCR_FC_TX_DIS; + /* Disable Rx flow control. */ + if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG0) == 0) + gmac |= GM_GPCR_FC_RX_DIS; + /* Disable Tx flow control. */ + if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG1) == 0) + gmac |= GM_GPCR_FC_TX_DIS; gmac |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, gmac); /* Read again to ensure writing. */ @@ -530,6 +524,7 @@ msk_link_task(void *arg, int pending) msk_phy_writereg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_MASK, 0); /* Disable Rx/Tx MAC. */ + gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); gmac &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, gmac); /* Read again to ensure writing. */ |