From 88430b7e8a2ccd45527c382c96e0c70804e3e3d5 Mon Sep 17 00:00:00 2001 From: Yojiro Uo Date: Fri, 31 May 2013 15:20:50 +0000 Subject: enable REALTEK 8211C(L) GbE phy with axe(4). ok jsg@ --- sys/dev/usb/if_axe.c | 56 ++++++++++++++++++++++++++++++------------------- sys/dev/usb/if_axereg.h | 20 +++++++++++++++++- 2 files changed, 53 insertions(+), 23 deletions(-) (limited to 'sys/dev') 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 @@ -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 -- cgit v1.2.3