600-of_net-add-mac-address-ascii-support.patch 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. From: Yousong Zhou <[email protected]>
  2. Subject: [PATCH] ath79: add nvmem cell mac-address-ascii support
  3. This is needed for devices with mac address stored in ascii format, e.g.
  4. HiWiFi HC6361 to be ported in the following patch.
  5. Submitted-by: Yousong Zhou <[email protected]>
  6. ---
  7. net/ethernet/eth.c | 83 ++++++++++++------
  8. 1 files changed, 72 insertions(+), 11 deletions(-)
  9. --- a/net/ethernet/eth.c
  10. +++ b/net/ethernet/eth.c
  11. @@ -544,6 +544,63 @@ int eth_platform_get_mac_address(struct
  12. }
  13. EXPORT_SYMBOL(eth_platform_get_mac_address);
  14. +static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell)
  15. +{
  16. + size_t len;
  17. + void *mac;
  18. +
  19. + mac = nvmem_cell_read(cell, &len);
  20. + if (IS_ERR(mac))
  21. + return PTR_ERR(mac);
  22. + if (len != ETH_ALEN) {
  23. + kfree(mac);
  24. + return ERR_PTR(-EINVAL);
  25. + }
  26. + return mac;
  27. +}
  28. +
  29. +static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell)
  30. +{
  31. + size_t len;
  32. + int ret;
  33. + void *mac_ascii;
  34. + u8 *mac;
  35. +
  36. + mac_ascii = nvmem_cell_read(cell, &len);
  37. + if (IS_ERR(mac_ascii))
  38. + return PTR_ERR(mac_ascii);
  39. + if (len != ETH_ALEN*2+5) {
  40. + kfree(mac_ascii);
  41. + return ERR_PTR(-EINVAL);
  42. + }
  43. + mac = kmalloc(ETH_ALEN, GFP_KERNEL);
  44. + if (!mac) {
  45. + kfree(mac_ascii);
  46. + return ERR_PTR(-ENOMEM);
  47. + }
  48. + ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
  49. + &mac[0], &mac[1], &mac[2],
  50. + &mac[3], &mac[4], &mac[5]);
  51. + kfree(mac_ascii);
  52. + if (ret == ETH_ALEN)
  53. + return mac;
  54. + kfree(mac);
  55. + return ERR_PTR(-EINVAL);
  56. +}
  57. +
  58. +static struct nvmem_cell_mac_address_property {
  59. + char *name;
  60. + void *(*read)(struct nvmem_cell *);
  61. +} nvmem_cell_mac_address_properties[] = {
  62. + {
  63. + .name = "mac-address",
  64. + .read = nvmem_cell_get_mac_address,
  65. + }, {
  66. + .name = "mac-address-ascii",
  67. + .read = nvmem_cell_get_mac_address_ascii,
  68. + },
  69. +};
  70. +
  71. /**
  72. * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
  73. * 'mac-address' associated with given device.
  74. @@ -557,19 +614,23 @@ int nvmem_get_mac_address(struct device
  75. {
  76. struct nvmem_cell *cell;
  77. const void *mac;
  78. - size_t len;
  79. + struct nvmem_cell_mac_address_property *property;
  80. + int i;
  81. - cell = nvmem_cell_get(dev, "mac-address");
  82. - if (IS_ERR(cell))
  83. - return PTR_ERR(cell);
  84. -
  85. - mac = nvmem_cell_read(cell, &len);
  86. - nvmem_cell_put(cell);
  87. -
  88. - if (IS_ERR(mac))
  89. - return PTR_ERR(mac);
  90. + for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
  91. + property = &nvmem_cell_mac_address_properties[i];
  92. + cell = nvmem_cell_get(dev, property->name);
  93. + if (IS_ERR(cell)) {
  94. + if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
  95. + return PTR_ERR(cell);
  96. + continue;
  97. + }
  98. + mac = property->read(cell);
  99. + nvmem_cell_put(cell);
  100. + break;
  101. + }
  102. - if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
  103. + if (!is_valid_ether_addr(mac)) {
  104. kfree(mac);
  105. return -EINVAL;
  106. }