linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 0/3] device property: Support MAC address in VPD
@ 2018-08-14 22:37 Brian Norris
  2018-08-14 22:37 ` [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property Brian Norris
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Brian Norris @ 2018-08-14 22:37 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki
  Cc: Andrew Lunn, Florian Fainelli, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd,
	Brian Norris

Hi all,

Preface: I'm sure there are at least a few minor issues with this
patchset as-is. But I'd appreciate ("RFC") if I can get general feedback
on the approach here; perhaps there are alternatives, or perhaps I've
missed similar proposals in the past. (My problems don't feel all that
unique.)

---

Today, we have generic support for 'mac-address' and 'local-mac-address'
properties in both Device Tree nodes and in generic Device Properties,
such that network device drivers can pick up a hardware address from
there, in cases where the MAC address isn't baked into the network card.
This method of MAC address retrieval presumes that either:
(a) there's a unique device tree (or similar) stored on a given device
    or
(b) some other entity (e.g., boot firmware) will modify device nodes
    runtime to place that MAC address into the appropriate device
    properties.

Option (a) is not feasbile for many systems.

Option (b) can work, but there are some reasons why one might not want
to do that:
 (1) This requires that system firmware understand the device tree
     structure, sometimes to the point of memorizing path names (e.g.,
     /soc/wifi@xxxxxxxx). At least for Device Tree, these path names are
     not necessarily an ABI, and so this introduces unneeded fragility.
 (2) Other than this device-tree shim requirement, system firmware may
     have no reason to understand anything about network devices.

So instead, I'm looking for a way to have a device node describe where
to find its MAC address, rather than having the device node contain the
MAC address directly. Then system firmware doesn't have to manage
anything.

In particular, I add support for the Google Vital Product Data (VPD)
format, used within the Coreboot project. The format is described here:

https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md

TL;DR: VPD consists of a TLV-like table, with key/value pairs of
strings. This is often stored persistently on the boot flash and
presented via in-memory Coreboot tables, for the operating system to
read.

We already have a VPD driver that parses this table and presents it to
user space. This series extends that driver to allow in-kernel lookups
of MAC address entries.

Thanks,
Brian


Brian Norris (3):
  dt-bindings: net: Add 'mac-address-lookup' property
  device property: Support complex MAC address lookup
  firmware: vpd: add MAC address parser

 .../devicetree/bindings/net/ethernet.txt      | 12 +++
 drivers/base/property.c                       | 83 ++++++++++++++++++-
 drivers/firmware/google/vpd.c                 | 67 +++++++++++++++
 include/linux/property.h                      | 23 +++++
 4 files changed, 183 insertions(+), 2 deletions(-)

-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property
  2018-08-14 22:37 [RFC PATCH v1 0/3] device property: Support MAC address in VPD Brian Norris
@ 2018-08-14 22:37 ` Brian Norris
  2018-08-15 20:45   ` Rob Herring
  2018-08-14 22:37 ` [RFC PATCH v1 2/3] device property: Support complex MAC address lookup Brian Norris
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Brian Norris @ 2018-08-14 22:37 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki
  Cc: Andrew Lunn, Florian Fainelli, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd,
	Brian Norris

Some firmwares present data tables that can be parsed to retrieve
device-specific details, like MAC addresses. While in some cases, one
could teach the firmware to understand the device tree format and insert
a 'mac-address'/'local-mac-address' property into the FDT on its own,
this method can be brittle (e.g., involving memorizing expected FDT
structure), and it's not strictly necessary -- especially when parsers
for such firmware formats are already needed in the OS for other
reasons.

One such format: the Vital Product Data (VPD) [1] used by Coreboot. It
supports a table of key/value pairs, and some systems keep MAC addresses
there in a well-known format. Allow a device tree to specify
  (1) that the MAC address for a given device is stored in the VPD table
      and
  (2) what key should be used to retrieve the MAC address for said
      device (e.g., "ethernet_mac0" or "wifi_mac1").

[1] Ref:
https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
TL;DR: VPD consists of a TLV-like table, with key/value pairs of
strings. This is often stored persistently on the boot flash and
presented via in-memory Coreboot tables, for the operating system to
read.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
 Documentation/devicetree/bindings/net/ethernet.txt | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt
index cfc376bc977a..d3fd1da18bf4 100644
--- a/Documentation/devicetree/bindings/net/ethernet.txt
+++ b/Documentation/devicetree/bindings/net/ethernet.txt
@@ -4,6 +4,18 @@ NOTE: All 'phy*' properties documented below are Ethernet specific. For the
 generic PHY 'phys' property, see
 Documentation/devicetree/bindings/phy/phy-bindings.txt.
 
+- mac-address-lookup: string, indicating a method by which a MAC address may be
+  discovered for this device. Methods may be parameterized by some value, such
+  that the method can determine the device's MAC address using that parameter.
+  For example, a firmware might store MAC addresses in a table, keyed by some
+  predetermined string, and baked in read-only flash. A lookup method "foo"
+  with a parameter "bar" should be written "foo:bar".
+  Supported values for method:
+    "google-vpd" - Google's Vital Product Data (VPD), as used in the Coreboot
+      project. Documentation for VPD can be found at:
+        https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
+  Example:
+    mac-address-lookup = "google-vpd:ethernet_mac0"
 - local-mac-address: array of 6 bytes, specifies the MAC address that was
   assigned to the network device;
 - mac-address: array of 6 bytes, specifies the MAC address that was last used by
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH v1 2/3] device property: Support complex MAC address lookup
  2018-08-14 22:37 [RFC PATCH v1 0/3] device property: Support MAC address in VPD Brian Norris
  2018-08-14 22:37 ` [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property Brian Norris
@ 2018-08-14 22:37 ` Brian Norris
  2018-08-14 22:37 ` [RFC PATCH v1 3/3] firmware: vpd: add MAC address parser Brian Norris
  2018-08-14 23:00 ` [RFC PATCH v1 0/3] device property: Support MAC address in VPD Florian Fainelli
  3 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2018-08-14 22:37 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki
  Cc: Andrew Lunn, Florian Fainelli, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd,
	Brian Norris

Some firmwares include data tables that can be used to derive a MAC
address for devices on the system, but those firmwares don't directly
stash the MAC address in a device property. Support having other drivers
register lookup functions, where the device property contains
"<format>:<key>" strings; a lookup driver can register support for
handling "<format>", and "<key>" can be used by the format parser to
identify which MAC address is being requested.

This is particularly useful for the Google Vital Product Data (VPD)
format [1], which holds various product-specific key/value pairs, often
stashed in the boot flash.

[1] Ref:
https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
 drivers/base/property.c  | 83 +++++++++++++++++++++++++++++++++++++++-
 include/linux/property.h | 23 +++++++++++
 2 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 240ab5230ff6..fae3390fc56c 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -10,6 +10,7 @@
 #include <linux/acpi.h>
 #include <linux/export.h>
 #include <linux/kernel.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_graph.h>
@@ -1264,6 +1265,78 @@ static void *fwnode_get_mac_addr(struct fwnode_handle *fwnode,
 	return NULL;
 }
 
