X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fqede%2Fbase%2Fecore_hw.c;h=1db39d6a36102ba19f354c971ab0973faa49694e;hb=1e8d75d8059701fd15876416be06064735ec5e87;hp=4914c0d131f19da4371b018a721ca265402fbca1;hpb=98abf84ee0e0719a6b64652cee239ab82e74f7b1;p=dpdk.git diff --git a/drivers/net/qede/base/ecore_hw.c b/drivers/net/qede/base/ecore_hw.c index 4914c0d131..1db39d6a36 100644 --- a/drivers/net/qede/base/ecore_hw.c +++ b/drivers/net/qede/base/ecore_hw.c @@ -1,9 +1,7 @@ -/* - * Copyright (c) 2016 QLogic Corporation. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2016 - 2018 Cavium Inc. * All rights reserved. - * www.qlogic.com - * - * See LICENSE.qede_pmd for copyright and licensing details. + * www.cavium.com */ #include "bcm_osal.h" @@ -14,6 +12,8 @@ #include "reg_addr.h" #include "ecore_utils.h" #include "ecore_iov_api.h" +#include "ecore_gtt_values.h" +#include "ecore_dev_api.h" #ifndef ASIC_ONLY #define ECORE_EMUL_FACTOR 2000 @@ -80,6 +80,20 @@ enum _ecore_status_t ecore_ptt_pool_alloc(struct ecore_hwfn *p_hwfn) return ECORE_SUCCESS; } +void ecore_gtt_init(struct ecore_hwfn *p_hwfn) +{ + u32 gtt_base; + u32 i; + + /* Set the global windows */ + gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START; + + for (i = 0; i < OSAL_ARRAY_SIZE(pxp_global_win); i++) + if (pxp_global_win[i]) + REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE, + pxp_global_win[i]); +} + void ecore_ptt_invalidate(struct ecore_hwfn *p_hwfn) { struct ecore_ptt *p_ptt; @@ -409,6 +423,30 @@ void ecore_port_unpretend(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) *(u32 *)&p_ptt->pxp.pretend); } +void ecore_port_fid_pretend(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + u8 port_id, u16 fid) +{ + u16 control = 0; + + SET_FIELD(control, PXP_PRETEND_CMD_PORT, port_id); + SET_FIELD(control, PXP_PRETEND_CMD_USE_PORT, 1); + SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_PORT, 1); + + SET_FIELD(control, PXP_PRETEND_CMD_IS_CONCRETE, 1); + SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_FUNCTION, 1); + + if (!GET_FIELD(fid, PXP_CONCRETE_FID_VFVALID)) + fid = GET_FIELD(fid, PXP_CONCRETE_FID_PFID); + + p_ptt->pxp.pretend.control = OSAL_CPU_TO_LE16(control); + p_ptt->pxp.pretend.fid.concrete_fid.fid = OSAL_CPU_TO_LE16(fid); + + REG_WR(p_hwfn, + ecore_ptt_config_addr(p_ptt) + + OFFSETOF(struct pxp_ptt_entry, pretend), + *(u32 *)&p_ptt->pxp.pretend); +} + u32 ecore_vfid_to_concrete(struct ecore_hwfn *p_hwfn, u8 vfid) { u32 concrete_fid = 0; @@ -428,14 +466,18 @@ u32 ecore_vfid_to_concrete(struct ecore_hwfn *p_hwfn, u8 vfid) * If this changes, this needs to be revisted. */ -/* Ecore DMAE - * ============= - */ +/* DMAE */ + +#define ECORE_DMAE_FLAGS_IS_SET(params, flag) \ + ((params) != OSAL_NULL && \ + GET_FIELD((params)->flags, DMAE_PARAMS_##flag)) + static void ecore_dmae_opcode(struct ecore_hwfn *p_hwfn, const u8 is_src_type_grc, const u8 is_dst_type_grc, - struct ecore_dmae_params *p_params) + struct dmae_params *p_params) { + u8 src_pf_id, dst_pf_id, port_id; u16 opcode_b = 0; u32 opcode = 0; @@ -443,18 +485,22 @@ static void ecore_dmae_opcode(struct ecore_hwfn *p_hwfn, * 0- The source is the PCIe * 1- The source is the GRC. */ - opcode |= (is_src_type_grc ? DMAE_CMD_SRC_MASK_GRC - : DMAE_CMD_SRC_MASK_PCIE) << DMAE_CMD_SRC_SHIFT; - opcode |= (p_hwfn->rel_pf_id & DMAE_CMD_SRC_PF_ID_MASK) << - DMAE_CMD_SRC_PF_ID_SHIFT; + opcode |= (is_src_type_grc ? dmae_cmd_src_grc : dmae_cmd_src_pcie) << + DMAE_CMD_SRC_SHIFT; + src_pf_id = ECORE_DMAE_FLAGS_IS_SET(p_params, SRC_PF_VALID) ? + p_params->src_pf_id : p_hwfn->rel_pf_id; + opcode |= (src_pf_id & DMAE_CMD_SRC_PF_ID_MASK) << + DMAE_CMD_SRC_PF_ID_SHIFT; /* The destination of the DMA can be: 0-None 1-PCIe 2-GRC 3-None */ - opcode |= (is_dst_type_grc ? DMAE_CMD_DST_MASK_GRC - : DMAE_CMD_DST_MASK_PCIE) << DMAE_CMD_DST_SHIFT; - opcode |= (p_hwfn->rel_pf_id & DMAE_CMD_DST_PF_ID_MASK) << - DMAE_CMD_DST_PF_ID_SHIFT; - - /* DMAE_E4_TODO need to check which value to specifiy here. */ + opcode |= (is_dst_type_grc ? dmae_cmd_dst_grc : dmae_cmd_dst_pcie) << + DMAE_CMD_DST_SHIFT; + dst_pf_id = ECORE_DMAE_FLAGS_IS_SET(p_params, DST_PF_VALID) ? + p_params->dst_pf_id : p_hwfn->rel_pf_id; + opcode |= (dst_pf_id & DMAE_CMD_DST_PF_ID_MASK) << + DMAE_CMD_DST_PF_ID_SHIFT; + + /* DMAE_E4_TODO need to check which value to specify here. */ /* opcode |= (!b_complete_to_host)<< DMAE_CMD_C_DST_SHIFT; */ /* Whether to write a completion word to the completion destination: @@ -464,7 +510,7 @@ static void ecore_dmae_opcode(struct ecore_hwfn *p_hwfn, opcode |= DMAE_CMD_COMP_WORD_EN_MASK << DMAE_CMD_COMP_WORD_EN_SHIFT; opcode |= DMAE_CMD_SRC_ADDR_RESET_MASK << DMAE_CMD_SRC_ADDR_RESET_SHIFT; - if (p_params->flags & ECORE_DMAE_FLAG_COMPLETION_DST) + if (ECORE_DMAE_FLAGS_IS_SET(p_params, COMPLETION_DST)) opcode |= 1 << DMAE_CMD_COMP_FUNC_SHIFT; /* swapping mode 3 - big endian there should be a define ifdefed in @@ -472,7 +518,9 @@ static void ecore_dmae_opcode(struct ecore_hwfn *p_hwfn, */ opcode |= DMAE_CMD_ENDIANITY << DMAE_CMD_ENDIANITY_MODE_SHIFT; - opcode |= p_hwfn->port_id << DMAE_CMD_PORT_ID_SHIFT; + port_id = (ECORE_DMAE_FLAGS_IS_SET(p_params, PORT_VALID)) ? + p_params->port_id : p_hwfn->port_id; + opcode |= port_id << DMAE_CMD_PORT_ID_SHIFT; /* reset source address in next go */ opcode |= DMAE_CMD_SRC_ADDR_RESET_MASK << DMAE_CMD_SRC_ADDR_RESET_SHIFT; @@ -481,16 +529,16 @@ static void ecore_dmae_opcode(struct ecore_hwfn *p_hwfn, opcode |= DMAE_CMD_DST_ADDR_RESET_MASK << DMAE_CMD_DST_ADDR_RESET_SHIFT; /* SRC/DST VFID: all 1's - pf, otherwise VF id */ - if (p_params->flags & ECORE_DMAE_FLAG_VF_SRC) { + if (ECORE_DMAE_FLAGS_IS_SET(p_params, SRC_VF_VALID)) { opcode |= (1 << DMAE_CMD_SRC_VF_ID_VALID_SHIFT); - opcode_b |= (p_params->src_vfid << DMAE_CMD_SRC_VF_ID_SHIFT); + opcode_b |= (p_params->src_vf_id << DMAE_CMD_SRC_VF_ID_SHIFT); } else { opcode_b |= (DMAE_CMD_SRC_VF_ID_MASK << DMAE_CMD_SRC_VF_ID_SHIFT); } - if (p_params->flags & ECORE_DMAE_FLAG_VF_DST) { + if (ECORE_DMAE_FLAGS_IS_SET(p_params, DST_VF_VALID)) { opcode |= 1 << DMAE_CMD_DST_VF_ID_VALID_SHIFT; - opcode_b |= p_params->dst_vfid << DMAE_CMD_DST_VF_ID_SHIFT; + opcode_b |= p_params->dst_vf_id << DMAE_CMD_DST_VF_ID_SHIFT; } else { opcode_b |= DMAE_CMD_DST_VF_ID_MASK << DMAE_CMD_DST_VF_ID_SHIFT; } @@ -664,7 +712,7 @@ static enum _ecore_status_t ecore_dmae_operation_wait(struct ecore_hwfn *p_hwfn) while (*p_hwfn->dmae_info.p_completion_word != DMAE_COMPLETION_VAL) { OSAL_UDELAY(DMAE_MIN_WAIT_TIME); if (++wait_cnt > wait_cnt_limit) { - DP_NOTICE(p_hwfn->p_dev, ECORE_MSG_HW, + DP_NOTICE(p_hwfn->p_dev, false, "Timed-out waiting for operation to" " complete. Completion word is 0x%08x" " expected 0x%08x.\n", @@ -685,6 +733,12 @@ static enum _ecore_status_t ecore_dmae_operation_wait(struct ecore_hwfn *p_hwfn) return ecore_status; } +enum ecore_dmae_address_type { + ECORE_DMAE_ADDRESS_HOST_VIRT, + ECORE_DMAE_ADDRESS_HOST_PHYS, + ECORE_DMAE_ADDRESS_GRC +}; + static enum _ecore_status_t ecore_dmae_execute_sub_operation(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, @@ -751,7 +805,7 @@ ecore_dmae_execute_sub_operation(struct ecore_hwfn *p_hwfn, length_dw * sizeof(u32), true); if (ecore_status != ECORE_SUCCESS) { - DP_NOTICE(p_hwfn, ECORE_MSG_HW, + DP_NOTICE(p_hwfn, false, "Wait Failed. source_addr 0x%lx, grc_addr 0x%lx, size_in_dwords 0x%x, intermediate buffer 0x%lx.\n", (unsigned long)src_addr, (unsigned long)dst_addr, length_dw, @@ -775,7 +829,7 @@ ecore_dmae_execute_command(struct ecore_hwfn *p_hwfn, u8 src_type, u8 dst_type, u32 size_in_dwords, - struct ecore_dmae_params *p_params) + struct dmae_params *p_params) { dma_addr_t phys = p_hwfn->dmae_info.completion_word_phys_addr; u16 length_cur = 0, i = 0, cnt_split = 0, length_mod = 0; @@ -833,7 +887,7 @@ ecore_dmae_execute_command(struct ecore_hwfn *p_hwfn, for (i = 0; i <= cnt_split; i++) { offset = length_limit * i; - if (!(p_params->flags & ECORE_DMAE_FLAG_RW_REPL_SRC)) { + if (!ECORE_DMAE_FLAGS_IS_SET(p_params, RW_REPL_SRC)) { if (src_type == ECORE_DMAE_ADDRESS_GRC) src_addr_split = src_addr + offset; else @@ -874,51 +928,45 @@ ecore_dmae_execute_command(struct ecore_hwfn *p_hwfn, return ecore_status; } -enum _ecore_status_t -ecore_dmae_host2grc(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt, - u64 source_addr, - u32 grc_addr, u32 size_in_dwords, u32 flags) +enum _ecore_status_t ecore_dmae_host2grc(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt, + u64 source_addr, + u32 grc_addr, + u32 size_in_dwords, + struct dmae_params *p_params) { u32 grc_addr_in_dw = grc_addr / sizeof(u32); - struct ecore_dmae_params params; enum _ecore_status_t rc; - OSAL_MEMSET(¶ms, 0, sizeof(struct ecore_dmae_params)); - params.flags = flags; - OSAL_SPIN_LOCK(&p_hwfn->dmae_info.lock); rc = ecore_dmae_execute_command(p_hwfn, p_ptt, source_addr, grc_addr_in_dw, ECORE_DMAE_ADDRESS_HOST_VIRT, ECORE_DMAE_ADDRESS_GRC, - size_in_dwords, ¶ms); + size_in_dwords, p_params); OSAL_SPIN_UNLOCK(&p_hwfn->dmae_info.lock); return rc; } -enum _ecore_status_t -ecore_dmae_grc2host(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt, - u32 grc_addr, - dma_addr_t dest_addr, u32 size_in_dwords, u32 flags) +enum _ecore_status_t ecore_dmae_grc2host(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt, + u32 grc_addr, + dma_addr_t dest_addr, + u32 size_in_dwords, + struct dmae_params *p_params) { u32 grc_addr_in_dw = grc_addr / sizeof(u32); - struct ecore_dmae_params params; enum _ecore_status_t rc; - OSAL_MEMSET(¶ms, 0, sizeof(struct ecore_dmae_params)); - params.flags = flags; - OSAL_SPIN_LOCK(&p_hwfn->dmae_info.lock); rc = ecore_dmae_execute_command(p_hwfn, p_ptt, grc_addr_in_dw, dest_addr, ECORE_DMAE_ADDRESS_GRC, ECORE_DMAE_ADDRESS_HOST_VIRT, - size_in_dwords, ¶ms); + size_in_dwords, p_params); OSAL_SPIN_UNLOCK(&p_hwfn->dmae_info.lock); @@ -930,7 +978,8 @@ ecore_dmae_host2host(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, dma_addr_t source_addr, dma_addr_t dest_addr, - u32 size_in_dwords, struct ecore_dmae_params *p_params) + u32 size_in_dwords, + struct dmae_params *p_params) { enum _ecore_status_t rc; @@ -967,7 +1016,6 @@ enum _ecore_status_t ecore_dmae_sanity(struct ecore_hwfn *p_hwfn, const char *phase) { u32 size = OSAL_PAGE_SIZE / 2, val; - struct ecore_dmae_params params; enum _ecore_status_t rc = ECORE_SUCCESS; dma_addr_t p_phys; void *p_virt; @@ -999,9 +1047,9 @@ enum _ecore_status_t ecore_dmae_sanity(struct ecore_hwfn *p_hwfn, (unsigned long)(p_phys + size), (u8 *)p_virt + size, size); - OSAL_MEMSET(¶ms, 0, sizeof(params)); rc = ecore_dmae_host2host(p_hwfn, p_ptt, p_phys, p_phys + size, - size / 4 /* size_in_dwords */, ¶ms); + size / 4 /* size_in_dwords */, + OSAL_NULL /* default parameters */); if (rc != ECORE_SUCCESS) { DP_NOTICE(p_hwfn, false, "DMAE sanity [%s]: ecore_dmae_host2host() failed. rc = %d.\n", @@ -1032,3 +1080,32 @@ out: OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev, p_virt, p_phys, 2 * size); return rc; } + +void ecore_ppfid_wr(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + u8 abs_ppfid, u32 hw_addr, u32 val) +{ + u8 pfid = ECORE_PFID_BY_PPFID(p_hwfn, abs_ppfid); + + ecore_fid_pretend(p_hwfn, p_ptt, + pfid << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT); + ecore_wr(p_hwfn, p_ptt, hw_addr, val); + ecore_fid_pretend(p_hwfn, p_ptt, + p_hwfn->rel_pf_id << + PXP_PRETEND_CONCRETE_FID_PFID_SHIFT); +} + +u32 ecore_ppfid_rd(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + u8 abs_ppfid, u32 hw_addr) +{ + u8 pfid = ECORE_PFID_BY_PPFID(p_hwfn, abs_ppfid); + u32 val; + + ecore_fid_pretend(p_hwfn, p_ptt, + pfid << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT); + val = ecore_rd(p_hwfn, p_ptt, hw_addr); + ecore_fid_pretend(p_hwfn, p_ptt, + p_hwfn->rel_pf_id << + PXP_PRETEND_CONCRETE_FID_PFID_SHIFT); + + return val; +}