drivers/fsl-mc: Make MC boot error messages more readable
Subsystems (3)
PATCH v4 1/13 drivers/fsl-mc: Make MC boot error messages more readable
From: "J. German Rivera" <[email protected]>
Make it easier for the user to notice when the MC firmware had problems booting.
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
drivers/net/fsl-mc/mc.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-)
drivers/net/fsl-mc/mc.c +13 -18
@@ -224,13 +224,13 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)* Don't return with error here, since the MC firmware can * still boot without a DPC */ -printf ("fsl-mc: WARNING: No DPC image found\n" ); +printf ("\nfsl-mc: WARNING: No DPC image found" );return 0 ; } dpc_size =fdt_totalsize (dpc_fdt_hdr);if (dpc_size >CONFIG_SYS_LS_MC_DPC_MAX_LENGTH ) { -printf ("fsl-mc: ERROR: Bad DPC image (too large: %d)\n" , +printf ("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n" , dpc_size);return -EINVAL ; }
@@ -278,13 +278,13 @@ static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size) error =fdt_check_header (dpl_fdt_hdr);if (error !=0 ) { -printf ("fsl-mc: ERROR: Bad DPL image (bad header)\n" ); +printf ("\nfsl-mc: ERROR: Bad DPL image (bad header)\n" );return error; } dpl_size =fdt_totalsize (dpl_fdt_hdr);if (dpl_size >CONFIG_SYS_LS_MC_DPL_MAX_LENGTH ) { -printf ("fsl-mc: ERROR: Bad DPL image (too large: %d)\n" , +printf ("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n" , dpl_size);return -EINVAL ; }
@@ -329,7 +329,6 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)struct mc_ccsr_registers __iomem *mc_ccsr_regs =MC_CCSR_BASE_ADDR ;dmb (); -debug ("Polling mc_ccsr_regs->reg_gsr ...\n" );assert (timeout_ms >0 );for (;;) {udelay (1000 );/* throttle polling */
@@ -344,10 +343,7 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) }if (timeout_ms ==0 ) { -if (booting_mc) -printf ("fsl-mc: timeout booting management complex firmware\n" ); -else -printf ("fsl-mc: timeout deploying data path layout\n" ); +printf ("ERROR: timeout\n" );/* TODO: Get an error status from an MC CCSR register */ return -ETIMEDOUT ;
@@ -360,15 +356,13 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)* appropriate errno, so that the status property is set to * failure in the fsl,dprc device tree node. */ -if (booting_mc) { -printf ("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n" , - reg_gsr); - }else { -printf ("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n" , - reg_gsr); - } +printf ("WARNING: Firmware returned an error (GSR: %#x)\n" , + reg_gsr); + }else { +printf ("SUCCESS\n" ); } + *final_reg_gsr = reg_gsr;return 0 ; }
@@ -464,7 +458,7 @@ int mc_init(void)*/ out_le32 (&mc_ccsr_regs->reg_gsr,0xDD00 ); -printf ("\nfsl-mc: Booting Management Complex ...\n" ); +printf ("\nfsl-mc: Booting Management Complex ... " );/* * Deassert reset and release MC core 0 to run
@@ -517,10 +511,11 @@ int mc_init(void)* Tell the MC to deploy the DPL: */ out_le32 (&mc_ccsr_regs->reg_gsr,0x0 ); -printf ("\nfsl-mc: Deploying data path layout ...\n" ); +printf ("fsl-mc: Deploying data path layout ... " ); error =wait_for_mc (false, ®_gsr);if (error !=0 ) goto out; + out:if (error !=0 ) mc_boot_status = -error;
Signature · 1 line
1.9.1
PATCH v4 2/13 driver/ldpaa_eth:Flush buffer before seeding BMAN after TX_conf
Flush buffer before releasing to BMan after TX_conf to ensure, the core does not have any cachelines that the WRIOP will DMA to.
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
drivers/net/ldpaa_eth/ldpaa_eth.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ldpaa_eth/ldpaa_eth.c +1 -0
@@ -153,6 +153,7 @@ static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv, } } +flush_dcache_range (fd_addr, fd_addr +LDPAA_ETH_RX_BUFFER_SIZE );qbman_release_desc_clear (&releasedesc);qbman_release_desc_set_bpid (&releasedesc, dflt_dpbp->dpbp_attr.bpid); do {
Signature · 1 line
1.9.1
PATCH v4 3/13 drivers/fsl-mc: Autoload AOIP image from NOR flash
In reply to Prabhakar KushwahaFrom: "J. German Rivera" <[email protected]>
Load AIOP image from NOR flash into DDR so that the MC firmware the MC fw can start it at boot time
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
drivers/net/fsl-mc/mc.c | 23 +++++++++++++++++++++++ include/configs/ls2085a_common.h | 2 ++ include/configs/ls2085aqds.h | 2 ++ include/configs/ls2085ardb.h | 2 ++ 4 files changed, 29 insertions(+)
drivers/net/fsl-mc/mc.c +23 -0
@@ -321,6 +321,23 @@ static unsigned long get_mc_boot_timeout_ms(void)return timeout_ms; } +#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR +static int load_mc_aiop_img (u64 mc_ram_addr,size_t mc_ram_size) +{ +void *aiop_img; + +/* +* Load the MC AIOP image in the MC private DRAM block: +*/ + + aiop_img = (void *)CONFIG_SYS_LS_MC_AIOP_IMG_ADDR ; +mc_copy_image ("MC AIOP image" , + (u64 )aiop_img,CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH , + mc_ram_addr +CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET ); + +return 0 ; +} +#endif static int wait_for_mc (bool booting_mc,u32 *final_reg_gsr) {u32 reg_gsr;
@@ -440,6 +457,12 @@ int mc_init(void)if (error !=0 ) goto out; +#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR + error =load_mc_aiop_img (mc_ram_addr, mc_ram_size); +if (error !=0 ) + goto out; +#endif +debug ("mc_ccsr_regs %p\n" , mc_ccsr_regs);dump_mc_ccsr_regs (mc_ccsr_regs);
include/configs/ls2085a_common.h +2 -0
@@ -174,6 +174,8 @@ unsigned long long get_qixis_addr(void);#define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000 +#define CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH 0x200000 +#define CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 0x07000000/* * Carve out a DDR region which will not be used by u-boot/Linux
include/configs/ls2085aqds.h +2 -0
@@ -261,6 +261,8 @@ unsigned long get_board_ddr_clk(void);#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 +#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR +#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL/* * I2C
include/configs/ls2085ardb.h +2 -0
@@ -234,6 +234,8 @@ unsigned long get_board_sys_clk(void);#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 +#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR +#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL/* * I2C
Signature · 1 line
1.9.1
PATCH v4 4/13 drivers: fsl-mc: Update flibs to mc-0.6.0.1
In reply to Prabhakar KushwahaUpdate flibs changes to mc-0.6.0.1 for dpmang, dprc, dpni and dpio objects Also rename qbman_portal_ce/ci_paddr to qbman_portal_ce/ci_offset in dpio_attr. These are now offsets from the SoC QBMan portals base.
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
drivers/net/fsl-mc/dpni.c | 2 +- drivers/net/fsl-mc/mc.c | 12 ++-- include/fsl-mc/fsl_dpio.h | 32 ++++------ include/fsl-mc/fsl_dpmng.h | 2 +- include/fsl-mc/fsl_dpni.h | 144 ++++++++++++++++++++++++++++++++++++++------- include/fsl-mc/fsl_dprc.h | 64 +++++++++++++++++--- include/fsl-mc/fsl_mc.h | 1 + 7 files changed, 199 insertions(+), 58 deletions(-)
drivers/net/fsl-mc/dpni.c +1 -1
@@ -313,7 +313,7 @@ int dpni_set_counter(struct fsl_mc_io *mc_io,int dpni_set_link_cfg (struct fsl_mc_io *mc_io,uint16_t token, -struct dpni_link_cfg *cfg) +const struct dpni_link_cfg *cfg) {struct mc_command cmd = {0 };
drivers/net/fsl-mc/mc.c +7 -5
@@ -610,14 +610,16 @@ int dpio_init(struct dprc_obj_desc obj_desc)printf ("dpio_enable() failed %d\n" , err); goto err_get_enable; } -debug ("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n" , - attr.qbman_portal_ce_paddr, - attr.qbman_portal_ci_paddr, +debug ("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n" , + attr.qbman_portal_ce_offset, + attr.qbman_portal_ci_offset, attr.qbman_portal_id, attr.num_priorities); - p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr; - p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr; + p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR + + attr.qbman_portal_ce_offset); + p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR + + attr.qbman_portal_ci_offset); dflt_dpio->sw_portal =qbman_swp_init (&p_des);if (dflt_dpio->sw_portal ==NULL ) {
include/fsl-mc/fsl_dpio.h +11 -21
@@ -8,8 +8,8 @@#define _FSL_DPIO_H/* DPIO Version */ -#define DPIO_VER_MAJOR 2 -#define DPIO_VER_MINOR 1 +#define DPIO_VER_MAJOR 3 +#define DPIO_VER_MINOR 0/* Command IDs */ #define DPIO_CMDID_CLOSE 0x800
@@ -31,8 +31,8 @@ do { \MC_RSP_OP (cmd,0 ,32 ,16 , uint16_t, attr->qbman_portal_id);\MC_RSP_OP (cmd,0 ,48 ,8 , uint8_t, attr->num_priorities);\ MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\ -MC_RSP_OP (cmd,1 ,0 ,64 , uint64_t, attr->qbman_portal_ce_paddr);\ -MC_RSP_OP (cmd,2 ,0 ,64 , uint64_t, attr->qbman_portal_ci_paddr);\ +MC_RSP_OP (cmd,1 ,0 ,64 , uint64_t, attr->qbman_portal_ce_offset);\ +MC_RSP_OP (cmd,2 ,0 ,64 , uint64_t, attr->qbman_portal_ci_offset);\MC_RSP_OP (cmd,3 ,0 ,16 , uint16_t, attr->version.major);\MC_RSP_OP (cmd,3 ,16 ,16 , uint16_t, attr->version.minor);\ }while (0 )
@@ -42,6 +42,7 @@ do { \*/ struct fsl_mc_io ; +/** * dpio_open() - Open a control session for the specified object * @mc_io: Pointer to MC portal's I/O object
@@ -61,18 +62,9 @@ struct fsl_mc_io;int dpio_open (struct fsl_mc_io *mc_io,int dpio_id,uint16_t *token);/** -* dpio_open() - Open a control session for the specified object +* dpio_close() - Close the control session of the object * @mc_io: Pointer to MC portal's I/O object -* @dpio_id: DPIO unique ID -* @token: Returned token; use in subsequent API calls -* -* This function can be used to open a control session for an -* already created object; an object may have been declared in -* the DPL or by calling the dpio_create() function. -* This function returns a unique authentication token, -* associated with the specific object ID and the specific MC -* portal; this token must be used in all subsequent commands for -* this specific object. +* @token: Token of DPIO object * * Return: '0' on Success; Error code otherwise. */
@@ -121,10 +113,8 @@ int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token);* struct dpio_attr - Structure representing DPIO attributes * @id: DPIO object ID * @version: DPIO version -* @qbman_portal_ce_paddr: Physical address of the software portal -* cache-enabled area -* @qbman_portal_ci_paddr: Physical address of the software portal -* cache-inhibited area +* @qbman_portal_ce_offset: offset of the software portal cache-enabled area +* @qbman_portal_ci_offset: offset of the software portal cache-inhibited area * @qbman_portal_id: Software portal ID * @channel_mode: Notification channel mode * @num_priorities: Number of priorities for the notification channel (1-8);
@@ -141,8 +131,8 @@ struct dpio_attr {uint16_t major;uint16_t minor; } version; -uint64_t qbman_portal_ce_paddr; -uint64_t qbman_portal_ci_paddr; +uint64_t qbman_portal_ce_offset; +uint64_t qbman_portal_ci_offset;uint16_t qbman_portal_id;enum dpio_channel_mode channel_mode;uint8_t num_priorities;
include/fsl-mc/fsl_dpmng.h +1 -1
@@ -14,7 +14,7 @@ struct fsl_mc_io;/** * Management Complex firmware version information */ -#define MC_VER_MAJOR 6 +#define MC_VER_MAJOR 7#define MC_VER_MINOR 0/**
include/fsl-mc/fsl_dpni.h +123 -21
324 lines not on this page · raw message
include/fsl-mc/fsl_dprc.h +55 -9
142 lines not on this page · raw message
include/fsl-mc/fsl_mc.h +1 -0
@@ -27,6 +27,7 @@ (MCFAPR_PL_MASK | MCFAPR_BMT_MASK)#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000) +#define SOC_QBMAN_PORTALS_BASE_ADDR ((void __iomem *)0x000818000000)#define SOC_MC_PORTAL_STRIDE 0x10000#define SOC_MC_PORTAL_ADDR (_portal_id) \
Signature · 1 line
1.9.1
PATCH v4 5/13 drivers: fsl-mc: Update qbman driver
In reply to Prabhakar KushwahaUpdate qbman driver
- As per latest available qbman driver
- Use of atomic APIs
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
drivers/net/fsl-mc/dpio/qbman_portal.c | 66 ++++++++++++++++++--------------- drivers/net/fsl-mc/dpio/qbman_portal.h | 22 ++++++++--- drivers/net/fsl-mc/dpio/qbman_private.h | 2 +- 3 files changed, 53 insertions(+), 37 deletions(-)
drivers/net/fsl-mc/dpio/qbman_portal.c +36 -30
@@ -64,7 +64,7 @@ enum qbman_sdqcr_fc {struct qbman_swp *qbman_swp_init (const struct qbman_swp_desc *d) {int ret; -struct qbman_swp *p =kmalloc (sizeof (*p),GFP_KERNEL ); +struct qbman_swp *p =malloc (sizeof (struct qbman_swp ));if (!p)return NULL ;
@@ -77,7 +77,7 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)qb_attr_code_encode (&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);qb_attr_code_encode (&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);qb_attr_code_encode (&code_sdqcr_tok, &p->sdq,0xbb ); - p->vdq.busy =0 ;/* TODO: convert to atomic_t */ +atomic_set (&p->vdq.busy,1 ); p->vdq.valid_bit =QB_VALID_BIT ; p->dqrr.next_idx =0 ; p->dqrr.valid_bit =QB_VALID_BIT ;
@@ -165,7 +165,6 @@ static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);static struct qb_attr_code code_eq_qd_pri =QB_CODE (4 ,16 ,4 );static struct qb_attr_code code_eq_rsp_stash =QB_CODE (5 ,16 ,1 );static struct qb_attr_code code_eq_rsp_lo =QB_CODE (6 ,0 ,32 ); -static struct qb_attr_code code_eq_rsp_hi =QB_CODE (7 ,0 ,32 );enum qbman_eq_cmd_e {/* No enqueue, primarily for plugging ORP gaps for dropped frames */
@@ -197,8 +196,7 @@ void qbman_eq_desc_set_response(struct qbman_eq_desc *d, {uint32_t *cl =qb_cl (d); -qb_attr_code_encode (&code_eq_rsp_lo, cl,lower32 (storage_phys)); -qb_attr_code_encode (&code_eq_rsp_hi, cl,upper32 (storage_phys)); +qb_attr_code_encode_64 (&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);qb_attr_code_encode (&code_eq_rsp_stash, cl, !!stash); }
@@ -253,7 +251,6 @@ static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);static struct qb_attr_code code_pull_token =QB_CODE (0 ,16 ,8 );static struct qb_attr_code code_pull_dqsource =QB_CODE (1 ,0 ,24 );static struct qb_attr_code code_pull_rsp_lo =QB_CODE (2 ,0 ,32 ); -static struct qb_attr_code code_pull_rsp_hi =QB_CODE (3 ,0 ,32 );enum qb_pull_dt_e { qb_pull_dt_channel,
@@ -282,8 +279,7 @@ void qbman_pull_desc_set_storage(struct qbman_pull_desc *d, }qb_attr_code_encode (&code_pull_rls, cl,1 );qb_attr_code_encode (&code_pull_stash, cl, !!stash); -qb_attr_code_encode (&code_pull_rsp_lo, cl,lower32 (storage_phys)); -qb_attr_code_encode (&code_pull_rsp_hi, cl,upper32 (storage_phys)); +qb_attr_code_encode_64 (&code_pull_rsp_lo, (uint64_t *)cl, storage_phys); }void qbman_pull_desc_set_numframes (struct qbman_pull_desc *d,uint8_t numframes)
@@ -316,10 +312,10 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)uint32_t *p;uint32_t *cl =qb_cl (d); -/* TODO: convert to atomic_t */ -if (s->vdq.busy) +if (!atomic_dec_and_test (&s->vdq.busy)) { +atomic_inc (&s->vdq.busy);return -EBUSY ; - s->vdq.busy =1 ; + } s->vdq.storage = *(void **)&cl[4 ]; s->vdq.token =qb_attr_code_decode (&code_pull_token, cl); p =qbman_cena_write_start (&s->sys,QBMAN_CENA_SWP_VDQCR );
@@ -359,36 +355,44 @@ const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s) {uint32_t verb;uint32_t response_verb; -const struct ldpaa_dq *dq =qbman_cena_read (&s->sys, -QBMAN_CENA_SWP_DQRR (s->dqrr.next_idx)); -const uint32_t *p =qb_cl (dq); +uint32_t flags; +const struct ldpaa_dq *dq; +const uint32_t *p; + dq =qbman_cena_read (&s->sys,QBMAN_CENA_SWP_DQRR (s->dqrr.next_idx)); + p =qb_cl (dq); verb =qb_attr_code_decode (&code_dqrr_verb, p); -/* If the valid-bit isn't of the expected polarity, nothing there */ + +/* If the valid-bit isn't of the expected polarity, nothing there. Note, +* in the DQRR reset bug workaround, we shouldn't need to skip these +* check, because we've already determined that a new entry is available +* and we've invalidated the cacheline before reading it, so the +* valid-bit behaviour is repaired and should tell us what we already +* knew from reading PI. +*/ if ((verb &QB_VALID_BIT ) != s->dqrr.valid_bit) {qbman_cena_invalidate_prefetch (&s->sys, -QBMAN_CENA_SWP_DQRR ( - s->dqrr.next_idx)); +QBMAN_CENA_SWP_DQRR (s->dqrr.next_idx));return NULL ; }/* There's something there. Move "next_idx" attention to the next ring * entry (and prefetch it) before returning what we found. */ s->dqrr.next_idx++; - s->dqrr.next_idx &=3 ;/* Wrap around at 4 */ + s->dqrr.next_idx &=QBMAN_DQRR_SIZE -1 ;/* Wrap around at 4 */ /* TODO: it's possible to do all this without conditionals, optimise it * later. */ if (!s->dqrr.next_idx) s->dqrr.valid_bit ^=QB_VALID_BIT ; -/* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a -* VDQCR result, mark it as non-busy. */ -if (s->vdq.busy) { -uint32_t flags =ldpaa_dq_flags (dq); - - response_verb =qb_attr_code_decode (&code_dqrr_response, &verb); -if ((response_verb ==QBMAN_DQRR_RESPONSE_DQ ) && - (flags &LDPAA_DQ_STAT_VOLATILE )) - s->vdq.busy =0 ; - } + +/* If this is the final response to a volatile dequeue command +indicate that the vdq is no longer busy */ + flags =ldpaa_dq_flags (dq); + response_verb =qb_attr_code_decode (&code_dqrr_response, &verb); +if ((response_verb ==QBMAN_DQRR_RESPONSE_DQ ) && + (flags &LDPAA_DQ_STAT_VOLATILE ) && + (flags &LDPAA_DQ_STAT_EXPIRED )) +atomic_inc (&s->vdq.busy); +qbman_cena_invalidate_prefetch (&s->sys,QBMAN_CENA_SWP_DQRR (s->dqrr.next_idx));return dq;
@@ -448,8 +452,10 @@ int qbman_dq_entry_has_newtoken(struct qbman_swp *s,* reset "busy". We instead base the decision on whether the current * result is sitting at the first 'storage' location of the busy * command. */ -if (s->vdq.busy && (s->vdq.storage == dq)) - s->vdq.busy =0 ; +if (s->vdq.storage == dq) { + s->vdq.storage =NULL ; +atomic_inc (&s->vdq.busy); + }return 1 ; }
drivers/net/fsl-mc/dpio/qbman_portal.h +16 -6
@@ -14,6 +14,10 @@/* Management command result codes */ #define QBMAN_MC_RSLT_OK 0xf0 +/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */ +#define QBMAN_DQRR_SIZE 4 + +/* --------------------- */ /* portal data structure */ /* --------------------- */
@@ -48,14 +52,13 @@ struct qbman_swp {* to whether or not a command can be submitted, not whether or * not a previously-submitted command is still executing. In * other words, once proof is seen that the previously-submitted -* command is executing, "vdq" is no longer "busy". TODO: -* convert this to "atomic_t" so that it is thread-safe (without -* locking). */ -int busy; +* command is executing, "vdq" is no longer "busy". +*/ +atomic_t busy;uint32_t valid_bit;/* 0x00 or 0x80 */ /* We need to determine when vdq is no longer busy. This depends * on whether the "busy" (last-submitted) dequeue command is -* targetting DQRR or main-memory, and detected is based on the +* targeting DQRR or main-memory, and detected is based on the * presence of the dequeue command's "token" showing up in * dequeue entries in DQRR or main-memory (respectively). Debug * builds will, when submitting vdq commands, verify that the
@@ -127,6 +130,7 @@ static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,return d32_uint32_t (code->lsoffset, code->width, cacheline[code->word]); } +/* encode a field to a cacheline */ static inline void qb_attr_code_encode (const struct qb_attr_code *code,uint32_t *cacheline,uint32_t val)
@@ -136,6 +140,12 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code, | e32_uint32_t(code->lsoffset, code->width, val); } +static inline void qb_attr_code_encode_64 (const struct qb_attr_code *code, +uint64_t *cacheline,uint64_t val) +{ + cacheline[code->word /2 ] = val; +} +/* ---------------------- */ /* Descriptors/cachelines */ /* ---------------------- */
@@ -144,7 +154,7 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code,* a "descriptor" type that the caller can instantiate however they like. * Ultimately though, it is just a cacheline of binary storage (or something * smaller when it is known that the descriptor doesn't need all 64 bytes) for -* holding pre-formatted pieces of harware commands. The performance-critical +* holding pre-formatted pieces of hardware commands. The performance-critical * code can then copy these descriptors directly into hardware command * registers more efficiently than trying to construct/format commands * on-the-fly. The API user sees the descriptor as an array of 32-bit words in
drivers/net/fsl-mc/dpio/qbman_private.h +1 -1
@@ -9,7 +9,7 @@#include <errno.h> #include <asm/io.h> #include <linux/types.h> -#include <linux/compat.h> +#include <asm/atomic.h> #include <malloc.h> #include <fsl-mc/fsl_qbman_base.h>
Signature · 1 line
1.9.1
PATCH v4 6/13 drivers: fsl-mc: Return error for major version mismatch
In reply to Prabhakar KushwahaManagement complex major version should match to the firmware present in flash.
Return error during mismatch of major version.
---
Changes for v2: Sending as it is for patchset Changes for v3: Incorporated Joe Hershberger's comments
- Use ENODEV instead of "1"
Changes for v4: Incorporated Joe Hershberger's comments
- Use -ENODEV
drivers/net/fsl-mc/mc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/fsl-mc/mc.c +7 -2
@@ -518,9 +518,14 @@ int mc_init(void) goto out; } -if (MC_VER_MAJOR != mc_ver_info.major) +if (MC_VER_MAJOR != mc_ver_info.major) {printf ("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n" , mc_ver_info.major,MC_VER_MAJOR ); +printf ("fsl-mc: Update the Management Complex firmware\n" ); + + error = -ENODEV ; + goto out; + }if (MC_VER_MINOR != mc_ver_info.minor) printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
@@ -541,7 +546,7 @@ int mc_init(void) out:if (error !=0 ) - mc_boot_status = -error; + mc_boot_status = error;else mc_boot_status =0 ;
Signature · 1 line
1.9.1
PATCH v4 6/13 drivers: fsl-mc: Return error for major version mismatch
Hi Prabhakar,
Quoted 6 lines · Prabhakar Kushwaha
Management complex major version should match to the firmware present in flash.
Return error during mismatch of major version.
Signed-off-by Prabhakar Kushwaha <[email protected]>---
PATCH v4 7/13 armv8/fsl-lsch3: partition stream IDs
In reply to Prabhakar KushwahaFrom: Stuart Yoder <[email protected]>
Stream IDs on ls2085a devices are not hardwired and are programmed by sw. There are a limited number of stream IDs available, and the partitioning of them is scenario dependent. This header defines the partitioning between legacy, PCI, and DPAA2 devices.
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
.../include/asm/arch-fsl-lsch3/ls2085a_stream_id.h | 64 ++++++++++++++++++++++ drivers/net/fsl-mc/mc.c | 2 +- include/configs/ls2085a_common.h | 1 + include/fsl-mc/fsl_mc.h | 4 -- 4 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h
arch/arm/include/asm/arch-fsl-lsch3/ls2085a_stream_id.h new file +64 -0
@@ -0,0 +1,64 @@ +/* +* Copyright 2014 Freescale Semiconductor, Inc. +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ +#ifndef __FSL_STREAM_ID_H +#define __FSL_STREAM_ID_H + +/* Stream IDs on ls2085a devices are not hardwired and are +* programmed by sw. There are a limited number of stream IDs +* available, and the partitioning of them is scenario dependent. +* This header defines the partitioning between legacy, PCI, +* and DPAA2 devices. +* +* This partitiong can be customized in this file depending +* on the specific hardware config-- e.g. perhaps not all +* PEX controllers are in use. +* +* On LS2085 stream IDs are programmed in AMQ registers (32-bits) for +* each of the different bus masters. The relationship between +* the AMQ registers and stream IDs is defined in the table below: +* AMQ bit streamID bit +* --------------------------- +* PL[18] 9 +* BMT[17] 8 +* VA[16] 7 +* [15] - +* ICID[14:7] - +* ICID[6:0] 6-0 +* ---------------------------- +*/ + +#define AMQ_PL_MASK (0x1 << 18)/* priviledge bit */ +#define AMQ_BMT_MASK (0x1 << 17)/* bypass bit */ + +#define FSL_INVALID_STREAM_ID 0 + +#define FSL_BYPASS_AMQ (AMQ_PL_MASK | AMQ_BMT_MASK) + +/* legacy devices */ +#define FSL_USB1_STREAM_ID 1 +#define FSL_USB2_STREAM_ID 2 +#define FSL_SDMMC_STREAM_ID 3 +#define FSL_SATA1_STREAM_ID 4 +#define FSL_SATA2_STREAM_ID 5 +#define FSL_DMA_STREAM_ID 6 + +/* PCI - programmed in PEXn_LUT by OS */ +/* 4 IDs per controller */ +#define FSL_PEX1_STREAM_ID_START 7 +#define FSL_PEX1_STREAM_ID_END 10 +#define FSL_PEX2_STREAM_ID_START 11 +#define FSL_PEX2_STREAM_ID_END 14 +#define FSL_PEX3_STREAM_ID_START 15 +#define FSL_PEX3_STREAM_ID_END 18 +#define FSL_PEX4_STREAM_ID_START 19 +#define FSL_PEX4_STREAM_ID_END 22 + +/* DPAA2 - set in MC DPC and alloced by MC */ +#define FSL_DPAA2_STREAM_ID_START 23 +#define FSL_DPAA2_STREAM_ID_END 63 + +#endif
drivers/net/fsl-mc/mc.c +1 -1
@@ -474,7 +474,7 @@ int mc_init(void)out_le32 (&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);out_le32 (&mc_ccsr_regs->reg_mcfbahr, (u32)(mc_ram_aligned_base_addr >>32 )); -out_le32 (&mc_ccsr_regs->reg_mcfapr,MCFAPR_BYPASS_ICID_MASK ); +out_le32 (&mc_ccsr_regs->reg_mcfapr,FSL_BYPASS_AMQ );/* * Tell the MC that we want delayed DPL deployment.
include/configs/ls2085a_common.h +1 -0
@@ -19,6 +19,7 @@#define CONFIG_ARM_ERRATA_828024 #define CONFIG_ARM_ERRATA_826974 +#include <asm/arch-fsl-lsch3/ls2085a_stream_id.h> #include <asm/arch-fsl-lsch3/config.h> #if (defined(CONFIG_SYS_FSL_SRDS_1 ) || defined(CONFIG_SYS_FSL_SRDS_2 ))#define CONFIG_SYS_HAS_SERDES
include/fsl-mc/fsl_mc.h +0 -4
@@ -21,10 +21,6 @@#define GCR1_M2_DE_RST BIT(14)#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST)#define GSR_FS_MASK 0x3fffffff -#define MCFAPR_PL_MASK (0x1 << 18) -#define MCFAPR_BMT_MASK (0x1 << 17) -#define MCFAPR_BYPASS_ICID_MASK \ - (MCFAPR_PL_MASK | MCFAPR_BMT_MASK)#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000)#define SOC_QBMAN_PORTALS_BASE_ADDR ((void __iomem *)0x000818000000)
Signature · 1 line
1.9.1
PATCH v4 8/13 drivers/fsl-mc: dynamically create ICID pool in DPC
In reply to Prabhakar KushwahaFrom: Stuart Yoder <[email protected]>
delete any existing ICID pools in the DPC and create a new one based on the stream ID partitioning for the SoC
---
Changes for v2: Sending as it is for patchset Changes for v3: Sending as it is for patchset Changes for v4: Sending as it is for patchset
drivers/net/fsl-mc/mc.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
drivers/net/fsl-mc/mc.c +36 -0
@@ -3,8 +3,11 @@* * SPDX-License-Identifier: GPL-2.0+ */ +#include <common.h> #include <errno.h> #include <asm/io.h> +#include <libfdt.h> +#include <fdt_support.h> #include <fsl-mc/fsl_mc.h> #include <fsl-mc/fsl_mc_sys.h> #include <fsl-mc/fsl_mc_private.h>
@@ -185,6 +188,36 @@ static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,return 0 ; } +static int mc_fixup_dpc (u64 dpc_addr) +{ +void *blob = (void *)dpc_addr; +int nodeoffset; + +/* delete any existing ICID pools */ + nodeoffset =fdt_path_offset (blob,"/resources/icid_pools" ); +if (fdt_del_node (blob, nodeoffset) <0 ) +printf ("\nfsl-mc: WARNING: could not delete ICID pool\n" ); + +/* add a new pool */ + nodeoffset =fdt_path_offset (blob,"/resources" ); +if (nodeoffset <0 ) { +printf ("\nfsl-mc: ERROR: DPC is missing /resources\n" ); +return -EINVAL ; + } + nodeoffset =fdt_add_subnode (blob, nodeoffset,"icid_pools" ); + nodeoffset =fdt_add_subnode (blob, nodeoffset,"icid_pool at 0" ); +do_fixup_by_path_u32 (blob,"/resources/icid_pools/icid_pool at 0" , +"base_icid" ,FSL_DPAA2_STREAM_ID_START ,1 ); +do_fixup_by_path_u32 (blob,"/resources/icid_pools/icid_pool@0" , +"num" , +FSL_DPAA2_STREAM_ID_END - +FSL_DPAA2_STREAM_ID_START +1 ,1 ); + +flush_dcache_range (dpc_addr, dpc_addr +fdt_totalsize (blob)); + +return 0 ; +} +static int load_mc_dpc (u64 mc_ram_addr,size_t mc_ram_size) {u64 mc_dpc_offset;
@@ -239,6 +272,9 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size) (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ +if (mc_fixup_dpc (mc_ram_addr + mc_dpc_offset)) +return -EINVAL ; +dump_ram_words ("DPC" , (void *)(mc_ram_addr + mc_dpc_offset));return 0 ; }
Signature · 1 line
1.9.1
PATCH v4 9/13 armv8/fsl-lsch3: device tree fixups for PCI stream IDs
In reply to Prabhakar KushwahaFrom: Stuart Yoder <[email protected]>
This patch adds the infrastructure to update device tree nodes to convey SMMU stream IDs in the device tree. Fixups are implemented for PCI controllers initially.
---
changes for v2
- define in fdt_fixup_smmu_pcie in fdt.h
- put fdt_fixup_smmu_pcie in CONFIG_PCI
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
arch/arm/cpu/armv8/fsl-lsch3/fdt.c | 110 ++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-fsl-lsch3/fdt.h | 10 +++ drivers/pci/pcie_layerscape.c | 62 +++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 arch/arm/include/asm/arch-fsl-lsch3/fdt.h
arch/arm/cpu/armv8/fsl-lsch3/fdt.c +110 -0
@@ -7,6 +7,7 @@#include <common.h> #include <libfdt.h> #include <fdt_support.h> +#include <asm/arch-fsl-lsch3/fdt.h> #ifdef CONFIG_FSL_ESDHC #include <fsl_esdhc.h> #endif
@@ -58,6 +59,113 @@ void ft_fixup_cpu(void *blob) }#endif +/* +* the burden is on the the caller to not request a count +* exceeding the bounds of the stream_ids[] array +*/ +void alloc_stream_ids (int start_id,int count,u32 *stream_ids,int max_cnt) +{ +int i; + +if (count > max_cnt) { +printf ("\n%s: ERROR: max per-device stream ID count exceed\n" , + __func__); +return ; + } + +for (i =0 ; i < count; i++) + stream_ids[i] = start_id++; +} + +/* +* This function updates the mmu-masters property on the SMMU +* node as per the SMMU binding-- phandle and list of stream IDs +* for each MMU master. +*/ +void append_mmu_masters (void *blob,const char *smmu_path, +const char *master_name,u32 *stream_ids,int count) +{ +u32 phandle; +int smmu_nodeoffset; +int master_nodeoffset; +int i; + +/* get phandle of mmu master device */ + master_nodeoffset =fdt_path_offset (blob, master_name); +if (master_nodeoffset <0 ) { +printf ("\n%s: ERROR: master not found\n" , __func__); +return ; + } + phandle =fdt_get_phandle (blob, master_nodeoffset); +if (!phandle) {/* if master has no phandle, create one */ + phandle =fdt_create_phandle (blob, master_nodeoffset); +if (!phandle) { +printf ("\n%s: ERROR: unable to create phandle\n" , + __func__); +return ; + } + } + +/* append it to mmu-masters */ + smmu_nodeoffset =fdt_path_offset (blob, smmu_path); +if (fdt_appendprop_u32 (blob, smmu_nodeoffset,"mmu-masters" , + phandle) <0 ) { +printf ("\n%s: ERROR: unable to update SMMU node\n" , __func__); +return ; + } + +/* for each stream ID, append to mmu-masters */ +for (i =0 ; i < count; i++) { +fdt_appendprop_u32 (blob, smmu_nodeoffset,"mmu-masters" , + stream_ids[i]); + } + +/* fix up #stream-id-cells with stream ID count */ +if (fdt_setprop_u32 (blob, master_nodeoffset,"#stream-id-cells" , + count) <0 ) +printf ("\n%s: ERROR: unable to update #stream-id-cells\n" , + __func__); +} + + +/* +* The info below summarizes how streamID partitioning works +* for ls2085a and how it is conveyed to the OS via the device tree. +* +* -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA) +* -all legacy devices get a unique ICID assigned and programmed in +* their AMQR registers by u-boot +* -u-boot updates the hardware device tree with streamID properties +* for each platform/legacy device (smmu-masters property) +* +* -PCIe +* -for each PCI controller that is active (as per RCW settings), +* u-boot will allocate a range of ICID and convey that to Linux via +* the device tree (smmu-masters property) +* +* -DPAA2 +* -u-boot will allocate a range of ICIDs to be used by the Management +* Complex for containers and will set these values in the MC DPC image. +* -the MC is responsible for allocating and setting up ICIDs +* for all DPAA2 devices. +* +*/ +static void fdt_fixup_smmu (void *blob) +{ +int nodeoffset; + + nodeoffset =fdt_path_offset (blob,"/iommu@5000000" ); +if (nodeoffset <0 ) { +printf ("\n%s: WARNING: no SMMU node found\n" , __func__); +return ; + } + +/* fixup for all PCI controllers */ +#ifdef CONFIG_PCI +fdt_fixup_smmu_pcie (blob); +#endif +} +void ft_cpu_setup (void *blob,bd_t *bd) {#ifdef CONFIG_MP
@@ -76,4 +184,6 @@ void ft_cpu_setup(void *blob, bd_t *bd)#if defined(CONFIG_FSL_ESDHC )fdt_fixup_esdhc (blob, bd);#endif + +fdt_fixup_smmu (blob); }
arch/arm/include/asm/arch-fsl-lsch3/fdt.h new file +10 -0
@@ -0,0 +1,10 @@ +/* +* Copyright 2015 Freescale Semiconductor +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +void alloc_stream_ids (int start_id,int count,u32 *stream_ids,int max_cnt); +void append_mmu_masters (void *blob,const char *smmu_path, +const char *master_name,u32 *stream_ids,int count); +void fdt_fixup_smmu_pcie (void *blob);
drivers/pci/pcie_layerscape.c +62 -0
71 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 10/13 driver/ldpaa_eth: Retry enqueue if portal was busy
In reply to Prabhakar KushwahaDo not immediately return if the enqueue function returns -EBUSY; re-try mulitple times.
if timeout occures, release the buffer.
---
Changes for v2: Sending as it is for patchset
Changes for v3: Incorporated Joe Hershberger's comments
- Squash with "driver/ldpaa_eth:Avoid infinite loop in QBMAN buf release"
- use err instead of calling get_timer() again
Changes for v4: Incorporated Joe Hershberger's comments
- unsquashed from "driver/ldpaa_eth:Avoid infinite loop in QBMAN buf release"
- Avoided infinte loop from v2 version
drivers/net/ldpaa_eth/ldpaa_eth.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
drivers/net/ldpaa_eth/ldpaa_eth.c +30 -2
@@ -221,8 +221,11 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)struct dpaa_fd fd;u64 buffer_start;int data_offset, err; +u32 timeo = (CONFIG_SYS_HZ *10 ) /1000 ; +u32 time_start;struct qbman_swp *swp = dflt_dpio->sw_portal;struct qbman_eq_desc ed; +struct qbman_release_desc releasedesc;/* Setup the FD fields */ memset (&fd,0 ,sizeof (fd));
@@ -258,9 +261,20 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)qbman_eq_desc_clear (&ed);qbman_eq_desc_set_no_orp (&ed,0 );qbman_eq_desc_set_qd (&ed, priv->tx_qdid, priv->tx_flow_id,0 ); - err =qbman_swp_enqueue (swp, &ed, (const struct qbman_fd *)(&fd)); -if (err <0 ) + + time_start =get_timer (0 ); + +while (get_timer (time_start) < timeo) { + err =qbman_swp_enqueue (swp, &ed, + (const struct qbman_fd *)(&fd)); +if (err != -EBUSY ) +break ; + } + +if (err <0 ) {printf ("error enqueueing Tx frame\n" ); + goto error; + }mdelay (1 );
@@ -269,6 +283,20 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)printf ("error Tx Conf frame\n" );return err; + +error: +qbman_release_desc_clear (&releasedesc); +qbman_release_desc_set_bpid (&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start =get_timer (0 ); +do { +/* Release buffer into the QBMAN */ + err =qbman_swp_release (swp, &releasedesc, &buffer_start,1 ); + }while (get_timer (time_start) < timeo && err == -EBUSY ); + +if (err == -EBUSY ) +printf ("TX data: QBMAN buffer release fails\n" ); + +return err; }static int ldpaa_eth_open (struct eth_device *net_dev,bd_t *bd)
Signature · 1 line
1.9.1
PATCH v4 10/13 driver/ldpaa_eth: Retry enqueue if portal was busy
Hi Prabhakar,
Quoted 7 lines · Prabhakar Kushwaha
Do not immediately return if the enqueue function returns
-EBUSY; re-try mulitple times.if timeout occures, release the buffer.
Signed-off-by Prabhakar Kushwaha <[email protected]>---
PATCH v4 11/13 driver/ldpaa_eth: Add timeout handling DQRR entry read
In reply to Prabhakar KushwahaVolatile command does not return frame immidiately, need to wait till a frame is available in DQRR. Ideally it should be a blocking call.
Add timeout handling for DQRR frame instead of retry counter.
---
Changes for v2: Sending as it is for patchset Changes for v3: Incorporated Joe Hershberger's comments
- Use err variable instead of err = 1
Changes for v4: Sending as it is for patchset
drivers/net/ldpaa_eth/ldpaa_eth.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-)
drivers/net/ldpaa_eth/ldpaa_eth.c +22 -14
@@ -77,7 +77,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;const struct ldpaa_dq *dq;const struct dpaa_fd *fd; -int i =5 , err =0 , status, loop =20 ; +int i =5 , err =0 , status; +u32 timeo = (CONFIG_SYS_HZ *2 ) /1000 ; +u32 time_start;static struct qbman_pull_desc pulldesc;struct qbman_swp *swp = dflt_dpio->sw_portal;
@@ -92,13 +94,11 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)continue ; } -do { - loop--; - dq =qbman_swp_dqrr_next (swp); + time_start =get_timer (0 ); -if (!loop) -break ; - }while (!dq); +do { + dq =qbman_swp_dqrr_next (swp); + }while (get_timer (time_start) < timeo && !dq);if (dq) {/* Check for valid frame. If not sent a consume
@@ -121,6 +121,10 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)ldpaa_eth_rx (priv, fd);qbman_swp_dqrr_consume (swp, dq);break ; + }else { + err = -ENODATA ; +debug ("No DQRR entries\n" ); +break ; } }
@@ -167,7 +171,9 @@ static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)const struct ldpaa_dq *dq;const struct dpaa_fd *fd;int err =0 ; -int i =5 , status, loop =20 ; +int i =5 , status; +u32 timeo = (CONFIG_SYS_HZ *10 ) /1000 ; +u32 time_start;static struct qbman_pull_desc pulldesc;struct qbman_swp *swp = dflt_dpio->sw_portal;
@@ -182,13 +188,11 @@ static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)continue ; } -do { - loop--; - dq =qbman_swp_dqrr_next (swp); + time_start =get_timer (0 ); -if (!loop) -break ; - }while (!dq); +do { + dq =qbman_swp_dqrr_next (swp); + }while (get_timer (time_start) < timeo && !dq);if (dq) {/* Check for valid frame. If not sent a consume
@@ -209,6 +213,10 @@ static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)ldpaa_eth_tx_conf (priv, fd);qbman_swp_dqrr_consume (swp, dq);break ; + }else { + err = -ENODATA ; +debug ("No DQRR entries\n" ); +break ; } }
Signature · 1 line
1.9.1
PATCH v4 12/13 driver/ldpaa_eth: Avoid TX conf frames
In reply to Prabhakar KushwahaPolling of TX conf frames is not a mandatory option. Packets can be transferred via WRIOP without TX conf frame.
Configure ldpaa_eth driver to use TX path without confirmation frame
---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
drivers/net/ldpaa_eth/ldpaa_eth.c | 114 ++------------------------------------ drivers/net/ldpaa_eth/ldpaa_eth.h | 1 - 2 files changed, 4 insertions(+), 111 deletions(-)
drivers/net/ldpaa_eth/ldpaa_eth.c +4 -110
@@ -112,7 +112,7 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)debug ("No frame delivered\n" );qbman_swp_dqrr_consume (swp, dq); -break ; +continue ; } fd =ldpaa_dq_fd (dq);
@@ -131,98 +131,6 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)return err; } -static void ldpaa_eth_tx_conf (struct ldpaa_eth_priv *priv, -const struct dpaa_fd *fd) -{ -uint64_t fd_addr; -struct ldpaa_fas *fas; -uint32_t status, err; -struct qbman_release_desc releasedesc; -struct qbman_swp *swp = dflt_dpio->sw_portal; - - fd_addr =ldpaa_fd_get_addr (fd); - - -debug ("TX Conf frame:data addr=0x%p\n" , (u64 *)fd_addr); - -/* Check the status from the Frame Annotation */ -if (fd->simple.frc &LDPAA_FD_FRC_FASV ) { - fas = (struct ldpaa_fas *) - ((uint8_t *)(fd_addr) + - priv->buf_layout.private_data_size); - status =le32_to_cpu (fas->status); -if (status &LDPAA_ETH_TXCONF_ERR_MASK ) { -printf ("TxConf frame error(s): 0x%08x\n" , - status &LDPAA_ETH_TXCONF_ERR_MASK ); - } - } - -flush_dcache_range (fd_addr, fd_addr +LDPAA_ETH_RX_BUFFER_SIZE ); -qbman_release_desc_clear (&releasedesc); -qbman_release_desc_set_bpid (&releasedesc, dflt_dpbp->dpbp_attr.bpid); -do { -/* Release buffer into the QBMAN */ - err =qbman_swp_release (swp, &releasedesc, &fd_addr,1 ); - }while (err == -EBUSY ); -} - -static int ldpaa_eth_pull_dequeue_tx_conf (struct ldpaa_eth_priv *priv) -{ -const struct ldpaa_dq *dq; -const struct dpaa_fd *fd; -int err =0 ; -int i =5 , status; -u32 timeo = (CONFIG_SYS_HZ *10 ) /1000 ; -u32 time_start; -static struct qbman_pull_desc pulldesc; -struct qbman_swp *swp = dflt_dpio->sw_portal; - -while (--i) { -qbman_pull_desc_clear (&pulldesc); -qbman_pull_desc_set_numframes (&pulldesc,1 ); -qbman_pull_desc_set_fq (&pulldesc, priv->tx_conf_fqid); - - err =qbman_swp_pull (swp, &pulldesc); -if (err <0 ) { -printf ("Dequeue TX conf frames error:0x%08x\n" , err); -continue ; - } - - time_start =get_timer (0 ); - -do { - dq =qbman_swp_dqrr_next (swp); - }while (get_timer (time_start) < timeo && !dq); - -if (dq) { -/* Check for valid frame. If not sent a consume -* confirmation to QBMAN otherwise give it to NADK -* application and then send consume confirmation to -* QBMAN. -*/ - status = (uint8_t )ldpaa_dq_flags (dq); -if ((status &LDPAA_DQ_STAT_VALIDFRAME ) ==0 ) { -debug ("Dequeue TX conf frames:" ); -debug ("No frame is delivered\n" ); - -qbman_swp_dqrr_consume (swp, dq); -break ; - } - fd =ldpaa_dq_fd (dq); - -ldpaa_eth_tx_conf (priv, fd); -qbman_swp_dqrr_consume (swp, dq); -break ; - }else { - err = -ENODATA ; -debug ("No DQRR entries\n" ); -break ; - } - } - -return err; -} -static int ldpaa_eth_tx (struct eth_device *net_dev,void *buf,int len) {struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
@@ -284,12 +192,6 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) goto error; } -mdelay (1 ); - - err =ldpaa_eth_pull_dequeue_tx_conf (priv); -if (err <0 ) -printf ("error Tx Conf frame\n" ); -return err; error:
@@ -311,7 +213,6 @@ 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 dpni_tx_flow_attr tx_flow_attr;uint8_t mac_addr[6 ];int err;
@@ -382,21 +283,11 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) goto err_qdid; } - err =dpni_get_tx_flow (dflt_mc_io, priv->dpni_handle, priv->tx_flow_id, - &tx_flow_attr); -if (err) { -printf ("dpni_get_tx_flow() failed\n" ); - goto err_tx_flow; - } - - priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid; -if (!priv->phydev->link)printf ("%s: No link.\n" , priv->phydev->dev->name);return priv->phydev->link ?0 :-1 ; -err_tx_flow: err_qdid: err_rx_flow:dpni_disable (dflt_mc_io, priv->dpni_handle);
@@ -663,6 +554,9 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) priv->tx_flow_id =DPNI_NEW_FLOW_ID ;memset (&dflt_tx_flow,0 ,sizeof (dflt_tx_flow)); + dflt_tx_flow.options =DPNI_TX_FLOW_OPT_ONLY_TX_ERROR ; + dflt_tx_flow.conf_err_cfg.use_default_queue =0 ; + dflt_tx_flow.conf_err_cfg.errors_only =1 ; err =dpni_set_tx_flow (dflt_mc_io, priv->dpni_handle, &priv->tx_flow_id, &dflt_tx_flow);if (err) {
drivers/net/ldpaa_eth/ldpaa_eth.h +0 -1
@@ -128,7 +128,6 @@ struct ldpaa_eth_priv {uint32_t rx_dflt_fqid;uint16_t tx_qdid; -uint32_t tx_conf_fqid;uint16_t tx_flow_id;enum ldpaa_eth_type type;/* 1G or 10G ethernet */
Signature · 1 line
1.9.1
PATCH v4 13/13 driver/ldpaa_eth:Avoid infinite loop in ldpaa_eth_rx
In reply to Prabhakar KushwahaChange infinite loop mechanism to timer based polling for QBMAN release in ldpaa_eth_rx.
---
Changes for v2: Sending as it is for patchset Changes for v3: Squashed with other patch Changes for v4: reverted the squash and only have rx path
drivers/net/ldpaa_eth/ldpaa_eth.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/ldpaa_eth/ldpaa_eth.c +8 -1
@@ -31,6 +31,8 @@ static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,uint32_t fd_length;struct ldpaa_fas *fas;uint32_t status, err; +u32 timeo = (CONFIG_SYS_HZ *2 ) /1000 ; +u32 time_start;struct qbman_release_desc releasedesc;struct qbman_swp *swp = dflt_dpio->sw_portal;
@@ -65,10 +67,15 @@ error:flush_dcache_range (fd_addr, fd_addr +LDPAA_ETH_RX_BUFFER_SIZE );qbman_release_desc_clear (&releasedesc);qbman_release_desc_set_bpid (&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start =get_timer (0 );do {/* Release buffer into the QBMAN */ err =qbman_swp_release (swp, &releasedesc, &fd_addr,1 ); - }while (err == -EBUSY ); + }while (get_timer (time_start) < timeo && err == -EBUSY ); + +if (err == -EBUSY ) +printf ("Rx frame: QBMAN buffer release fails\n" ); +return ; }
Signature · 1 line
1.9.1
PATCH v4 1/13 drivers/fsl-mc: Make MC boot error messages more readable
In reply to Prabhakar KushwahaQuoted 11 lines · Prabhakar Kushwaha
From: "J. German Rivera" <[email protected]>
Make it easier for the user to notice when the MC firmware had problems booting.
Signed-off-by J. German Rivera <[email protected]>Signed-off-by Prabhakar Kushwaha <[email protected]>---
Changes for v2: Sending as it is for patchset
Changes for v3: Sending as it is for patchset
Changes for v4: Sending as it is for patchset
This set (v4) is applied to u-boot-fsl-qoriq master branch.
York