svn commit: r212130 - head/sys/dev/usb/net

Andrew Thompson thompsa at FreeBSD.org
Thu Sep 2 03:47:08 UTC 2010


Author: thompsa
Date: Thu Sep  2 03:47:07 2010
New Revision: 212130
URL: http://svn.freebsd.org/changeset/base/212130

Log:
  Add GPIO programming for more PHY hardware.
  
  Submitted by:	yongari

Modified:
  head/sys/dev/usb/net/if_axe.c
  head/sys/dev/usb/net/if_axereg.h

Modified: head/sys/dev/usb/net/if_axe.c
==============================================================================
--- head/sys/dev/usb/net/if_axe.c	Thu Sep  2 03:44:56 2010	(r212129)
+++ head/sys/dev/usb/net/if_axe.c	Thu Sep  2 03:47:07 2010	(r212130)
@@ -515,12 +515,19 @@ axe_get_phyno(struct axe_softc *sc, int 
 	return (phyno);
 }
 
+#define	AXE_GPIO_WRITE(x, y)	do {				\
+	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL);		\
+	uether_pause(ue, (y));					\
+} while (0)
+
 static void
 axe_ax88178_init(struct axe_softc *sc)
 {
-	int gpio0 = 0, phymode = 0;
-	uint16_t eeprom;
+	struct usb_ether *ue;
+	int gpio0, phymode;
+	uint16_t eeprom, val;
 
+	ue = &sc->sc_ue;
 	axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
 	/* XXX magic */
 	axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
@@ -529,46 +536,89 @@ 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;
 	} else {
-		phymode = eeprom & 7;
+		phymode = eeprom & 0x7f;
 		gpio0 = (eeprom & 0x80) ? 0 : 1;
 	}
 
-	axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
-	uether_pause(&sc->sc_ue, hz / 16);
-
-	if ((eeprom >> 8) != 0x01) {
-		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
-		uether_pause(&sc->sc_ue, hz / 32);
-
-		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
-		uether_pause(&sc->sc_ue, hz / 3);
-
-		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
-		uether_pause(&sc->sc_ue, hz / 32);
-	} else {
-		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
-		uether_pause(&sc->sc_ue, hz / 32);
-
-		axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
-		uether_pause(&sc->sc_ue, hz / 32);
+	if (bootverbose)
+		device_printf(sc->sc_ue.ue_dev, "EEPROM data : 0x%04x\n",
+		    eeprom);
+	/* Program GPIOs depending on PHY hardware. */
+	switch (phymode) {
+	case AXE_PHY_MODE_MARVELL:
+		if (gpio0 == 1) {
+			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0_EN,
+			    hz / 32);
+			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
+			    hz / 32);
+			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4);
+			AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN,
+			    hz / 32);
+		} else
+			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
+			    AXE_GPIO1_EN, hz / 32);
+		break;
+	case AXE_PHY_MODE_CICADA:
+		if (gpio0 == 1)
+			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 |
+			    AXE_GPIO0_EN, hz / 32);
+		else
+			AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
+			    AXE_GPIO1_EN, hz / 32);
+		break;
+	case AXE_PHY_MODE_AGERE:
+		AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 |
+		    AXE_GPIO1_EN, hz / 32);
+		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
+		    AXE_GPIO2_EN, hz / 32);
+		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2_EN, hz / 4);
+		AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 |
+		    AXE_GPIO2_EN, hz / 32);
+		break;
+	case AXE_PHY_MODE_REALTEK_8211CL:
+	case AXE_PHY_MODE_REALTEK_8211BN:
+	case AXE_PHY_MODE_REALTEK_8251CL:
+		val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN :
+		    AXE_GPIO1 | AXE_GPIO1_EN;
+		AXE_GPIO_WRITE(val, hz / 32);
+		AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
+		AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4);
+		AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
+		if (phymode == AXE_PHY_MODE_REALTEK_8211CL) {
+			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
+			    0x1F, 0x0005);
+			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
+			    0x0C, 0x0000);
+			val = axe_miibus_readreg(ue->ue_dev, sc->sc_phyno,
+			    0x0001);
+			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
+			    0x01, val | 0x0080);
+			axe_miibus_writereg(ue->ue_dev, sc->sc_phyno,
+			    0x1F, 0x0000);
+		}
+		break;
+	default:
+		/* Unknown PHY model or no need to program GPIOs. */
+		break;
 	}
 
 	/* soft reset */
 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
-	uether_pause(&sc->sc_ue, hz / 4);
+	uether_pause(ue, hz / 4);
 
 	axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
 	    AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
-	uether_pause(&sc->sc_ue, hz / 4);
+	uether_pause(ue, hz / 4);
 	/* Enable MII/GMII/RGMII interface to work with external PHY. */
 	axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL);
-	uether_pause(&sc->sc_ue, hz / 4);
+	uether_pause(ue, hz / 4);
 
 	axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
 }
+#undef	AXE_GPIO_WRITE
 
 static void
 axe_ax88772_init(struct axe_softc *sc)
@@ -637,10 +687,9 @@ axe_attach_post(struct usb_ether *ue)
 	 * Load PHY indexes first. Needed by axe_xxx_init().
 	 */
 	axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs);
-#if 1
-	device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n",
-	    sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]);
-#endif
+	if (bootverbose)
+		device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n",
+		    sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]);
 	sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI);
 	if (sc->sc_phyno == -1)
 		sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC);

Modified: head/sys/dev/usb/net/if_axereg.h
==============================================================================
--- head/sys/dev/usb/net/if_axereg.h	Thu Sep  2 03:44:56 2010	(r212129)
+++ head/sys/dev/usb/net/if_axereg.h	Thu Sep  2 03:47:07 2010	(r212130)
@@ -153,6 +153,25 @@
 
 #define	AXE_772_PHY_NO_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_AGERE_GMII		0x06
+#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_BULK_BUF_SIZE	16384	/* bytes */
 
 #define	AXE_CTL_READ		0x01


More information about the svn-src-all mailing list