On Sun, Dec 14, 2008 at 06:26:30PM +0100, Mam Ruoc wrote:
 > Hi!
 > 
 > With problems with my VIA ITX Velocity driver problem, I bought this 
 > device. In the supported hardware list of FreeBSD 7.0, this should be 
 > supported just fine.
 > 
 > I get this on bootup, and the device seems "up", but does not working:
 > 
 > axe0: <vendor 0x050d product 0x5055, class 255/255, rev 2.00/0.01, addr 
 > 2> on uhub3
 > axe0: AX88178, bufsz 1536, boundary 64
 > miibus0: <MII bus> on axe0
 > ukphy0: <Generic IEEE 802.3u media interface> PHY 0 on miibus0
 > ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseSX, 
 > 1000baseT, 1000baseT-FDX auto
 > axe0: using obsoleted if_watchdog interface
 > axe0: Ethernet address: 00:11:50:e7:94:70
 > axe0: if_start running deferred for Giant
 > 
 > 
 > Anyboy have the same experience?
 > 

I have a patch for axe(4) but the patch seem to break AX88172.
Try attached patch. Since ukphy(4) was attached to axe(4) I guess 
you may need a dedicated PHY driver. Show me the output of
"devinfo -rv | grep phy".

-- 
Regards,
Pyun YongHyeon
Index: sys/dev/usb/if_axe.c
===================================================================
--- sys/dev/usb/if_axe.c        (revision 183636)
+++ sys/dev/usb/if_axe.c        (working copy)
@@ -162,6 +162,7 @@
 static miibus_writereg_t axe_miibus_writereg;
 static miibus_statchg_t axe_miibus_statchg;
 
+static int axe_get_phyno(struct axe_softc *, int);
 static int axe_encap(struct axe_softc *, struct mbuf *, int);
 static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
 static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
@@ -248,21 +249,10 @@
                return(0);
 
        AXE_SLEEPLOCKASSERT(sc);
-#ifdef notdef
-       /*
-        * The chip tells us the MII address of any supported
-        * PHYs attached to the chip, so only read from those.
-        */
 
-       if (sc->axe_phyaddrs[0] != AXE_NOPHY && phy != sc->axe_phyaddrs[0])
+       if (sc->axe_phyno != phy)
                return (0);
 
-       if (sc->axe_phyaddrs[1] != AXE_NOPHY && phy != sc->axe_phyaddrs[1])
-               return (0);
-#endif
-       if (sc->axe_phyaddrs[0] != 0xFF && sc->axe_phyaddrs[0] != phy)
-               return (0);
-
        AXE_LOCK(sc);
        axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
        err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, (void *)&val);
@@ -274,10 +264,18 @@
                return(-1);
        }
 
-       if (val && val != 0xffff)
-               sc->axe_phyaddrs[0] = phy;
+       val = le16toh(val);
+       if ((sc->axe_flags & AX772) != 0 && reg == MII_BMSR) {
+               /*
+                * BMSR of AX88772 indicates that it supports extended
+                * capability but the extended status register is
+                * revered for embedded ethernet PHY. So clear the
+                * extended capability bit of BMSR.
+                */
+               val &= ~BMSR_EXTCAP;
+       }
 
-       return (le16toh(val));
+       return (val);
 }
 
 static int
@@ -290,6 +288,10 @@
                return(0);
 
        AXE_SLEEPLOCKASSERT(sc);
+
+       if (sc->axe_phyno != phy)
+               return (0);
+
        AXE_LOCK(sc);
        axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
        val = htole32(val);
