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_env_get_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; }
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); /* node not found - create it */ noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name); if (noff < 0) { err = fdt_increase_size(blob, 200); if (err) { printf("fdt_increase_size: err=%s\n", fdt_strerror(err)); return err; } 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 */ err = fdt_appendprop_string(blob, noff, "link_type", link_type_mode); if (err) { printf("fdt_appendprop_string: err=%s\n", fdt_strerror(err)); return err; } } return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev, MC_FIXUP_DPC); }
void fsl_sgmii_riser_fdt_fixup(void *fdt) { struct eth_device *dev; int node; int mdio_node; int i = -1; int etsec_num = 0; node = fdt_path_offset(fdt, "/aliases"); if (node < 0) return; while ((dev = eth_get_dev_by_index(++i)) != NULL) { struct tsec_private *priv; int phy_node; int enet_node; uint32_t ph; char sgmii_phy[16]; char enet[16]; const char *model; const char *path; if (!strstr(dev->name, "eTSEC")) continue; priv = dev->priv; if (!(priv->flags & TSEC_SGMII)) { etsec_num++; continue; } mdio_node = fdt_node_offset_by_compatible(fdt, -1, "fsl,gianfar-mdio"); if (mdio_node < 0) return; sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num); phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy); if (phy_node < 0) continue; fdt_increase_size(fdt, 32); ph = fdt_create_phandle(fdt, phy_node); if (!ph) continue; sprintf(enet, "ethernet%d", etsec_num++); path = fdt_getprop(fdt, node, enet, NULL); if (!path) { debug("No alias for %s\n", enet); continue; } enet_node = fdt_path_offset(fdt, path); if (enet_node < 0) continue; model = fdt_getprop(fdt, enet_node, "model", NULL); /* * We only want to do this to eTSECs. On some platforms * there are more than one type of gianfar-style ethernet * controller, and as we are creating an implicit connection * between ethernet nodes and eTSEC devices, it is best to * make the connection use as much explicit information * as exists. */ if (!strstr(model, "TSEC")) continue; fdt_setprop(fdt, enet_node, "phy-handle", &ph, sizeof(ph)); fdt_setprop_string(fdt, enet_node, "phy-connection-type", phy_string_for_interface(PHY_INTERFACE_MODE_SGMII)); } }
static int ft_hs_fixup_crossbar(void *fdt, bd_t *bd) { const char *path; int offs; int ret; int len, i, old_cnt, new_cnt; u32 *temp; const u32 *p_data; /* * Increase the size of the fdt * so we have some breathing room */ ret = fdt_increase_size(fdt, 512); if (ret < 0) { printf("Could not increase size of device tree: %s\n", fdt_strerror(ret)); return ret; } /* Reserve IRQs that are used/needed by secure world */ path = "/ocp/crossbar"; offs = fdt_path_offset(fdt, path); if (offs < 0) { debug("Node %s not found.\n", path); return 0; } /* Get current entries */ p_data = fdt_getprop(fdt, offs, "ti,irqs-skip", &len); if (p_data) old_cnt = len / sizeof(u32); else old_cnt = 0; new_cnt = sizeof(hs_irq_skip) / sizeof(hs_irq_skip[0]); /* Create new/updated skip list for HS parts */ temp = malloc(sizeof(u32) * (old_cnt + new_cnt)); for (i = 0; i < new_cnt; i++) temp[i] = cpu_to_fdt32(hs_irq_skip[i]); for (i = 0; i < old_cnt; i++) temp[i + new_cnt] = p_data[i]; /* Blow away old data and set new data */ fdt_delprop(fdt, offs, "ti,irqs-skip"); ret = fdt_setprop(fdt, offs, "ti,irqs-skip", temp, (old_cnt + new_cnt) * sizeof(u32)); free(temp); /* Check if the update worked */ if (ret < 0) { printf("Could not add ti,irqs-skip property to node %s: %s\n", path, fdt_strerror(ret)); return ret; } return 0; }