+static LIST_HEAD(mac_addr_providers);
+static DEFINE_MUTEX(mac_addr_providers_mutex);
+
+void device_register_mac_addr_provider(struct device_mac_addr_provider *prov)
+{
+	mutex_lock(&mac_addr_providers_mutex);
+	list_add(&prov->entry, &mac_addr_providers);
+	mutex_unlock(&mac_addr_providers_mutex);
+}
+EXPORT_SYMBOL(device_register_mac_addr_provider);
+
+void device_unregister_mac_addr_provider(struct device_mac_addr_provider *prov)
+{
+	struct device_mac_addr_provider *p;
+
+	mutex_lock(&mac_addr_providers_mutex);
+	list_for_each_entry(p, &mac_addr_providers, entry) {
+		if (p == prov) {
+			list_del(&p->entry);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&mac_addr_providers_mutex);
+}
+EXPORT_SYMBOL(device_unregister_mac_addr_provider);
+
+static void *fwnode_lookup_mac_addr(struct fwnode_handle *fwnode,
+				    char *addr, int alen)
+{
+	struct device_mac_addr_provider *prov;
+	const char *prop, *sep;
+	u8 mac[ETH_ALEN];
+	int ret;
+
+	ret = fwnode_property_read_string(fwnode, "mac-address-lookup", &prop);
+	if (ret)
+		return NULL;
+
+	sep = strchr(prop, ':');
+	if (!sep)
+		return NULL;
+
+	if (alen != ETH_ALEN)
+		return NULL;
+
+	mutex_lock(&mac_addr_providers_mutex);
+	list_for_each_entry(prov, &mac_addr_providers, entry) {
+		if (strncmp(prov->prefix, prop, strlen(prov->prefix)))
+			continue;
+
+		if (prop + strlen(prov->prefix) != sep)
+			continue;
+
+		ret = prov->lookup(sep + 1, mac);
+		if (ret)
+			continue;
+
+		if (!is_valid_ether_addr(mac))
+			continue;
+
+		ether_addr_copy(addr, mac);
+
+		mutex_unlock(&mac_addr_providers_mutex);
+		return addr;
+	}
+	mutex_unlock(&mac_addr_providers_mutex);
+
+	return NULL;
+}
+
 /**
  * fwnode_get_mac_address - Get the MAC from the firmware node
  * @fwnode:	Pointer to the firmware node
@@ -1274,7 +1347,9 @@ static void *fwnode_get_mac_addr(struct fwnode_handle *fwnode,
  * checked first, because that is supposed to contain to "most recent" MAC
  * address. If that isn't set, then 'local-mac-address' is checked next,
  * because that is the default address.  If that isn't set, then the obsolete
- * 'address' is checked, just in case we're using an old device tree.
+ * 'address' is checked, just in case we're using an old device tree.  And
+ * finally, we check for a method of indirect MAC address lookup, via
+ * 'mac-address-lookup'.
  *
  * Note that the 'address' property is supposed to contain a virtual address of
  * the register set, but some DTS files have redefined that property to be the
@@ -1299,7 +1374,11 @@ void *fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr, int alen)
 	if (res)
 		return res;
 
-	return fwnode_get_mac_addr(fwnode, "address", addr, alen);
+	res = fwnode_get_mac_addr(fwnode, "address", addr, alen);
+	if (res)
+		return res;
+
+	return fwnode_lookup_mac_addr(fwnode, addr, alen);
 }
 EXPORT_SYMBOL(fwnode_get_mac_address);
 
diff --git a/include/linux/property.h b/include/linux/property.h
index ac8a1ebc4c1b..aca5dbb51e19 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -14,6 +14,7 @@
 #define _LINUX_PROPERTY_H_
 
 #include <linux/fwnode.h>
+#include <linux/list.h>
 #include <linux/types.h>
 
 struct device;
@@ -285,6 +286,28 @@ const void *device_get_match_data(struct device *dev);
 
 int device_get_phy_mode(struct device *dev);
 
+/**
+ * struct device_mac_addr_provider - MAC address provider
+ *
+ * Provide methods by which the rest of the kernel can retrieve MAC addresses,
+ * e.g., from a firmware table.
+ *
+ * @entry: list head, for keeping track of all providers
+ * @prefix: string which uniquely identifies the provider
+ * @lookup: Look up a MAC address by key. The provider may associate this @key
+ *	with a stored MAC address; if a match is found, the provider copies the
+ *	associated MAC address to @mac. If not found, a non-zero error code is
+ *	returned.
+ */
+struct device_mac_addr_provider {
+	struct list_head entry;
+	const char *prefix;
+	int (*lookup)(const char *key, u8 *mac);
+};
+
+void device_register_mac_addr_provider(struct device_mac_addr_provider *prov);
+void device_unregister_mac_addr_provider(struct device_mac_addr_provider *prov);
+
 void *device_get_mac_address(struct device *dev, char *addr, int alen);
 
 int fwnode_get_phy_mode(struct fwnode_handle *fwnode);
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH v1 3/3] firmware: vpd: add MAC address parser
  2018-08-14 22:37 [RFC PATCH v1 0/3] device property: Support MAC address in VPD Brian Norris
  2018-08-14 22:37 ` [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property Brian Norris
  2018-08-14 22:37 ` [RFC PATCH v1 2/3] device property: Support complex MAC address lookup Brian Norris
@ 2018-08-14 22:37 ` Brian Norris
  2018-08-14 23:00 ` [RFC PATCH v1 0/3] device property: Support MAC address in VPD Florian Fainelli
  3 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2018-08-14 22:37 UTC (permalink / raw)
  To: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki
  Cc: Andrew Lunn, Florian Fainelli, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd,
	Brian Norris

Device trees can now specify their MAC address via something like:

	mac-address-lookup = "vpd:wifi_mac0";

instead of requiring boot firmware to parse and splice the FDT itself.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
 drivers/firmware/google/vpd.c | 67 +++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c
index e9db895916c3..b2b08497db32 100644
--- a/drivers/firmware/google/vpd.c
+++ b/drivers/firmware/google/vpd.c
@@ -16,6 +16,7 @@
  */
 
 #include <linux/ctype.h>
+#include <linux/if_ether.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -24,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 
@@ -173,6 +175,36 @@ static ssize_t vpd_section_read(struct file *filp, struct kobject *kobp,
 				       sec->bin_attr.size);
 }
 
+static const char *__vpd_get_entry(struct vpd_section *sec, const char *key)
+{
+	struct vpd_attrib_info *info;
+
+	list_for_each_entry(info, &sec->attribs, list)
+		if (!strcmp(info->key, key))
+			return info->value;
+
+	return NULL;
+}
+
+static const char *vpd_get_entry(const char *key)
+{
+	const char *value;
+
+	if (rw_vpd.enabled) {
+		value = __vpd_get_entry(&rw_vpd, key);
+		if (value)
+			return value;
+	}
+
+	if (ro_vpd.enabled) {
+		value = __vpd_get_entry(&ro_vpd, key);
+		if (value)
+			return value;
+	}
+
+	return NULL;
+}
+
 static int vpd_section_create_attribs(struct vpd_section *sec)
 {
 	s32 consumed;
@@ -286,6 +318,37 @@ static int vpd_sections_init(phys_addr_t physaddr)
 	return 0;
 }
 
