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"

Reply via email to