Hi! Some days back I put card in Win7 machine. Win7 hang own network subsystem if connected to gigabit switch. I tried last night your patches. Now when put in gigabit switch no hangs or errors, but link (autodetect) 100mbit/s and work good. I think I bought buggy network cards :((.
Index: sys/dev/mii/ip1000phy.c =================================================================== --- sys/dev/mii/ip1000phy.c (revision 227501) +++ sys/dev/mii/ip1000phy.c (working copy) @@ -324,7 +324,6 @@ PHY_WRITE(sc, IP1000PHY_MII_ANAR, reg | IP1000PHY_ANAR_CSMA); reg = IP1000PHY_1000CR_1000T | IP1000PHY_1000CR_1000T_FDX; - reg |= IP1000PHY_1000CR_MASTER; PHY_WRITE(sc, IP1000PHY_MII_1000CR, reg); PHY_WRITE(sc, IP1000PHY_MII_BMCR, (IP1000PHY_BMCR_FDX | IP1000PHY_BMCR_AUTOEN | IP1000PHY_BMCR_STARTNEG)); Index: sys/dev/vge/if_vge.c =================================================================== --- sys/dev/vge/if_vge.c (revision 227501) +++ sys/dev/vge/if_vge.c (working copy) @@ -173,6 +173,7 @@ static void vge_freebufs(struct vge_softc *); static void vge_ifmedia_sts(struct ifnet *, struct ifmediareq *); static int vge_ifmedia_upd(struct ifnet *); +static int vge_ifmedia_upd_locked(struct vge_softc *); static void vge_init(void *); static void vge_init_locked(struct vge_softc *); static void vge_intr(void *); @@ -180,7 +181,6 @@ static int vge_ioctl(struct ifnet *, u_long, caddr_t); static void vge_link_statchg(void *); static int vge_miibus_readreg(device_t, int, int); -static void vge_miibus_statchg(device_t); static int vge_miibus_writereg(device_t, int, int, int); static void vge_miipoll_start(struct vge_softc *); static void vge_miipoll_stop(struct vge_softc *); @@ -190,6 +190,7 @@ static int vge_rx_list_init(struct vge_softc *); static int vge_rxeof(struct vge_softc *, int); static void vge_rxfilter(struct vge_softc *); +static void vge_setmedia(struct vge_softc *); static void vge_setvlan(struct vge_softc *); static void vge_setwol(struct vge_softc *); static void vge_start(struct ifnet *); @@ -218,7 +219,6 @@ /* MII interface */ DEVMETHOD(miibus_readreg, vge_miibus_readreg), DEVMETHOD(miibus_writereg, vge_miibus_writereg), - DEVMETHOD(miibus_statchg, vge_miibus_statchg), { 0, 0 } }; @@ -1099,10 +1099,11 @@ goto fail; } + vge_miipoll_start(sc); /* Do MII setup */ error = mii_attach(dev, &sc->vge_miibus, ifp, vge_ifmedia_upd, vge_ifmedia_sts, BMSR_DEFCAPMASK, sc->vge_phyaddr, MII_OFFSET_ANY, - 0); + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -1660,30 +1661,41 @@ { struct vge_softc *sc; struct ifnet *ifp; - struct mii_data *mii; + uint8_t physts; sc = xsc; ifp = sc->vge_ifp; VGE_LOCK_ASSERT(sc); - mii = device_get_softc(sc->vge_miibus); - mii_pollstat(mii); - if ((sc->vge_flags & VGE_FLAG_LINK) != 0) { - if (!(mii->mii_media_status & IFM_ACTIVE)) { + physts = CSR_READ_1(sc, VGE_PHYSTS0); + if ((physts & VGE_PHYSTS_RESETSTS) == 0) { + if ((physts & VGE_PHYSTS_LINK) == 0) { sc->vge_flags &= ~VGE_FLAG_LINK; if_link_state_change(sc->vge_ifp, LINK_STATE_DOWN); - } - } else { - if (mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { + } else { sc->vge_flags |= VGE_FLAG_LINK; if_link_state_change(sc->vge_ifp, LINK_STATE_UP); + CSR_WRITE_1(sc, VGE_CRC2, VGE_CR2_FDX_TXFLOWCTL_ENABLE | + VGE_CR2_FDX_RXFLOWCTL_ENABLE); + if ((physts & VGE_PHYSTS_FDX) != 0) { + if ((physts & VGE_PHYSTS_TXFLOWCAP) != 0) + CSR_WRITE_1(sc, VGE_CRS2, + VGE_CR2_FDX_TXFLOWCTL_ENABLE); + if ((physts & VGE_PHYSTS_RXFLOWCAP) != 0) + CSR_WRITE_1(sc, VGE_CRS2, + VGE_CR2_FDX_RXFLOWCTL_ENABLE); + } if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) vge_start_locked(ifp); } } + /* + * Restart MII auto-polling because link state change interrupt + * will disable it. + */ + vge_miipoll_start(sc); } #ifdef DEVICE_POLLING @@ -2028,6 +2040,7 @@ */ vge_stop(sc); vge_reset(sc); + vge_miipoll_start(sc); /* * Initialize the RX and TX descriptors and mbufs. @@ -2099,10 +2112,17 @@ vge_rxfilter(sc); vge_setvlan(sc); - /* Enable flow control */ + /* Initialize pause timer. */ + CSR_WRITE_2(sc, VGE_TX_PAUSE_TIMER, 0xFFFF); + /* + * Initialize flow control parameters. + * TX XON high threshold : 48 + * TX pause low threshold : 24 + * Disable hald-duplex flow control + */ + CSR_WRITE_1(sc, VGE_CRC2, 0xFF); + CSR_WRITE_1(sc, VGE_CRS2, VGE_CR2_XON_ENABLE | 0x0B); - CSR_WRITE_1(sc, VGE_CRS2, 0x8B); - /* Enable jumbo frame reception (if desired) */ /* Start the MAC. */ @@ -2129,7 +2149,7 @@ CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK); sc->vge_flags &= ~VGE_FLAG_LINK; - mii_mediachg(mii); + vge_ifmedia_upd_locked(sc); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -2143,14 +2163,28 @@ vge_ifmedia_upd(struct ifnet *ifp) { struct vge_softc *sc; - struct mii_data *mii; int error; sc = ifp->if_softc; VGE_LOCK(sc); + error = vge_ifmedia_upd_locked(sc); + VGE_UNLOCK(sc); + + return (error); +} + +static int +vge_ifmedia_upd_locked(struct vge_softc *sc) +{ + struct mii_data *mii; + struct mii_softc *miisc; + int error; + mii = device_get_softc(sc->vge_miibus); + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + PHY_RESET(miisc); + vge_setmedia(sc); error = mii_mediachg(mii); - VGE_UNLOCK(sc); return (error); } @@ -2179,13 +2213,11 @@ } static void -vge_miibus_statchg(device_t dev) +vge_setmedia(struct vge_softc *sc) { - struct vge_softc *sc; struct mii_data *mii; struct ifmedia_entry *ife; - sc = device_get_softc(dev); mii = device_get_softc(sc->vge_miibus); ife = mii->mii_media.ifm_cur; @@ -2219,7 +2251,7 @@ } break; default: - device_printf(dev, "unknown media type: %x\n", + device_printf(sc->vge_dev, "unknown media type: %x\n", IFM_SUBTYPE(ife->ifm_media)); break; } @@ -2772,6 +2804,9 @@ break; } } + /* Clear forced MAC speed/duplex configuration. */ + CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE); + CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE); vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_100T2CR, 0); vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_ANAR, ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA);
_______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"