@@ -310,12 +312,58 @@
 {
        struct axe_softc        *sc = device_get_softc(dev);
        struct mii_data         *mii = GET_MII(sc);
+       struct ifnet            *ifp;
        int                     val, err;
 
-       val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ?
-           AXE_MEDIA_FULL_DUPLEX : 0;
+       ifp = sc->axe_ifp;
+       if (mii == NULL || ifp == NULL ||
+           (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+               return;
+
+       sc->axe_link = 0;
+       if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+           (IFM_ACTIVE | IFM_AVALID)) {
+               switch (IFM_SUBTYPE(mii->mii_media_active)) {
+               case IFM_10_T:
+                       sc->axe_link++;
+#if 1
+                       device_printf(dev, "LINK UP 10Mbps\n");
+#endif
+                       break;
+               case IFM_100_TX:
+                       sc->axe_link++;
+#if 1
+                       device_printf(dev, "LINK UP 100Mbps\n");
+#endif
+                       break;
+               case IFM_1000_T:
+                       if ((sc->axe_flags & AX178) == 0)
+                               break;
+                       sc->axe_link++;
+#if 1
+                       device_printf(dev, "LINK UP 1000Mbps\n");
+#endif
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       /* Lost link, do nothing. */
+       if (sc->axe_link == 0) {
+#if 1
+               device_printf(dev, "LINK DOWN\n");
+#endif
+               return;
+       }
+
+       val = 0;
+       if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+               val |= AXE_MEDIA_FULL_DUPLEX;
        if (sc->axe_flags & (AX178|AX772)) {
                val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
+               if (sc->axe_flags & AX178)
+                       val |= AXE_178_MEDIA_ENCK;
 
                switch (IFM_SUBTYPE(mii->mii_media_active)) {
                case IFM_1000_T:
@@ -343,7 +391,6 @@
         struct axe_softc        *sc = ifp->if_softc;
         struct mii_data         *mii = GET_MII(sc);
 
-        sc->axe_link = 0;
         if (mii->mii_instance) {
                 struct mii_softc        *miisc;
                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
@@ -456,6 +503,9 @@
        axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
            AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
        usbd_delay_ms(sc->axe_udev, 150);
+       /* Enable MII/GMII/RGMII interface to work with external PHY. */
+       axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
+       usbd_delay_ms(sc->axe_udev, 150);
        axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
 }
 
@@ -465,7 +515,7 @@
        axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
        usbd_delay_ms(sc->axe_udev, 40);
 
-       if (sc->axe_phyaddrs[1] == AXE_INTPHY) {
+       if (sc->axe_phyno == AXE_PHY_NO_AX772_EPHY) {
                /* ask for embedded PHY */
                axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
                usbd_delay_ms(sc->axe_udev, 10);
@@ -516,6 +566,30 @@
        return;
 }
 
+static int
+axe_get_phyno(struct axe_softc *sc, int sel)
+{
+       int             phyno;
+
+       phyno = -1;
+       switch (AXE_PHY_TYPE(sc->axe_phyaddrs[sel])) {
+       case PHY_TYPE_100_HOME:
+       case PHY_TYPE_GIG:
+               phyno  = AXE_PHY_NO(sc->axe_phyaddrs[sel]);
+               break;
+       case PHY_TYPE_SPECIAL:
+               /* FALLTHROUGH */
+       case PHY_TYPE_RSVD:
+               /* FALLTHROUGH */
+       case PHY_TYPE_NON_SUP:
+               /* FALLTHROUGH */
+       default:
+               break;
+       }
+
+       return (phyno);
+}
+
 /*
  * Probe for a AX88172 chip.
  */
@@ -610,6 +684,18 @@
 
        /* We need the PHYID for the init dance in some cases */
        axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs);
+#if 1
+       device_printf(sc->axe_dev, "PHYADDR 0x%02x:0x%02x\n",
+           sc->axe_phyaddrs[0], sc->axe_phyaddrs[1]);
+#endif
+       sc->axe_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
+       if (sc->axe_phyno == -1)
+               sc->axe_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);
+       if (sc->axe_phyno == -1) {
+               device_printf(sc->axe_dev,
+                "no valid PHY address found, assuming PHY address 0\n");
+               sc->axe_phyno = 0;
+       }
 
        if (sc->axe_flags & AX178)
                axe_ax88178_init(sc);
@@ -629,12 +715,6 @@
         */
        axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs);
 
-       /*
-        * Work around broken adapters that appear to lie about
-        * their PHY addresses.
-        */
-       sc->axe_phyaddrs[0] = sc->axe_phyaddrs[1] = 0xFF;
-
        ifp = sc->axe_ifp = if_alloc(IFT_ETHER);
        if (ifp == NULL) {
                device_printf(sc->axe_dev, "can not if_alloc()\n");
@@ -999,12 +1079,8 @@
        }
 
        mii_tick(mii);
-       if (!sc->axe_link && mii->mii_media_status & IFM_ACTIVE &&
-           IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
-               sc->axe_link++;
-               if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-                       axe_start(ifp);
-       }
+       if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+               axe_start(ifp);
 
        sc->axe_stat_ch = timeout(axe_tick, sc, hz);
 
@@ -1122,6 +1198,7 @@
 {
        struct axe_softc        *sc = xsc;
        struct ifnet            *ifp = sc->axe_ifp;
+       struct mii_data         *mii = GET_MII(sc);
        struct axe_chain        *c;
        usbd_status             err;
        int                     i;
@@ -1223,6 +1300,9 @@
                usbd_transfer(c->axe_xfer);
        }
 
+       sc->axe_link = 0;
+       mii_mediachg(mii);
+
        ifp->if_drv_flags |= IFF_DRV_RUNNING;
        ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
Index: sys/dev/usb/if_axereg.h
===================================================================
--- sys/dev/usb/if_axereg.h     (revision 183636)
+++ sys/dev/usb/if_axereg.h     (working copy)
@@ -134,9 +134,24 @@
 #define AXE_178_RXCMD_MFB_8192                 0x0200  /* 8K max frame burst */
 #define AXE_178_RXCMD_MFB_16384                        0x0300  /* 16K max 
frame burst*/
 
-#define AXE_NOPHY                              0xE0
-#define AXE_INTPHY                             0x10
+#define        AXE_PHY_SEL_PRI         1
+#define        AXE_PHY_SEL_SEC         0
+#define        AXE_PHY_TYPE_MASK       0xE0
+#define        AXE_PHY_TYPE_SHIFT      5
+#define        AXE_PHY_TYPE(x)         \
+       (((x) & AXE_PHY_TYPE_MASK) >> AXE_PHY_TYPE_SHIFT)
 
+#define        PHY_TYPE_100_HOME       0       /* 10/100 or 1M HOME PHY */
+#define        PHY_TYPE_GIG            1       /* Gigabit PHY */
+#define        PHY_TYPE_SPECIAL        4       /* Special case */
+#define        PHY_TYPE_RSVD           5       /* Reserved */
+#define        PHY_TYPE_NON_SUP        7       /* Non-supported PHY */
+
+#define        AXE_PHY_NO_MASK         0x1F
+#define        AXE_PHY_NO(x)           ((x) & AXE_PHY_NO_MASK)
+
+#define        AXE_PHY_NO_AX772_EPHY   0x10    /* Embedded 10/100 PHY of 
AX88772 */
+
 #define AXE_TIMEOUT            1000
 #define AXE_172_BUFSZ          1536
 #define AXE_178_MIN_BUFSZ      2048
@@ -236,6 +251,7 @@
        int                     axe_link;
        unsigned char           axe_ipgs[3];
        unsigned char           axe_phyaddrs[2];
+       int                     axe_phyno;
        struct timeval          axe_rx_notice;
        struct usb_task         axe_tick_task;
        int                     axe_bufsz;
_______________________________________________
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