| Summary: | ADMtek USB To LAN Converter does not work | ||
|---|---|---|---|
| Product: | Base System | Reporter: | josla972 |
| Component: | powerpc | Assignee: | Pyun YongHyeon <yongari> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 10.0-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->feedback Would you try the patch at the following URL? http://people.freebsd.org/~yongari/aue/aue.endianness.diff Responsible Changed From-To: freebsd-ppc->yongari Grab. It works! I did a similar easy fix just to test after I reported the bug and got it working, but this code is nicer. Thanks! Author: yongari Date: Thu Apr 3 01:32:43 2014 New Revision: 264062 URL: http://svnweb.freebsd.org/changeset/base/264062 Log: Correct endianness handling in getting station address from EEPROM. While I'm here, remove aue_eeprom_getword() as its only usage is to read station address and make it more readable. This change is inspired by NetBSD. With this change, aue(4) should work on big endian architectures. PR: 188177 Modified: head/sys/dev/usb/net/if_aue.c Modified: head/sys/dev/usb/net/if_aue.c ============================================================================== --- head/sys/dev/usb/net/if_aue.c Thu Apr 3 01:02:14 2014 (r264061) +++ head/sys/dev/usb/net/if_aue.c Thu Apr 3 01:32:43 2014 (r264062) @@ -212,9 +212,7 @@ static uint8_t aue_csr_read_1(struct aue static uint16_t aue_csr_read_2(struct aue_softc *, uint16_t); static void aue_csr_write_1(struct aue_softc *, uint16_t, uint8_t); static void aue_csr_write_2(struct aue_softc *, uint16_t, uint16_t); -static void aue_eeprom_getword(struct aue_softc *, int, uint16_t *); -static void aue_read_eeprom(struct aue_softc *, uint8_t *, uint16_t, - uint16_t); +static uint16_t aue_eeprom_getword(struct aue_softc *, int); static void aue_reset(struct aue_softc *); static void aue_reset_pegasus_II(struct aue_softc *); @@ -376,11 +374,10 @@ aue_csr_write_2(struct aue_softc *sc, ui /* * Read a word of data stored in the EEPROM at address 'addr.' */ -static void -aue_eeprom_getword(struct aue_softc *sc, int addr, uint16_t *dest) +static uint16_t +aue_eeprom_getword(struct aue_softc *sc, int addr) { int i; - uint16_t word = 0; aue_csr_write_1(sc, AUE_EE_REG, addr); aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); @@ -395,22 +392,23 @@ aue_eeprom_getword(struct aue_softc *sc, if (i == AUE_TIMEOUT) device_printf(sc->sc_ue.ue_dev, "EEPROM read timed out\n"); - word = aue_csr_read_2(sc, AUE_EE_DATA); - *dest = word; + return (aue_csr_read_2(sc, AUE_EE_DATA)); } /* - * Read a sequence of words from the EEPROM. + * Read station address(offset 0) from the EEPROM. */ static void -aue_read_eeprom(struct aue_softc *sc, uint8_t *dest, - uint16_t off, uint16_t len) +aue_read_mac(struct aue_softc *sc, uint8_t *eaddr) { - uint16_t *ptr = (uint16_t *)dest; - int i; + int i, offset; + uint16_t word; - for (i = 0; i != len; i++, ptr++) - aue_eeprom_getword(sc, off + i, ptr); + for (i = 0, offset = 0; i < ETHER_ADDR_LEN / 2; i++) { + word = aue_eeprom_getword(sc, offset + i); + eaddr[i * 2] = (uint8_t)word; + eaddr[i * 2 + 1] = (uint8_t)(word >> 8); + } } static int @@ -636,7 +634,7 @@ aue_attach_post(struct usb_ether *ue) aue_reset(sc); /* get station address from the EEPROM */ - aue_read_eeprom(sc, ue->ue_eaddr, 0, 3); + aue_read_mac(sc, ue->ue_eaddr); } /* _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" State Changed From-To: feedback->patched Thanks for testing! Fixed in r264062. Author: yongari Date: Tue Apr 22 04:30:24 2014 New Revision: 264745 URL: http://svnweb.freebsd.org/changeset/base/264745 Log: MFC r264062: Correct endianness handling in getting station address from EEPROM. While I'm here, remove aue_eeprom_getword() as its only usage is to read station address and make it more readable. This change is inspired by NetBSD. With this change, aue(4) should work on big endian architectures. PR: 188177 Modified: stable/10/sys/dev/usb/net/if_aue.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/usb/net/if_aue.c ============================================================================== --- stable/10/sys/dev/usb/net/if_aue.c Mon Apr 21 22:52:18 2014 (r264744) +++ stable/10/sys/dev/usb/net/if_aue.c Tue Apr 22 04:30:24 2014 (r264745) @@ -208,9 +208,7 @@ static uint8_t aue_csr_read_1(struct aue static uint16_t aue_csr_read_2(struct aue_softc *, uint16_t); static void aue_csr_write_1(struct aue_softc *, uint16_t, uint8_t); static void aue_csr_write_2(struct aue_softc *, uint16_t, uint16_t); -static void aue_eeprom_getword(struct aue_softc *, int, uint16_t *); -static void aue_read_eeprom(struct aue_softc *, uint8_t *, uint16_t, - uint16_t); +static uint16_t aue_eeprom_getword(struct aue_softc *, int); static void aue_reset(struct aue_softc *); static void aue_reset_pegasus_II(struct aue_softc *); @@ -372,11 +370,10 @@ aue_csr_write_2(struct aue_softc *sc, ui /* * Read a word of data stored in the EEPROM at address 'addr.' */ -static void -aue_eeprom_getword(struct aue_softc *sc, int addr, uint16_t *dest) +static uint16_t +aue_eeprom_getword(struct aue_softc *sc, int addr) { int i; - uint16_t word = 0; aue_csr_write_1(sc, AUE_EE_REG, addr); aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); @@ -391,22 +388,23 @@ aue_eeprom_getword(struct aue_softc *sc, if (i == AUE_TIMEOUT) device_printf(sc->sc_ue.ue_dev, "EEPROM read timed out\n"); - word = aue_csr_read_2(sc, AUE_EE_DATA); - *dest = word; + return (aue_csr_read_2(sc, AUE_EE_DATA)); } /* - * Read a sequence of words from the EEPROM. + * Read station address(offset 0) from the EEPROM. */ static void -aue_read_eeprom(struct aue_softc *sc, uint8_t *dest, - uint16_t off, uint16_t len) +aue_read_mac(struct aue_softc *sc, uint8_t *eaddr) { - uint16_t *ptr = (uint16_t *)dest; - int i; + int i, offset; + uint16_t word; - for (i = 0; i != len; i++, ptr++) - aue_eeprom_getword(sc, off + i, ptr); + for (i = 0, offset = 0; i < ETHER_ADDR_LEN / 2; i++) { + word = aue_eeprom_getword(sc, offset + i); + eaddr[i * 2] = (uint8_t)word; + eaddr[i * 2 + 1] = (uint8_t)(word >> 8); + } } static int @@ -632,7 +630,7 @@ aue_attach_post(struct usb_ether *ue) aue_reset(sc); /* get station address from the EEPROM */ - aue_read_eeprom(sc, ue->ue_eaddr, 0, 3); + aue_read_mac(sc, ue->ue_eaddr); } /* _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" Author: yongari Date: Tue Apr 22 04:31:07 2014 New Revision: 264746 URL: http://svnweb.freebsd.org/changeset/base/264746 Log: MFC r264062: Correct endianness handling in getting station address from EEPROM. While I'm here, remove aue_eeprom_getword() as its only usage is to read station address and make it more readable. This change is inspired by NetBSD. With this change, aue(4) should work on big endian architectures. PR: 188177 Modified: stable/9/sys/dev/usb/net/if_aue.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/usb/net/if_aue.c ============================================================================== --- stable/9/sys/dev/usb/net/if_aue.c Tue Apr 22 04:30:24 2014 (r264745) +++ stable/9/sys/dev/usb/net/if_aue.c Tue Apr 22 04:31:07 2014 (r264746) @@ -208,9 +208,7 @@ static uint8_t aue_csr_read_1(struct aue static uint16_t aue_csr_read_2(struct aue_softc *, uint16_t); static void aue_csr_write_1(struct aue_softc *, uint16_t, uint8_t); static void aue_csr_write_2(struct aue_softc *, uint16_t, uint16_t); -static void aue_eeprom_getword(struct aue_softc *, int, uint16_t *); -static void aue_read_eeprom(struct aue_softc *, uint8_t *, uint16_t, - uint16_t); +static uint16_t aue_eeprom_getword(struct aue_softc *, int); static void aue_reset(struct aue_softc *); static void aue_reset_pegasus_II(struct aue_softc *); @@ -372,11 +370,10 @@ aue_csr_write_2(struct aue_softc *sc, ui /* * Read a word of data stored in the EEPROM at address 'addr.' */ -static void -aue_eeprom_getword(struct aue_softc *sc, int addr, uint16_t *dest) +static uint16_t +aue_eeprom_getword(struct aue_softc *sc, int addr) { int i; - uint16_t word = 0; aue_csr_write_1(sc, AUE_EE_REG, addr); aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); @@ -391,22 +388,23 @@ aue_eeprom_getword(struct aue_softc *sc, if (i == AUE_TIMEOUT) device_printf(sc->sc_ue.ue_dev, "EEPROM read timed out\n"); - word = aue_csr_read_2(sc, AUE_EE_DATA); - *dest = word; + return (aue_csr_read_2(sc, AUE_EE_DATA)); } /* - * Read a sequence of words from the EEPROM. + * Read station address(offset 0) from the EEPROM. */ static void -aue_read_eeprom(struct aue_softc *sc, uint8_t *dest, - uint16_t off, uint16_t len) +aue_read_mac(struct aue_softc *sc, uint8_t *eaddr) { - uint16_t *ptr = (uint16_t *)dest; - int i; + int i, offset; + uint16_t word; - for (i = 0; i != len; i++, ptr++) - aue_eeprom_getword(sc, off + i, ptr); + for (i = 0, offset = 0; i < ETHER_ADDR_LEN / 2; i++) { + word = aue_eeprom_getword(sc, offset + i); + eaddr[i * 2] = (uint8_t)word; + eaddr[i * 2 + 1] = (uint8_t)(word >> 8); + } } static int @@ -632,7 +630,7 @@ aue_attach_post(struct usb_ether *ue) aue_reset(sc); /* get station address from the EEPROM */ - aue_read_eeprom(sc, ue->ue_eaddr, 0, 3); + aue_read_mac(sc, ue->ue_eaddr); } /* _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" State Changed From-To: patched->closed MFC to both stable/10 and stable/9 complete. Thanks for reporting! |
(About the uname -a output: I use an experimental kernel where I tried using aue as a module instead. The problem is also present with the GENERIC kernel.) I'm having problems with my ADMtek USB ethernet adapter on my Mac Mini G4 (PowerPC). It works flawlessly on the raspberry pi. The driver is detected on the Mac Mini but I cannot use it, even ping does not work. Comparing the MAC addresses, it seems that there might be an endian issue. Device (dmesg output): aue0: <ADMtek USB To LAN Converter, rev 2.00/1.01, addr 5> on usbus0 miibus1: <MII bus> on aue0 Mac mini: ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=80000<LINKSTATE> ether 05:00:05:1b:b4:28 inet 192.168.0.8 netmask 0xffffff00 broadcast 192.168.0.255 inet6 fe80::20d:93ff:fe60:fc1c%ue0 prefixlen 64 scopeid 0x3 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (100baseTX <full-duplex>) status: active raspberry pi (FreeBSD fbsdpi 10.0-CURRENT FreeBSD 10.0-CURRENT #9 r250604M: Mon May 13 21:20:03 CEST 2013): ue1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=80000<LINKSTATE> ether 00:05:1b:05:28:b4 inet ***.***.***.*** netmask 0xffffff00 broadcast ***.***.***.*** nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (100baseTX <full-duplex>) status: active Fix: I am unsure about a fix, but at least I did some investigation: If I interpreted the code correctly, the MAC address is read from eeprom as 3 words which are then saved contiguously in memory. In the following function there is an interesting line: static uint16_t aue_csr_read_2(struct aue_softc *sc, uint16_t reg) return (le16toh(val)); This is probably correct if we can guarantee that the earlier function call uether_do_request(&sc->sc_ue, &req, &val, 1000); results in a value that comes in little endian form, but is this necessarily the case? I think the USB standard uses little endian form, but I am not sure if this is compensated for by the USB stack. Maybe I am looking at the wrong things, but I still do find it peculiar that the MAC adresses differs when I use ifconfig. How-To-Repeat: I guess you would need a similar USB ethernet adapter and a powerpc to reproduce it.