drivers: net: fsl-mc: Include MAC addr fixup to DPL
Previous to MC v10.x, port mac address was specified via DPL. Since newer MC versions are compatible with old style DPLs, make the u-boot env mac addresses visible there. This applies only to DPLs that have an older version. DPLs use 32 bit values for specifying MAC addresses. U-boot environment variables take precedence over the MAC addresses already visible in the DPL/DPC. Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com> Signed-off-by: Heinz Wrobel <heinz.wrobel@nxp.com> Reviewed-by: York Sun <york.sun@nxp.com>
This commit is contained in:
		
							parent
							
								
									33a8991a87
								
							
						
					
					
						commit
						1161dbcc0a
					
				|  | @ -156,19 +156,142 @@ int parse_mc_firmware_fit_image(u64 mc_fw_addr, | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id, | #define MC_DT_INCREASE_SIZE	64 | ||||||
|  | 
 | ||||||
|  | enum mc_fixup_type { | ||||||
|  | 	MC_FIXUP_DPL, | ||||||
|  | 	MC_FIXUP_DPC | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static int mc_fixup_mac_addr(void *blob, int nodeoffset, | ||||||
|  | 			     const char *propname, struct eth_device *eth_dev, | ||||||
|  | 			     enum mc_fixup_type type) | ||||||
|  | { | ||||||
|  | 	int err = 0, len = 0, size, i; | ||||||
|  | 	unsigned char env_enetaddr[ARP_HLEN]; | ||||||
|  | 	unsigned int enetaddr_32[ARP_HLEN]; | ||||||
|  | 	void *val = NULL; | ||||||
|  | 
 | ||||||
|  | 	switch (type) { | ||||||
|  | 	case MC_FIXUP_DPL: | ||||||
|  | 	/* DPL likes its addresses on 32 * ARP_HLEN bits */ | ||||||
|  | 	for (i = 0; i < ARP_HLEN; i++) | ||||||
|  | 		enetaddr_32[i] = cpu_to_fdt32(eth_dev->enetaddr[i]); | ||||||
|  | 	val = enetaddr_32; | ||||||
|  | 	len = sizeof(enetaddr_32); | ||||||
|  | 	break; | ||||||
|  | 
 | ||||||
|  | 	case MC_FIXUP_DPC: | ||||||
|  | 	val = eth_dev->enetaddr; | ||||||
|  | 	len = ARP_HLEN; | ||||||
|  | 	break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* MAC address property present */ | ||||||
|  | 	if (fdt_get_property(blob, nodeoffset, propname, NULL)) { | ||||||
|  | 		/* u-boot MAC addr randomly assigned - leave the present one */ | ||||||
|  | 		if (!eth_getenv_enetaddr_by_index("eth", eth_dev->index, | ||||||
|  | 						  env_enetaddr)) | ||||||
|  | 			return err; | ||||||
|  | 	} else { | ||||||
|  | 		size = MC_DT_INCREASE_SIZE + strlen(propname) + len; | ||||||
|  | 		/* make room for mac address property */ | ||||||
|  | 		err = fdt_increase_size(blob, size); | ||||||
|  | 		if (err) { | ||||||
|  | 			printf("fdt_increase_size: err=%s\n", | ||||||
|  | 			       fdt_strerror(err)); | ||||||
|  | 			return err; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err = fdt_setprop(blob, nodeoffset, propname, val, len); | ||||||
|  | 	if (err) { | ||||||
|  | 		printf("fdt_setprop: err=%s\n", fdt_strerror(err)); | ||||||
|  | 		return err; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return err; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define is_dpni(s) (s != NULL ? !strncmp(s, "dpni@", 5) : 0) | ||||||
|  | 
 | ||||||
|  | const char *dpl_get_connection_endpoint(void *blob, char *endpoint) | ||||||
|  | { | ||||||
|  | 	int connoffset = fdt_path_offset(blob, "/connections"), off; | ||||||
|  | 	const char *s1, *s2; | ||||||
|  | 
 | ||||||
|  | 	for (off = fdt_first_subnode(blob, connoffset); | ||||||
|  | 	     off >= 0; | ||||||
|  | 	     off = fdt_next_subnode(blob, off)) { | ||||||
|  | 		s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL); | ||||||
|  | 		s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL); | ||||||
|  | 
 | ||||||
|  | 		if (!s1 || !s2) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if (strcmp(endpoint, s1) == 0) | ||||||
|  | 			return s2; | ||||||
|  | 
 | ||||||
|  | 		if (strcmp(endpoint, s2) == 0) | ||||||
|  | 			return s1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mc_fixup_dpl_mac_addr(void *blob, int dpmac_id, | ||||||
| 				 struct eth_device *eth_dev) | 				 struct eth_device *eth_dev) | ||||||
| { | { | ||||||
| 	int nodeoffset, err = 0; | 	int objoff = fdt_path_offset(blob, "/objects"); | ||||||
|  | 	int dpmacoff = -1, dpnioff = -1; | ||||||
|  | 	const char *endpoint; | ||||||
| 	char mac_name[10]; | 	char mac_name[10]; | ||||||
| 	const char link_type_mode[] = "FIXED_LINK"; | 	int err; | ||||||
| 	unsigned char env_enetaddr[6]; | 
 | ||||||
|  | 	sprintf(mac_name, "dpmac@%d", dpmac_id); | ||||||
|  | 	dpmacoff = fdt_subnode_offset(blob, objoff, mac_name); | ||||||
|  | 	if (dpmacoff < 0) | ||||||
|  | 		/* dpmac not defined in DPL, so skip it. */ | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	err = mc_fixup_mac_addr(blob, dpmacoff, "mac_addr", eth_dev, | ||||||
|  | 				MC_FIXUP_DPL); | ||||||
|  | 	if (err) { | ||||||
|  | 		printf("Error fixing up dpmac mac_addr in DPL\n"); | ||||||
|  | 		return err; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* now we need to figure out if there is any
 | ||||||
|  | 	 * DPNI connected to this MAC, so we walk the | ||||||
|  | 	 * connection list | ||||||
|  | 	 */ | ||||||
|  | 	endpoint = dpl_get_connection_endpoint(blob, mac_name); | ||||||
|  | 	if (!is_dpni(endpoint)) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	/* let's see if we can fixup the DPNI as well */ | ||||||
|  | 	dpnioff = fdt_subnode_offset(blob, objoff, endpoint); | ||||||
|  | 	if (dpnioff < 0) | ||||||
|  | 		/* DPNI not defined in DPL in the objects area */ | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	return mc_fixup_mac_addr(blob, dpnioff, "mac_addr", eth_dev, | ||||||
|  | 				 MC_FIXUP_DPL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id, | ||||||
|  | 				 struct eth_device *eth_dev) | ||||||
|  | { | ||||||
|  | 	int nodeoffset = fdt_path_offset(blob, "/board_info/ports"), noff; | ||||||
|  | 	int err = 0; | ||||||
|  | 	char mac_name[10]; | ||||||
|  | 	const char link_type_mode[] = "MAC_LINK_TYPE_FIXED"; | ||||||
| 
 | 
 | ||||||
| 	sprintf(mac_name, "mac@%d", dpmac_id); | 	sprintf(mac_name, "mac@%d", dpmac_id); | ||||||
| 
 | 
 | ||||||
| 	/* node not found - create it */ | 	/* node not found - create it */ | ||||||
| 	nodeoffset = fdt_subnode_offset(blob, noff, (const char *) mac_name); | 	noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name); | ||||||
| 	if (nodeoffset < 0) { | 	if (noff < 0) { | ||||||
| 		err = fdt_increase_size(blob, 200); | 		err = fdt_increase_size(blob, 200); | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			printf("fdt_increase_size: err=%s\n", | 			printf("fdt_increase_size: err=%s\n", | ||||||
|  | @ -176,10 +299,15 @@ static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id, | ||||||
| 			return err; | 			return err; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		nodeoffset = fdt_add_subnode(blob, noff, mac_name); | 		noff = fdt_add_subnode(blob, nodeoffset, mac_name); | ||||||
|  | 		if (noff < 0) { | ||||||
|  | 			printf("fdt_add_subnode: err=%s\n", | ||||||
|  | 			       fdt_strerror(err)); | ||||||
|  | 			return err; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		/* add default property of fixed link */ | 		/* add default property of fixed link */ | ||||||
| 		err = fdt_appendprop_string(blob, nodeoffset, | 		err = fdt_appendprop_string(blob, noff, | ||||||
| 					    "link_type", link_type_mode); | 					    "link_type", link_type_mode); | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			printf("fdt_appendprop_string: err=%s\n", | 			printf("fdt_appendprop_string: err=%s\n", | ||||||
|  | @ -188,49 +316,53 @@ static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* port_mac_address property present in DPC */ | 	return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev, | ||||||
| 	if (fdt_get_property(blob, nodeoffset, "port_mac_address", NULL)) { | 				 MC_FIXUP_DPC); | ||||||
| 		/* MAC addr randomly assigned - leave the one in DPC */ | } | ||||||
| 		eth_getenv_enetaddr_by_index("eth", eth_dev->index, |  | ||||||
| 						env_enetaddr); |  | ||||||
| 		if (is_zero_ethaddr(env_enetaddr)) |  | ||||||
| 			return err; |  | ||||||
| 
 | 
 | ||||||
| 		/* replace DPC MAC address with u-boot env one */ | static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type) | ||||||
| 		err = fdt_setprop(blob, nodeoffset, "port_mac_address", | { | ||||||
| 				  eth_dev->enetaddr, 6); | 	int i, err = 0, ret = 0; | ||||||
| 		if (err) { | 	char ethname[10]; | ||||||
| 			printf("fdt_setprop mac: err=%s\n", fdt_strerror(err)); | 	struct eth_device *eth_dev; | ||||||
| 			return err; | 
 | ||||||
|  | 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { | ||||||
|  | 		/* port not enabled */ | ||||||
|  | 		if ((wriop_is_enabled_dpmac(i) != 1) || | ||||||
|  | 		    (wriop_get_phy_address(i) == -1)) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		sprintf(ethname, "DPMAC%d@%s", i, | ||||||
|  | 			phy_interface_strings[wriop_get_enet_if(i)]); | ||||||
|  | 
 | ||||||
|  | 		eth_dev = eth_get_dev_by_name(ethname); | ||||||
|  | 		if (eth_dev == NULL) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		switch (type) { | ||||||
|  | 		case MC_FIXUP_DPL: | ||||||
|  | 			err = mc_fixup_dpl_mac_addr(blob, i, eth_dev); | ||||||
|  | 			break; | ||||||
|  | 		case MC_FIXUP_DPC: | ||||||
|  | 			err = mc_fixup_dpc_mac_addr(blob, i, eth_dev); | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return 0; | 		if (err) | ||||||
|  | 			printf("fsl-mc: ERROR fixing mac address for %s\n", | ||||||
|  | 			       ethname); | ||||||
|  | 		ret |= err; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* append port_mac_address property to mac node in DPC */ | 	return ret; | ||||||
| 	err = fdt_increase_size(blob, 80); |  | ||||||
| 	if (err) { |  | ||||||
| 		printf("fdt_increase_size: err=%s\n", fdt_strerror(err)); |  | ||||||
| 		return err; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	err = fdt_appendprop(blob, nodeoffset, |  | ||||||
| 			     "port_mac_address", eth_dev->enetaddr, 6); |  | ||||||
| 	if (err) { |  | ||||||
| 		printf("fdt_appendprop: err=%s\n", fdt_strerror(err)); |  | ||||||
| 		return err; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return err; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int mc_fixup_dpc(u64 dpc_addr) | static int mc_fixup_dpc(u64 dpc_addr) | ||||||
| { | { | ||||||
| 	void *blob = (void *)dpc_addr; | 	void *blob = (void *)dpc_addr; | ||||||
| 	int nodeoffset, err = 0; | 	int nodeoffset, err = 0; | ||||||
| 	char ethname[10]; |  | ||||||
| 	struct eth_device *eth_dev; |  | ||||||
| 	int i; |  | ||||||
| 
 | 
 | ||||||
| 	/* delete any existing ICID pools */ | 	/* delete any existing ICID pools */ | ||||||
| 	nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); | 	nodeoffset = fdt_path_offset(blob, "/resources/icid_pools"); | ||||||
|  | @ -255,30 +387,9 @@ static int mc_fixup_dpc(u64 dpc_addr) | ||||||
| 	/* fixup MAC addresses for dpmac ports */ | 	/* fixup MAC addresses for dpmac ports */ | ||||||
| 	nodeoffset = fdt_path_offset(blob, "/board_info/ports"); | 	nodeoffset = fdt_path_offset(blob, "/board_info/ports"); | ||||||
| 	if (nodeoffset < 0) | 	if (nodeoffset < 0) | ||||||
| 		goto out; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { | 	err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPC); | ||||||
| 		/* port not enabled */ |  | ||||||
| 		if ((wriop_is_enabled_dpmac(i) != 1) || |  | ||||||
| 		    (wriop_get_phy_address(i) == -1)) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		sprintf(ethname, "DPMAC%d@%s", i, |  | ||||||
| 			phy_interface_strings[wriop_get_enet_if(i)]); |  | ||||||
| 
 |  | ||||||
| 		eth_dev = eth_get_dev_by_name(ethname); |  | ||||||
| 		if (eth_dev == NULL) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		err = mc_fixup_dpc_mac_addr(blob, nodeoffset, i, eth_dev); |  | ||||||
| 		if (err) { |  | ||||||
| 			printf("mc_fixup_dpc_mac_addr failed: err=%s\n", |  | ||||||
| 			fdt_strerror(err)); |  | ||||||
| 			goto out; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| out: |  | ||||||
| 	flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); | 	flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob)); | ||||||
| 
 | 
 | ||||||
| 	return err; | 	return err; | ||||||
|  | @ -341,6 +452,25 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | static int mc_fixup_dpl(u64 dpl_addr) | ||||||
|  | { | ||||||
|  | 	void *blob = (void *)dpl_addr; | ||||||
|  | 	u32 ver = fdt_getprop_u32_default(blob, "/", "dpl-version", 0); | ||||||
|  | 	int err = 0; | ||||||
|  | 
 | ||||||
|  | 	/* The DPL fixup for mac addresses is only relevant
 | ||||||
|  | 	 * for old-style DPLs | ||||||
|  | 	 */ | ||||||
|  | 	if (ver >= 10) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPL); | ||||||
|  | 	flush_dcache_range(dpl_addr, dpl_addr + fdt_totalsize(blob)); | ||||||
|  | 
 | ||||||
|  | 	return err; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) | static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) | ||||||
| { | { | ||||||
| 	u64 mc_dpl_offset; | 	u64 mc_dpl_offset; | ||||||
|  | @ -387,6 +517,8 @@ static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr) | ||||||
| 		      (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); | 		      (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); | ||||||
| #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ | #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ | ||||||
| 
 | 
 | ||||||
|  | 	if (mc_fixup_dpl(mc_ram_addr + mc_dpl_offset)) | ||||||
|  | 		return -EINVAL; | ||||||
| 	dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); | 	dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue