2018-04-18 15:47:24

by Phil Elwell

[permalink] [raw]
Subject: [PATCH v2 0/3] lan78xx: Read configuration from Device Tree

The Microchip LAN78XX family of devices are Ethernet controllers with
a USB interface. Despite being discoverable devices it can be useful to
be able to configure them from Device Tree, particularly in low-cost
applications without an EEPROM or programmed OTP.

This patch set adds support for reading the MAC address and LED modes from
Device Tree.

v2:
- Use eth_platform_get_mac_address.
- Support up to 4 LEDs, and move LED mode constants into dt-bindings header.
- Improve bindings document.
- Remove EEE support.

Phil Elwell (3):
lan78xx: Read MAC address from DT if present
lan78xx: Read LED states from Device Tree
dt-bindings: Document the DT bindings for lan78xx

.../devicetree/bindings/net/microchip,lan78xx.txt | 43 +++++++++++++++
MAINTAINERS | 2 +
drivers/net/usb/lan78xx.c | 62 ++++++++++++++--------
include/dt-bindings/net/microchip-78xx.h | 40 ++++++++++++++
4 files changed, 125 insertions(+), 22 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/microchip,lan78xx.txt
create mode 100644 include/dt-bindings/net/microchip-78xx.h

--
2.7.4



2018-04-18 15:47:58

by Phil Elwell

[permalink] [raw]
Subject: [PATCH v2 1/3] lan78xx: Read MAC address from DT if present

There is a standard mechanism for locating and using a MAC address from
the Device Tree. Use this facility in the lan78xx driver to support
applications without programmed EEPROM or OTP. At the same time,
regularise the handling of the different address sources.

Signed-off-by: Phil Elwell <[email protected]>
---
drivers/net/usb/lan78xx.c | 42 ++++++++++++++++++++----------------------
1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 0867f72..a823f01 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -37,6 +37,7 @@
#include <linux/irqchip/chained_irq.h>
#include <linux/microchipphy.h>
#include <linux/phy.h>
+#include <linux/of_net.h>
#include "lan78xx.h"

#define DRIVER_AUTHOR "WOOJUNG HUH <[email protected]>"
@@ -1652,34 +1653,31 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev)
addr[5] = (addr_hi >> 8) & 0xFF;

if (!is_valid_ether_addr(addr)) {
- /* reading mac address from EEPROM or OTP */
- if ((lan78xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
- addr) == 0) ||
- (lan78xx_read_otp(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
- addr) == 0)) {
- if (is_valid_ether_addr(addr)) {
- /* eeprom values are valid so use them */
- netif_dbg(dev, ifup, dev->net,
- "MAC address read from EEPROM");
- } else {
- /* generate random MAC */
- random_ether_addr(addr);
- netif_dbg(dev, ifup, dev->net,
- "MAC address set to random addr");
- }
-
- addr_lo = addr[0] | (addr[1] << 8) |
- (addr[2] << 16) | (addr[3] << 24);
- addr_hi = addr[4] | (addr[5] << 8);
-
- ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
- ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
+ if (!eth_platform_get_mac_address(&dev->udev->dev, addr)) {
+ /* valid address present in Device Tree */
+ netif_dbg(dev, ifup, dev->net,
+ "MAC address read from Device Tree");
+ } else if (((lan78xx_read_eeprom(dev, EEPROM_MAC_OFFSET,
+ ETH_ALEN, addr) == 0) ||
+ (lan78xx_read_otp(dev, EEPROM_MAC_OFFSET,
+ ETH_ALEN, addr) == 0)) &&
+ is_valid_ether_addr(addr)) {
+ /* eeprom values are valid so use them */
+ netif_dbg(dev, ifup, dev->net,
+ "MAC address read from EEPROM");
} else {
/* generate random MAC */
random_ether_addr(addr);
netif_dbg(dev, ifup, dev->net,
"MAC address set to random addr");
}
+
+ addr_lo = addr[0] | (addr[1] << 8) |
+ (addr[2] << 16) | (addr[3] << 24);
+ addr_hi = addr[4] | (addr[5] << 8);
+
+ ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo);
+ ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi);
}

ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo);
--
2.7.4


2018-04-18 15:48:09

by Phil Elwell

