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); |  	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; |  	return mac; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| +static const void *of_get_mac_address_mtd(struct device_node *np) | +static const void *of_get_mac_address_mtd(struct device_node *np) | ||||||
| +{ | +{ | ||||||
| +#ifdef CONFIG_MTD | +#ifdef CONFIG_MTD | ||||||
|  | +	struct platform_device *pdev = of_find_device_by_node(np); | ||||||
| +	struct device_node *mtd_np = NULL; | +	struct device_node *mtd_np = NULL; | ||||||
| +	struct property *prop; | +	struct property *prop; | ||||||
| +	size_t retlen; | +	size_t retlen; | ||||||
| @@ -77,46 +78,30 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | |||||||
| +	if (!is_valid_ether_addr(mac)) | +	if (!is_valid_ether_addr(mac)) | ||||||
| +		return NULL; | +		return NULL; | ||||||
| + | + | ||||||
| +	addr = of_get_mac_addr(np, "mac-address"); | +	addr = devm_kmemdup(&pdev->dev, mac, ETH_ALEN, GFP_KERNEL); | ||||||
| +	if (addr) { | +	if (!addr) | ||||||
| +		memcpy(addr, mac, ETH_ALEN); | +		return ERR_PTR(-ENOMEM); | ||||||
| +		return addr; |  | ||||||
| +	} |  | ||||||
| + | + | ||||||
| +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | +	return addr; | ||||||
| +	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 | +#endif | ||||||
| +	return NULL; |  | ||||||
| +} | +} | ||||||
| + | + | ||||||
| + | + | ||||||
|  /** |  /** | ||||||
|   * Search the device tree for the best MAC address to use.  'mac-address' is |   * 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 |   * 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 |   * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists | ||||||
|   * but is all zeros. |   * but is all zeros. | ||||||
|   * |   * | ||||||
| + * | + * | ||||||
| + * If a mtd-mac-address property exists, try to fetch the MAC address from the | + * 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. |   * 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) |  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) |  	if (addr) | ||||||
|  		return 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) | +static void *of_get_mac_address_mtd(struct device_node *np) | ||||||
|  { |  { | ||||||
|  #ifdef CONFIG_MTD |  #ifdef CONFIG_MTD | ||||||
|  	struct device_node *mtd_np = NULL; |  	struct platform_device *pdev = of_find_device_by_node(np); | ||||||
| @@ -167,28 +172,54 @@ free: | @@ -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 |   * 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 | + * DT can tell the system to increment the mac-address after is extracted by | ||||||
| + * using: | + * 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); |  	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; |  	return mac; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| +static const void *of_get_mac_address_mtd(struct device_node *np) | +static const void *of_get_mac_address_mtd(struct device_node *np) | ||||||
| +{ | +{ | ||||||
| +#ifdef CONFIG_MTD | +#ifdef CONFIG_MTD | ||||||
|  | +	struct platform_device *pdev = of_find_device_by_node(np); | ||||||
| +	struct device_node *mtd_np = NULL; | +	struct device_node *mtd_np = NULL; | ||||||
| +	struct property *prop; | +	struct property *prop; | ||||||
| +	size_t retlen; | +	size_t retlen; | ||||||
| @@ -77,46 +78,30 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> | |||||||
| +	if (!is_valid_ether_addr(mac)) | +	if (!is_valid_ether_addr(mac)) | ||||||
| +		return NULL; | +		return NULL; | ||||||
| + | + | ||||||
| +	addr = of_get_mac_addr(np, "mac-address"); | +	addr = devm_kmemdup(&pdev->dev, mac, ETH_ALEN, GFP_KERNEL); | ||||||
| +	if (addr) { | +	if (!addr) | ||||||
| +		memcpy(addr, mac, ETH_ALEN); | +		return ERR_PTR(-ENOMEM); | ||||||
| +		return addr; |  | ||||||
| +	} |  | ||||||
| + | + | ||||||
| +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); | +	return addr; | ||||||
| +	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 | +#endif | ||||||
| +	return NULL; |  | ||||||
| +} | +} | ||||||
| + | + | ||||||
| + | + | ||||||
|  /** |  /** | ||||||
|   * Search the device tree for the best MAC address to use.  'mac-address' is |   * 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 |   * 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 |   * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists | ||||||
|   * but is all zeros. |   * but is all zeros. | ||||||
|   * |   * | ||||||
| + * | + * | ||||||
| + * If a mtd-mac-address property exists, try to fetch the MAC address from the | + * 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. |   * 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) |  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) |  	if (addr) | ||||||
|  		return 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) | +static void *of_get_mac_address_mtd(struct device_node *np) | ||||||
|  { |  { | ||||||
|  #ifdef CONFIG_MTD |  #ifdef CONFIG_MTD | ||||||
|  	struct device_node *mtd_np = NULL; |  	struct platform_device *pdev = of_find_device_by_node(np); | ||||||
| @@ -161,28 +166,54 @@ free: | @@ -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 |   * 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 | + * DT can tell the system to increment the mac-address after is extracted by | ||||||
| + * using: | + * 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