+/*
+ * 'key' is typically something like 'wifi_mac0' or 'ether_mac1'. Values are 12
+ * character strings of MAC address digits, in hex.
+ */
+static int vpd_lookup_mac_address(const char *key, u8 *mac)
+{
+	const char *entry;
+	int ret;
+
+	if (!key)
+		return -EINVAL;
+
+	entry = vpd_get_entry(key);
+	if (!entry)
+		return -ENOENT;
+
+	if (strlen(entry) != ETH_ALEN * 2)
+		return -EINVAL;
+
+	ret = hex2bin(mac, entry, ETH_ALEN);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static struct device_mac_addr_provider vpd_mac_addr_provider = {
+	.prefix		= "google-vpd",
+	.lookup		= &vpd_lookup_mac_address,
+};
+
 static int vpd_probe(struct coreboot_device *dev)
 {
 	int ret;
@@ -300,11 +363,15 @@ static int vpd_probe(struct coreboot_device *dev)
 		return ret;
 	}
 
+	device_register_mac_addr_provider(&vpd_mac_addr_provider);
+
 	return 0;
 }
 
 static int vpd_remove(struct coreboot_device *dev)
 {
+	device_unregister_mac_addr_provider(&vpd_mac_addr_provider);
+
 	vpd_section_destroy(&ro_vpd);
 	vpd_section_destroy(&rw_vpd);
 
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-14 22:37 [RFC PATCH v1 0/3] device property: Support MAC address in VPD Brian Norris
                   ` (2 preceding siblings ...)
  2018-08-14 22:37 ` [RFC PATCH v1 3/3] firmware: vpd: add MAC address parser Brian Norris
@ 2018-08-14 23:00 ` Florian Fainelli
  2018-08-15  0:22   ` Brian Norris
  3 siblings, 1 reply; 15+ messages in thread
From: Florian Fainelli @ 2018-08-14 23:00 UTC (permalink / raw)
  To: Brian Norris, Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki
  Cc: Andrew Lunn, Dmitry Torokhov, Guenter Roeck, netdev, devicetree,
	linux-kernel, Julius Werner, Stephen Boyd, Brian Norris

On 08/14/2018 03:37 PM, Brian Norris wrote:
> Hi all,
> 
> Preface: I'm sure there are at least a few minor issues with this
> patchset as-is. But I'd appreciate ("RFC") if I can get general feedback
> on the approach here; perhaps there are alternatives, or perhaps I've
> missed similar proposals in the past. (My problems don't feel all that
> unique.)
> 
> ---
> 
> Today, we have generic support for 'mac-address' and 'local-mac-address'
> properties in both Device Tree nodes and in generic Device Properties,
> such that network device drivers can pick up a hardware address from
> there, in cases where the MAC address isn't baked into the network card.
> This method of MAC address retrieval presumes that either:
> (a) there's a unique device tree (or similar) stored on a given device
>     or
> (b) some other entity (e.g., boot firmware) will modify device nodes
>     runtime to place that MAC address into the appropriate device
>     properties.
> 
> Option (a) is not feasbile for many systems.
> 
> Option (b) can work, but there are some reasons why one might not want
> to do that:
>  (1) This requires that system firmware understand the device tree
>      structure, sometimes to the point of memorizing path names (e.g.,
>      /soc/wifi@xxxxxxxx). At least for Device Tree, these path names are
>      not necessarily an ABI, and so this introduces unneeded fragility.

The path to a node is something that is well defined and should be
stable given that the high level function of the node and its unit
address are not supposed to change. Under which circumstances, besides
incorrect specification of either of these two things, do they not
consist an ABI? Not refuting your statement here, just curious when/how
this can happen?

Also, aliases in DT are meant to provide some stability.

>  (2) Other than this device-tree shim requirement, system firmware may
>      have no reason to understand anything about network devices.
> 
> So instead, I'm looking for a way to have a device node describe where
> to find its MAC address, rather than having the device node contain the
> MAC address directly. Then system firmware doesn't have to manage
> anything.
> 
> In particular, I add support for the Google Vital Product Data (VPD)
> format, used within the Coreboot project. The format is described here:
> 
> https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
> 
> TL;DR: VPD consists of a TLV-like table, with key/value pairs of
> strings. This is often stored persistently on the boot flash and
> presented via in-memory Coreboot tables, for the operating system to
> read.
> 
> We already have a VPD driver that parses this table and presents it to
> user space. This series extends that driver to allow in-kernel lookups
> of MAC address entries.

A possible alternative approach is to have the VPD driver become a NVMEM
producer to expose the VPD keys, did you look into that and possibly
found that it was not a good model? The downside to that approach though
is that you might have to have a phandle for the VPD provider in the
Device Tree, but AFAICS this should solve your needs?

[1]: https://patchwork.ozlabs.org/cover/956062/
[2]: https://lkml.org/lkml/2018/3/24/312

> 
> Thanks,
> Brian
> 
> 
> Brian Norris (3):
>   dt-bindings: net: Add 'mac-address-lookup' property
>   device property: Support complex MAC address lookup
>   firmware: vpd: add MAC address parser
> 
>  .../devicetree/bindings/net/ethernet.txt      | 12 +++
>  drivers/base/property.c                       | 83 ++++++++++++++++++-
>  drivers/firmware/google/vpd.c                 | 67 +++++++++++++++
>  include/linux/property.h                      | 23 +++++
>  4 files changed, 183 insertions(+), 2 deletions(-)
> 


-- 
Florian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-14 23:00 ` [RFC PATCH v1 0/3] device property: Support MAC address in VPD Florian Fainelli
@ 2018-08-15  0:22   ` Brian Norris
  2018-08-15  0:52     ` Florian Fainelli
  0 siblings, 1 reply; 15+ messages in thread
From: Brian Norris @ 2018-08-15  0:22 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Andrew Lunn,
	Dmitry Torokhov, Guenter Roeck, netdev, devicetree, linux-kernel,
	Julius Werner, Stephen Boyd, Brian Norris, Srinivas Kandagatla

+ Srinivas, as there are NVMEM questions

Hi Florian,

Thanks for the quick reply.

On Tue, Aug 14, 2018 at 04:00:28PM -0700, Florian Fainelli wrote:
> On 08/14/2018 03:37 PM, Brian Norris wrote:
> > Today, we have generic support for 'mac-address' and 'local-mac-address'
> > properties in both Device Tree nodes and in generic Device Properties,
> > such that network device drivers can pick up a hardware address from
> > there, in cases where the MAC address isn't baked into the network card.
> > This method of MAC address retrieval presumes that either:
> > (a) there's a unique device tree (or similar) stored on a given device
> >     or
> > (b) some other entity (e.g., boot firmware) will modify device nodes
> >     runtime to place that MAC address into the appropriate device
> >     properties.
> > 
> > Option (a) is not feasbile for many systems.
> > 
> > Option (b) can work, but there are some reasons why one might not want
> > to do that:
> >  (1) This requires that system firmware understand the device tree
> >      structure, sometimes to the point of memorizing path names (e.g.,
> >      /soc/wifi@xxxxxxxx). At least for Device Tree, these path names are
> >      not necessarily an ABI, and so this introduces unneeded fragility.
> 
> The path to a node is something that is well defined and should be
> stable given that the high level function of the node and its unit
> address are not supposed to change. Under which circumstances, besides
> incorrect specification of either of these two things, do they not
> consist an ABI? Not refuting your statement here, just curious when/how
> this can happen?

I can think of a few reasons:

 * it's not really standardized whether to use a /soc/ node or to
   just put top-level SoC blocks directly under /. There might be
   "recommendations", but I certainly have seen it both ways.

 * the "high level function name" is not set in stone AFAICT. Or at
   least, I've never seen a list of documented names. So while on one
   system I might see 'wlan@', another might use 'wifi@'.

 * in any of the above (and in any other case of lack of clarity), one
   can make slightly different choices when, e.g., submitting a device
   tree upstream vs. a downstream tree. While we may try our hardest to
   document and stick to documented bindings, I personally can't
   guarantee that one of these choices will be made differently during
   review, possibly breaking any firmware that made assumptions based on
   those choices. So I might end up with a firmware that satisfies
   documented bindings and works with a downstream device tree, but
   doesn't work with a device tree that gets submitted upstream.

> Also, aliases in DT are meant to provide some stability.

How, specifically? I don't see any relevant binding description for
aliases under Documentation/devicetree/bindings/net/.

> >  (2) Other than this device-tree shim requirement, system firmware may
> >      have no reason to understand anything about network devices.
> > 
> > So instead, I'm looking for a way to have a device node describe where
> > to find its MAC address, rather than having the device node contain the
> > MAC address directly. Then system firmware doesn't have to manage
> > anything.
> > 
> > In particular, I add support for the Google Vital Product Data (VPD)
> > format, used within the Coreboot project. The format is described here:
> > 
> > https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
> > 
> > TL;DR: VPD consists of a TLV-like table, with key/value pairs of
> > strings. This is often stored persistently on the boot flash and
> > presented via in-memory Coreboot tables, for the operating system to
> > read.
> > 
> > We already have a VPD driver that parses this table and presents it to
> > user space. This series extends that driver to allow in-kernel lookups
> > of MAC address entries.
> 
> A possible alternative approach is to have the VPD driver become a NVMEM
> producer to expose the VPD keys, did you look into that and possibly
> found that it was not a good model? The downside to that approach though
> is that you might have to have a phandle for the VPD provider in the
> Device Tree, but AFAICS this should solve your needs?

I did notice some NVMEM work. The MTD links you point at shouldn't be
relevant, since this table is already present in RAM. But I suppose I
could shoehorn the memory table into being a fake NVMEM...

And then, how would you recommend doing the parameterization I note
here? Is the expectation that I define a new cell for every single type?
Each cell might have a different binary format, so I'd have to describe:
(a) that they contain MAC addresses (so the "reader" knows to translate
    the ASCII strings into equivalent binary representation) and
(b) which key matches (it's not just "mac_address=xxxxx"; there may be
    many MAC addresses, with keys "ether_mac0", "ether_mac1",
    "wifi_mac0")
Part (a) especially doesn't really sound like the typical NVMEM, which
seems to pretend it provides raw access to these memory regions.

Additionally, VPD is not stored at a fixed address, nor are any
particular entries within it (it uses TLV), so it seems like there are
plenty of other bits of the nvmem.txt documentation I'd have to violate
to get there, such as the definition of 'reg':

reg:    specifies the offset in byte within the storage device.

And finally, this may be surmountable, but the existing APIs seem very
device tree centric. We use this same format on ACPI systems, and the
current series would theoretically work on both [1]. I'd have to rewrite
the current (OF-only) helpers to get equivalent support...

BTW, it's quite annoying that we have all of these:

fwnode_get_mac_address()
device_get_mac_address()
of_get_mac_address()
of_get_nvmem_mac_address()

and only 2 of those share any code! Brilliant!

> [1]: https://patchwork.ozlabs.org/cover/956062/
> [2]: https://lkml.org/lkml/2018/3/24/312

Brian

[1] Fortunately, I've only needed this on DT so far.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-15  0:22   ` Brian Norris
@ 2018-08-15  0:52     ` Florian Fainelli
  2018-08-15  1:44       ` Brian Norris
  0 siblings, 1 reply; 15+ messages in thread
From: Florian Fainelli @ 2018-08-15  0:52 UTC (permalink / raw)
  To: Brian Norris
  Cc: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Andrew Lunn,
	Dmitry Torokhov, Guenter Roeck, netdev, devicetree, linux-kernel,
	Julius Werner, Stephen Boyd, Brian Norris, Srinivas Kandagatla

On 08/14/2018 05:22 PM, Brian Norris wrote:
> + Srinivas, as there are NVMEM questions
> 
> Hi Florian,
> 
> Thanks for the quick reply.
> 
> On Tue, Aug 14, 2018 at 04:00:28PM -0700, Florian Fainelli wrote:
>> On 08/14/2018 03:37 PM, Brian Norris wrote:
>>> Today, we have generic support for 'mac-address' and 'local-mac-address'
>>> properties in both Device Tree nodes and in generic Device Properties,
>>> such that network device drivers can pick up a hardware address from
>>> there, in cases where the MAC address isn't baked into the network card.
>>> This method of MAC address retrieval presumes that either:
>>> (a) there's a unique device tree (or similar) stored on a given device
>>>     or
>>> (b) some other entity (e.g., boot firmware) will modify device nodes
>>>     runtime to place that MAC address into the appropriate device
>>>     properties.
>>>
>>> Option (a) is not feasbile for many systems.
>>>
>>> Option (b) can work, but there are some reasons why one might not want
>>> to do that:
>>>  (1) This requires that system firmware understand the device tree
>>>      structure, sometimes to the point of memorizing path names (e.g.,
>>>      /soc/wifi@xxxxxxxx). At least for Device Tree, these path names are
>>>      not necessarily an ABI, and so this introduces unneeded fragility.
>>
>> The path to a node is something that is well defined and should be
>> stable given that the high level function of the node and its unit
>> address are not supposed to change. Under which circumstances, besides
>> incorrect specification of either of these two things, do they not
>> consist an ABI? Not refuting your statement here, just curious when/how
>> this can happen?
> 
> I can think of a few reasons:
> 
>  * it's not really standardized whether to use a /soc/ node or to
>    just put top-level SoC blocks directly under /. There might be
>    "recommendations", but I certainly have seen it both ways.

That type of stability and standardization, ok

> 
>  * the "high level function name" is not set in stone AFAICT. Or at
>    least, I've never seen a list of documented names. So while on one
>    system I might see 'wlan@', another might use 'wifi@'.

There are some recommended function names defined in devicetree-spec,
not everything is covered since the spec is still lagging a bit behind
as far as recommending names for what a modern SoC/board would embed
(with some definition of "modern").

> 
>  * in any of the above (and in any other case of lack of clarity), one
>    can make slightly different choices when, e.g., submitting a device
>    tree upstream vs. a downstream tree. While we may try our hardest to
>    document and stick to documented bindings, I personally can't
>    guarantee that one of these choices will be made differently during
>    review, possibly breaking any firmware that made assumptions based on
>    those choices. So I might end up with a firmware that satisfies
>    documented bindings and works with a downstream device tree, but
>    doesn't work with a device tree that gets submitted upstream.

Sure, this is kind of a self inflicted problem but agreed this does exist.

> 
>> Also, aliases in DT are meant to provide some stability.
> 
> How, specifically? I don't see any relevant binding description for
> aliases under Documentation/devicetree/bindings/net/.

Indeed they are not, likewise, we should probably update devicetree-spec
to come up with standard names that of_alias_get_id() already consumes.

> 
>>>  (2) Other than this device-tree shim requirement, system firmware may
>>>      have no reason to understand anything about network devices.
>>>
>>> So instead, I'm looking for a way to have a device node describe where
>>> to find its MAC address, rather than having the device node contain the
>>> MAC address directly. Then system firmware doesn't have to manage
>>> anything.
>>>
>>> In particular, I add support for the Google Vital Product Data (VPD)
>>> format, used within the Coreboot project. The format is described here:
>>>
>>> https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
>>>
>>> TL;DR: VPD consists of a TLV-like table, with key/value pairs of
>>> strings. This is often stored persistently on the boot flash and
>>> presented via in-memory Coreboot tables, for the operating system to
>>> read.
>>>
>>> We already have a VPD driver that parses this table and presents it to
>>> user space. This series extends that driver to allow in-kernel lookups
>>> of MAC address entries.
>>
>> A possible alternative approach is to have the VPD driver become a NVMEM
>> producer to expose the VPD keys, did you look into that and possibly
>> found that it was not a good model? The downside to that approach though
>> is that you might have to have a phandle for the VPD provider in the
>> Device Tree, but AFAICS this should solve your needs?
> 
> I did notice some NVMEM work. The MTD links you point at shouldn't be
> relevant, since this table is already present in RAM. But I suppose I
> could shoehorn the memory table into being a fake NVMEM...
> 
> And then, how would you recommend doing the parameterization I note
> here? Is the expectation that I define a new cell for every single type?
> Each cell might have a different binary format, so I'd have to describe:
> (a) that they contain MAC addresses (so the "reader" knows to translate
>     the ASCII strings into equivalent binary representation) and

I see, in your current patch series that knowledge is pushed to both the
VPD producer and the specific object lookup function, so this scales better.

> (b) which key matches (it's not just "mac_address=xxxxx"; there may be
>     many MAC addresses, with keys "ether_mac0", "ether_mac1",
>     "wifi_mac0")

The key to lookup is definitively node specific, it is just unfortunate
that there is not a better way to infer which key to lookup for (as
opposed to just having to specify it directly) based on the Device Tree
topology. By that I mean, if you have a "mac-address-lookup" property
associated with Wi-Fi adapter #1 (with numbering starting at 0), then
this automatically means looking up for "wifi_mac1", etc.

> Part (a) especially doesn't really sound like the typical NVMEM, which
> seems to pretend it provides raw access to these memory regions.
> 
> Additionally, VPD is not stored at a fixed address, nor are any
> particular entries within it (it uses TLV), so it seems like there are
> plenty of other bits of the nvmem.txt documentation I'd have to violate
> to get there, such as the definition of 'reg':
> 
> reg:    specifies the offset in byte within the storage device.
> 
> And finally, this may be surmountable, but the existing APIs seem very
> device tree centric. We use this same format on ACPI systems, and the
> current series would theoretically work on both [1]. I'd have to rewrite
> the current (OF-only) helpers to get equivalent support...

All fair points, never mind NVMEM, I was just too keen on thinking this
would be finally the way to make the consumers and producers of such
information into a single API, but your proposal appears valid too.

Is ChromeOS' directly inspired from the PCI's spec VPD?

> 
> BTW, it's quite annoying that we have all of these:
> 
> fwnode_get_mac_address()
> device_get_mac_address()
> of_get_mac_address()
> of_get_nvmem_mac_address()
> 
> and only 2 of those share any code! Brilliant!

Sounds like you just found another area to improve on ;)

