if_muge: add LAN7850 support

Differences between LAN7800 and LAN7850 from the driver's perspective:

* The LAN7800 muxes EEPROM signals with LEDs, so LED mode needs to be
  disabled when reading/writing EEPROM.  The EEPROM is not muxed on the
  LAN7850.

* The Linux driver enables automatic duplex and speed detection when
  there is no EEPROM, for the LAN7800 only.  With this FreeBSD driver
  LAN7850-based adapters without a configuration EEPROM fail to link
  (with or without the automatic duplex and speed detection code), so
  I have just followed the example of the Linux driver for now.

Sponsored by:	The FreeBSD Foundation
Sponsored by:	Microchip (hardware)
This commit is contained in:
Ed Maste 2018-06-11 18:44:56 +00:00
parent 0ea9d9376e
commit 2d14fb8bec
2 changed files with 30 additions and 9 deletions

View File

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 17, 2018
.Dd June 11, 2018
.Dt MUGE 4
.Os
.Sh NAME
@ -56,6 +56,8 @@ driver supports:
.It
Microchip LAN7800 USB 3.1 Gigabit Ethernet controller with PHY
.It
Microchip LAN7850 USB 2.0 Gigabit Ethernet controller with PHY
.It
Microchip LAN7515 USB 2 hub and Gigabit Ethernet controller with PHY
.El
.Sh SEE ALSO
@ -68,3 +70,6 @@ The
.Nm
device driver first appeared in
.Fx 12.0 .
.Sh BUGS
USB-Ethernet adapters that use the LAN7850 without a configuration EEPROM
will not work.

View File

@ -40,6 +40,9 @@ __FBSDID("$FreeBSD$");
* USB 3.1 to 10/100/1000 Mbps Ethernet
* LAN7800 http://www.microchip.com/wwwproducts/en/LAN7800
*
* USB 2.0 to 10/100/1000 Mbps Ethernet
* LAN7850 http://www.microchip.com/wwwproducts/en/LAN7850
*
* USB 2 to 10/100/1000 Mbps Ethernet with built-in USB hub
* LAN7515 (no datasheet available, but probes and functions as LAN7800)
*
@ -386,11 +389,14 @@ lan78xx_eeprom_read_raw(struct muge_softc *sc, uint16_t off, uint8_t *buf,
if (!locked)
MUGE_LOCK(sc);
err = lan78xx_read_reg(sc, ETH_HW_CFG, &val);
saved = val;
if (sc->chipid == ETH_ID_REV_CHIP_ID_7800_) {
/* EEDO/EECLK muxed with LED0/LED1 on LAN7800. */
err = lan78xx_read_reg(sc, ETH_HW_CFG, &val);
saved = val;
val &= ~(ETH_HW_CFG_LEDO_EN_ | ETH_HW_CFG_LED1_EN_);
err = lan78xx_write_reg(sc, ETH_HW_CFG, val);
val &= ~(ETH_HW_CFG_LEDO_EN_ | ETH_HW_CFG_LED1_EN_);
err = lan78xx_write_reg(sc, ETH_HW_CFG, val);
}
err = lan78xx_wait_for_bits(sc, ETH_E2P_CMD, ETH_E2P_CMD_BUSY_);
if (err != 0) {
@ -432,7 +438,10 @@ lan78xx_eeprom_read_raw(struct muge_softc *sc, uint16_t off, uint8_t *buf,
done:
if (!locked)
MUGE_UNLOCK(sc);
lan78xx_write_reg(sc, ETH_HW_CFG, saved);
if (sc->chipid == ETH_ID_REV_CHIP_ID_7800_) {
/* Restore saved LED configuration. */
lan78xx_write_reg(sc, ETH_HW_CFG, saved);
}
return (err);
}
@ -982,7 +991,11 @@ lan78xx_chip_init(struct muge_softc *sc)
}
sc->chipid = (buf & ETH_ID_REV_CHIP_ID_MASK_) >> 16;
sc->chiprev = buf & ETH_ID_REV_CHIP_REV_MASK_;
if (sc->chipid != ETH_ID_REV_CHIP_ID_7800_) {
switch (sc->chipid) {
case ETH_ID_REV_CHIP_ID_7800_:
case ETH_ID_REV_CHIP_ID_7850_:
break;
default:
muge_warn_printf(sc, "Chip ID 0x%04x not yet supported\n",
sc->chipid);
goto init_failed;
@ -1078,9 +1091,12 @@ lan78xx_chip_init(struct muge_softc *sc)
goto init_failed;
}
/* Enable automatic duplex detection and automatic speed detection. */
err = lan78xx_read_reg(sc, ETH_MAC_CR, &buf);
buf |= ETH_MAC_CR_AUTO_DUPLEX_ | ETH_MAC_CR_AUTO_SPEED_;
if (sc->chipid == ETH_ID_REV_CHIP_ID_7800_ &&
!lan78xx_eeprom_present(sc)) {
/* Set automatic duplex and speed on LAN7800 without EEPROM. */
buf |= ETH_MAC_CR_AUTO_DUPLEX_ | ETH_MAC_CR_AUTO_SPEED_;
}
err = lan78xx_write_reg(sc, ETH_MAC_CR, buf);
/*