summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorYojiro Uo <yuo@cvs.openbsd.org>2013-05-31 15:20:50 +0000
committerYojiro Uo <yuo@cvs.openbsd.org>2013-05-31 15:20:50 +0000
commit88430b7e8a2ccd45527c382c96e0c70804e3e3d5 (patch)
treed458457c96b7bef05b6f69d72be4ad89e1797fb2 /sys/dev
parent9e211909ec1753490770ac0dc071e1df1e0e9674 (diff)
enable REALTEK 8211C(L) GbE phy with axe(4).
ok jsg@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/if_axe.c56
-rw-r--r--sys/dev/usb/if_axereg.h20
2 files changed, 53 insertions, 23 deletions
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c
index e013cc35f59..927bbc377b3 100644
--- a/sys/dev/usb/if_axe.c
+++ b/sys/dev/usb/if_axe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_axe.c,v 1.118 2013/04/15 09:23:01 mglocker Exp $ */
+/* $OpenBSD: if_axe.c,v 1.119 2013/05/31 15:20:49 yuo Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org>
@@ -521,11 +521,16 @@ axe_reset(struct axe_softc *sc)
return;
}
+#define AXE_GPIO_WRITE(x,y) do { \
+ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL); \
+ usbd_delay_ms(sc->axe_udev, (y)); \
+} while (0)
+
void
axe_ax88178_init(struct axe_softc *sc)
{
- int gpio0 = 0, phymode = 0;
- u_int16_t eeprom;
+ int gpio0 = 0, phymode = 0, ledmode;
+ u_int16_t eeprom, val;
axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
/* XXX magic */
@@ -538,32 +543,39 @@ axe_ax88178_init(struct axe_softc *sc)
/* if EEPROM is invalid we have to use to GPIO0 */
if (eeprom == 0xffff) {
- phymode = 0;
+ phymode = AXE_PHY_MODE_MARVELL;
gpio0 = 1;
+ ledmode = 0;
} else {
- phymode = eeprom & 7;
+ phymode = eeprom & 0x7f;
gpio0 = (eeprom & 0x80) ? 0 : 1;
+ ledmode = eeprom >> 8;
}
- DPRINTF(("use gpio0: %d, phymode %d\n", gpio0, phymode));
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
- usbd_delay_ms(sc->axe_udev, 40);
- if ((eeprom >> 8) != 1) {
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
- usbd_delay_ms(sc->axe_udev, 300);
+ DPRINTF(("use gpio0: %d, phymode 0x%02x, eeprom 0x%04x\n",
+ gpio0, phymode, eeprom));
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
+ /* power up external phy */
+ AXE_GPIO_WRITE(AXE_GPIO1|AXE_GPIO1_EN | AXE_GPIO_RELOAD_EEPROM, 40);
+ if (ledmode == 1) {
+ AXE_GPIO_WRITE(AXE_GPIO1_EN, 30);
+ AXE_GPIO_WRITE(AXE_GPIO1_EN | AXE_GPIO1, 30);
} else {
- DPRINTF(("axe gpio phymode == 1 path\n"));
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
+ val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN :
+ AXE_GPIO1 | AXE_GPIO1_EN;
+ AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, 30);
+ AXE_GPIO_WRITE(val | AXE_GPIO2_EN, 300);
+ AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, 30);
+ }
+
+ /* initialize phy */
+ if (phymode == AXE_PHY_MODE_REALTEK_8211CL) {
+ axe_miibus_writereg(&sc->axe_dev, sc->axe_phyno, 0x1f, 0x0005);
+ axe_miibus_writereg(&sc->axe_dev, sc->axe_phyno, 0x0c, 0x0000);
+ val = axe_miibus_readreg(&sc->axe_dev, sc->axe_phyno, 0x0001);
+ axe_miibus_writereg(&sc->axe_dev, sc->axe_phyno, 0x01,
+ val | 0x0080);
+ axe_miibus_writereg(&sc->axe_dev, sc->axe_phyno, 0x1f, 0x0000);
}
/* soft reset */
diff --git a/sys/dev/usb/if_axereg.h b/sys/dev/usb/if_axereg.h
index 84ea37a29b7..3af57ebfcd2 100644
--- a/sys/dev/usb/if_axereg.h
+++ b/sys/dev/usb/if_axereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_axereg.h,v 1.23 2013/04/15 09:23:01 mglocker Exp $ */
+/* $OpenBSD: if_axereg.h,v 1.24 2013/05/31 15:20:49 yuo Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003
@@ -149,6 +149,24 @@
#define AXE_PHY_NO_AX772_EPHY 0x10 /* Embedded 10/100 PHY of AX88772 */
+#define AXE_GPIO0_EN 0x01
+#define AXE_GPIO0 0x02
+#define AXE_GPIO1_EN 0x04
+#define AXE_GPIO1 0x08
+#define AXE_GPIO2_EN 0x10
+#define AXE_GPIO2 0x20
+#define AXE_GPIO_RELOAD_EEPROM 0x80
+
+#define AXE_PHY_MODE_MARVELL 0x00
+#define AXE_PHY_MODE_CICADA 0x01
+#define AXE_PHY_MODE_AGERE 0x02
+#define AXE_PHY_MODE_CICADA_V2 0x05
+#define AXE_PHY_MODE_CICADA_V2_ASIX 0x09
+#define AXE_PHY_MODE_REALTEK_8211CL 0x0c
+#define AXE_PHY_MODE_REALTEK_8211BN 0x0d
+#define AXE_PHY_MODE_REALTEK_8251CL 0x0e
+#define AXE_PHY_MODE_ATTANSIC 0x40
+
#define AXE_772B_RXCMD_RH1M 0x0100
#define AXE_772B_RXCMD_RH2M 0x0200
#define AXE_772B_RXCMD_RH3M 0x0400