[permalink] [raw]
Subject: [PATCH v2 3/3] dt-bindings: Document the DT bindings for lan78xx

The Microchip LAN78XX family of devices are Ethernet controllers with
a USB interface. Despite being discoverable devices it can be useful to
be able to configure them from Device Tree, particularly in low-cost
applications without an EEPROM or programmed OTP.

Document the supported properties in a bindings file.

Signed-off-by: Phil Elwell <[email protected]>
---
.../devicetree/bindings/net/microchip,lan78xx.txt | 44 ++++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 45 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/microchip,lan78xx.txt

diff --git a/Documentation/devicetree/bindings/net/microchip,lan78xx.txt b/Documentation/devicetree/bindings/net/microchip,lan78xx.txt
new file mode 100644
index 0000000..fa68f9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/microchip,lan78xx.txt
@@ -0,0 +1,44 @@
+Microchip LAN78xx Gigabit Ethernet controller
+
+The LAN78XX devices are usually configured by programming their OTP or with
+an external EEPROM, but some platforms (e.g. Raspberry Pi 3 B+) have neither.
+The Device Tree properties, if present, override the OTP and EEPROM.
+
+Required properties:
+- compatible: Should be one of "usb424,7800", "usb424,7801" or "usb424,7850".
+
+Optional properties:
+- local-mac-address: see ethernet.txt
+- mac-address: see ethernet.txt
+- microchip,led-modes: a 0..4 element vector, with each element configuring
+ the operating mode of an LED. Omitted LEDs are turned off. Allowed values
+ are defined in "include/dt-bindings/net/microchip-78xx.h".
+
+Example:
+
+/* Standard configuration for a Raspberry Pi 3 B+ */
+&usb {
+ usb1@1 {
+ compatible = "usb424,2514";
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb1_1@1 {
+ compatible = "usb424,2514";
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet: usbether@1 {
+ compatible = "usb424,7800";
+ reg = <1>;
+ local-mac-address = [ 00 11 22 33 44 55 ];
+ microchip,led-modes = <
+ LAN78XX_LINK_1000_ACTIVITY
+ LAN78XX_LINK_10_100_ACTIVITY
+ >;
+ };
+ };
+ };
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 9c9bc63..5352bbb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14572,6 +14572,7 @@ M: Woojung Huh <[email protected]>
M: Microchip Linux Driver Support <[email protected]>
L: [email protected]
S: Maintained
+F: Documentation/devicetree/bindings/net/microchip,lan78xx.txt
F: drivers/net/usb/lan78xx.*
F: include/dt-bindings/net/microchip-78xx.h

--
2.7.4


2018-04-18 15:48:19

by Phil Elwell

[permalink] [raw]
Subject: [PATCH v2 2/3] lan78xx: Read LED states from Device Tree

Add support for DT property "microchip,led-modes", a vector of zero
to four cells (u32s) in the range 0-15, each of which sets the mode
for one of the LEDs. Some possible values are:

0=link/activity 1=link1000/activity
2=link100/activity 3=link10/activity
4=link100/1000/activity 5=link10/1000/activity
6=link10/100/activity 14=off 15=on

These values are given symbolic constants in a dt-bindings header.

Also use the presence of the DT property to indicate that the
LEDs should be enabled - necessary in the event that no valid OTP
or EEPROM is available.

Signed-off-by: Phil Elwell <[email protected]>
---
MAINTAINERS | 1 +
drivers/net/usb/lan78xx.c | 35 ++++++++++++++++++++++++++++++++
include/dt-bindings/net/microchip-78xx.h | 21 +++++++++++++++++++
3 files changed, 57 insertions(+)
create mode 100644 include/dt-bindings/net/microchip-78xx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b60179d..9c9bc63 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14573,6 +14573,7 @@ M: Microchip Linux Driver Support <[email protected]>
L: [email protected]
S: Maintained
F: drivers/net/usb/lan78xx.*
+F: include/dt-bindings/net/microchip-78xx.h

USB MASS STORAGE DRIVER
M: Alan Stern <[email protected]>
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index a823f01..f47ffea 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -38,6 +38,7 @@
#include <linux/microchipphy.h>
#include <linux/phy.h>
#include <linux/of_net.h>
+#include <dt-bindings/net/microchip-78xx.h>
#include "lan78xx.h"

#define DRIVER_AUTHOR "WOOJUNG HUH <[email protected]>"
@@ -74,6 +75,9 @@
#define LAN78XX_EEPROM_MAGIC (0x78A5)
#define LAN78XX_OTP_MAGIC (0x78F3)

+/* This register is specific to the LAN7800 and LAN7850 embedded PHYs */
+#define LAN78XX_PHY_LED_MODE_SELECT 29
+
#define MII_READ 1
#define MII_WRITE 0

@@ -2005,6 +2009,8 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
{
int ret;
u32 mii_adv;
+ u32 led_modes[4];
+ int len;
struct phy_device *phydev;

phydev = phy_find_first(dev->mdiobus);
@@ -2077,6 +2083,35 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control);
phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv);

