muge: update FDT LED configuration

Also use LED mode settings from the FDT to set the PHY.
From v3 of the patch submitted in the PR.

I moved the sc_led_modes and sc_led_modes_mask default setting outside
of the #ifdef FDT case.

PR:		237325
Submitted by:	Ralf <iz-rpi03@hs-karlsruhe.de>
Reviewed by:	ian
MFC after:	2 weeks
MFC with:	r348001
Event:		Waterloo Hackathon 2019
Differential Revision:	https://reviews.freebsd.org/D20325
This commit is contained in:
Ed Maste 2019-05-20 19:31:49 +00:00
parent ff7449d6f5
commit 03dec17347
2 changed files with 30 additions and 35 deletions

View file

@ -174,6 +174,8 @@ struct muge_softc {
struct usb_xfer *sc_xfer[MUGE_N_TRANSFER];
int sc_phyno;
uint32_t sc_leds;
uint16_t sc_led_modes;
uint16_t sc_led_modes_mask;
/* Settings for the mac control (MAC_CSR) register. */
uint32_t sc_rfe_ctl;
@ -890,7 +892,7 @@ static int
lan78xx_phy_init(struct muge_softc *sc)
{
muge_dbg_printf(sc, "Initializing PHY.\n");
uint16_t bmcr;
uint16_t bmcr, lmsr;
usb_ticks_t start_ticks;
uint32_t hw_reg;
const usb_ticks_t max_ticks = USB_MS_TO_TICKS(1000);
@ -934,6 +936,16 @@ lan78xx_phy_init(struct muge_softc *sc)
lan78xx_miibus_writereg(sc->sc_ue.ue_dev, sc->sc_phyno, MII_BMCR, bmcr);
bmcr = lan78xx_miibus_readreg(sc->sc_ue.ue_dev, sc->sc_phyno, MII_BMCR);
/* Configure LED Modes. */
if (sc->sc_led_modes_mask != 0xffff) {
lmsr = lan78xx_miibus_readreg(sc->sc_ue.ue_dev, sc->sc_phyno,
MUGE_PHY_LED_MODE);
lmsr &= sc->sc_led_modes_mask;
lmsr |= sc->sc_led_modes;
lan78xx_miibus_writereg(sc->sc_ue.ue_dev, sc->sc_phyno,
MUGE_PHY_LED_MODE, lmsr);
}
/* Enable appropriate LEDs. */
if (sc->sc_leds != 0 &&
lan78xx_read_reg(sc, ETH_HW_CFG, &hw_reg) == 0) {
@ -1534,37 +1546,6 @@ muge_fdt_find_mac(const char *compatible, unsigned char *mac)
return (ENXIO);
}
/**
* muge_fdt_count_led_modes - read number of LED modes from node
* @compatible: compatible string for DTB node in the form
* "usb[N]NNN,[M]MMM"
* where NNN is vendor id and MMM is product id
* @amount: memory to store number of LED entries to
*
* Tries to find matching node in DTS and obtain number of entries from it.
*
* RETURNS:
* Returns 0 on success, error code otherwise
*/
static int
muge_fdt_count_led_modes(struct muge_softc *sc, const char *compatible,
uint32_t *amount)
{
phandle_t node, root;
ssize_t proplen;
*amount = 0;
root = OF_finddevice("/");
node = muge_fdt_find_eth_node(root, compatible);
if (node != -1 &&
(proplen = OF_getproplen(node, "microchip,led-modes")) > 0) {
*amount = proplen / sizeof( uint32_t );
return (0);
}
return (ENXIO);
}
#endif
/**
@ -1646,25 +1627,37 @@ muge_set_leds(struct usb_ether *ue)
#ifdef FDT
char compatible[16];
struct usb_attach_arg *uaa = device_get_ivars(ue->ue_dev);
phandle_t root, node;
pcell_t led_modes[4]; /* 4 LEDs are possible */
ssize_t proplen;
uint32_t count;
#endif
sc->sc_leds = 0; /* no LED mode is set */
sc->sc_led_modes = 0;
sc->sc_led_modes_mask = 0xffff;
if (lan78xx_eeprom_present(sc))
return;
#ifdef FDT
snprintf(compatible, sizeof(compatible), "usb%x,%x",
uaa->info.idVendor, uaa->info.idProduct);
if (muge_fdt_count_led_modes(sc, compatible, &count) == 0) {
root = OF_finddevice("/");
if ((node = muge_fdt_find_eth_node(root, compatible)) != -1 &&
(proplen = OF_getencprop(node, "microchip,led-modes", led_modes,
sizeof(led_modes))) > 0) {
count = proplen / sizeof( uint32_t );
sc->sc_leds = (count > 0) * ETH_HW_CFG_LEDO_EN_ |
(count > 1) * ETH_HW_CFG_LED1_EN_ |
(count > 2) * ETH_HW_CFG_LED2_EN_ |
(count > 3) * ETH_HW_CFG_LED3_EN_;
while (count-- > 0) {
sc->sc_led_modes |=
(led_modes[count] & 0xf) << (4 * count);
sc->sc_led_modes_mask <<= 4;
}
muge_dbg_printf(sc, "LED modes set from FDT blob\n");
return;
}
#endif
muge_dbg_printf(sc, "LED configuration not available\n");
}
/**

View file

@ -190,6 +190,8 @@
#define MUGE_EXT_PAGE_SPACE_1 0x0001
#define MUGE_EXT_PAGE_SPACE_2 0x0002
#define MUGE_PHY_LED_MODE 29
/* Extended Register Page 1 Space */
#define MUGE_EXT_MODE_CTRL 0x0013
#define MUGE_EXT_MODE_CTRL_MDIX_MASK_ 0x000C