> 
>> [1]: https://patchwork.ozlabs.org/cover/956062/
>> [2]: https://lkml.org/lkml/2018/3/24/312
> 
> Brian
> 
> [1] Fortunately, I've only needed this on DT so far.
> 


-- 
Florian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-15  0:52     ` Florian Fainelli
@ 2018-08-15  1:44       ` Brian Norris
  2018-08-15 22:07         ` Stephen Boyd
  2018-08-15 22:16         ` Rob Herring
  0 siblings, 2 replies; 15+ messages in thread
From: Brian Norris @ 2018-08-15  1:44 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Andrew Lunn,
	Dmitry Torokhov, Guenter Roeck, netdev, devicetree, linux-kernel,
	Julius Werner, Stephen Boyd, Brian Norris, Srinivas Kandagatla

Hi,

On Tue, Aug 14, 2018 at 05:52:49PM -0700, Florian Fainelli wrote:
> On 08/14/2018 05:22 PM, Brian Norris wrote:
> >  * in any of the above (and in any other case of lack of clarity), one
> >    can make slightly different choices when, e.g., submitting a device
> >    tree upstream vs. a downstream tree. While we may try our hardest to
> >    document and stick to documented bindings, I personally can't
> >    guarantee that one of these choices will be made differently during
> >    review, possibly breaking any firmware that made assumptions based on
> >    those choices. So I might end up with a firmware that satisfies
> >    documented bindings and works with a downstream device tree, but
> >    doesn't work with a device tree that gets submitted upstream.
> 
> Sure, this is kind of a self inflicted problem but agreed this does exist.

