PERFORCE change 179721 for review

Hans Petter Selasky hselasky at FreeBSD.org
Thu Jun 17 17:46:46 UTC 2010


http://p4web.freebsd.org/@@179721?ac=10

Change 179721 by hselasky at hselasky_laptop001 on 2010/06/17 17:46:27

	
	USB ethernet:
		- fix for AXE USB driver
		- patch by: Pyun YongHyeon
	
	Reviewed by:	hselasky @

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/net/if_axe.c#24 edit
.. //depot/projects/usb/src/sys/dev/usb/net/if_axereg.h#4 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/net/if_axe.c#24 (text+ko) ====

@@ -514,12 +514,19 @@
 	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);
@@ -528,46 +535,89 @@
 
 	/* 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)
@@ -636,10 +686,9 @@
 	 * 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);

==== //depot/projects/usb/src/sys/dev/usb/net/if_axereg.h#4 (text+ko) ====

@@ -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 p4-projects mailing list