1f31e4b6fSAnirudh Venkataramanan // SPDX-License-Identifier: GPL-2.0 2f31e4b6fSAnirudh Venkataramanan /* Copyright (c) 2018, Intel Corporation. */ 3f31e4b6fSAnirudh Venkataramanan 4f31e4b6fSAnirudh Venkataramanan #include "ice_common.h" 5f31e4b6fSAnirudh Venkataramanan 6f31e4b6fSAnirudh Venkataramanan /** 7f31e4b6fSAnirudh Venkataramanan * ice_aq_read_nvm 8f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 9f31e4b6fSAnirudh Venkataramanan * @module_typeid: module pointer location in words from the NVM beginning 10f31e4b6fSAnirudh Venkataramanan * @offset: byte offset from the module beginning 11f31e4b6fSAnirudh Venkataramanan * @length: length of the section to be read (in bytes from the offset) 12f31e4b6fSAnirudh Venkataramanan * @data: command buffer (size [bytes] = length) 13f31e4b6fSAnirudh Venkataramanan * @last_command: tells if this is the last command in a series 14f31e4b6fSAnirudh Venkataramanan * @cd: pointer to command details structure or NULL 15f31e4b6fSAnirudh Venkataramanan * 16f31e4b6fSAnirudh Venkataramanan * Read the NVM using the admin queue commands (0x0701) 17f31e4b6fSAnirudh Venkataramanan */ 18f31e4b6fSAnirudh Venkataramanan static enum ice_status 1943c89b16SAnirudh Venkataramanan ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length, 20f31e4b6fSAnirudh Venkataramanan void *data, bool last_command, struct ice_sq_cd *cd) 21f31e4b6fSAnirudh Venkataramanan { 22f31e4b6fSAnirudh Venkataramanan struct ice_aq_desc desc; 23f31e4b6fSAnirudh Venkataramanan struct ice_aqc_nvm *cmd; 24f31e4b6fSAnirudh Venkataramanan 25f31e4b6fSAnirudh Venkataramanan cmd = &desc.params.nvm; 26f31e4b6fSAnirudh Venkataramanan 27f31e4b6fSAnirudh Venkataramanan /* In offset the highest byte must be zeroed. */ 28f31e4b6fSAnirudh Venkataramanan if (offset & 0xFF000000) 29f31e4b6fSAnirudh Venkataramanan return ICE_ERR_PARAM; 30f31e4b6fSAnirudh Venkataramanan 31f31e4b6fSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read); 32f31e4b6fSAnirudh Venkataramanan 33f31e4b6fSAnirudh Venkataramanan /* If this is the last command in a series, set the proper flag. */ 34f31e4b6fSAnirudh Venkataramanan if (last_command) 35f31e4b6fSAnirudh Venkataramanan cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD; 3643c89b16SAnirudh Venkataramanan cmd->module_typeid = cpu_to_le16(module_typeid); 3743c89b16SAnirudh Venkataramanan cmd->offset_low = cpu_to_le16(offset & 0xFFFF); 3843c89b16SAnirudh Venkataramanan cmd->offset_high = (offset >> 16) & 0xFF; 39f31e4b6fSAnirudh Venkataramanan cmd->length = cpu_to_le16(length); 40f31e4b6fSAnirudh Venkataramanan 41f31e4b6fSAnirudh Venkataramanan return ice_aq_send_cmd(hw, &desc, data, length, cd); 42f31e4b6fSAnirudh Venkataramanan } 43f31e4b6fSAnirudh Venkataramanan 44f31e4b6fSAnirudh Venkataramanan /** 45f31e4b6fSAnirudh Venkataramanan * ice_check_sr_access_params - verify params for Shadow RAM R/W operations. 46f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 47f31e4b6fSAnirudh Venkataramanan * @offset: offset in words from module start 48f31e4b6fSAnirudh Venkataramanan * @words: number of words to access 49f31e4b6fSAnirudh Venkataramanan */ 50f31e4b6fSAnirudh Venkataramanan static enum ice_status 51f31e4b6fSAnirudh Venkataramanan ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words) 52f31e4b6fSAnirudh Venkataramanan { 53f31e4b6fSAnirudh Venkataramanan if ((offset + words) > hw->nvm.sr_words) { 54f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_NVM, 55f31e4b6fSAnirudh Venkataramanan "NVM error: offset beyond SR lmt.\n"); 56f31e4b6fSAnirudh Venkataramanan return ICE_ERR_PARAM; 57f31e4b6fSAnirudh Venkataramanan } 58f31e4b6fSAnirudh Venkataramanan 59f31e4b6fSAnirudh Venkataramanan if (words > ICE_SR_SECTOR_SIZE_IN_WORDS) { 60f31e4b6fSAnirudh Venkataramanan /* We can access only up to 4KB (one sector), in one AQ write */ 61f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_NVM, 62f31e4b6fSAnirudh Venkataramanan "NVM error: tried to access %d words, limit is %d.\n", 63f31e4b6fSAnirudh Venkataramanan words, ICE_SR_SECTOR_SIZE_IN_WORDS); 64f31e4b6fSAnirudh Venkataramanan return ICE_ERR_PARAM; 65f31e4b6fSAnirudh Venkataramanan } 66f31e4b6fSAnirudh Venkataramanan 67f31e4b6fSAnirudh Venkataramanan if (((offset + (words - 1)) / ICE_SR_SECTOR_SIZE_IN_WORDS) != 68f31e4b6fSAnirudh Venkataramanan (offset / ICE_SR_SECTOR_SIZE_IN_WORDS)) { 69f31e4b6fSAnirudh Venkataramanan /* A single access cannot spread over two sectors */ 70f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_NVM, 71f31e4b6fSAnirudh Venkataramanan "NVM error: cannot spread over two sectors.\n"); 72f31e4b6fSAnirudh Venkataramanan return ICE_ERR_PARAM; 73f31e4b6fSAnirudh Venkataramanan } 74f31e4b6fSAnirudh Venkataramanan 75f31e4b6fSAnirudh Venkataramanan return 0; 76f31e4b6fSAnirudh Venkataramanan } 77f31e4b6fSAnirudh Venkataramanan 78f31e4b6fSAnirudh Venkataramanan /** 79f31e4b6fSAnirudh Venkataramanan * ice_read_sr_aq - Read Shadow RAM. 80f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 81f31e4b6fSAnirudh Venkataramanan * @offset: offset in words from module start 82f31e4b6fSAnirudh Venkataramanan * @words: number of words to read 83f31e4b6fSAnirudh Venkataramanan * @data: buffer for words reads from Shadow RAM 84f31e4b6fSAnirudh Venkataramanan * @last_command: tells the AdminQ that this is the last command 85f31e4b6fSAnirudh Venkataramanan * 86f31e4b6fSAnirudh Venkataramanan * Reads 16-bit word buffers from the Shadow RAM using the admin command. 87f31e4b6fSAnirudh Venkataramanan */ 88f31e4b6fSAnirudh Venkataramanan static enum ice_status 89f31e4b6fSAnirudh Venkataramanan ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, u16 *data, 90f31e4b6fSAnirudh Venkataramanan bool last_command) 91f31e4b6fSAnirudh Venkataramanan { 92f31e4b6fSAnirudh Venkataramanan enum ice_status status; 93f31e4b6fSAnirudh Venkataramanan 94f31e4b6fSAnirudh Venkataramanan status = ice_check_sr_access_params(hw, offset, words); 95f31e4b6fSAnirudh Venkataramanan 96f31e4b6fSAnirudh Venkataramanan /* values in "offset" and "words" parameters are sized as words 97f31e4b6fSAnirudh Venkataramanan * (16 bits) but ice_aq_read_nvm expects these values in bytes. 98f31e4b6fSAnirudh Venkataramanan * So do this conversion while calling ice_aq_read_nvm. 99f31e4b6fSAnirudh Venkataramanan */ 100f31e4b6fSAnirudh Venkataramanan if (!status) 101f31e4b6fSAnirudh Venkataramanan status = ice_aq_read_nvm(hw, 0, 2 * offset, 2 * words, data, 102f31e4b6fSAnirudh Venkataramanan last_command, NULL); 103f31e4b6fSAnirudh Venkataramanan 104f31e4b6fSAnirudh Venkataramanan return status; 105f31e4b6fSAnirudh Venkataramanan } 106f31e4b6fSAnirudh Venkataramanan 107f31e4b6fSAnirudh Venkataramanan /** 108f31e4b6fSAnirudh Venkataramanan * ice_read_sr_word_aq - Reads Shadow RAM via AQ 109f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 110f31e4b6fSAnirudh Venkataramanan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 111f31e4b6fSAnirudh Venkataramanan * @data: word read from the Shadow RAM 112f31e4b6fSAnirudh Venkataramanan * 113f31e4b6fSAnirudh Venkataramanan * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_aq method. 114f31e4b6fSAnirudh Venkataramanan */ 115f31e4b6fSAnirudh Venkataramanan static enum ice_status 116f31e4b6fSAnirudh Venkataramanan ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data) 117f31e4b6fSAnirudh Venkataramanan { 118f31e4b6fSAnirudh Venkataramanan enum ice_status status; 119f31e4b6fSAnirudh Venkataramanan 120f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_aq(hw, offset, 1, data, true); 121f31e4b6fSAnirudh Venkataramanan if (!status) 122feee3cb3SBruce Allan *data = le16_to_cpu(*(__force __le16 *)data); 123f31e4b6fSAnirudh Venkataramanan 124f31e4b6fSAnirudh Venkataramanan return status; 125f31e4b6fSAnirudh Venkataramanan } 126f31e4b6fSAnirudh Venkataramanan 127f31e4b6fSAnirudh Venkataramanan /** 1284c98ab55SBruce Allan * ice_read_sr_buf_aq - Reads Shadow RAM buf via AQ 1294c98ab55SBruce Allan * @hw: pointer to the HW structure 1304c98ab55SBruce Allan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 1314c98ab55SBruce Allan * @words: (in) number of words to read; (out) number of words actually read 1324c98ab55SBruce Allan * @data: words read from the Shadow RAM 1334c98ab55SBruce Allan * 1344c98ab55SBruce Allan * Reads 16 bit words (data buf) from the SR using the ice_read_sr_aq 1354c98ab55SBruce Allan * method. Ownership of the NVM is taken before reading the buffer and later 1364c98ab55SBruce Allan * released. 1374c98ab55SBruce Allan */ 1384c98ab55SBruce Allan static enum ice_status 1394c98ab55SBruce Allan ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data) 1404c98ab55SBruce Allan { 1414c98ab55SBruce Allan enum ice_status status; 1424c98ab55SBruce Allan bool last_cmd = false; 1434c98ab55SBruce Allan u16 words_read = 0; 1444c98ab55SBruce Allan u16 i = 0; 1454c98ab55SBruce Allan 1464c98ab55SBruce Allan do { 1474c98ab55SBruce Allan u16 read_size, off_w; 1484c98ab55SBruce Allan 1494c98ab55SBruce Allan /* Calculate number of bytes we should read in this step. 1504c98ab55SBruce Allan * It's not allowed to read more than one page at a time or 1514c98ab55SBruce Allan * to cross page boundaries. 1524c98ab55SBruce Allan */ 1534c98ab55SBruce Allan off_w = offset % ICE_SR_SECTOR_SIZE_IN_WORDS; 1544c98ab55SBruce Allan read_size = off_w ? 15532a64994SBruce Allan min_t(u16, *words, 15632a64994SBruce Allan (ICE_SR_SECTOR_SIZE_IN_WORDS - off_w)) : 15732a64994SBruce Allan min_t(u16, (*words - words_read), 15832a64994SBruce Allan ICE_SR_SECTOR_SIZE_IN_WORDS); 1594c98ab55SBruce Allan 1604c98ab55SBruce Allan /* Check if this is last command, if so set proper flag */ 1614c98ab55SBruce Allan if ((words_read + read_size) >= *words) 1624c98ab55SBruce Allan last_cmd = true; 1634c98ab55SBruce Allan 1644c98ab55SBruce Allan status = ice_read_sr_aq(hw, offset, read_size, 1654c98ab55SBruce Allan data + words_read, last_cmd); 1664c98ab55SBruce Allan if (status) 1674c98ab55SBruce Allan goto read_nvm_buf_aq_exit; 1684c98ab55SBruce Allan 1694c98ab55SBruce Allan /* Increment counter for words already read and move offset to 1704c98ab55SBruce Allan * new read location 1714c98ab55SBruce Allan */ 1724c98ab55SBruce Allan words_read += read_size; 1734c98ab55SBruce Allan offset += read_size; 1744c98ab55SBruce Allan } while (words_read < *words); 1754c98ab55SBruce Allan 1764c98ab55SBruce Allan for (i = 0; i < *words; i++) 177feee3cb3SBruce Allan data[i] = le16_to_cpu(((__force __le16 *)data)[i]); 1784c98ab55SBruce Allan 1794c98ab55SBruce Allan read_nvm_buf_aq_exit: 1804c98ab55SBruce Allan *words = words_read; 1814c98ab55SBruce Allan return status; 1824c98ab55SBruce Allan } 1834c98ab55SBruce Allan 1844c98ab55SBruce Allan /** 185f31e4b6fSAnirudh Venkataramanan * ice_acquire_nvm - Generic request for acquiring the NVM ownership 186f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 187f31e4b6fSAnirudh Venkataramanan * @access: NVM access type (read or write) 188f31e4b6fSAnirudh Venkataramanan * 189f31e4b6fSAnirudh Venkataramanan * This function will request NVM ownership. 190f31e4b6fSAnirudh Venkataramanan */ 1913968540bSAnirudh Venkataramanan static enum ice_status 1923968540bSAnirudh Venkataramanan ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access) 193f31e4b6fSAnirudh Venkataramanan { 194f31e4b6fSAnirudh Venkataramanan if (hw->nvm.blank_nvm_mode) 195f31e4b6fSAnirudh Venkataramanan return 0; 196f31e4b6fSAnirudh Venkataramanan 197ff2b1321SDan Nowlin return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT); 198f31e4b6fSAnirudh Venkataramanan } 199f31e4b6fSAnirudh Venkataramanan 200f31e4b6fSAnirudh Venkataramanan /** 201f31e4b6fSAnirudh Venkataramanan * ice_release_nvm - Generic request for releasing the NVM ownership 202f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 203f31e4b6fSAnirudh Venkataramanan * 204f31e4b6fSAnirudh Venkataramanan * This function will release NVM ownership. 205f31e4b6fSAnirudh Venkataramanan */ 206f31e4b6fSAnirudh Venkataramanan static void ice_release_nvm(struct ice_hw *hw) 207f31e4b6fSAnirudh Venkataramanan { 208f31e4b6fSAnirudh Venkataramanan if (hw->nvm.blank_nvm_mode) 209f31e4b6fSAnirudh Venkataramanan return; 210f31e4b6fSAnirudh Venkataramanan 211f31e4b6fSAnirudh Venkataramanan ice_release_res(hw, ICE_NVM_RES_ID); 212f31e4b6fSAnirudh Venkataramanan } 213f31e4b6fSAnirudh Venkataramanan 214f31e4b6fSAnirudh Venkataramanan /** 215f31e4b6fSAnirudh Venkataramanan * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary 216f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 217f31e4b6fSAnirudh Venkataramanan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 218f31e4b6fSAnirudh Venkataramanan * @data: word read from the Shadow RAM 219f31e4b6fSAnirudh Venkataramanan * 220f31e4b6fSAnirudh Venkataramanan * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq. 221f31e4b6fSAnirudh Venkataramanan */ 222031f2147SMd Fahad Iqbal Polash enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data) 223f31e4b6fSAnirudh Venkataramanan { 224f31e4b6fSAnirudh Venkataramanan enum ice_status status; 225f31e4b6fSAnirudh Venkataramanan 226f31e4b6fSAnirudh Venkataramanan status = ice_acquire_nvm(hw, ICE_RES_READ); 227f31e4b6fSAnirudh Venkataramanan if (!status) { 228f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_word_aq(hw, offset, data); 229f31e4b6fSAnirudh Venkataramanan ice_release_nvm(hw); 230f31e4b6fSAnirudh Venkataramanan } 231f31e4b6fSAnirudh Venkataramanan 232f31e4b6fSAnirudh Venkataramanan return status; 233f31e4b6fSAnirudh Venkataramanan } 234f31e4b6fSAnirudh Venkataramanan 235f31e4b6fSAnirudh Venkataramanan /** 236f31e4b6fSAnirudh Venkataramanan * ice_init_nvm - initializes NVM setting 237f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 238f31e4b6fSAnirudh Venkataramanan * 239f31e4b6fSAnirudh Venkataramanan * This function reads and populates NVM settings such as Shadow RAM size, 240f31e4b6fSAnirudh Venkataramanan * max_timeout, and blank_nvm_mode 241f31e4b6fSAnirudh Venkataramanan */ 242f31e4b6fSAnirudh Venkataramanan enum ice_status ice_init_nvm(struct ice_hw *hw) 243f31e4b6fSAnirudh Venkataramanan { 244031f2147SMd Fahad Iqbal Polash u16 oem_hi, oem_lo, boot_cfg_tlv, boot_cfg_tlv_len; 245f31e4b6fSAnirudh Venkataramanan struct ice_nvm_info *nvm = &hw->nvm; 246f31e4b6fSAnirudh Venkataramanan u16 eetrack_lo, eetrack_hi; 247031f2147SMd Fahad Iqbal Polash enum ice_status status; 248f31e4b6fSAnirudh Venkataramanan u32 fla, gens_stat; 249f31e4b6fSAnirudh Venkataramanan u8 sr_size; 250f31e4b6fSAnirudh Venkataramanan 251f9867df6SAnirudh Venkataramanan /* The SR size is stored regardless of the NVM programming mode 252f31e4b6fSAnirudh Venkataramanan * as the blank mode may be used in the factory line. 253f31e4b6fSAnirudh Venkataramanan */ 254f31e4b6fSAnirudh Venkataramanan gens_stat = rd32(hw, GLNVM_GENS); 255f31e4b6fSAnirudh Venkataramanan sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S; 256f31e4b6fSAnirudh Venkataramanan 257f31e4b6fSAnirudh Venkataramanan /* Switching to words (sr_size contains power of 2) */ 258f31e4b6fSAnirudh Venkataramanan nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB; 259f31e4b6fSAnirudh Venkataramanan 260f31e4b6fSAnirudh Venkataramanan /* Check if we are in the normal or blank NVM programming mode */ 261f31e4b6fSAnirudh Venkataramanan fla = rd32(hw, GLNVM_FLA); 262f31e4b6fSAnirudh Venkataramanan if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */ 263f31e4b6fSAnirudh Venkataramanan nvm->blank_nvm_mode = false; 264031f2147SMd Fahad Iqbal Polash } else { 265031f2147SMd Fahad Iqbal Polash /* Blank programming mode */ 266f31e4b6fSAnirudh Venkataramanan nvm->blank_nvm_mode = true; 267f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_NVM, 268f31e4b6fSAnirudh Venkataramanan "NVM init error: unsupported blank mode.\n"); 269031f2147SMd Fahad Iqbal Polash return ICE_ERR_NVM_BLANK_MODE; 270f31e4b6fSAnirudh Venkataramanan } 271f31e4b6fSAnirudh Venkataramanan 272031f2147SMd Fahad Iqbal Polash status = ice_read_sr_word(hw, ICE_SR_NVM_DEV_STARTER_VER, &nvm->ver); 273f31e4b6fSAnirudh Venkataramanan if (status) { 274f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 275f31e4b6fSAnirudh Venkataramanan "Failed to read DEV starter version.\n"); 276f31e4b6fSAnirudh Venkataramanan return status; 277f31e4b6fSAnirudh Venkataramanan } 278f31e4b6fSAnirudh Venkataramanan 279f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_LO, &eetrack_lo); 280f31e4b6fSAnirudh Venkataramanan if (status) { 281f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK lo.\n"); 282f31e4b6fSAnirudh Venkataramanan return status; 283f31e4b6fSAnirudh Venkataramanan } 284f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_HI, &eetrack_hi); 285f31e4b6fSAnirudh Venkataramanan if (status) { 286f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK hi.\n"); 287f31e4b6fSAnirudh Venkataramanan return status; 288f31e4b6fSAnirudh Venkataramanan } 289f31e4b6fSAnirudh Venkataramanan 290031f2147SMd Fahad Iqbal Polash nvm->eetrack = (eetrack_hi << 16) | eetrack_lo; 291f31e4b6fSAnirudh Venkataramanan 292031f2147SMd Fahad Iqbal Polash status = ice_get_pfa_module_tlv(hw, &boot_cfg_tlv, &boot_cfg_tlv_len, 293031f2147SMd Fahad Iqbal Polash ICE_SR_BOOT_CFG_PTR); 294031f2147SMd Fahad Iqbal Polash if (status) { 295031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, 296031f2147SMd Fahad Iqbal Polash "Failed to read Boot Configuration Block TLV.\n"); 297f31e4b6fSAnirudh Venkataramanan return status; 298f31e4b6fSAnirudh Venkataramanan } 2994c98ab55SBruce Allan 300031f2147SMd Fahad Iqbal Polash /* Boot Configuration Block must have length at least 2 words 301031f2147SMd Fahad Iqbal Polash * (Combo Image Version High and Combo Image Version Low) 302031f2147SMd Fahad Iqbal Polash */ 303031f2147SMd Fahad Iqbal Polash if (boot_cfg_tlv_len < 2) { 304031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, 305031f2147SMd Fahad Iqbal Polash "Invalid Boot Configuration Block TLV size.\n"); 306031f2147SMd Fahad Iqbal Polash return ICE_ERR_INVAL_SIZE; 307031f2147SMd Fahad Iqbal Polash } 308031f2147SMd Fahad Iqbal Polash 309031f2147SMd Fahad Iqbal Polash status = ice_read_sr_word(hw, (boot_cfg_tlv + ICE_NVM_OEM_VER_OFF), 310031f2147SMd Fahad Iqbal Polash &oem_hi); 311031f2147SMd Fahad Iqbal Polash if (status) { 312031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, "Failed to read OEM_VER hi.\n"); 313031f2147SMd Fahad Iqbal Polash return status; 314031f2147SMd Fahad Iqbal Polash } 315031f2147SMd Fahad Iqbal Polash 316031f2147SMd Fahad Iqbal Polash status = ice_read_sr_word(hw, (boot_cfg_tlv + ICE_NVM_OEM_VER_OFF + 1), 317031f2147SMd Fahad Iqbal Polash &oem_lo); 318031f2147SMd Fahad Iqbal Polash if (status) { 319031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, "Failed to read OEM_VER lo.\n"); 320031f2147SMd Fahad Iqbal Polash return status; 321031f2147SMd Fahad Iqbal Polash } 322031f2147SMd Fahad Iqbal Polash 323031f2147SMd Fahad Iqbal Polash nvm->oem_ver = ((u32)oem_hi << 16) | oem_lo; 324031f2147SMd Fahad Iqbal Polash 325031f2147SMd Fahad Iqbal Polash return 0; 326031f2147SMd Fahad Iqbal Polash } 327031f2147SMd Fahad Iqbal Polash 3284c98ab55SBruce Allan /** 3294c98ab55SBruce Allan * ice_read_sr_buf - Reads Shadow RAM buf and acquire lock if necessary 3304c98ab55SBruce Allan * @hw: pointer to the HW structure 3314c98ab55SBruce Allan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 3324c98ab55SBruce Allan * @words: (in) number of words to read; (out) number of words actually read 3334c98ab55SBruce Allan * @data: words read from the Shadow RAM 3344c98ab55SBruce Allan * 3354c98ab55SBruce Allan * Reads 16 bit words (data buf) from the SR using the ice_read_nvm_buf_aq 3364c98ab55SBruce Allan * method. The buf read is preceded by the NVM ownership take 3374c98ab55SBruce Allan * and followed by the release. 3384c98ab55SBruce Allan */ 3394c98ab55SBruce Allan enum ice_status 3404c98ab55SBruce Allan ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data) 3414c98ab55SBruce Allan { 3424c98ab55SBruce Allan enum ice_status status; 3434c98ab55SBruce Allan 3444c98ab55SBruce Allan status = ice_acquire_nvm(hw, ICE_RES_READ); 3454c98ab55SBruce Allan if (!status) { 3464c98ab55SBruce Allan status = ice_read_sr_buf_aq(hw, offset, words, data); 3474c98ab55SBruce Allan ice_release_nvm(hw); 3484c98ab55SBruce Allan } 3494c98ab55SBruce Allan 3504c98ab55SBruce Allan return status; 3514c98ab55SBruce Allan } 3520e674aebSAnirudh Venkataramanan 3530e674aebSAnirudh Venkataramanan /** 3540e674aebSAnirudh Venkataramanan * ice_nvm_validate_checksum 3550e674aebSAnirudh Venkataramanan * @hw: pointer to the HW struct 3560e674aebSAnirudh Venkataramanan * 3570e674aebSAnirudh Venkataramanan * Verify NVM PFA checksum validity (0x0706) 3580e674aebSAnirudh Venkataramanan */ 3590e674aebSAnirudh Venkataramanan enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw) 3600e674aebSAnirudh Venkataramanan { 3610e674aebSAnirudh Venkataramanan struct ice_aqc_nvm_checksum *cmd; 3620e674aebSAnirudh Venkataramanan struct ice_aq_desc desc; 3630e674aebSAnirudh Venkataramanan enum ice_status status; 3640e674aebSAnirudh Venkataramanan 3650e674aebSAnirudh Venkataramanan status = ice_acquire_nvm(hw, ICE_RES_READ); 3660e674aebSAnirudh Venkataramanan if (status) 3670e674aebSAnirudh Venkataramanan return status; 3680e674aebSAnirudh Venkataramanan 3690e674aebSAnirudh Venkataramanan cmd = &desc.params.nvm_checksum; 3700e674aebSAnirudh Venkataramanan 3710e674aebSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum); 3720e674aebSAnirudh Venkataramanan cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY; 3730e674aebSAnirudh Venkataramanan 3740e674aebSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 3750e674aebSAnirudh Venkataramanan ice_release_nvm(hw); 3760e674aebSAnirudh Venkataramanan 3770e674aebSAnirudh Venkataramanan if (!status) 3780e674aebSAnirudh Venkataramanan if (le16_to_cpu(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT) 3790e674aebSAnirudh Venkataramanan status = ICE_ERR_NVM_CHECKSUM; 3800e674aebSAnirudh Venkataramanan 3810e674aebSAnirudh Venkataramanan return status; 3820e674aebSAnirudh Venkataramanan } 383