broadcom-wl: fixup mac addresses.
Some series of devices are using the same mac address, which causes conflicts for these devices we generate a new mac address based on the base address. This patch adds this functionality to braodcom-wl. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> SVN-Revision: 41514
This commit is contained in:
		| @@ -0,0 +1,92 @@ | |||||||
|  | --- a/driver/nvram_stub.c | ||||||
|  | +++ b/driver/nvram_stub.c | ||||||
|  | @@ -5,6 +5,7 @@ | ||||||
|  |  #include <siutils.h> | ||||||
|  |  #include <bcmendian.h> | ||||||
|  |  #include <bcmnvram.h> | ||||||
|  | +#include <proto/ethernet.h> | ||||||
|  |   | ||||||
|  |  #ifdef BCMDBG_ERR | ||||||
|  |  #define NVR_MSG(x) printf x | ||||||
|  | @@ -24,6 +25,7 @@ typedef struct _vars { | ||||||
|  |  static vars_t *vars = NULL; | ||||||
|  |  static int nvram_init_done = 0; | ||||||
|  |  extern char *nvram_buf[]; | ||||||
|  | +static void fixup_mac_addr(vars_t *new); | ||||||
|  |   | ||||||
|  |  int | ||||||
|  |  BCMATTACHFN(nvram_init)(void *si) | ||||||
|  | @@ -55,6 +57,7 @@ BCMATTACHFN(nvram_init)(void *si) | ||||||
|  |  	vars = new; | ||||||
|  |   | ||||||
|  |  	bcopy((char *)(&nvh[1]), new->vars, nvs); | ||||||
|  | +	fixup_mac_addr(new); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -164,3 +167,65 @@ nvram_getall(char *buf, int count) | ||||||
|  |  	*buf = '\0'; | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | + | ||||||
|  | +static bool nvram_is_valid_mac(struct ether_addr *mac) | ||||||
|  | +{ | ||||||
|  | +	return mac && !(mac->octet[0] == 0x00 && mac->octet[1] == 0x90 && mac->octet[2] == 0x4c); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int nvram_increase_mac_addr(struct ether_addr *mac, u8 num) | ||||||
|  | +{ | ||||||
|  | +	u8 *oui = mac->octet + ETHER_ADDR_LEN/2 - 1; | ||||||
|  | +	u8 *p = mac->octet + ETHER_ADDR_LEN - 1; | ||||||
|  | + | ||||||
|  | +	do { | ||||||
|  | +		(*p) += num; | ||||||
|  | +		if (*p > num) | ||||||
|  | +			break; | ||||||
|  | +		p--; | ||||||
|  | +		num = 1; | ||||||
|  | +	} while (p != oui); | ||||||
|  | + | ||||||
|  | +	if (p == oui) { | ||||||
|  | +		pr_err("unable to fetch mac address\n"); | ||||||
|  | +		return -ENOENT; | ||||||
|  | +	} | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void nvram_change_mac_addr(vars_t *new, struct ether_addr *valid, const char *name) | ||||||
|  | +{ | ||||||
|  | +	char *macaddr_c; | ||||||
|  | +	struct ether_addr macaddr; | ||||||
|  | + | ||||||
|  | +	macaddr_c = findvar(new->vars, new->vars + new->size, name); | ||||||
|  | +	if (!macaddr_c) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	bcm_ether_atoe(macaddr_c, &macaddr); | ||||||
|  | +	if (nvram_is_valid_mac(&macaddr)) | ||||||
|  | +		return; | ||||||
|  | +	nvram_increase_mac_addr(valid, 1); | ||||||
|  | +	bcm_ether_ntoa(valid, macaddr_c); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void fixup_mac_addr(vars_t *new) | ||||||
|  | +{ | ||||||
|  | +	char *macaddr_base_c; | ||||||
|  | +	struct ether_addr macaddr_base; | ||||||
|  | + | ||||||
|  | +	macaddr_base_c = findvar(new->vars, new->vars + new->size, "et0macaddr"); | ||||||
|  | +	if (!macaddr_base_c) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	bcm_ether_atoe(macaddr_base_c, &macaddr_base); | ||||||
|  | +	if (!nvram_is_valid_mac(&macaddr_base)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	/* jump over the first free address so it can be used for wan */ | ||||||
|  | +	nvram_increase_mac_addr(&macaddr_base, 1); | ||||||
|  | +	nvram_change_mac_addr(new, &macaddr_base, "pci/1/1/macaddr"); | ||||||
|  | +	nvram_change_mac_addr(new, &macaddr_base, "pci/1/2/macaddr"); | ||||||
|  | +	nvram_change_mac_addr(new, &macaddr_base, "pci/2/1/macaddr"); | ||||||
|  | +	nvram_change_mac_addr(new, &macaddr_base, "sb/1/macaddr"); | ||||||
|  | +} | ||||||
		Reference in New Issue
	
	Block a user
	 Hauke Mehrtens
					Hauke Mehrtens