From patchwork Sun Mar 6 15:41:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Helin" X-Patchwork-Id: 11098 X-Patchwork-Delegate: bruce.richardson@intel.com 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 C5FA82C54; Sun, 6 Mar 2016 16:42:19 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 7B4B92C60 for ; Sun, 6 Mar 2016 16:42:16 +0100 (CET) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP; 06 Mar 2016 07:42:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,546,1449561600"; d="scan'208";a="60850204" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga004.fm.intel.com with ESMTP; 06 Mar 2016 07:42:14 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id u26FgDQA032057; Sun, 6 Mar 2016 23:42:13 +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 u26FgA6f030863; Sun, 6 Mar 2016 23:42:12 +0800 Received: (from hzhan75@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u26FgAjs030859; Sun, 6 Mar 2016 23:42:10 +0800 From: Helin Zhang To: dev@dpdk.org Date: Sun, 6 Mar 2016 23:41:34 +0800 Message-Id: <1457278919-30800-5-git-send-email-helin.zhang@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1457278919-30800-1-git-send-email-helin.zhang@intel.com> References: <1455806076-18497-1-git-send-email-helin.zhang@intel.com> <1457278919-30800-1-git-send-email-helin.zhang@intel.com> Subject: [dpdk-dev] [PATCH v4 04/29] i40e/base: add X722 support on nvm read 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" In X722, NVM reads can't be done through SRCTL registers. And require AQ calls, which require grabbing the NVM lock. Unfortunately some paths need the lock to be acquired once and do a whole bunch of stuff and then release it. This patch creates an unsafe version of the read calls, so that it can be called from the paths that need the bulk access. Signed-off-by: Helin Zhang Acked-by: Jingjing Wu --- drivers/net/i40e/base/i40e_nvm.c | 109 ++++++++++++++++++++++++++------- drivers/net/i40e/base/i40e_prototype.h | 8 ++- 2 files changed, 92 insertions(+), 25 deletions(-) v4: - Reworded the commit logs. diff --git a/drivers/net/i40e/base/i40e_nvm.c b/drivers/net/i40e/base/i40e_nvm.c index a1b150a..f4e4eaa 100644 --- a/drivers/net/i40e/base/i40e_nvm.c +++ b/drivers/net/i40e/base/i40e_nvm.c @@ -53,7 +53,7 @@ enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, * once per NVM initialization, e.g. inside the i40e_init_shared_code(). * Please notice that the NVM term is used here (& in all methods covered * in this file) as an equivalent of the FLASH part mapped into the SR. - * We are accessing FLASH always thru the Shadow RAM. + * We are accessing FLASH always through the Shadow RAM. **/ enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw) { @@ -207,7 +207,7 @@ static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) } /** - * i40e_read_nvm_word - Reads Shadow RAM + * i40e_read_nvm_word - Reads nvm word and acquire lock if necessary * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) * @data: word read from the Shadow RAM @@ -236,6 +236,31 @@ enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, } /** + * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) + * @data: word read from the Shadow RAM + * + * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. + **/ +enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw, + u16 offset, + u16 *data) +{ + enum i40e_status_code ret_code = I40E_SUCCESS; + +#ifdef X722_SUPPORT + if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) + ret_code = i40e_read_nvm_word_aq(hw, offset, data); + else + ret_code = i40e_read_nvm_word_srctl(hw, offset, data); +#else + ret_code = i40e_read_nvm_word_srctl(hw, offset, data); +#endif + return ret_code; +} + +/** * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) @@ -307,7 +332,35 @@ enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, } /** - * i40e_read_nvm_buffer - Reads Shadow RAM buffer + * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). + * @words: (in) number of words to read; (out) number of words actually read + * @data: words read from the Shadow RAM + * + * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() + * method. The buffer read is preceded by the NVM ownership take + * and followed by the release. + **/ +enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw, + u16 offset, + u16 *words, u16 *data) +{ + enum i40e_status_code ret_code = I40E_SUCCESS; + +#ifdef X722_SUPPORT + if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) + ret_code = i40e_read_nvm_buffer_aq(hw, offset, words, data); + else + ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data); +#else + ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data); +#endif + return ret_code; +} + +/** + * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acuire lock if necessary * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). * @words: (in) number of words to read; (out) number of words actually read @@ -327,7 +380,7 @@ enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); if (!ret_code) { ret_code = i40e_read_nvm_buffer_aq(hw, offset, words, - data); + data); i40e_release_nvm(hw); } } else { @@ -358,7 +411,7 @@ enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, DEBUGFUNC("i40e_read_nvm_buffer_srctl"); - /* Loop thru the selected region */ + /* Loop through the selected region */ for (word = 0; word < *words; word++) { index = offset + word; ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]); @@ -530,7 +583,7 @@ enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer, } /** - * i40e_write_nvm_word - Writes Shadow RAM word + * __i40e_write_nvm_word - Writes Shadow RAM word * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to write * @data: word to write to the Shadow RAM @@ -540,8 +593,8 @@ enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer, * reception) by caller. To commit SR to NVM update checksum function * should be called. **/ -enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, - void *data) +enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, + void *data) { DEBUGFUNC("i40e_write_nvm_word"); @@ -552,7 +605,7 @@ enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, } /** - * i40e_write_nvm_buffer - Writes Shadow RAM buffer + * __i40e_write_nvm_buffer - Writes Shadow RAM buffer * @hw: pointer to the HW structure * @module_pointer: module pointer location in words from the NVM beginning * @offset: offset of the Shadow RAM buffer to write @@ -564,9 +617,9 @@ enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, * on ARQ completion event reception by caller. To commit SR to NVM update * checksum function should be called. **/ -enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw, - u8 module_pointer, u32 offset, - u16 words, void *data) +enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw, + u8 module_pointer, u32 offset, + u16 words, void *data) { __le16 *le_word_ptr = (__le16 *)data; u16 *word_ptr = (u16 *)data; @@ -613,15 +666,17 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum) data = (u16 *)vmem.va; /* read pointer to VPD area */ - ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module); + ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, + &vpd_module); if (ret_code != I40E_SUCCESS) { ret_code = I40E_ERR_NVM_CHECKSUM; goto i40e_calc_nvm_checksum_exit; } /* read pointer to PCIe Alt Auto-load module */ - ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, - &pcie_alt_module); + ret_code = __i40e_read_nvm_word(hw, + I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, + &pcie_alt_module); if (ret_code != I40E_SUCCESS) { ret_code = I40E_ERR_NVM_CHECKSUM; goto i40e_calc_nvm_checksum_exit; @@ -635,7 +690,7 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum) if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) { u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS; - ret_code = i40e_read_nvm_buffer(hw, i, &words, data); + ret_code = __i40e_read_nvm_buffer(hw, i, &words, data); if (ret_code != I40E_SUCCESS) { ret_code = I40E_ERR_NVM_CHECKSUM; goto i40e_calc_nvm_checksum_exit; @@ -710,13 +765,18 @@ enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw, DEBUGFUNC("i40e_validate_nvm_checksum"); - ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); - if (ret_code != I40E_SUCCESS) + if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) + ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); + if (!ret_code) { + ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); + if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) + i40e_release_nvm(hw); + if (ret_code != I40E_SUCCESS) + goto i40e_validate_nvm_checksum_exit; + } else { goto i40e_validate_nvm_checksum_exit; + } - /* Do not use i40e_read_nvm_word() because we do not want to take - * the synchronization semaphores twice here. - */ i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr); /* Verify read checksum from EEPROM is the same as @@ -812,10 +872,11 @@ enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw, /* early check for status command and debug msgs */ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno); - i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n", + i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d cmd 0x%08x config 0x%08x offset 0x%08x data_size 0x%08x\n", i40e_nvm_update_state_str[upd_cmd], hw->nvmupd_state, - hw->aq.nvm_release_on_done); + hw->aq.nvm_release_on_done, + cmd->command, cmd->config, cmd->offset, cmd->data_size); if (upd_cmd == I40E_NVMUPD_INVALID) { *perrno = -EFAULT; @@ -1083,6 +1144,7 @@ retry: break; case I40E_NVMUPD_CSUM_CON: + /* Assumes the caller has acquired the nvm */ status = i40e_update_nvm_checksum(hw); if (status) { *perrno = hw->aq.asq_last_status ? @@ -1096,6 +1158,7 @@ retry: break; case I40E_NVMUPD_CSUM_LCB: + /* Assumes the caller has acquired the nvm */ status = i40e_update_nvm_checksum(hw); if (status) { *perrno = hw->aq.asq_last_status ? diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h index 76dc5b6..93fddf1 100644 --- a/drivers/net/i40e/base/i40e_prototype.h +++ b/drivers/net/i40e/base/i40e_prototype.h @@ -437,9 +437,13 @@ enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module, u32 offset, u16 words, void *data, bool last_command); -enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, +enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, + u16 *data); +enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, + u16 *words, u16 *data); +enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset, void *data); -enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw, u8 module, +enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw, u8 module, u32 offset, u16 words, void *data); enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum); enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw);