generic: write back netdev MAC-address to device-tree
The label-mac logic relies on the mac-address property of a netdev devices of-node. However, the mac address can also be stored as a different property or read from e.g. an mtd device. Create this node when reading a mac-address from OF if it does not already exist and copy the mac-address used for the device to this property. This way, the MAC address can be accessed using procfs. Signed-off-by: David Bauer <mail@david-bauer.net>
This commit is contained in:
		| @@ -34,13 +34,14 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | ||||
|  { | ||||
|  	struct property *pp = of_find_property(np, name, NULL); | ||||
|   | ||||
| @@ -78,6 +79,70 @@ static const void *of_get_mac_addr_nvmem | ||||
| @@ -78,6 +79,55 @@ static const void *of_get_mac_addr_nvmem | ||||
|  	return mac; | ||||
|  } | ||||
|   | ||||
| +static const void *of_get_mac_address_mtd(struct device_node *np) | ||||
| +{ | ||||
| +#ifdef CONFIG_MTD | ||||
| +	struct platform_device *pdev = of_find_device_by_node(np); | ||||
| +	struct device_node *mtd_np = NULL; | ||||
| +	struct property *prop; | ||||
| +	size_t retlen; | ||||
| @@ -77,46 +78,30 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | ||||
| +	if (!is_valid_ether_addr(mac)) | ||||
| +		return NULL; | ||||
| + | ||||
| +	addr = of_get_mac_addr(np, "mac-address"); | ||||
| +	if (addr) { | ||||
| +		memcpy(addr, mac, ETH_ALEN); | ||||
| +	addr = devm_kmemdup(&pdev->dev, mac, ETH_ALEN, GFP_KERNEL); | ||||
| +	if (!addr) | ||||
| +		return ERR_PTR(-ENOMEM); | ||||
| + | ||||
| +	return addr; | ||||
| +	} | ||||
| + | ||||
| +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||||
| +	if (!prop) | ||||
| +		return NULL; | ||||
| + | ||||
| +	prop->name = "mac-address"; | ||||
| +	prop->length = ETH_ALEN; | ||||
| +	prop->value = kmemdup(mac, ETH_ALEN, GFP_KERNEL); | ||||
| +	if (!prop->value || of_add_property(np, prop)) | ||||
| +		goto free; | ||||
| + | ||||
| +	return prop->value; | ||||
| +free: | ||||
| +	kfree(prop->value); | ||||
| +	kfree(prop); | ||||
| +#endif | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| + | ||||
|  /** | ||||
|   * Search the device tree for the best MAC address to use.  'mac-address' is | ||||
|   * checked first, because that is supposed to contain to "most recent" MAC | ||||
| @@ -98,6 +163,10 @@ static const void *of_get_mac_addr_nvmem | ||||
| @@ -98,6 +148,10 @@ static const void *of_get_mac_addr_nvmem | ||||
|   * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists | ||||
|   * but is all zeros. | ||||
|   * | ||||
| + * | ||||
| + * If a mtd-mac-address property exists, try to fetch the MAC address from the | ||||
| + * specified mtd device, and store it as a 'mac-address' property | ||||
| + * specified mtd device. | ||||
| + * | ||||
|   * Return: Will be a valid pointer on success and ERR_PTR in case of error. | ||||
|  */ | ||||
|  const void *of_get_mac_address(struct device_node *np) | ||||
| @@ -116,6 +185,10 @@ const void *of_get_mac_address(struct de | ||||
| @@ -116,6 +170,10 @@ const void *of_get_mac_address(struct de | ||||
|  	if (addr) | ||||
|  		return addr; | ||||
|   | ||||
|   | ||||
| @@ -64,10 +64,10 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | ||||
| +static void *of_get_mac_address_mtd(struct device_node *np) | ||||
|  { | ||||
|  #ifdef CONFIG_MTD | ||||
|  	struct device_node *mtd_np = NULL; | ||||
| @@ -167,28 +172,54 @@ free: | ||||
|  	struct platform_device *pdev = of_find_device_by_node(np); | ||||
| @@ -152,28 +157,54 @@ static const void *of_get_mac_address_mt | ||||
|   * If a mtd-mac-address property exists, try to fetch the MAC address from the | ||||
|   * specified mtd device, and store it as a 'mac-address' property | ||||
|   * specified mtd device. | ||||
|   * | ||||
| + * DT can tell the system to increment the mac-address after is extracted by | ||||
| + * using: | ||||
|   | ||||
| @@ -0,0 +1,44 @@ | ||||
| --- a/drivers/of/of_net.c | ||||
| +++ b/drivers/of/of_net.c | ||||
| @@ -132,6 +132,33 @@ static void *of_get_mac_address_mtd(stru | ||||
|  #endif | ||||
|  } | ||||
|   | ||||
| +static int of_add_mac_address(struct device_node *np, u8* addr) | ||||
| +{ | ||||
| +	struct property *prop; | ||||
| +	u8 *np_addr; | ||||
| + | ||||
| +	np_addr = of_get_mac_addr(np, "mac-address"); | ||||
| +	if (np_addr) { | ||||
| +		memcpy(np_addr, addr, ETH_ALEN); | ||||
| +		return 0; | ||||
| +	} | ||||
| + | ||||
| +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||||
| +	if (!prop) | ||||
| +		return 0; | ||||
| + | ||||
| +	prop->name = "mac-address"; | ||||
| +	prop->length = ETH_ALEN; | ||||
| +	prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL); | ||||
| +	if (!prop->value || of_add_property(np, prop)) | ||||
| +		goto free; | ||||
| + | ||||
| +	return 0; | ||||
| +free: | ||||
| +	kfree(prop->value); | ||||
| +	kfree(prop); | ||||
| +	return -ENOMEM; | ||||
| +} | ||||
|   | ||||
|  /** | ||||
|   * Search the device tree for the best MAC address to use.  'mac-address' is | ||||
| @@ -205,6 +232,7 @@ found: | ||||
|  	if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) | ||||
|  		addr[inc_idx] += mac_inc; | ||||
|   | ||||
| +	of_add_mac_address(np, addr); | ||||
|  	return addr; | ||||
|  } | ||||
|  EXPORT_SYMBOL(of_get_mac_address); | ||||
| @@ -34,13 +34,14 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | ||||
|  { | ||||
|  	struct property *pp = of_find_property(np, name, NULL); | ||||
|   | ||||
| @@ -72,6 +73,70 @@ static const void *of_get_mac_addr_nvmem | ||||
| @@ -72,6 +73,55 @@ static const void *of_get_mac_addr_nvmem | ||||
|  	return mac; | ||||
|  } | ||||
|   | ||||
| +static const void *of_get_mac_address_mtd(struct device_node *np) | ||||
| +{ | ||||
| +#ifdef CONFIG_MTD | ||||
| +	struct platform_device *pdev = of_find_device_by_node(np); | ||||
| +	struct device_node *mtd_np = NULL; | ||||
| +	struct property *prop; | ||||
| +	size_t retlen; | ||||
| @@ -77,46 +78,30 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | ||||
| +	if (!is_valid_ether_addr(mac)) | ||||
| +		return NULL; | ||||
| + | ||||
| +	addr = of_get_mac_addr(np, "mac-address"); | ||||
| +	if (addr) { | ||||
| +		memcpy(addr, mac, ETH_ALEN); | ||||
| +	addr = devm_kmemdup(&pdev->dev, mac, ETH_ALEN, GFP_KERNEL); | ||||
| +	if (!addr) | ||||
| +		return ERR_PTR(-ENOMEM); | ||||
| + | ||||
| +	return addr; | ||||
| +	} | ||||
| + | ||||
| +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||||
| +	if (!prop) | ||||
| +		return NULL; | ||||
| + | ||||
| +	prop->name = "mac-address"; | ||||
| +	prop->length = ETH_ALEN; | ||||
| +	prop->value = kmemdup(mac, ETH_ALEN, GFP_KERNEL); | ||||
| +	if (!prop->value || of_add_property(np, prop)) | ||||
| +		goto free; | ||||
| + | ||||
| +	return prop->value; | ||||
| +free: | ||||
| +	kfree(prop->value); | ||||
| +	kfree(prop); | ||||
| +#endif | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| + | ||||
|  /** | ||||
|   * Search the device tree for the best MAC address to use.  'mac-address' is | ||||
|   * checked first, because that is supposed to contain to "most recent" MAC | ||||
| @@ -92,6 +157,10 @@ static const void *of_get_mac_addr_nvmem | ||||
| @@ -92,6 +142,10 @@ static const void *of_get_mac_addr_nvmem | ||||
|   * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists | ||||
|   * but is all zeros. | ||||
|   * | ||||
| + * | ||||
| + * If a mtd-mac-address property exists, try to fetch the MAC address from the | ||||
| + * specified mtd device, and store it as a 'mac-address' property | ||||
| + * specified mtd device. | ||||
| + * | ||||
|   * Return: Will be a valid pointer on success and ERR_PTR in case of error. | ||||
|  */ | ||||
|  const void *of_get_mac_address(struct device_node *np) | ||||
| @@ -110,6 +179,10 @@ const void *of_get_mac_address(struct de | ||||
| @@ -110,6 +164,10 @@ const void *of_get_mac_address(struct de | ||||
|  	if (addr) | ||||
|  		return addr; | ||||
|   | ||||
|   | ||||
| @@ -64,10 +64,10 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | ||||
| +static void *of_get_mac_address_mtd(struct device_node *np) | ||||
|  { | ||||
|  #ifdef CONFIG_MTD | ||||
|  	struct device_node *mtd_np = NULL; | ||||
| @@ -161,28 +166,54 @@ free: | ||||
|  	struct platform_device *pdev = of_find_device_by_node(np); | ||||
| @@ -146,28 +151,54 @@ static const void *of_get_mac_address_mt | ||||
|   * If a mtd-mac-address property exists, try to fetch the MAC address from the | ||||
|   * specified mtd device, and store it as a 'mac-address' property | ||||
|   * specified mtd device. | ||||
|   * | ||||
| + * DT can tell the system to increment the mac-address after is extracted by | ||||
| + * using: | ||||
|   | ||||
| @@ -0,0 +1,44 @@ | ||||
| --- a/drivers/of/of_net.c | ||||
| +++ b/drivers/of/of_net.c | ||||
| @@ -125,6 +125,33 @@ static void *of_get_mac_address_mtd(stru | ||||
|  #endif | ||||
|  } | ||||
|   | ||||
| +static int of_add_mac_address(struct device_node *np, u8* addr) | ||||
| +{ | ||||
| +	struct property *prop; | ||||
| +	u8 *np_addr; | ||||
| + | ||||
| +	np_addr = of_get_mac_addr(np, "mac-address"); | ||||
| +	if (np_addr) { | ||||
| +		memcpy(np_addr, addr, ETH_ALEN); | ||||
| +		return 0; | ||||
| +	} | ||||
| + | ||||
| +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||||
| +	if (!prop) | ||||
| +		return 0; | ||||
| + | ||||
| +	prop->name = "mac-address"; | ||||
| +	prop->length = ETH_ALEN; | ||||
| +	prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL); | ||||
| +	if (!prop->value || of_add_property(np, prop)) | ||||
| +		goto free; | ||||
| + | ||||
| +	return 0; | ||||
| +free: | ||||
| +	kfree(prop->value); | ||||
| +	kfree(prop); | ||||
| +	return -ENOMEM; | ||||
| +} | ||||
|   | ||||
|  /** | ||||
|   * Search the device tree for the best MAC address to use.  'mac-address' is | ||||
| @@ -198,6 +225,7 @@ found: | ||||
|  	if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) | ||||
|  		addr[inc_idx] += mac_inc; | ||||
|   | ||||
| +	of_add_mac_address(np, addr); | ||||
|  	return addr; | ||||
|  } | ||||
|  EXPORT_SYMBOL(of_get_mac_address); | ||||
		Reference in New Issue
	
	Block a user
	 David Bauer
					David Bauer