+ len = of_property_read_variable_u32_array(dev->udev->dev.of_node,
+ "microchip,led-modes",
+ led_modes,
+ 0,
+ ARRAY_SIZE(led_modes));
+ if (len >= 0) {
+ u32 reg = 0;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (led_modes[i] > 15) {
+ ret = -EINVAL;
+ goto error;
+ }
+ reg |= led_modes[i] << (i * 4);
+ }
+ for (; i < ARRAY_SIZE(led_modes); i++)
+ reg |= LAN78XX_FORCE_LED_OFF << (i * 4);
+ (void)phy_write(phydev, LAN78XX_PHY_LED_MODE_SELECT, reg);
+
+ /* Ensure the LEDs are enabled */
+ lan78xx_read_reg(dev, HW_CFG, &reg);
+ reg |= HW_CFG_LED0_EN_ | HW_CFG_LED1_EN_;
+ lan78xx_write_reg(dev, HW_CFG, reg);
+ } else if (len == -EOVERFLOW) {
+ ret = -EINVAL;
+ goto error;
+ }
+
genphy_config_aneg(phydev);

dev->fc_autoneg = phydev->autoneg;
diff --git a/include/dt-bindings/net/microchip-78xx.h b/include/dt-bindings/net/microchip-78xx.h
new file mode 100644
index 0000000..dcf4a43
--- /dev/null
+++ b/include/dt-bindings/net/microchip-78xx.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _DT_BINDINGS_MICROCHIP_LAN78XX_H
+#define _DT_BINDINGS_MICROCHIP_LAN78XX_H
+
+/* LED modes */
+
+#define LAN78XX_LINK_ACTIVITY 0
+#define LAN78XX_LINK_1000_ACTIVITY 1
+#define LAN78XX_LINK_100_ACTIVITY 2
+#define LAN78XX_LINK_10_ACTIVITY 3
+#define LAN78XX_LINK_100_1000_ACTIVITY 4
+#define LAN78XX_LINK_10_1000_ACTIVITY 5
+#define LAN78XX_LINK_10_100_ACTIVITY 6
+#define LAN78XX_DUPLEX_COLLISION 8
+#define LAN78XX_COLLISION 9
+#define LAN78XX_ACTIVITY 10
+#define LAN78XX_AUTONEG_FAULT 12
+#define LAN78XX_FORCE_LED_OFF 14
+#define LAN78XX_FORCE_LED_ON 15
+
+#endif
--
2.7.4


2018-04-18 16:13:13

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] lan78xx: Read LED states from Device Tree

On Wed, Apr 18, 2018 at 04:45:22PM +0100, Phil Elwell wrote:
> Add support for DT property "microchip,led-modes", a vector of zero
> to four cells (u32s) in the range 0-15, each of which sets the mode
> for one of the LEDs. Some possible values are:
>
> 0=link/activity 1=link1000/activity
> 2=link100/activity 3=link10/activity
> 4=link100/1000/activity 5=link10/1000/activity
> 6=link10/100/activity 14=off 15=on
>
> These values are given symbolic constants in a dt-bindings header.
>
> Also use the presence of the DT property to indicate that the
> LEDs should be enabled - necessary in the event that no valid OTP
> or EEPROM is available.

Hi Phil

As i said last week, these are PHY properties, so should be in the PHY
node in device tree. It should be the PHY driver which parses these
properties and configures the LEDs, not the MAC.

Andrew