120-fixup-mac-addresses.patch 2.2 KB

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