You can say "self-inflicted", but of all the things that need to go
upstream, the DTS files themselves are the least integral. I mean, why
else do we ever pretend to have anything close to an ABI for device
tree bindings?

> >> Also, aliases in DT are meant to provide some stability.
> > 
> > How, specifically? I don't see any relevant binding description for
> > aliases under Documentation/devicetree/bindings/net/.
> 
> Indeed they are not, likewise, we should probably update devicetree-spec
> to come up with standard names that of_alias_get_id() already consumes.

A quick grep shows we already have divergence: both "eth" and "ethernet"
are in use.

But anyway, would the idea be that you just put 'ethernet{0,1,...}' and
'wifi{0,1,...}' aliases in the /chosen node, then require boot firmware
to insert any {ethernet,wifi}_mac{0,1,...} into the paths represented by
the corresponding aliases? I suppose that would reduce the problems with
(1), but it still doesn't really help with (2).

In some circles, the gold standard of boot firmware is to be as thin as
possible, doing only what's needed to get a kernel up and running, and
this function seems wholly unrelated to the firmware's core
functionality. I mean, the kernel already knows how to parse VPD, so why
can't it learn to find the right field?

> >>>  (2) Other than this device-tree shim requirement, system firmware may
> >>>      have no reason to understand anything about network devices.
> >>>
> >>> So instead, I'm looking for a way to have a device node describe where
> >>> to find its MAC address, rather than having the device node contain the
> >>> MAC address directly. Then system firmware doesn't have to manage
> >>> anything.
> >>>
> >>> In particular, I add support for the Google Vital Product Data (VPD)
> >>> format, used within the Coreboot project. The format is described here:
> >>>
> >>> https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
> >>>
> >>> TL;DR: VPD consists of a TLV-like table, with key/value pairs of
> >>> strings. This is often stored persistently on the boot flash and
> >>> presented via in-memory Coreboot tables, for the operating system to
> >>> read.
> >>>
> >>> We already have a VPD driver that parses this table and presents it to
> >>> user space. This series extends that driver to allow in-kernel lookups
> >>> of MAC address entries.
> >>
> >> A possible alternative approach is to have the VPD driver become a NVMEM
> >> producer to expose the VPD keys, did you look into that and possibly
> >> found that it was not a good model? The downside to that approach though
> >> is that you might have to have a phandle for the VPD provider in the
> >> Device Tree, but AFAICS this should solve your needs?
> > 
> > I did notice some NVMEM work. The MTD links you point at shouldn't be
> > relevant, since this table is already present in RAM. But I suppose I
> > could shoehorn the memory table into being a fake NVMEM...
> > 
> > And then, how would you recommend doing the parameterization I note
> > here? Is the expectation that I define a new cell for every single type?
> > Each cell might have a different binary format, so I'd have to describe:
> > (a) that they contain MAC addresses (so the "reader" knows to translate
> >     the ASCII strings into equivalent binary representation) and
> 
> I see, in your current patch series that knowledge is pushed to both the
> VPD producer and the specific object lookup function, so this scales better.

Yeah, one of the advantages is that my API is specialized to exactly one
data type ;) With the nvmem API, the data format isn't really specified,
so you gotta hope that either the NVMEM stores MAC addresses as 6 bytes
of binary data, or else that the NVMEM driver figures out how to do any
translation for you implicitly.

If I understand the NVMEM subsystem correctly, that is.

> > (b) which key matches (it's not just "mac_address=xxxxx"; there may be
> >     many MAC addresses, with keys "ether_mac0", "ether_mac1",
> >     "wifi_mac0")
> 
> The key to lookup is definitively node specific, it is just unfortunate
> that there is not a better way to infer which key to lookup for (as
> opposed to just having to specify it directly) based on the Device Tree
> topology. By that I mean, if you have a "mac-address-lookup" property
> associated with Wi-Fi adapter #1 (with numbering starting at 0), then
> this automatically means looking up for "wifi_mac1", etc.

Would that really be a virtue, though? Keys can really be anything (in
VPD, or in any other hypothetical MAC address store), and it seems nice
to avoid entangling them with device tree specifics too much. And how
does one figure out what's Device 0 anyway? Based on the FDT layout? I
don't actually know what order 'dtc' puts my nodes in.

> > Part (a) especially doesn't really sound like the typical NVMEM, which
> > seems to pretend it provides raw access to these memory regions.
> > 
> > Additionally, VPD is not stored at a fixed address, nor are any
> > particular entries within it (it uses TLV), so it seems like there are
> > plenty of other bits of the nvmem.txt documentation I'd have to violate
> > to get there, such as the definition of 'reg':
> > 
> > reg:    specifies the offset in byte within the storage device.
> > 
> > And finally, this may be surmountable, but the existing APIs seem very
> > device tree centric. We use this same format on ACPI systems, and the
> > current series would theoretically work on both [1]. I'd have to rewrite
> > the current (OF-only) helpers to get equivalent support...
> 
> All fair points, never mind NVMEM, I was just too keen on thinking this
> would be finally the way to make the consumers and producers of such
> information into a single API, but your proposal appears valid too.

I don't want to throw out any notion of unification from the start, but
I don't immediately see how one would do that reasonably. I'm still open
to education though, and I'm definitely not wedded to my specific
proposal.

> Is ChromeOS' directly inspired from the PCI's spec VPD?

I really don't have any idea. From glancing at the PCI spec, its format
isn't very similar, relative to how simple each of them are.

> > BTW, it's quite annoying that we have all of these:
> > 
> > fwnode_get_mac_address()
> > device_get_mac_address()
> > of_get_mac_address()
> > of_get_nvmem_mac_address()
> > 
> > and only 2 of those share any code! Brilliant!
> 
> Sounds like you just found another area to improve on ;)

Sure ;) I knew about the useless duplication of of_get_mac_address(),
but I wasn't aware of of_get_nvmem_mac_address(). It seems like it might
have come out of a deficiency that I already noticed in
of_get_mac_address(): that it assumes you can return a const pointer.

I'll probably try to remove as many uses of of_get_mac_address() as
possible and settle on fwnode_get_mac_address() /
device_get_mac_address(). Probably would be good to have
fwnode_get_mac_address() also do the of_get_nvmem_mac_address() work and
deprecate of_get_nvmem_mac_address() too.

