Subject: Re: vge not working on bigendian, either (was Re: CVS commit: src/sys/dev/pci)
To: None <riz@NetBSD.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: tech-net
Date: 12/01/2005 08:11:52
In article <438E026C.8040100@NetBSD.org>
riz@NetBSD.org wrote:

> I just got a vge(4) device, and it doesn't work on macppc.  I'm looking
> into it...

If it only works on the promisc mode (i.e. if tcpdump(8) works),
please try the following patch:

---
Index: if_vge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_vge.c,v
retrieving revision 1.7
diff -u -r1.7 if_vge.c
--- if_vge.c	21 Nov 2005 20:25:15 -0000	1.7
+++ if_vge.c	30 Nov 2005 23:10:00 -0000
@@ -147,8 +147,7 @@
 static int vge_ifmedia_upd	(struct ifnet *);
 static void vge_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
 
-static void vge_eeprom_getword	(struct vge_softc *, int, u_int16_t *);
-static void vge_read_eeprom	(struct vge_softc *, caddr_t, int, int, int);
+static uint16_t vge_read_eeprom	(struct vge_softc *, int);
 
 static void vge_miipoll_start	(struct vge_softc *);
 static void vge_miipoll_stop	(struct vge_softc *);
@@ -228,14 +227,11 @@
 /*
  * Read a word of data stored in the EEPROM at address 'addr.'
  */
-static void
-vge_eeprom_getword(sc, addr, dest)
-	struct vge_softc	*sc;
-	int			addr;
-	u_int16_t		*dest;
+static uint16_t
+vge_read_eeprom(struct vge_softc *sc, int addr)
 {
-	register int		i;
-	u_int16_t		word = 0;
+	int i;
+	uint16_t word = 0;
 
 	/*
 	 * Enter EEPROM embedded programming mode. In order to
@@ -259,8 +255,7 @@
 
 	if (i == VGE_TIMEOUT) {
 		printf("%s: EEPROM read timed out\n", sc->sc_dev.dv_xname);
-		*dest = 0;
-		return;
+		return 0;
 	}
 
 	/* Read the result */
@@ -270,33 +265,7 @@
 	CSR_CLRBIT_1(sc, VGE_EECSR, VGE_EECSR_EMBP/*|VGE_EECSR_ECS*/);
 	CSR_CLRBIT_1(sc, VGE_CHIPCFG2, VGE_CHIPCFG2_EELOAD);
 
-	*dest = word;
-
-	return;
-}
-
-/*
- * Read a sequence of words from the EEPROM.
- */
-static void
-vge_read_eeprom(sc, dest, off, cnt, swap)
-	struct vge_softc	*sc;
-	caddr_t			dest;
-	int			off;
-	int			cnt;
-	int			swap;
-{
-	int			i;
-	u_int16_t		word = 0, *ptr;
-
-	for (i = 0; i < cnt; i++) {
-		vge_eeprom_getword(sc, off + i, &word);
-		ptr = (u_int16_t *)(dest + (i * 2));
-		if (swap)
-			*ptr = ntohs(word);
-		else
-			*ptr = word;
-	}
+	return word;
 }
 
 static void
@@ -884,6 +853,7 @@
 	pci_chipset_tag_t pc = pa->pa_pc;
 	const char *intrstr;
 	pci_intr_handle_t ih;
+	uint16_t val;
 
 	aprint_normal(": VIA VT612X Gigabit Ethernet (rev. %#x)\n",
 		PCI_REVISION(pa->pa_class));
@@ -930,8 +900,15 @@
 	/*
 	 * Get station address from the EEPROM.
 	 */
-	vge_read_eeprom(sc, (caddr_t)eaddr, VGE_EE_EADDR, 3, 0);
-	bcopy(eaddr, (char *)&sc->vge_eaddr, ETHER_ADDR_LEN);
+	val = vge_read_eeprom(sc, VGE_EE_EADDR + 0);
+	eaddr[0] = val & 0xff;
+	eaddr[1] = val >> 8;
+	val = vge_read_eeprom(sc, VGE_EE_EADDR + 1);
+	eaddr[2] = val & 0xff;
+	eaddr[3] = val >> 8;
+	val = vge_read_eeprom(sc, VGE_EE_EADDR + 2);
+	eaddr[4] = val & 0xff;
+	eaddr[5] = val >> 8;
 
 	printf("%s: Ethernet address: %s\n", sc->sc_dev.dv_xname,
 	    ether_sprintf(eaddr));

---
Izumi Tsutsui