From 1730a17db9a9ce21380ba99eb4d2f10884186cca Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Wed, 4 Nov 2015 12:25:59 +0530 Subject: driver: net: fsl-mc: Create DPAA2 object at run-time Freescale's DPAA2 ethernet driver depends upon the static DPL for the DPRC, DPNI, DPBP, DPIO objects. Instead of static objects, Create DPNI, DPBP, DPIO objects at run-time. Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun --- drivers/net/fsl-mc/mc.c | 467 +++++++++++++++++++++++++++++++++++--- drivers/net/ldpaa_eth/ldpaa_eth.c | 4 +- 2 files changed, 435 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index d2ca5c6..d80be1c 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -31,11 +31,14 @@ static int mc_dpl_applied = -1; #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET static int mc_aiop_applied = -1; #endif -struct fsl_mc_io *dflt_mc_io = NULL; +struct fsl_mc_io *root_mc_io = NULL; +struct fsl_mc_io *dflt_mc_io = NULL; /* child container */ +uint16_t root_dprc_handle = 0; uint16_t dflt_dprc_handle = 0; +int child_dprc_id; struct fsl_dpbp_obj *dflt_dpbp = NULL; struct fsl_dpio_obj *dflt_dpio = NULL; -uint16_t dflt_dpio_handle = 0; +struct fsl_dpni_obj *dflt_dpni = NULL; #ifdef DEBUG void dump_ram_words(const char *title, void *addr) @@ -521,17 +524,17 @@ int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) * Initialize the global default MC portal * And check that the MC firmware is responding portal commands: */ - dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); - if (!dflt_mc_io) { + root_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); + if (!root_mc_io) { printf(" No memory: malloc() failed\n"); return -ENOMEM; } - dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); + root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", - portal_id, dflt_mc_io->mmio_regs); + portal_id, root_mc_io->mmio_regs); - error = mc_get_version(dflt_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); + error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info); if (error != 0) { printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", error); @@ -654,36 +657,51 @@ unsigned long mc_get_dram_block_size(void) return dram_block_size; } -int dpio_init(struct dprc_obj_desc obj_desc) +int fsl_mc_ldpaa_init(bd_t *bis) +{ + return 0; +} + +static int dpio_init(void) { struct qbman_swp_desc p_des; struct dpio_attr attr; + struct dpio_cfg dpio_cfg; int err = 0; dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); if (!dflt_dpio) { - printf(" No memory: malloc() failed\n"); - return -ENOMEM; + printf("No memory: malloc() failed\n"); + err = -ENOMEM; + goto err_malloc; } - dflt_dpio->dpio_id = obj_desc.id; + dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL; + dpio_cfg.num_priorities = 8; - err = dpio_open(dflt_mc_io, MC_CMD_NO_FLAGS, obj_desc.id, - &dflt_dpio_handle); - if (err) { - printf("dpio_open() failed\n"); - goto err_open; + err = dpio_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpio_cfg, + &dflt_dpio->dpio_handle); + if (err < 0) { + printf("dpio_create() failed: %d\n", err); + err = -ENODEV; + goto err_create; } + memset(&attr, 0, sizeof(struct dpio_attr)); err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, - dflt_dpio_handle, &attr); - if (err) { - printf("dpio_get_attributes() failed %d\n", err); + dflt_dpio->dpio_handle, &attr); + if (err < 0) { + printf("dpio_get_attributes() failed: %d\n", err); goto err_get_attr; } - err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio_handle); - if (err) { + dflt_dpio->dpio_id = attr.id; +#ifdef DEBUG + printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id); +#endif + + err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); + if (err < 0) { printf("dpio_enable() failed %d\n", err); goto err_get_enable; } @@ -706,36 +724,412 @@ int dpio_init(struct dprc_obj_desc obj_desc) return 0; err_get_swp_init: + dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); err_get_enable: - dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio_handle); -err_get_attr: - dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio_handle); -err_open: free(dflt_dpio); +err_get_attr: + dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); + dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); +err_create: +err_malloc: + return err; +} + +static int dpio_exit(void) +{ + int err; + + err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); + if (err < 0) { + printf("dpio_disable() failed: %d\n", err); + goto err; + } + + err = dpio_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle); + if (err < 0) { + printf("dpio_destroy() failed: %d\n", err); + goto err; + } + +#ifdef DEBUG + printf("Exit: DPIO id=0x%d\n", dflt_dpio->dpio_id); +#endif + + if (dflt_dpio) + free(dflt_dpio); + + return 0; +err: + return err; +} + +static int dprc_init(void) +{ + int err, child_portal_id, container_id; + struct dprc_cfg cfg; + uint64_t mc_portal_offset; + + /* Open root container */ + err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id); + if (err < 0) { + printf("dprc_get_container_id(): Root failed: %d\n", err); + goto err_root_container_id; + } + +#ifdef DEBUG + printf("Root container id = %d\n", container_id); +#endif + err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id, + &root_dprc_handle); + if (err < 0) { + printf("dprc_open(): Root Container failed: %d\n", err); + goto err_root_open; + } + + if (!root_dprc_handle) { + printf("dprc_open(): Root Container Handle is not valid\n"); + goto err_root_open; + } + + cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED | + DPRC_CFG_OPT_OBJ_CREATE_ALLOWED | + DPRC_CFG_OPT_ALLOC_ALLOWED; + cfg.icid = DPRC_GET_ICID_FROM_POOL; + cfg.portal_id = 250; + err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS, + root_dprc_handle, + &cfg, + &child_dprc_id, + &mc_portal_offset); + if (err < 0) { + printf("dprc_create_container() failed: %d\n", err); + goto err_create; + } + + dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); + if (!dflt_mc_io) { + err = -ENOMEM; + printf(" No memory: malloc() failed\n"); + goto err_malloc; + } + + child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset); + dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id); +#ifdef DEBUG + printf("MC portal of child DPRC container: %d, physical addr %p)\n", + child_dprc_id, dflt_mc_io->mmio_regs); +#endif + + err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id, + &dflt_dprc_handle); + if (err < 0) { + printf("dprc_open(): Child container failed: %d\n", err); + goto err_child_open; + } + + if (!dflt_dprc_handle) { + printf("dprc_open(): Child container Handle is not valid\n"); + goto err_child_open; + } + + return 0; +err_child_open: + free(dflt_mc_io); +err_malloc: + dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, + root_dprc_handle, child_dprc_id); +err_create: + dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); +err_root_open: +err_root_container_id: + return err; +} + +static int dprc_exit(void) +{ + int err; + + err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); + if (err < 0) { + printf("dprc_close(): Child failed: %d\n", err); + goto err; + } + + err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS, + root_dprc_handle, child_dprc_id); + if (err < 0) { + printf("dprc_destroy_container() failed: %d\n", err); + goto err; + } + + err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle); + if (err < 0) { + printf("dprc_close(): Root failed: %d\n", err); + goto err; + } + + if (dflt_mc_io) + free(dflt_mc_io); + + if (root_mc_io) + free(root_mc_io); + + return 0; + +err: return err; } -int dpbp_init(struct dprc_obj_desc obj_desc) +static int dpbp_init(void) { + int err; + struct dpbp_attr dpbp_attr; + struct dpbp_cfg dpbp_cfg; + dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); if (!dflt_dpbp) { - printf(" No memory: malloc() failed\n"); - return -ENOMEM; + printf("No memory: malloc() failed\n"); + err = -ENOMEM; + goto err_malloc; + } + + dpbp_cfg.options = 512; + + err = dpbp_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpbp_cfg, + &dflt_dpbp->dpbp_handle); + + if (err < 0) { + err = -ENODEV; + printf("dpbp_create() failed: %d\n", err); + goto err_create; + } + + memset(&dpbp_attr, 0, sizeof(struct dpbp_attr)); + err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpbp->dpbp_handle, + &dpbp_attr); + if (err < 0) { + printf("dpbp_get_attributes() failed: %d\n", err); + goto err_get_attr; + } + + dflt_dpbp->dpbp_attr.id = dpbp_attr.id; +#ifdef DEBUG + printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); +#endif + + err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + if (err < 0) { + printf("dpbp_close() failed: %d\n", err); + goto err_close; } - dflt_dpbp->dpbp_attr.id = obj_desc.id; return 0; + +err_close: + free(dflt_dpbp); +err_get_attr: + dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); +err_create: +err_malloc: + return err; } -int fsl_mc_ldpaa_init(bd_t *bis) +static int dpbp_exit(void) +{ + int err; + + err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, + &dflt_dpbp->dpbp_handle); + if (err < 0) { + printf("dpbp_open() failed: %d\n", err); + goto err; + } + + err = dpbp_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpbp->dpbp_handle); + if (err < 0) { + printf("dpbp_destroy() failed: %d\n", err); + goto err; + } + +#ifdef DEBUG + printf("Exit: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id); +#endif + + if (dflt_dpbp) + free(dflt_dpbp); + return 0; + +err: + return err; +} + +static int dpni_init(void) +{ + int err; + struct dpni_attr dpni_attr; + struct dpni_cfg dpni_cfg; + + dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj)); + if (!dflt_dpni) { + printf("No memory: malloc() failed\n"); + err = -ENOMEM; + goto err_malloc; + } + + memset(&dpni_cfg, 0, sizeof(dpni_cfg)); + dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER | + DPNI_OPT_MULTICAST_FILTER; + + err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg, + &dflt_dpni->dpni_handle); + + if (err < 0) { + err = -ENODEV; + printf("dpni_create() failed: %d\n", err); + goto err_create; + } + + memset(&dpni_attr, 0, sizeof(struct dpni_attr)); + err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + &dpni_attr); + if (err < 0) { + printf("dpni_get_attributes() failed: %d\n", err); + goto err_get_attr; + } + + dflt_dpni->dpni_id = dpni_attr.id; +#ifdef DEBUG + printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id); +#endif + + err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); + if (err < 0) { + printf("dpni_close() failed: %d\n", err); + goto err_close; + } + + return 0; + +err_close: + free(dflt_dpni); +err_get_attr: + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); + dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); +err_create: +err_malloc: + return err; +} + +static int dpni_exit(void) +{ + int err; + + err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, + &dflt_dpni->dpni_handle); + if (err < 0) { + printf("dpni_open() failed: %d\n", err); + goto err; + } + + err = dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle); + if (err < 0) { + printf("dpni_destroy() failed: %d\n", err); + goto err; + } + +#ifdef DEBUG + printf("Exit: DPNI id=0x%d\n", dflt_dpni->dpni_id); +#endif + + if (dflt_dpni) + free(dflt_dpni); + return 0; + +err: + return err; +} + +static int mc_init_object(void) { + int err = 0; + + err = dprc_init(); + if (err < 0) { + printf("dprc_init() failed: %d\n", err); + goto err; + } + + err = dpbp_init(); + if (err < 0) { + printf("dpbp_init() failed: %d\n", err); + goto err; + } + + err = dpio_init(); + if (err < 0) { + printf("dpio_init() failed: %d\n", err); + goto err; + } + + err = dpni_init(); + if (err < 0) { + printf("dpni_init() failed: %d\n", err); + goto err; + } return 0; +err: + return err; } -void fsl_mc_ldpaa_exit(bd_t *bis) +int fsl_mc_ldpaa_exit(bd_t *bd) { - return; + int err = 0; + + if (bd && get_mc_boot_status() == -1) + 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("dpni_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; } static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -763,7 +1157,9 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) mc_fw_addr = simple_strtoull(argv[3], NULL, 16); mc_dpc_addr = simple_strtoull(argv[4], NULL, 16); - err = mc_init(mc_fw_addr, mc_dpc_addr); + + if (!mc_init(mc_fw_addr, mc_dpc_addr)) + err = mc_init_object(); break; #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET @@ -806,12 +1202,15 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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; } - err = mc_apply_dpl(mc_dpl_addr); + + if (!fsl_mc_ldpaa_exit(NULL)) + err = mc_apply_dpl(mc_dpl_addr); break; } default: diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 99acb7a..cfeb45f 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -601,7 +601,7 @@ static int ldpaa_eth_netdev_init(struct eth_device *net_dev) return 0; } -int ldpaa_eth_init(struct dprc_obj_desc obj_desc) +int ldpaa_eth_init(int id) { struct eth_device *net_dev = NULL; struct ldpaa_eth_priv *priv = NULL; @@ -626,7 +626,7 @@ int ldpaa_eth_init(struct dprc_obj_desc obj_desc) net_dev->priv = (void *)priv; priv->net_dev = (struct eth_device *)net_dev; - priv->dpni_id = obj_desc.id; + priv->dpni_id = id; err = ldpaa_eth_netdev_init(net_dev); if (err) -- cgit v1.1