Author: emaste
Date: Mon May 20 18:41:07 2019
New Revision: 348001
URL: https://svnweb.freebsd.org/changeset/base/348001

Log:
  muge: configure LEDs per dtb (for Raspberry Pi 3B+)
  
  Also apply some style(9) and remove the message about EEPROM configuration
  (if there's an EEPROM the hardware handles LED configuration itself).
  
  PR:           237325
  Reviewed by:  ian
  MFC after:    2 weeks
  Submitted by: Ralf <[email protected]>

Modified:
  head/sys/dev/usb/net/if_muge.c

Modified: head/sys/dev/usb/net/if_muge.c
==============================================================================
--- head/sys/dev/usb/net/if_muge.c      Mon May 20 18:35:23 2019        
(r348000)
+++ head/sys/dev/usb/net/if_muge.c      Mon May 20 18:41:07 2019        
(r348001)
@@ -173,6 +173,7 @@ struct muge_softc {
        struct mtx              sc_mtx;
        struct usb_xfer         *sc_xfer[MUGE_N_TRANSFER];
        int                     sc_phyno;
+       uint32_t                sc_leds;
 
        /* Settings for the mac control (MAC_CSR) register. */
        uint32_t                sc_rfe_ctl;
@@ -891,6 +892,7 @@ lan78xx_phy_init(struct muge_softc *sc)
        muge_dbg_printf(sc, "Initializing PHY.\n");
        uint16_t bmcr;
        usb_ticks_t start_ticks;
+       uint32_t hw_reg;
        const usb_ticks_t max_ticks = USB_MS_TO_TICKS(1000);
 
        MUGE_LOCK_ASSERT(sc, MA_OWNED);
@@ -931,6 +933,15 @@ lan78xx_phy_init(struct muge_softc *sc)
        bmcr |= BMCR_AUTOEN;
        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);
+
+       /* Enable appropriate LEDs. */
+       if (sc->sc_leds != 0 &&
+           lan78xx_read_reg(sc, ETH_HW_CFG, &hw_reg) == 0) {
+               hw_reg &= ~(ETH_HW_CFG_LEDO_EN_ | ETH_HW_CFG_LED1_EN_ |
+                           ETH_HW_CFG_LED2_EN_ | ETH_HW_CFG_LED3_EN_ );
+               hw_reg |= sc->sc_leds;
+               lan78xx_write_reg(sc, ETH_HW_CFG, hw_reg);
+       }
        return (0);
 }
 
@@ -1523,6 +1534,37 @@ muge_fdt_find_mac(const char *compatible, unsigned cha
 
        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
 
 /**
@@ -1591,6 +1633,41 @@ muge_set_mac_addr(struct usb_ether *ue)
 }
 
 /**
+ *     muge_set_leds - Initializes NIC LEDs pattern
+ *     @ue: the USB ethernet device
+ *
+ *     Tries to store the LED modes.
+ *     Supports only DTB blob like the Linux driver does.
+ */
+static void
+muge_set_leds(struct usb_ether *ue)
+{
+       struct muge_softc *sc = uether_getsc(ue);
+#ifdef FDT
+       char compatible[16];
+       struct usb_attach_arg *uaa = device_get_ivars(ue->ue_dev);
+       uint32_t count;
+#endif
+
+       sc->sc_leds = 0;        /* no LED mode is set */
+       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) {
+               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_;
+               muge_dbg_printf(sc, "LED modes set from FDT blob\n");
+               return;
+       }
+#endif
+       muge_dbg_printf(sc, "LED configuration not available\n");
+}
+
+/**
  *     muge_attach_post - Called after the driver attached to the USB interface
  *     @ue: the USB ethernet device
  *
@@ -1610,6 +1687,7 @@ muge_attach_post(struct usb_ether *ue)
        sc->sc_phyno = 1;
 
        muge_set_mac_addr(ue);
+       muge_set_leds(ue);
 
        /* Initialise the chip for the first time */
        lan78xx_chip_init(sc);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to