Regards,
Brian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property
  2018-08-14 22:37 ` [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property Brian Norris
@ 2018-08-15 20:45   ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2018-08-15 20:45 UTC (permalink / raw)
  To: Brian Norris
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Andrew Lunn,
	Florian Fainelli, Dmitry Torokhov, Guenter Roeck, netdev,
	devicetree, linux-kernel, Julius Werner, Stephen Boyd,
	Brian Norris

On Tue, Aug 14, 2018 at 03:37:56PM -0700, Brian Norris wrote:
> Some firmwares present data tables that can be parsed to retrieve
> device-specific details, like MAC addresses. While in some cases, one
> could teach the firmware to understand the device tree format and insert
> a 'mac-address'/'local-mac-address' property into the FDT on its own,
> this method can be brittle (e.g., involving memorizing expected FDT
> structure), and it's not strictly necessary -- especially when parsers
> for such firmware formats are already needed in the OS for other
> reasons.

If you have an 'ethernetN' alias then you don't need to know the 
structure. IIRC, that is what u-boot does.

> 
> One such format: the Vital Product Data (VPD) [1] used by Coreboot. It
> supports a table of key/value pairs, and some systems keep MAC addresses
> there in a well-known format. Allow a device tree to specify
>   (1) that the MAC address for a given device is stored in the VPD table
>       and
>   (2) what key should be used to retrieve the MAC address for said
>       device (e.g., "ethernet_mac0" or "wifi_mac1").
> 
> [1] Ref:
> https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
> TL;DR: VPD consists of a TLV-like table, with key/value pairs of
> strings. This is often stored persistently on the boot flash and
> presented via in-memory Coreboot tables, for the operating system to
> read.
> 
> Signed-off-by: Brian Norris <briannorris@chromium.org>
> ---
>  Documentation/devicetree/bindings/net/ethernet.txt | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt
> index cfc376bc977a..d3fd1da18bf4 100644
> --- a/Documentation/devicetree/bindings/net/ethernet.txt
> +++ b/Documentation/devicetree/bindings/net/ethernet.txt
> @@ -4,6 +4,18 @@ NOTE: All 'phy*' properties documented below are Ethernet specific. For the
>  generic PHY 'phys' property, see
>  Documentation/devicetree/bindings/phy/phy-bindings.txt.
>  
> +- mac-address-lookup: string, indicating a method by which a MAC address may be
> +  discovered for this device. Methods may be parameterized by some value, such
> +  that the method can determine the device's MAC address using that parameter.
> +  For example, a firmware might store MAC addresses in a table, keyed by some
> +  predetermined string, and baked in read-only flash. A lookup method "foo"
> +  with a parameter "bar" should be written "foo:bar".
> +  Supported values for method:
> +    "google-vpd" - Google's Vital Product Data (VPD), as used in the Coreboot
> +      project. Documentation for VPD can be found at:
> +        https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
> +  Example:
> +    mac-address-lookup = "google-vpd:ethernet_mac0"

This doesn't strike me as a very DT style way of describing this. I 
would expect something like a phandle to the VPD and an identifier. 

Also, an already common way besides local-mac-address is using nvmem 
binding which wouldn't use this and perhaps could be used here? This 
feels very much Google specific, not common (and maybe that is fine).

Rob

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-15  1:44       ` Brian Norris
@ 2018-08-15 22:07         ` Stephen Boyd
  2018-08-31  0:55           ` Brian Norris
  2018-08-15 22:16         ` Rob Herring
  1 sibling, 1 reply; 15+ messages in thread
From: Stephen Boyd @ 2018-08-15 22:07 UTC (permalink / raw)
  To: Brian Norris, Florian Fainelli
  Cc: Rob Herring, Greg Kroah-Hartman, Rafael J. Wysocki, Andrew Lunn,
	Dmitry Torokhov, Guenter Roeck, netdev, devicetree, linux-kernel,
	Julius Werner, Brian Norris, Srinivas Kandagatla

Quoting Brian Norris (2018-08-14 18:44:36)
> Hi,
> 
> On Tue, Aug 14, 2018 at 05:52:49PM -0700, Florian Fainelli wrote:
> > On 08/14/2018 05:22 PM, Brian Norris wrote:
> 
> > >> Also, aliases in DT are meant to provide some stability.
> > > 
> > > How, specifically? I don't see any relevant binding description for
> > > aliases under Documentation/devicetree/bindings/net/.
> > 
> > Indeed they are not, likewise, we should probably update devicetree-spec
> > to come up with standard names that of_alias_get_id() already consumes.
> 
> A quick grep shows we already have divergence: both "eth" and "ethernet"
> are in use.
> 
> But anyway, would the idea be that you just put 'ethernet{0,1,...}' and
> 'wifi{0,1,...}' aliases in the /chosen node, then require boot firmware
> to insert any {ethernet,wifi}_mac{0,1,...} into the paths represented by
> the corresponding aliases? I suppose that would reduce the problems with
> (1), but it still doesn't really help with (2).

Yes. Aliases are the way to do this. It obviates much of this discussion
about finding things in DT by directly pointing to the node the
bootloader wants to go modify.

> > > 
> > > And finally, this may be surmountable, but the existing APIs seem very
> > > device tree centric. We use this same format on ACPI systems, and the
> > > current series would theoretically work on both [1]. I'd have to rewrite
> > > the current (OF-only) helpers to get equivalent support...

Where does it go on ACPI systems? Does the firmware stick it into some
ACPI table by reading from VPD?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-15  1:44       ` Brian Norris
  2018-08-15 22:07         ` Stephen Boyd
@ 2018-08-15 22:16         ` Rob Herring
  2018-08-31  1:26           ` Brian Norris
  1 sibling, 1 reply; 15+ messages in thread
From: Rob Herring @ 2018-08-15 22:16 UTC (permalink / raw)
  To: Brian Norris
  Cc: Florian Fainelli, Greg Kroah-Hartman, Rafael J. Wysocki,
	Andrew Lunn, Dmitry Torokhov, Guenter Roeck, netdev, devicetree,
	linux-kernel, Julius Werner, Stephen Boyd, Brian Norris,
	Srinivas Kandagatla

On Tue, Aug 14, 2018 at 06:44:36PM -0700, Brian Norris wrote:
> Hi,

I should have read the rest of this thread first...

> 
> On Tue, Aug 14, 2018 at 05:52:49PM -0700, Florian Fainelli wrote:
> > On 08/14/2018 05:22 PM, Brian Norris wrote:
> > >  * in any of the above (and in any other case of lack of clarity), one
> > >    can make slightly different choices when, e.g., submitting a device
> > >    tree upstream vs. a downstream tree. While we may try our hardest to
> > >    document and stick to documented bindings, I personally can't
> > >    guarantee that one of these choices will be made differently during
> > >    review, possibly breaking any firmware that made assumptions based on
> > >    those choices. So I might end up with a firmware that satisfies
> > >    documented bindings and works with a downstream device tree, but
> > >    doesn't work with a device tree that gets submitted upstream.
> > 
> > Sure, this is kind of a self inflicted problem but agreed this does exist.
> 
> You can say "self-inflicted", but of all the things that need to go
> upstream, the DTS files themselves are the least integral. I mean, why
> else do we ever pretend to have anything close to an ABI for device
> tree bindings?

That sounds like an inadequately documented binding.

> 
> > >> Also, aliases in DT are meant to provide some stability.
> > > 
> > > How, specifically? I don't see any relevant binding description for
> > > aliases under Documentation/devicetree/bindings/net/.
> > 
> > Indeed they are not, likewise, we should probably update devicetree-spec
> > to come up with standard names that of_alias_get_id() already consumes.
> 
> A quick grep shows we already have divergence: both "eth" and "ethernet"
> are in use.

Uggg, it would be nice to clean that up. 

There's several aliases I'd like to get rid of (some platforms went a 
little crazy with them) and I'd like to start requiring alias names to 
be documented. I created an issue for the spec. Patches welcomeTM. :)

> But anyway, would the idea be that you just put 'ethernet{0,1,...}' and
> 'wifi{0,1,...}' aliases in the /chosen node, then require boot firmware
> to insert any {ethernet,wifi}_mac{0,1,...} into the paths represented by
> the corresponding aliases?

In the /aliases node, but yes.

>  I suppose that would reduce the problems with
> (1), but it still doesn't really help with (2).
> 
> In some circles, the gold standard of boot firmware is to be as thin as
> possible, doing only what's needed to get a kernel up and running, and
> this function seems wholly unrelated to the firmware's core
> functionality. I mean, the kernel already knows how to parse VPD, so why
> can't it learn to find the right field?
> 
> > >>>  (2) Other than this device-tree shim requirement, system firmware may
> > >>>      have no reason to understand anything about network devices.
> > >>>
> > >>> So instead, I'm looking for a way to have a device node describe where
> > >>> to find its MAC address, rather than having the device node contain the
> > >>> MAC address directly. Then system firmware doesn't have to manage
> > >>> anything.
> > >>>
> > >>> In particular, I add support for the Google Vital Product Data (VPD)
> > >>> format, used within the Coreboot project. The format is described here:
> > >>>
> > >>> https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
> > >>>
> > >>> TL;DR: VPD consists of a TLV-like table, with key/value pairs of
> > >>> strings. This is often stored persistently on the boot flash and
> > >>> presented via in-memory Coreboot tables, for the operating system to
> > >>> read.
> > >>>
> > >>> We already have a VPD driver that parses this table and presents it to
> > >>> user space. This series extends that driver to allow in-kernel lookups
> > >>> of MAC address entries.
> > >>
> > >> A possible alternative approach is to have the VPD driver become a NVMEM
> > >> producer to expose the VPD keys, did you look into that and possibly
> > >> found that it was not a good model? The downside to that approach though
> > >> is that you might have to have a phandle for the VPD provider in the
> > >> Device Tree, but AFAICS this should solve your needs?
> > > 
> > > I did notice some NVMEM work. The MTD links you point at shouldn't be
> > > relevant, since this table is already present in RAM. But I suppose I
> > > could shoehorn the memory table into being a fake NVMEM...
> > > 
> > > And then, how would you recommend doing the parameterization I note
> > > here? Is the expectation that I define a new cell for every single type?
> > > Each cell might have a different binary format, so I'd have to describe:
> > > (a) that they contain MAC addresses (so the "reader" knows to translate
> > >     the ASCII strings into equivalent binary representation) and
> > 
> > I see, in your current patch series that knowledge is pushed to both the
> > VPD producer and the specific object lookup function, so this scales better.
> 
> Yeah, one of the advantages is that my API is specialized to exactly one
> data type ;) With the nvmem API, the data format isn't really specified,
> so you gotta hope that either the NVMEM stores MAC addresses as 6 bytes
> of binary data, or else that the NVMEM driver figures out how to do any
> translation for you implicitly.
> 
> If I understand the NVMEM subsystem correctly, that is.
> 
> > > (b) which key matches (it's not just "mac_address=xxxxx"; there may be
> > >     many MAC addresses, with keys "ether_mac0", "ether_mac1",
> > >     "wifi_mac0")
> > 
> > The key to lookup is definitively node specific, it is just unfortunate
> > that there is not a better way to infer which key to lookup for (as
> > opposed to just having to specify it directly) based on the Device Tree
> > topology. By that I mean, if you have a "mac-address-lookup" property
> > associated with Wi-Fi adapter #1 (with numbering starting at 0), then
> > this automatically means looking up for "wifi_mac1", etc.
> 
> Would that really be a virtue, though? Keys can really be anything (in
> VPD, or in any other hypothetical MAC address store), and it seems nice
> to avoid entangling them with device tree specifics too much. And how
> does one figure out what's Device 0 anyway? Based on the FDT layout? I
> don't actually know what order 'dtc' puts my nodes in.
> 
> > > Part (a) especially doesn't really sound like the typical NVMEM, which
> > > seems to pretend it provides raw access to these memory regions.
> > > 
> > > Additionally, VPD is not stored at a fixed address, nor are any
> > > particular entries within it (it uses TLV), so it seems like there are
> > > plenty of other bits of the nvmem.txt documentation I'd have to violate
> > > to get there, such as the definition of 'reg':
> > > 
> > > reg:    specifies the offset in byte within the storage device.
> > > 
> > > And finally, this may be surmountable, but the existing APIs seem very
> > > device tree centric. We use this same format on ACPI systems, and the
> > > current series would theoretically work on both [1]. I'd have to rewrite
> > > the current (OF-only) helpers to get equivalent support...
> > 
> > All fair points, never mind NVMEM, I was just too keen on thinking this
> > would be finally the way to make the consumers and producers of such
> > information into a single API, but your proposal appears valid too.
> 
> I don't want to throw out any notion of unification from the start, but
> I don't immediately see how one would do that reasonably. I'm still open
> to education though, and I'm definitely not wedded to my specific
> proposal.

Seems to me that nvmem needs to be extended to allow providers to 
retrieve and interpret data. Not everything is at some fixed offset and 
size. Something like this is valid dts:

nvmem = <&phandle> "a-string";

But that's pretty uncommon (I can't think of a binding that actually 
uses that). Perhaps the provider has an array of keys defined and the 
consumer just provides the index.

Or we could do '<key>-nvmem = <&phandle>', but parsing that is a bit 
more complicated.

Rob

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-15 22:07         ` Stephen Boyd
@ 2018-08-31  0:55           ` Brian Norris
  0 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2018-08-31  0:55 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Brian Norris, Florian Fainelli, Rob Herring, Greg Kroah-Hartman,
	Rafael J. Wysocki, Andrew Lunn, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner,
	Srinivas Kandagatla

(sorry for the delayed response here)

Hi,

On Wed, Aug 15, 2018 at 03:07:00PM -0700, Stephen Boyd wrote:
> Quoting Brian Norris (2018-08-14 18:44:36)
> > But anyway, would the idea be that you just put 'ethernet{0,1,...}' and
> > 'wifi{0,1,...}' aliases in the /chosen node, then require boot firmware
> > to insert any {ethernet,wifi}_mac{0,1,...} into the paths represented by
> > the corresponding aliases? I suppose that would reduce the problems with
> > (1), but it still doesn't really help with (2).
> 
> Yes. Aliases are the way to do this. It obviates much of this discussion
> about finding things in DT by directly pointing to the node the
> bootloader wants to go modify.

Sure, that does seem to help.

> > > > And finally, this may be surmountable, but the existing APIs seem very
> > > > device tree centric. We use this same format on ACPI systems, and the
> > > > current series would theoretically work on both [1]. I'd have to rewrite
> > > > the current (OF-only) helpers to get equivalent support...
> 
> Where does it go on ACPI systems? Does the firmware stick it into some
> ACPI table by reading from VPD?

I'm not aware of any ACPI system that needs to do something quite like
this. The closest I see is a Coreboot board for some Chromeboxes [1],
which handles Ethernet MAC addresses -- it does this by reading similar
VPD fields, but then it just goes and programs the MAC directly into the
Ethernet card's registers. This is a Realtek PCI Ethernet chip, and
apparently it even needs firmware to program its product and vendor ID
for it.

I'm not really sure what lesson to get out of that though. That
discoverable hardware is a giant dirty mess (even PCI gets a lot of help
from system firmware!)?

Or I guess maybe the lesson is: ACPI systems will always find a way to
do it in firmware, no matter how much bloat it costs. So I don't really
need to consider "does this solution work with ACPI"? But just, does it
work with {device,fwnode}_get_mac_address() -- e.g., by teaching them to
call of_get_nvmem_mac_address()?

Brian

[1] Here, and similar variants in other boards throughout the tree:
https://review.coreboot.org/cgit/coreboot.git/tree/src/mainboard/google/beltino/lan.c

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-15 22:16         ` Rob Herring
@ 2018-08-31  1:26           ` Brian Norris
  2018-08-31  8:43             ` Srinivas Kandagatla
  0 siblings, 1 reply; 15+ messages in thread
