Belkin F5D5055 not working in FreeBSD 7.0
Pyun YongHyeon
pyunyh at gmail.com
Sun Dec 14 16:30:48 PST 2008
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
-------------- next part --------------
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;
More information about the freebsd-net
mailing list