From: Yousong Zhou Date: Fri, 8 Apr 2022 10:20:08 +0000 (+0000) Subject: ath79: add nvmem cell mac-address-ascii support X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=ecd81de7a5ab4899cc95107b402f7a402caf70bd;p=openwrt%2Fstaging%2Fnoltari.git ath79: add nvmem cell mac-address-ascii support This is needed for devices with mac address stored in ascii format, e.g. HiWiFi HC6361 to be ported in the following patch. Signed-off-by: Yousong Zhou --- diff --git a/target/linux/ath79/patches-5.10/600-of_net-add-mac-address-ascii-support.patch b/target/linux/ath79/patches-5.10/600-of_net-add-mac-address-ascii-support.patch new file mode 100644 index 0000000000..8849afb4d6 --- /dev/null +++ b/target/linux/ath79/patches-5.10/600-of_net-add-mac-address-ascii-support.patch @@ -0,0 +1,103 @@ +Index: linux-5.15.31/net/ethernet/eth.c +=================================================================== +--- linux-5.15.31.orig/net/ethernet/eth.c ++++ linux-5.15.31/net/ethernet/eth.c +@@ -544,6 +544,63 @@ int eth_platform_get_mac_address(struct + } + EXPORT_SYMBOL(eth_platform_get_mac_address); + ++static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell) ++{ ++ size_t len; ++ void *mac; ++ ++ mac = nvmem_cell_read(cell, &len); ++ if (IS_ERR(mac)) ++ return PTR_ERR(mac); ++ if (len != ETH_ALEN) { ++ kfree(mac); ++ return ERR_PTR(-EINVAL); ++ } ++ return mac; ++} ++ ++static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell) ++{ ++ size_t len; ++ int ret; ++ void *mac_ascii; ++ u8 *mac; ++ ++ mac_ascii = nvmem_cell_read(cell, &len); ++ if (IS_ERR(mac_ascii)) ++ return PTR_ERR(mac_ascii); ++ if (len != ETH_ALEN*2+5) { ++ kfree(mac_ascii); ++ return ERR_PTR(-EINVAL); ++ } ++ mac = kmalloc(ETH_ALEN, GFP_KERNEL); ++ if (!mac) { ++ kfree(mac_ascii); ++ return ERR_PTR(-ENOMEM); ++ } ++ ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", ++ &mac[0], &mac[1], &mac[2], ++ &mac[3], &mac[4], &mac[5]); ++ kfree(mac_ascii); ++ if (ret == ETH_ALEN) ++ return mac; ++ kfree(mac); ++ return ERR_PTR(-EINVAL); ++} ++ ++static struct nvmem_cell_mac_address_property { ++ char *name; ++ void *(*read)(struct nvmem_cell *); ++} nvmem_cell_mac_address_properties[] = { ++ { ++ .name = "mac-address", ++ .read = nvmem_cell_get_mac_address, ++ }, { ++ .name = "mac-address-ascii", ++ .read = nvmem_cell_get_mac_address_ascii, ++ }, ++}; ++ + /** + * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named + * 'mac-address' associated with given device. +@@ -557,19 +614,23 @@ int nvmem_get_mac_address(struct device + { + struct nvmem_cell *cell; + const void *mac; +- size_t len; ++ struct nvmem_cell_mac_address_property *property; ++ int i; + +- cell = nvmem_cell_get(dev, "mac-address"); +- if (IS_ERR(cell)) +- return PTR_ERR(cell); +- +- mac = nvmem_cell_read(cell, &len); +- nvmem_cell_put(cell); +- +- if (IS_ERR(mac)) +- return PTR_ERR(mac); ++ for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) { ++ property = &nvmem_cell_mac_address_properties[i]; ++ cell = nvmem_cell_get(dev, property->name); ++ if (IS_ERR(cell)) { ++ if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1) ++ return PTR_ERR(cell); ++ continue; ++ } ++ mac = property->read(cell); ++ nvmem_cell_put(cell); ++ break; ++ } + +- if (len != ETH_ALEN || !is_valid_ether_addr(mac)) { ++ if (!is_valid_ether_addr(mac)) { + kfree(mac); + return -EINVAL; + } diff --git a/target/linux/ath79/patches-5.15/600-of_net-add-mac-address-ascii-support.patch b/target/linux/ath79/patches-5.15/600-of_net-add-mac-address-ascii-support.patch new file mode 100644 index 0000000000..8849afb4d6 --- /dev/null +++ b/target/linux/ath79/patches-5.15/600-of_net-add-mac-address-ascii-support.patch @@ -0,0 +1,103 @@ +Index: linux-5.15.31/net/ethernet/eth.c +=================================================================== +--- linux-5.15.31.orig/net/ethernet/eth.c ++++ linux-5.15.31/net/ethernet/eth.c +@@ -544,6 +544,63 @@ int eth_platform_get_mac_address(struct + } + EXPORT_SYMBOL(eth_platform_get_mac_address); + ++static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell) ++{ ++ size_t len; ++ void *mac; ++ ++ mac = nvmem_cell_read(cell, &len); ++ if (IS_ERR(mac)) ++ return PTR_ERR(mac); ++ if (len != ETH_ALEN) { ++ kfree(mac); ++ return ERR_PTR(-EINVAL); ++ } ++ return mac; ++} ++ ++static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell) ++{ ++ size_t len; ++ int ret; ++ void *mac_ascii; ++ u8 *mac; ++ ++ mac_ascii = nvmem_cell_read(cell, &len); ++ if (IS_ERR(mac_ascii)) ++ return PTR_ERR(mac_ascii); ++ if (len != ETH_ALEN*2+5) { ++ kfree(mac_ascii); ++ return ERR_PTR(-EINVAL); ++ } ++ mac = kmalloc(ETH_ALEN, GFP_KERNEL); ++ if (!mac) { ++ kfree(mac_ascii); ++ return ERR_PTR(-ENOMEM); ++ } ++ ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", ++ &mac[0], &mac[1], &mac[2], ++ &mac[3], &mac[4], &mac[5]); ++ kfree(mac_ascii); ++ if (ret == ETH_ALEN) ++ return mac; ++ kfree(mac); ++ return ERR_PTR(-EINVAL); ++} ++ ++static struct nvmem_cell_mac_address_property { ++ char *name; ++ void *(*read)(struct nvmem_cell *); ++} nvmem_cell_mac_address_properties[] = { ++ { ++ .name = "mac-address", ++ .read = nvmem_cell_get_mac_address, ++ }, { ++ .name = "mac-address-ascii", ++ .read = nvmem_cell_get_mac_address_ascii, ++ }, ++}; ++ + /** + * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named + * 'mac-address' associated with given device. +@@ -557,19 +614,23 @@ int nvmem_get_mac_address(struct device + { + struct nvmem_cell *cell; + const void *mac; +- size_t len; ++ struct nvmem_cell_mac_address_property *property; ++ int i; + +- cell = nvmem_cell_get(dev, "mac-address"); +- if (IS_ERR(cell)) +- return PTR_ERR(cell); +- +- mac = nvmem_cell_read(cell, &len); +- nvmem_cell_put(cell); +- +- if (IS_ERR(mac)) +- return PTR_ERR(mac); ++ for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) { ++ property = &nvmem_cell_mac_address_properties[i]; ++ cell = nvmem_cell_get(dev, property->name); ++ if (IS_ERR(cell)) { ++ if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1) ++ return PTR_ERR(cell); ++ continue; ++ } ++ mac = property->read(cell); ++ nvmem_cell_put(cell); ++ break; ++ } + +- if (len != ETH_ALEN || !is_valid_ether_addr(mac)) { ++ if (!is_valid_ether_addr(mac)) { + kfree(mac); + return -EINVAL; + }