From: Brian Norris @ 2018-08-31  1:26 UTC (permalink / raw)
  To: Rob Herring
  Cc: Brian Norris, Florian Fainelli, Greg Kroah-Hartman,
	Rafael J. Wysocki, Andrew Lunn, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd,
	Srinivas Kandagatla

Hi, sorry for the delay, and thanks for the response.

I'm still not sure whether I'll pursue this series further, but I'd like
to at least narrow down what it'd look like.

On Wed, Aug 15, 2018 at 04:16:01PM -0600, Rob Herring wrote:
> On Tue, Aug 14, 2018 at 06:44:36PM -0700, Brian Norris wrote:
> > On Tue, Aug 14, 2018 at 05:52:49PM -0700, Florian Fainelli wrote:
> > > On 08/14/2018 05:22 PM, Brian Norris wrote:
> > > >> Also, aliases in DT are meant to provide some stability.
> > > > 
> > > > How, specifically? I don't see any relevant binding description for
> > > > aliases under Documentation/devicetree/bindings/net/.
> > > 
> > > Indeed they are not, likewise, we should probably update devicetree-spec
> > > to come up with standard names that of_alias_get_id() already consumes.
> > 
> > A quick grep shows we already have divergence: both "eth" and "ethernet"
> > are in use.
> 
> Uggg, it would be nice to clean that up. 

Is it fair to just change them, since they were never documented? Of
course, only after documenting the "right" way.

> There's several aliases I'd like to get rid of (some platforms went a 
> little crazy with them) and I'd like to start requiring alias names to 
> be documented. I created an issue for the spec. Patches welcomeTM. :)

So e.g., new text in Documentation/devicetree/bindings/net/ethernet.txt
and Documentation/devicetree/bindings/net/wireless/ieee80211.txt about
'aliases' entries? I can do that, especially if I give up on a new
binding like in this series.

> > But anyway, would the idea be that you just put 'ethernet{0,1,...}' and
> > 'wifi{0,1,...}' aliases in the /chosen node, then require boot firmware
> > to insert any {ethernet,wifi}_mac{0,1,...} into the paths represented by
> > the corresponding aliases?
> 
> In the /aliases node, but yes.

Oops, yes.

> Seems to me that nvmem needs to be extended to allow providers to 
> retrieve and interpret data. Not everything is at some fixed offset and 
> size. Something like this is valid dts:
> 
> nvmem = <&phandle> "a-string";
> 
> But that's pretty uncommon (I can't think of a binding that actually 
> uses that). Perhaps the provider has an array of keys defined and the 
> consumer just provides the index.

In the case of VPD, all keys are 0-terminated strings (there's also a
length field, but the key is still 0-terminated), so that scheme could
work. (I'm not sure an indexed provider is extremely relevant right now,
although it probably could be supported if I expand the of_nvmem
retrieval to support a generic of_xlate() override anyway.) The
information represented is almost the same as in my proposal, except that:
(a) now I have to give the VPD a phandle -- so far, I've avoided that,
    as it's just an auto-enumerated device underneath the
    /firmware/coreboot device (see drivers/firmware/google/vpd.c)
