120-fixup-mac-addresses.patch 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. --- a/driver/nvram_stub.c
  2. +++ b/driver/nvram_stub.c
  3. @@ -5,6 +5,8 @@
  4. #include <siutils.h>
  5. #include <bcmendian.h>
  6. #include <bcmnvram.h>
  7. +#include <proto/ethernet.h>
  8. +#include <linux/errno.h>
  9. #ifdef BCMDBG_ERR
  10. #define NVR_MSG(x) printf x
  11. @@ -24,6 +26,7 @@ typedef struct _vars {
  12. static vars_t *vars = NULL;
  13. static int nvram_init_done = 0;
  14. extern char *nvram_buf[];
  15. +static void fixup_mac_addr(vars_t *new);
  16. int
  17. BCMATTACHFN(nvram_init)(void *si)
  18. @@ -55,6 +58,7 @@ BCMATTACHFN(nvram_init)(void *si)
  19. vars = new;
  20. bcopy((char *)(&nvh[1]), new->vars, nvs);
  21. + fixup_mac_addr(new);
  22. return 0;
  23. }
  24. @@ -164,3 +168,65 @@ nvram_getall(char *buf, int count)
  25. *buf = '\0';
  26. return 0;
  27. }
  28. +
  29. +static bool nvram_is_valid_mac(struct ether_addr *mac)
  30. +{
  31. + return mac && !(mac->octet[0] == 0x00 && mac->octet[1] == 0x90 && mac->octet[2] == 0x4c);
  32. +}
  33. +
  34. +static int nvram_increase_mac_addr(struct ether_addr *mac, u8 num)
  35. +{
  36. + u8 *oui = mac->octet + ETHER_ADDR_LEN/2 - 1;
  37. + u8 *p = mac->octet + ETHER_ADDR_LEN - 1;
  38. +
  39. + do {
  40. + (*p) += num;
  41. + if (*p > num)
  42. + break;
  43. + p--;
  44. + num = 1;
  45. + } while (p != oui);
  46. +
  47. + if (p == oui) {
  48. + pr_err("unable to fetch mac address\n");
  49. + return -ENOENT;
  50. + }
  51. + return 0;
  52. +}
  53. +
  54. +static void nvram_change_mac_addr(vars_t *new, struct ether_addr *valid, const char *name)
  55. +{
  56. + char *macaddr_c;
  57. + struct ether_addr macaddr;
  58. +
  59. + macaddr_c = findvar(new->vars, new->vars + new->size, name);
  60. + if (!macaddr_c)
  61. + return;
  62. +
  63. + bcm_ether_atoe(macaddr_c, &macaddr);
  64. + if (nvram_is_valid_mac(&macaddr))
  65. + return;
  66. + nvram_increase_mac_addr(valid, 1);
  67. + bcm_ether_ntoa(valid, macaddr_c);
  68. +}
  69. +
  70. +static void fixup_mac_addr(vars_t *new)
  71. +{
  72. + char *macaddr_base_c;
  73. + struct ether_addr macaddr_base;
  74. +
  75. + macaddr_base_c = findvar(new->vars, new->vars + new->size, "et0macaddr");
  76. + if (!macaddr_base_c)
  77. + return;
  78. +
  79. + bcm_ether_atoe(macaddr_base_c, &macaddr_base);
  80. + if (!nvram_is_valid_mac(&macaddr_base))
  81. + return;
  82. +
  83. + /* jump over the first free address so it can be used for wan */
  84. + nvram_increase_mac_addr(&macaddr_base, 1);
  85. + nvram_change_mac_addr(new, &macaddr_base, "sb/1/macaddr");
  86. + nvram_change_mac_addr(new, &macaddr_base, "pci/1/1/macaddr");
  87. + nvram_change_mac_addr(new, &macaddr_base, "pci/1/2/macaddr");
  88. + nvram_change_mac_addr(new, &macaddr_base, "pci/2/1/macaddr");
  89. +}