void fdt_fixup_board_enet(void *fdt) { int offset; offset = fdt_path_offset(fdt, "/soc/fsl-mc"); /* * TODO: Remove this when backward compatibility * with old DT node (/fsl-mc) is no longer needed. */ if (offset < 0) offset = fdt_path_offset(fdt, "/fsl-mc"); if (offset < 0) { printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", __func__, offset); return; } if (get_mc_boot_status() == 0 && (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0)) fdt_status_okay(fdt, offset); else fdt_status_fail(fdt, offset); }
void fsl_mc_ldpaa_exit(bd_t *bis) { int err; if (get_mc_boot_status() == 0) { err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio_handle); if (err < 0) { printf("dpio_disable() failed: %d\n", err); return; } err = dpio_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio_handle); if (err < 0) { printf("dpio_reset() failed: %d\n", err); return; } err = dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio_handle); if (err < 0) { printf("dpio_close() failed: %d\n", err); return; } free(dflt_dpio); free(dflt_dpbp); } if (dflt_mc_io) free(dflt_mc_io); }
int fsl_mc_ldpaa_exit(bd_t *bd) { int err = 0; /* MC is not loaded intentionally, So return success. */ if (bd && get_mc_boot_status() != 0) return 0; if (bd && !get_mc_boot_status() && get_dpl_apply_status() == -1) { printf("ERROR: fsl-mc: DPL is not applied\n"); err = -ENODEV; return err; } if (bd && !get_mc_boot_status() && !get_dpl_apply_status()) return err; err = dpbp_exit(); if (err < 0) { printf("dpbp_exit() failed: %d\n", err); goto err; } err = dpio_exit(); if (err < 0) { printf("dpio_exit() failed: %d\n", err); goto err; } err = dpni_exit(); if (err < 0) { printf("dpni_exit() failed: %d\n", err); goto err; } err = dprc_exit(); if (err < 0) { printf("dprc_exit() failed: %d\n", err); goto err; } return 0; err: return err; }
/* * Return the MC address of private DRAM block. * As per MC design document, MC initial base address * should be least significant 512MB address of MC private * memory, i.e. address should point to end address masked * with 512MB offset in private DRAM block. */ u64 mc_get_dram_addr(void) { size_t mc_ram_size = mc_get_dram_block_size(); if (!mc_memset_resv_ram || (get_mc_boot_status() < 0)) { mc_memset_resv_ram = 1; memset((void *)gd->arch.resv_ram, 0, mc_ram_size); } return (gd->arch.resv_ram + mc_ram_size - 1) & MC_RAM_BASE_ADDR_ALIGNMENT_MASK; }
void fdt_fixup_board_enet(void *fdt) { int offset; offset = fdt_path_offset(fdt, "/fsl-mc"); if (offset < 0) offset = fdt_path_offset(fdt, "/fsl,dprc@0"); if (offset < 0) { printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", __func__, offset); return; } if (get_mc_boot_status() == 0) fdt_status_okay(fdt, offset); else fdt_status_fail(fdt, offset); }
static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int err = 0; if (argc < 3) goto usage; switch (argv[1][0]) { case 's': { char sub_cmd; u64 mc_fw_addr, mc_dpc_addr; #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET u64 aiop_fw_addr; #endif sub_cmd = argv[2][0]; switch (sub_cmd) { case 'm': if (argc < 5) goto usage; if (get_mc_boot_status() == 0) { printf("fsl-mc: MC is already booted"); printf("\n"); return err; } mc_fw_addr = simple_strtoull(argv[3], NULL, 16); mc_dpc_addr = simple_strtoull(argv[4], NULL, 16); if (!mc_init(mc_fw_addr, mc_dpc_addr)) err = mc_init_object(); break; #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET case 'a': if (argc < 4) goto usage; if (get_aiop_apply_status() == 0) { printf("fsl-mc: AIOP FW is already"); printf(" applied\n"); return err; } aiop_fw_addr = simple_strtoull(argv[3], NULL, 16); err = load_mc_aiop_img(aiop_fw_addr); if (!err) printf("fsl-mc: AIOP FW applied\n"); break; #endif default: printf("Invalid option: %s\n", argv[2]); goto usage; break; } } break; case 'a': { u64 mc_dpl_addr; if (argc < 4) goto usage; if (get_dpl_apply_status() == 0) { printf("fsl-mc: DPL already applied\n"); return err; } mc_dpl_addr = simple_strtoull(argv[3], NULL, 16); if (get_mc_boot_status() != 0) { printf("fsl-mc: Deploying data path layout .."); printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (!fsl_mc_ldpaa_exit(NULL)) err = mc_apply_dpl(mc_dpl_addr); break; } default: printf("Invalid option: %s\n", argv[1]); goto usage; break; } return err; usage: return CMD_RET_USAGE; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; struct dpmac_link_state dpmac_link_state = { 0 }; #ifdef DEBUG struct dpni_link_state link_state; #endif int err; if (net_dev->state == ETH_STATE_ACTIVE) return 0; if (get_mc_boot_status() != 0) { printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (get_dpl_apply_status() == 0) { printf("ERROR (DPL is deployed. No device available)\n"); return -ENODEV; } /* DPMAC initialization */ err = ldpaa_dpmac_setup(priv); if (err < 0) goto err_dpmac_setup; /* DPMAC binding DPNI */ err = ldpaa_dpmac_bind(priv); if (err) goto err_dpamc_bind; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_dpni_bind; err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, net_dev->enetaddr); if (err) { printf("dpni_add_mac_addr() failed\n"); return err; } #ifdef CONFIG_PHYLIB /* TODO Check this path */ err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); return err; } #else priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } dpmac_link_state.rate = SPEED_1000; dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG; dpmac_link_state.up = 1; err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle, &dpmac_link_state); if (err < 0) { printf("dpmac_set_link_state() failed\n"); return err; } #ifdef DEBUG err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &link_state); if (err < 0) { printf("dpni_get_link_state() failed\n"); return err; } printf("link status: %d - ", link_state.up); link_state.up == 0 ? printf("down\n") : link_state.up == 1 ? printf("up\n") : printf("error state\n"); #endif /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } if (!priv->phydev->link) printf("%s: No link.\n", priv->phydev->dev->name); return priv->phydev->link ? 0 : -1; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_bind: ldpaa_dpbp_free(); err_dpbp_setup: err_dpamc_bind: dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_setup: err_dpmac_setup: return err; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; struct dpmac_link_state dpmac_link_state = { 0 }; #ifdef DEBUG struct dpni_link_state link_state; #endif int err = 0; struct mii_dev *bus; phy_interface_t enet_if; if (net_dev->state == ETH_STATE_ACTIVE) return 0; if (get_mc_boot_status() != 0) { printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (get_dpl_apply_status() == 0) { printf("ERROR (DPL is deployed. No device available)\n"); return -ENODEV; } /* DPMAC initialization */ err = ldpaa_dpmac_setup(priv); if (err < 0) goto err_dpmac_setup; #ifdef CONFIG_PHYLIB if (priv->phydev) err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); goto err_dpamc_bind; } #else priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif bus = wriop_get_mdio(priv->dpmac_id); enet_if = wriop_get_enet_if(priv->dpmac_id); if ((bus == NULL) && (enet_if == PHY_INTERFACE_MODE_XGMII)) { priv->phydev = (struct phy_device *) malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); priv->phydev->speed = SPEED_10000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; } if (!priv->phydev->link) { printf("%s: No link.\n", priv->phydev->dev->name); err = -1; goto err_dpamc_bind; } /* DPMAC binding DPNI */ err = ldpaa_dpmac_bind(priv); if (err) goto err_dpamc_bind; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_dpni_bind; err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, net_dev->enetaddr); if (err) { printf("dpni_add_mac_addr() failed\n"); return err; } err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } dpmac_link_state.rate = priv->phydev->speed; if (priv->phydev->autoneg == AUTONEG_DISABLE) dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG; else dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG; if (priv->phydev->duplex == DUPLEX_HALF) dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX; dpmac_link_state.up = priv->phydev->link; err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle, &dpmac_link_state); if (err < 0) { printf("dpmac_set_link_state() failed\n"); return err; } #ifdef DEBUG err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &link_state); if (err < 0) { printf("dpni_get_link_state() failed\n"); return err; } printf("link status: %d - ", link_state.up); link_state.up == 0 ? printf("down\n") : link_state.up == 1 ? printf("up\n") : printf("error state\n"); #endif /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } return priv->phydev->link; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_bind: ldpaa_dpbp_free(); err_dpbp_setup: dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_setup: err_dpamc_bind: dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); err_dpmac_setup: return err; }
int fsl_mc_ldpaa_exit(bd_t *bd) { int err = 0; bool is_dpl_apply_status = false; bool mc_boot_status = false; if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { err = mc_apply_dpl(mc_lazy_dpl_addr); if (!err) fdt_fixup_board_enet(working_fdt); mc_lazy_dpl_addr = 0; } if (!get_mc_boot_status()) mc_boot_status = true; /* MC is not loaded intentionally, So return success. */ if (bd && !mc_boot_status) return 0; /* If DPL is deployed, set is_dpl_apply_status as TRUE. */ if (!get_dpl_apply_status()) is_dpl_apply_status = true; /* * For case MC is loaded but DPL is not deployed, return success and * print message on console. Else FDT fix-up code execution hanged. */ if (bd && mc_boot_status && !is_dpl_apply_status) { printf("fsl-mc: DPL not deployed, DPAA2 ethernet not work\n"); goto mc_obj_cleanup; } if (bd && mc_boot_status && is_dpl_apply_status) return 0; mc_obj_cleanup: err = dpbp_exit(); if (err < 0) { printf("dpbp_exit() failed: %d\n", err); goto err; } err = dpio_exit(); if (err < 0) { printf("dpio_exit() failed: %d\n", err); goto err; } err = dpni_exit(); if (err < 0) { printf("dpni_exit() failed: %d\n", err); goto err; } err = dprc_exit(); if (err < 0) { printf("dprc_exit() failed: %d\n", err); goto err; } return 0; err: return err; }