From patchwork Mon Apr 20 08:22:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Helin" X-Patchwork-Id: 4374 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id CD748C426; Mon, 20 Apr 2015 10:23:16 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 7E4CBC3DA for ; Mon, 20 Apr 2015 10:23:11 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 20 Apr 2015 01:23:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,608,1422950400"; d="scan'208";a="712055342" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga002.fm.intel.com with ESMTP; 20 Apr 2015 01:23:10 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t3K8N74c013148; Mon, 20 Apr 2015 16:23:07 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t3K8N4H9028238; Mon, 20 Apr 2015 16:23:07 +0800 Received: (from hzhan75@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t3K8N4Ql028234; Mon, 20 Apr 2015 16:23:04 +0800 From: Helin Zhang To: dev@dpdk.org Date: Mon, 20 Apr 2015 16:22:27 +0800 Message-Id: <1429518150-28098-16-git-send-email-helin.zhang@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1429518150-28098-1-git-send-email-helin.zhang@intel.com> References: <1429518150-28098-1-git-send-email-helin.zhang@intel.com> Cc: monica.kenguva@intel.com, steven.j.murray@intel.com, chiu-pi.shih@intel.com Subject: [dpdk-dev] [PATCH 15/18] i40e: support of Fortpark FPGA X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" To support Fortpark FPGA devices, all device IDs and MAC types of FPGA were added. Also, special configurations and processings for FPGA were added. Signed-off-by: Helin Zhang --- lib/librte_pmd_i40e/i40e/i40e_adminq.c | 11 +++ lib/librte_pmd_i40e/i40e/i40e_common.c | 123 +++++++++++++++++++++++++++++- lib/librte_pmd_i40e/i40e/i40e_osdep.h | 62 +++++++++++++++ lib/librte_pmd_i40e/i40e/i40e_prototype.h | 1 + lib/librte_pmd_i40e/i40e/i40e_type.h | 1 + 5 files changed, 197 insertions(+), 1 deletion(-) diff --git a/lib/librte_pmd_i40e/i40e/i40e_adminq.c b/lib/librte_pmd_i40e/i40e/i40e_adminq.c index 8f9e870..0fd8ca9 100644 --- a/lib/librte_pmd_i40e/i40e/i40e_adminq.c +++ b/lib/librte_pmd_i40e/i40e/i40e_adminq.c @@ -582,6 +582,14 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) /* setup ASQ command write back timeout */ hw->aq.asq_cmd_timeout = I40E_ASQ_CMD_TIMEOUT; + /* emulator and FPGA needs a longer write back timeout + * (exclude FVL FPGA/FVL Blank Flash Si DeviceID) + */ + if ((hw->device_id == I40E_DEV_ID_BVL_I40Q) || + (hw->device_id == I40E_DEV_ID_FPK_FPGA) || + (hw->device_id == I40E_DEV_ID_FPK_FPGA_VF)) + hw->aq.asq_cmd_timeout = I40E_ASQ_CMD_TIMEOUT_FPGA; + /* allocate the ASQ */ ret_code = i40e_init_asq(hw); if (ret_code != I40E_SUCCESS) @@ -868,6 +876,9 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff, buff_size); + /* To increase stability */ + if (hw->mac.is_fpga) + i40e_msec_delay(10); (hw->aq.asq.next_to_use)++; if (hw->aq.asq.next_to_use == hw->aq.asq.count) hw->aq.asq.next_to_use = 0; diff --git a/lib/librte_pmd_i40e/i40e/i40e_common.c b/lib/librte_pmd_i40e/i40e/i40e_common.c index b6ca288..0ae88b8 100644 --- a/lib/librte_pmd_i40e/i40e/i40e_common.c +++ b/lib/librte_pmd_i40e/i40e/i40e_common.c @@ -799,6 +799,15 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw) else hw->pf_id = (u8)(func_rid & 0x7); + /* Check if we are working with FPGA */ + if ((hw->device_id == I40E_DEV_ID_FPGA_A) || + (hw->device_id == I40E_DEV_ID_FPGA_A_VF)) + hw->mac.is_fpga = true; + + if ((hw->device_id == I40E_DEV_ID_FPK_FPGA) || + (hw->device_id == I40E_DEV_ID_FPK_FPGA_VF)) + hw->mac.is_fpga = true; + status = i40e_init_nvm(hw); return status; } @@ -875,6 +884,21 @@ enum i40e_status_code i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr) status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL); + /* try the obsolete command if we are working with older FPGA or BVL */ + if ((status != I40E_SUCCESS) && + (hw->aq.asq_last_status == I40E_AQ_RC_ESRCH) && + (hw->mac.is_fpga)) { + struct i40e_aq_desc desc; + struct i40e_aqc_mng_laa *cmd_resp = + (struct i40e_aqc_mng_laa *)&desc.params.raw; + + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_mng_laa); + status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL); + + memcpy(&mac_addr[0], &cmd_resp->sal, 4); + memcpy(&mac_addr[4], &cmd_resp->sah, 2); + } + if (flags & I40E_AQC_LAN_ADDR_VALID) memcpy(mac_addr, &addrs.pf_lan_mac, sizeof(addrs.pf_lan_mac)); @@ -1062,6 +1086,21 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw) u32 reg = 0; u32 grst_del; + if (hw->mac.is_fpga) { + /* turn on Address Translation and protection */ + reg = rd32(hw, I40E_GLGEN_CSR_DEBUG_C); + reg |= I40E_GLGEN_CSR_DEBUG_C_CSR_ADDR_PROT_MASK; + wr32(hw, I40E_GLGEN_CSR_DEBUG_C, reg); + + /* NVM work around - force 0x8 into the GLGEN_RSTCTL reset + * delay + */ + grst_del = rd32(hw, I40E_GLGEN_RSTCTL); + grst_del &= ~I40E_GLGEN_RSTCTL_GRSTDEL_MASK; + grst_del |= (0x8 << I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT); + wr32(hw, I40E_GLGEN_RSTCTL, grst_del); + } + /* Poll for Global Reset steady state in case of recent GRST. * The grst delay value is in 100ms units, and we'll wait a * couple counts longer to be sure we don't just miss the end. @@ -1110,6 +1149,8 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw) reg = rd32(hw, I40E_PFGEN_CTRL); if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) break; + if (hw->mac.is_fpga) + i40e_msec_delay(500); i40e_msec_delay(1); } if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { @@ -1118,6 +1159,10 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw) } } + /* wait a lonnnnnng time */ + if (hw->mac.is_fpga) + i40e_msec_delay(2000); + i40e_clear_pxe_mode(hw); @@ -1228,8 +1273,14 @@ void i40e_clear_pxe_mode(struct i40e_hw *hw) { u32 reg; - if (i40e_check_asq_alive(hw)) + /* Clear single descriptor fetch/write-back mode */ + if (hw->mac.is_fpga) { + reg = rd32(hw, I40E_GLLAN_RCTL_0); + wr32(hw, I40E_GLLAN_RCTL_0, (reg | + (I40E_GLLAN_RCTL_0_PXE_MODE_MASK))); + } else if (i40e_check_asq_alive(hw)) { i40e_aq_clear_pxe_mode(hw, NULL); + } } /** @@ -1444,6 +1495,10 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw, *cmd = *config; + /* The PHY config cannot be set on the FPGA */ + if (hw->mac.is_fpga) + return I40E_SUCCESS; + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); return status; @@ -1650,6 +1705,18 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw, command_flags = I40E_AQ_LSE_DISABLE; resp->command_flags = CPU_TO_LE16(command_flags); + /* The PHY is not to be read on the FPGA, so lie about some defaults + * based on what we know is true about the FPGA + */ + if (hw->mac.is_fpga) { + hw_link_info->phy_type = I40E_PHY_TYPE_1000BASE_T; + hw->phy.media_type = i40e_get_media_type(hw); + hw_link_info->link_speed = I40E_LINK_SPEED_1GB; + hw_link_info->an_info = I40E_AQ_QUALIFIED_MODULE; + + return I40E_SUCCESS; + } + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); if (status != I40E_SUCCESS) @@ -5115,6 +5182,60 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status) } /** + * i40e_configure_hw + * @hw: pointer to the hardware structure + * + * Configure HW for FPGA + **/ +enum i40e_status_code i40e_configure_hw(struct i40e_hw *hw) +{ + enum i40e_status_code status = I40E_SUCCESS; + u32 base_idx; + u32 size; + u32 reg; + + base_idx = hw->pf_id & 0xFFF; + size = ((1 << 16) & 0x1FFF0000); + reg = size | base_idx; + + wr32(hw, I40E_GLGEN_RSTCTL, 0x8); + + wr32(hw, I40E_GLHMC_SDPART(hw->pf_id), reg); + wr32(hw, I40E_GLHMC_PFASSIGN(hw->pf_id), hw->pf_id); + wr32(hw, I40E_GLHMC_PMFTABLE(hw->pf_id), 0x80000000); + + reg = rd32(hw, I40E_GLLAN_TCTL_1); + reg &= ~I40E_GLLAN_TCTL_1_TXMAX_EXPANSION_MASK; + reg |= (1 << I40E_GLLAN_TCTL_1_TXMAX_EXPANSION_SHIFT); + wr32(hw, I40E_GLLAN_TCTL_1, reg); + reg = rd32(hw, I40E_GLLAN_TCTL_2); + reg &= ~I40E_GLLAN_TCTL_2_TXMAX_EXPANSION_MASK; + reg |= (1 << I40E_GLLAN_TCTL_2_TXMAX_EXPANSION_SHIFT); + wr32(hw, I40E_GLLAN_TCTL_2, reg); + + /* Check if auto-load succeeded from NVM, otherwise we fail */ + /* This check is not applicable to Fort Park. */ + if (hw->mac.type < I40E_MAC_FPK) { + reg = rd32(hw, I40E_GLNVM_GENS); + if (!(reg & I40E_GLNVM_GENS_NVM_PRES_MASK) || + !(reg & I40E_GLNVM_GENS_FL_AUTO_RD_MASK)) { + /* We are doomed, so just return error and bail */ + DEBUGOUT("NVM Autoload failed : Error Configuring HW\n"); + status = I40E_ERR_NVM; + return status; + } + /* Commenting out most of the NVM settings for RSS and FDIR + * for ww16 drop. We still need the FD guaranteed space to be + * programmed for ATR to work. Rest of it is in NVM image. + * UDP RSS is still broken or miss-configured in NVM */ + /* Allocate the filter table, size=2*32 */ + wr32(hw, I40E_PFQF_FDALLOC, 2); + } + + return status; +} + +/** * i40e_read_bw_from_alt_ram * @hw: pointer to the hardware structure * @max_bw: pointer for max_bw read diff --git a/lib/librte_pmd_i40e/i40e/i40e_osdep.h b/lib/librte_pmd_i40e/i40e/i40e_osdep.h index 3ce8057..bf56e0d 100644 --- a/lib/librte_pmd_i40e/i40e/i40e_osdep.h +++ b/lib/librte_pmd_i40e/i40e/i40e_osdep.h @@ -47,6 +47,68 @@ #include "../i40e_logs.h" +/* FPGA registers */ +#define I40E_GLGEN_CSR_DEBUG_C 0x00078E8C /* Reset: POR */ +#define I40E_GLGEN_CSR_DEBUG_C_CSR_ACCESS_EN_SHIFT 0 +#define I40E_GLGEN_CSR_DEBUG_C_CSR_ACCESS_EN_MASK \ + I40E_MASK(0x1, I40E_GLGEN_CSR_DEBUG_C_CSR_ACCESS_EN_SHIFT) +#define I40E_GLGEN_CSR_DEBUG_C_CSR_ADDR_PROT_SHIFT 1 +#define I40E_GLGEN_CSR_DEBUG_C_CSR_ADDR_PROT_MASK \ + I40E_MASK(0x1, I40E_GLGEN_CSR_DEBUG_C_CSR_ADDR_PROT_SHIFT) + +#define I40E_GLLAN_TCTL_1 0x000442F0 /* Reset: CORER */ +#define I40E_GLLAN_TCTL_1_TXMAX_EXPANSION_SHIFT 0 +#define I40E_GLLAN_TCTL_1_TXMAX_EXPANSION_MASK \ + I40E_MASK(0xF, I40E_GLLAN_TCTL_1_TXMAX_EXPANSION_SHIFT) +#define I40E_GLLAN_TCTL_1_TXDATARDROEN_SHIFT 4 +#define I40E_GLLAN_TCTL_1_TXDATARDROEN_MASK \ + I40E_MASK(0x1, I40E_GLLAN_TCTL_1_TXDATARDROEN_SHIFT) +#define I40E_GLLAN_TCTL_1_RCU_BYPASS_SHIFT 5 +#define I40E_GLLAN_TCTL_1_RCU_BYPASS_MASK \ + I40E_MASK(0x1, I40E_GLLAN_TCTL_1_RCU_BYPASS_SHIFT) +#define I40E_GLLAN_TCTL_1_LSO_CACHE_BYPASS_SHIFT 6 +#define I40E_GLLAN_TCTL_1_LSO_CACHE_BYPASS_MASK \ + I40E_MASK(0x1, I40E_GLLAN_TCTL_1_LSO_CACHE_BYPASS_SHIFT) +#define I40E_GLLAN_TCTL_1_DBG_WB_SEL_SHIFT 7 +#define I40E_GLLAN_TCTL_1_DBG_WB_SEL_MASK \ + I40E_MASK(0xF, I40E_GLLAN_TCTL_1_DBG_WB_SEL_SHIFT) +#define I40E_GLLAN_TCTL_1_DBG_FORCE_RS_SHIFT 11 +#define I40E_GLLAN_TCTL_1_DBG_FORCE_RS_MASK \ + I40E_MASK(0x1, I40E_GLLAN_TCTL_1_DBG_FORCE_RS_SHIFT) +#define I40E_GLLAN_TCTL_1_DBG_BYPASS_SHIFT 12 +#define I40E_GLLAN_TCTL_1_DBG_BYPASS_MASK \ + I40E_MASK(0x3FF, I40E_GLLAN_TCTL_1_DBG_BYPASS_SHIFT) +#define I40E_GLLAN_TCTL_1_PRE_L2_ENA_SHIFT 22 +#define I40E_GLLAN_TCTL_1_PRE_L2_ENA_MASK \ + I40E_MASK(0x1, I40E_GLLAN_TCTL_1_PRE_L2_ENA_SHIFT) +#define I40E_GLLAN_TCTL_1_UR_PROT_DIS_SHIFT 23 +#define I40E_GLLAN_TCTL_1_UR_PROT_DIS_MASK \ + I40E_MASK(0x1, I40E_GLLAN_TCTL_1_UR_PROT_DIS_SHIFT) +#define I40E_GLLAN_TCTL_1_DBG_ECO_SHIFT 24 +#define I40E_GLLAN_TCTL_1_DBG_ECO_MASK \ + I40E_MASK(0xFF, I40E_GLLAN_TCTL_1_DBG_ECO_SHIFT) + +#define I40E_GLLAN_TCTL_2 0x000AE080 /* Reset: CORER */ +#define I40E_GLLAN_TCTL_2_TXMAX_EXPANSION_SHIFT 0 +#define I40E_GLLAN_TCTL_2_TXMAX_EXPANSION_MASK \ + I40E_MASK(0xF, I40E_GLLAN_TCTL_2_TXMAX_EXPANSION_SHIFT) +#define I40E_GLLAN_TCTL_2_STAT_DBG_ADDR_SHIFT 4 +#define I40E_GLLAN_TCTL_2_STAT_DBG_ADDR_MASK \ + I40E_MASK(0x1F, I40E_GLLAN_TCTL_2_STAT_DBG_ADDR_SHIFT) +#define I40E_GLLAN_TCTL_2_STAT_DBG_DSEL_SHIFT 9 +#define I40E_GLLAN_TCTL_2_STAT_DBG_DSEL_MASK \ + I40E_MASK(0x7, I40E_GLLAN_TCTL_2_STAT_DBG_DSEL_SHIFT) +#define I40E_GLLAN_TCTL_2_ECO_SHIFT 12 +#define I40E_GLLAN_TCTL_2_ECO_MASK \ + I40E_MASK(0xFFFFF, I40E_GLLAN_TCTL_2_ECO_SHIFT) + +#define I40E_GLHMC_PMFTABLE(_i) \ + (0x000C0b00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */ +#define I40E_GLHMC_PMFTABLE_MAX_INDEX 15 +#define I40E_GLHMC_PMFTABLE_PM_FCN_TBL_ENTRY_VLD_SHIFT 31 +#define I40E_GLHMC_PMFTABLE_PM_FCN_TBL_ENTRY_VLD_MASK \ + I40E_MASK(0x1, I40E_GLHMC_PMFTABLE_PM_FCN_TBL_ENTRY_VLD_SHIFT) + #define INLINE inline #define STATIC static diff --git a/lib/librte_pmd_i40e/i40e/i40e_prototype.h b/lib/librte_pmd_i40e/i40e/i40e_prototype.h index 7ef441b..d716735 100644 --- a/lib/librte_pmd_i40e/i40e/i40e_prototype.h +++ b/lib/librte_pmd_i40e/i40e/i40e_prototype.h @@ -424,6 +424,7 @@ enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *); void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status); +enum i40e_status_code i40e_configure_hw(struct i40e_hw *hw); #endif /* PF_DRIVER */ #if defined(I40E_QV) || defined(VF_DRIVER) diff --git a/lib/librte_pmd_i40e/i40e/i40e_type.h b/lib/librte_pmd_i40e/i40e/i40e_type.h index 535694a..634ade2 100644 --- a/lib/librte_pmd_i40e/i40e/i40e_type.h +++ b/lib/librte_pmd_i40e/i40e/i40e_type.h @@ -344,6 +344,7 @@ struct i40e_mac_info { u8 san_addr[I40E_ETH_LENGTH_OF_ADDRESS]; u8 port_addr[I40E_ETH_LENGTH_OF_ADDRESS]; u16 max_fcoeq; + bool is_fpga; }; enum i40e_aq_resources_ids {