From patchwork Mon Dec 15 07:09:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Helin" X-Patchwork-Id: 1998 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 028018041; Mon, 15 Dec 2014 08:09:40 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 3221D803F for ; Mon, 15 Dec 2014 08:09:38 +0100 (CET) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 14 Dec 2014 23:09:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,578,1413270000"; d="scan'208";a="647652590" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga002.fm.intel.com with ESMTP; 14 Dec 2014 23:09:36 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id sBF79XYO000429; Mon, 15 Dec 2014 15:09:33 +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 sBF79Vml028220; Mon, 15 Dec 2014 15:09:33 +0800 Received: (from hzhan75@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id sBF79VUG028216; Mon, 15 Dec 2014 15:09:31 +0800 From: Helin Zhang To: dev@dpdk.org Date: Mon, 15 Dec 2014 15:09:30 +0800 Message-Id: <1418627370-28185-1-git-send-email-helin.zhang@intel.com> X-Mailer: git-send-email 1.7.4.1 Cc: aaron.f.rowden@intel.com Subject: [dpdk-dev] [PATCH] i40e: workaround for X710 performance issues 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" As the fixes of below performance issues on X710 may not be integrated in latest version of firmware, a workaround in software PMD is needed. It is to re-configure 3 specific registers after being initialized. - Cannot achieve line rate on X710. - Performance reduction when promiscuous mode is disabled. Note that this workaround can be removed if the fixes are integrated in the firmware in future. Signed-off-by: Helin Zhang --- lib/librte_pmd_i40e/i40e_ethdev.c | 87 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c index 008d62c..adaab93 100644 --- a/lib/librte_pmd_i40e/i40e_ethdev.c +++ b/lib/librte_pmd_i40e/i40e_ethdev.c @@ -198,6 +198,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, enum rte_filter_op filter_op, void *arg); +static void i40e_configure_registers(struct i40e_hw *hw); /* Default hash key buffer for RSS */ static uint32_t rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1]; @@ -443,6 +444,15 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv, /* Clear PXE mode */ i40e_clear_pxe_mode(hw); + /* + * On X710, as old version of firmwares may have performance issues, + * 3 registers need to be re-configured with new values. And the latest + * version of firmware may not contain the fixes, workaround in SW + * driver is needed. This workaround can be removed when the fixes are + * integrated in firmware in future. + */ + i40e_configure_registers(hw); + /* Get hw capabilities */ ret = i40e_get_cap(hw); if (ret != I40E_SUCCESS) { @@ -5294,3 +5304,80 @@ i40e_pctype_to_flowtype(enum i40e_filter_pctype pctype) return flowtype_table[pctype]; } + +static int +i40e_debug_read_register(struct i40e_hw *hw, uint32_t addr, uint64_t *val) +{ + struct i40e_aq_desc desc; + struct i40e_aqc_debug_reg_read_write *cmd = + (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw; + enum i40e_status_code status; + + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg); + cmd->address = rte_cpu_to_le_32(addr); + status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL); + if (status < 0) + return status; + + *val = ((uint64_t)(rte_le_to_cpu_32(cmd->value_high)) << (CHAR_BIT * + sizeof(uint32_t))) + rte_le_to_cpu_32(cmd->value_low); + + return status; +} + +/* + * On X710, as old version of firmwares may have performance issues, + * 3 registers need to be re-configured with new values. And the latest version + * of firmware may not contain the fixes, workaround in SW driver is needed. + * This workaround can be removed when the fixes are integrated in firmware in + * future. + */ +static void +i40e_configure_registers(struct i40e_hw *hw) +{ +#define I40E_GL_SWR_PRI_JOIN_MAP_0 0x26CE00 +#define I40E_GL_SWR_PRI_JOIN_MAP_2 0x26CE08 +#define I40E_GL_SWR_PM_UP_THR 0x269FBC +#define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x10000200 +#define I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200 +#define I40E_GL_SWR_PM_UP_THR_VALUE 0x03030303 + + static const struct { + uint32_t addr; + uint64_t val; + } reg_table[] = { + {I40E_GL_SWR_PRI_JOIN_MAP_0, I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE}, + {I40E_GL_SWR_PRI_JOIN_MAP_2, I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE}, + {I40E_GL_SWR_PM_UP_THR, I40E_GL_SWR_PM_UP_THR_VALUE}, + }; + uint64_t reg; + uint32_t i; + int ret; + + /* Below fix is for X710 only */ + if (i40e_is_40G_device(hw->device_id)) + return; + + for (i = 0; i < RTE_DIM(reg_table); i++) { + ret = i40e_debug_read_register(hw, reg_table[i].addr, ®); + if (ret < 0) { + PMD_DRV_LOG(ERR, "Failed to read from 0x%x\n", + reg_table[i].addr); + break; + } + PMD_DRV_LOG(DEBUG, "Read from 0x%x: 0x%lx", reg_table[i].addr, + reg); + if (reg == reg_table[i].val) + continue; + + ret = i40e_aq_debug_write_register(hw, reg_table[i].addr, + reg_table[i].val, NULL); + if (ret < 0) { + PMD_DRV_LOG(ERR, "Failed to write 0x%x to 0x%x\n", + reg_table[i].val, reg_table[i].addr); + break; + } + PMD_DRV_LOG(DEBUG, "Write to 0x%x: 0x%lx", reg_table[i].addr, + reg_table[i].val); + } +}