Date: Mon, 15 Dec 2008 09:30:40 +0900 From: Pyun YongHyeon <pyunyh@gmail.com> To: Mam Ruoc <mamruoc@gmail.com> Cc: freebsd-net@freebsd.org Subject: Re: Belkin F5D5055 not working in FreeBSD 7.0 Message-ID: <20081215003040.GB58724@cdnetworks.co.kr> In-Reply-To: <494541C6.2090106@gmail.com> References: <494541C6.2090106@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--r5Pyd7+fXNt84Ff3 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --r5Pyd7+fXNt84Ff3 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="axe.88178.patch3" 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; --r5Pyd7+fXNt84Ff3--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081215003040.GB58724>