(b) this is no longer directly useful to ACPI systems -- I'm not
    actually sure how (if at all) nvmem provider/consumer is supposed to
    work there

But maybe this isn't really that useful to ACPI, and it's sufficient to
just have fwnode_get_mac_address() call of_get_nvmem_mac_address() when
we're using DT.

> Or we could do '<key>-nvmem = <&phandle>', but parsing that is a bit 
> more complicated.

That doesn't seem to have much advantage to me.

Brian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-31  1:26           ` Brian Norris
@ 2018-08-31  8:43             ` Srinivas Kandagatla
  2018-08-31 21:28               ` Brian Norris
  0 siblings, 1 reply; 15+ messages in thread
From: Srinivas Kandagatla @ 2018-08-31  8:43 UTC (permalink / raw)
  To: Brian Norris, Rob Herring
  Cc: Brian Norris, Florian Fainelli, Greg Kroah-Hartman,
	Rafael J. Wysocki, Andrew Lunn, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd

Sorry for the delay!! For some reason I missed this email thread totally!

On 31/08/18 02:26, Brian Norris wrote:
>> Seems to me that nvmem needs to be extended to allow providers to
>> retrieve and interpret data. Not everything is at some fixed offset and
>> size. Something like this is valid dts:
>>
>> nvmem = <&phandle> "a-string";
>>

There has been some discussion on extending nvmem support to MTD and 
non-DT users in https://patchwork.kernel.org/cover/10562365/

One of the thing which we discussed in this thread is adding compatible 
strings to cells mainly to
1> Differentiate between actual cells and partitions for MTD case.

2> Allow provider specific bindings for each cell, in VPD instance key 
string & value length could be one them.

This means that we would endup adding xlate callback support to the 
nvmem_config.

AFAIU, From consumer side old bindings should still work!

 From non-dt or ACPI side these cells can be parsed by the provider 
driver and add it to the nvmem_config.

Does this make sense? Or Did I miss anything obvious ?


>> But that's pretty uncommon (I can't think of a binding that actually
>> uses that). Perhaps the provider has an array of keys defined and the
>> consumer just provides the index.
> In the case of VPD, all keys are 0-terminated strings (there's also a
> length field, but the key is still 0-terminated), so that scheme could
> work. (I'm not sure an indexed provider is extremely relevant right now,
> although it probably could be supported if I expand the of_nvmem
> retrieval to support a generic of_xlate() override anyway.) The
> information represented is almost the same as in my proposal, except that:
> (a) now I have to give the VPD a phandle -- so far, I've avoided that,
>      as it's just an auto-enumerated device underneath the
>      /firmware/coreboot device (see drivers/firmware/google/vpd.c)
> (b) this is no longer directly useful to ACPI systems -- I'm not
>      actually sure how (if at all) nvmem provider/consumer is supposed to
>      work there
> 
> But maybe this isn't really that useful to ACPI, and it's sufficient to
> just have fwnode_get_mac_address() call of_get_nvmem_mac_address() when
> we're using DT.
> 
>> Or we could do '<key>-nvmem = <&phandle>', but parsing that is a bit
>> more complicated.
> That doesn't seem to have much advantage to me.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH v1 0/3] device property: Support MAC address in VPD
  2018-08-31  8:43             ` Srinivas Kandagatla
@ 2018-08-31 21:28               ` Brian Norris
  0 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2018-08-31 21:28 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rob Herring, Brian Norris, Florian Fainelli, Greg Kroah-Hartman,
	Rafael J. Wysocki, Andrew Lunn, Dmitry Torokhov, Guenter Roeck,
	netdev, devicetree, linux-kernel, Julius Werner, Stephen Boyd

Hi Srinivas,

On Fri, Aug 31, 2018 at 09:43:30AM +0100, Srinivas Kandagatla wrote:

> On 31/08/18 02:26, Brian Norris wrote:
> > > Seems to me that nvmem needs to be extended to allow providers to
> > > retrieve and interpret data. Not everything is at some fixed offset and
> > > size. Something like this is valid dts:
> > > 
> > > nvmem = <&phandle> "a-string";
> > > 
> 
> There has been some discussion on extending nvmem support to MTD and non-DT
> users in https://patchwork.kernel.org/cover/10562365/
> 
> One of the thing which we discussed in this thread is adding compatible
> strings to cells mainly to
> 1> Differentiate between actual cells and partitions for MTD case.

I'm not particularly worried about the MTD case. As I mentioned earlier,
while VPD is stored on flash (and could be exposed as an MTD), coreboot
places these tables in memory, and we currently just read them from
there instead of from flash.

> 2> Allow provider specific bindings for each cell, in VPD instance key
> string & value length could be one them.

I'm not sure we'd need to have a binding for value length -- VPD encodes
the length itself, and for many properties, the length is understood by
both sides anyway (2x6 bytes for a MAC address).

> This means that we would endup adding xlate callback support to the
> nvmem_config.

OK, but that's not in the current series, correct?

> AFAIU, From consumer side old bindings should still work!

I'm still trying to wrap my head around all the existing and proposed
behaviors of nvmem, but I see a few things lacking (IIUC):

(1) for the new "lookup" method, you would only support a single MAC
    address, identified by looking up for "mac-address" -- this means
    you can't support two devices (e.g., we have systems with VPD
    entries for "ethernet_mac0" and "etherent_mac1")
(2) the consumer API isn't very flexible -- it assumes that the data you
    read out of an NVMEM cell is directly usable as a MAC address; this
    fails for VPD, because VPD uses ASCII encoding. To resolve this,
    you'd need the consumer/provider relationship to know something
    about the data type -- to know that we should decode the ASCII
    values

> From non-dt or ACPI side these cells can be parsed by the provider driver
> and add it to the nvmem_config.

I think that might work, except for the above problems. But perhaps I'm
misreading.

> Does this make sense? Or Did I miss anything obvious ?
> 
> 
> > > But that's pretty uncommon (I can't think of a binding that actually
> > > uses that). Perhaps the provider has an array of keys defined and the
> > > consumer just provides the index.
> > In the case of VPD, all keys are 0-terminated strings (there's also a
> > length field, but the key is still 0-terminated), so that scheme could
> > work. (I'm not sure an indexed provider is extremely relevant right now,
> > although it probably could be supported if I expand the of_nvmem
> > retrieval to support a generic of_xlate() override anyway.) The
> > information represented is almost the same as in my proposal, except that:

@Rob:
I forgot about problem (2) above -- NVMEM is not very expressive about
the *type* of information. My proposal makes it explicit that the
provider is presenting MAC addresses. To make a generic VPD NVMEM
provider, I'd need to do ASCII decoding on some fields but not on
others.

Brian

> > (a) now I have to give the VPD a phandle -- so far, I've avoided that,
> >      as it's just an auto-enumerated device underneath the
> >      /firmware/coreboot device (see drivers/firmware/google/vpd.c)
> > (b) this is no longer directly useful to ACPI systems -- I'm not
> >      actually sure how (if at all) nvmem provider/consumer is supposed to
> >      work there
> > 
> > But maybe this isn't really that useful to ACPI, and it's sufficient to
> > just have fwnode_get_mac_address() call of_get_nvmem_mac_address() when
> > we're using DT.
> > 
> > > Or we could do '<key>-nvmem = <&phandle>', but parsing that is a bit
> > > more complicated.
> > That doesn't seem to have much advantage to me.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-08-31 21:28 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-14 22:37 [RFC PATCH v1 0/3] device property: Support MAC address in VPD Brian Norris
2018-08-14 22:37 ` [RFC PATCH v1 1/3] dt-bindings: net: Add 'mac-address-lookup' property Brian Norris
2018-08-15 20:45   ` Rob Herring
2018-08-14 22:37 ` [RFC PATCH v1 2/3] device property: Support complex MAC address lookup Brian Norris
2018-08-14 22:37 ` [RFC PATCH v1 3/3] firmware: vpd: add MAC address parser Brian Norris
2018-08-14 23:00 ` [RFC PATCH v1 0/3] device property: Support MAC address in VPD Florian Fainelli
2018-08-15  0:22   ` Brian Norris
2018-08-15  0:52     ` Florian Fainelli
2018-08-15  1:44       ` Brian Norris
2018-08-15 22:07         ` Stephen Boyd
2018-08-31  0:55           ` Brian Norris
2018-08-15 22:16         ` Rob Herring
2018-08-31  1:26           ` Brian Norris
2018-08-31  8:43             ` Srinivas Kandagatla
2018-08-31 21:28               ` Brian Norris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).