Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
/*
 * 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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}