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 832efefb56SJacob Keller * @data: storage for the words read from Shadow RAM (Little Endian) 84f31e4b6fSAnirudh Venkataramanan * @last_command: tells the AdminQ that this is the last command 85f31e4b6fSAnirudh Venkataramanan * 862efefb56SJacob Keller * Reads 16-bit Little Endian word buffers from the Shadow RAM using the admin 872efefb56SJacob Keller * command. 88f31e4b6fSAnirudh Venkataramanan */ 89f31e4b6fSAnirudh Venkataramanan static enum ice_status 902efefb56SJacob Keller ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, __le16 *data, 91f31e4b6fSAnirudh Venkataramanan bool last_command) 92f31e4b6fSAnirudh Venkataramanan { 93f31e4b6fSAnirudh Venkataramanan enum ice_status status; 94f31e4b6fSAnirudh Venkataramanan 95f31e4b6fSAnirudh Venkataramanan status = ice_check_sr_access_params(hw, offset, words); 96f31e4b6fSAnirudh Venkataramanan 97f31e4b6fSAnirudh Venkataramanan /* values in "offset" and "words" parameters are sized as words 98f31e4b6fSAnirudh Venkataramanan * (16 bits) but ice_aq_read_nvm expects these values in bytes. 99f31e4b6fSAnirudh Venkataramanan * So do this conversion while calling ice_aq_read_nvm. 100f31e4b6fSAnirudh Venkataramanan */ 101f31e4b6fSAnirudh Venkataramanan if (!status) 102f31e4b6fSAnirudh Venkataramanan status = ice_aq_read_nvm(hw, 0, 2 * offset, 2 * words, data, 103f31e4b6fSAnirudh Venkataramanan last_command, NULL); 104f31e4b6fSAnirudh Venkataramanan 105f31e4b6fSAnirudh Venkataramanan return status; 106f31e4b6fSAnirudh Venkataramanan } 107f31e4b6fSAnirudh Venkataramanan 108f31e4b6fSAnirudh Venkataramanan /** 109f31e4b6fSAnirudh Venkataramanan * ice_read_sr_word_aq - Reads Shadow RAM via AQ 110f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 111f31e4b6fSAnirudh Venkataramanan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 112f31e4b6fSAnirudh Venkataramanan * @data: word read from the Shadow RAM 113f31e4b6fSAnirudh Venkataramanan * 114f31e4b6fSAnirudh Venkataramanan * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_aq method. 115f31e4b6fSAnirudh Venkataramanan */ 116f31e4b6fSAnirudh Venkataramanan static enum ice_status 117f31e4b6fSAnirudh Venkataramanan ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data) 118f31e4b6fSAnirudh Venkataramanan { 119f31e4b6fSAnirudh Venkataramanan enum ice_status status; 1202efefb56SJacob Keller __le16 data_local; 121f31e4b6fSAnirudh Venkataramanan 1222efefb56SJacob Keller status = ice_read_sr_aq(hw, offset, 1, &data_local, true); 123f31e4b6fSAnirudh Venkataramanan if (!status) 1242efefb56SJacob Keller *data = le16_to_cpu(data_local); 125f31e4b6fSAnirudh Venkataramanan 126f31e4b6fSAnirudh Venkataramanan return status; 127f31e4b6fSAnirudh Venkataramanan } 128f31e4b6fSAnirudh Venkataramanan 129f31e4b6fSAnirudh Venkataramanan /** 1304c98ab55SBruce Allan * ice_read_sr_buf_aq - Reads Shadow RAM buf via AQ 1314c98ab55SBruce Allan * @hw: pointer to the HW structure 1324c98ab55SBruce Allan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 1334c98ab55SBruce Allan * @words: (in) number of words to read; (out) number of words actually read 1344c98ab55SBruce Allan * @data: words read from the Shadow RAM 1354c98ab55SBruce Allan * 1364c98ab55SBruce Allan * Reads 16 bit words (data buf) from the SR using the ice_read_sr_aq 1374c98ab55SBruce Allan * method. Ownership of the NVM is taken before reading the buffer and later 1384c98ab55SBruce Allan * released. 1394c98ab55SBruce Allan */ 1404c98ab55SBruce Allan static enum ice_status 1414c98ab55SBruce Allan ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data) 1424c98ab55SBruce Allan { 1434c98ab55SBruce Allan enum ice_status status; 1444c98ab55SBruce Allan bool last_cmd = false; 1454c98ab55SBruce Allan u16 words_read = 0; 1464c98ab55SBruce Allan u16 i = 0; 1474c98ab55SBruce Allan 1484c98ab55SBruce Allan do { 1494c98ab55SBruce Allan u16 read_size, off_w; 1504c98ab55SBruce Allan 1514c98ab55SBruce Allan /* Calculate number of bytes we should read in this step. 1524c98ab55SBruce Allan * It's not allowed to read more than one page at a time or 1534c98ab55SBruce Allan * to cross page boundaries. 1544c98ab55SBruce Allan */ 1554c98ab55SBruce Allan off_w = offset % ICE_SR_SECTOR_SIZE_IN_WORDS; 1564c98ab55SBruce Allan read_size = off_w ? 15732a64994SBruce Allan min_t(u16, *words, 15832a64994SBruce Allan (ICE_SR_SECTOR_SIZE_IN_WORDS - off_w)) : 15932a64994SBruce Allan min_t(u16, (*words - words_read), 16032a64994SBruce Allan ICE_SR_SECTOR_SIZE_IN_WORDS); 1614c98ab55SBruce Allan 1624c98ab55SBruce Allan /* Check if this is last command, if so set proper flag */ 1634c98ab55SBruce Allan if ((words_read + read_size) >= *words) 1644c98ab55SBruce Allan last_cmd = true; 1654c98ab55SBruce Allan 1664c98ab55SBruce Allan status = ice_read_sr_aq(hw, offset, read_size, 1674c98ab55SBruce Allan data + words_read, last_cmd); 1684c98ab55SBruce Allan if (status) 1694c98ab55SBruce Allan goto read_nvm_buf_aq_exit; 1704c98ab55SBruce Allan 1714c98ab55SBruce Allan /* Increment counter for words already read and move offset to 1724c98ab55SBruce Allan * new read location 1734c98ab55SBruce Allan */ 1744c98ab55SBruce Allan words_read += read_size; 1754c98ab55SBruce Allan offset += read_size; 1764c98ab55SBruce Allan } while (words_read < *words); 1774c98ab55SBruce Allan 1784c98ab55SBruce Allan for (i = 0; i < *words; i++) 179feee3cb3SBruce Allan data[i] = le16_to_cpu(((__force __le16 *)data)[i]); 1804c98ab55SBruce Allan 1814c98ab55SBruce Allan read_nvm_buf_aq_exit: 1824c98ab55SBruce Allan *words = words_read; 1834c98ab55SBruce Allan return status; 1844c98ab55SBruce Allan } 1854c98ab55SBruce Allan 1864c98ab55SBruce Allan /** 187f31e4b6fSAnirudh Venkataramanan * ice_acquire_nvm - Generic request for acquiring the NVM ownership 188f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 189f31e4b6fSAnirudh Venkataramanan * @access: NVM access type (read or write) 190f31e4b6fSAnirudh Venkataramanan * 191f31e4b6fSAnirudh Venkataramanan * This function will request NVM ownership. 192f31e4b6fSAnirudh Venkataramanan */ 1933968540bSAnirudh Venkataramanan static enum ice_status 1943968540bSAnirudh Venkataramanan ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access) 195f31e4b6fSAnirudh Venkataramanan { 196f31e4b6fSAnirudh Venkataramanan if (hw->nvm.blank_nvm_mode) 197f31e4b6fSAnirudh Venkataramanan return 0; 198f31e4b6fSAnirudh Venkataramanan 199ff2b1321SDan Nowlin return ice_acquire_res(hw, ICE_NVM_RES_ID, access, ICE_NVM_TIMEOUT); 200f31e4b6fSAnirudh Venkataramanan } 201f31e4b6fSAnirudh Venkataramanan 202f31e4b6fSAnirudh Venkataramanan /** 203f31e4b6fSAnirudh Venkataramanan * ice_release_nvm - Generic request for releasing the NVM ownership 204f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 205f31e4b6fSAnirudh Venkataramanan * 206f31e4b6fSAnirudh Venkataramanan * This function will release NVM ownership. 207f31e4b6fSAnirudh Venkataramanan */ 208f31e4b6fSAnirudh Venkataramanan static void ice_release_nvm(struct ice_hw *hw) 209f31e4b6fSAnirudh Venkataramanan { 210f31e4b6fSAnirudh Venkataramanan if (hw->nvm.blank_nvm_mode) 211f31e4b6fSAnirudh Venkataramanan return; 212f31e4b6fSAnirudh Venkataramanan 213f31e4b6fSAnirudh Venkataramanan ice_release_res(hw, ICE_NVM_RES_ID); 214f31e4b6fSAnirudh Venkataramanan } 215f31e4b6fSAnirudh Venkataramanan 216f31e4b6fSAnirudh Venkataramanan /** 217f31e4b6fSAnirudh Venkataramanan * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary 218f31e4b6fSAnirudh Venkataramanan * @hw: pointer to the HW structure 219f31e4b6fSAnirudh Venkataramanan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 220f31e4b6fSAnirudh Venkataramanan * @data: word read from the Shadow RAM 221f31e4b6fSAnirudh Venkataramanan * 222f31e4b6fSAnirudh Venkataramanan * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq. 223f31e4b6fSAnirudh Venkataramanan */ 224031f2147SMd Fahad Iqbal Polash enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data) 225f31e4b6fSAnirudh Venkataramanan { 226f31e4b6fSAnirudh Venkataramanan enum ice_status status; 227f31e4b6fSAnirudh Venkataramanan 228f31e4b6fSAnirudh Venkataramanan status = ice_acquire_nvm(hw, ICE_RES_READ); 229f31e4b6fSAnirudh Venkataramanan if (!status) { 230f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_word_aq(hw, offset, data); 231f31e4b6fSAnirudh Venkataramanan ice_release_nvm(hw); 232f31e4b6fSAnirudh Venkataramanan } 233f31e4b6fSAnirudh Venkataramanan 234f31e4b6fSAnirudh Venkataramanan return status; 235f31e4b6fSAnirudh Venkataramanan } 236f31e4b6fSAnirudh Venkataramanan 237f31e4b6fSAnirudh Venkataramanan /** 238f31e4b6fSAnirudh Venkataramanan * ice_init_nvm - initializes NVM setting 239f9867df6SAnirudh Venkataramanan * @hw: pointer to the HW struct 240f31e4b6fSAnirudh Venkataramanan * 241f31e4b6fSAnirudh Venkataramanan * This function reads and populates NVM settings such as Shadow RAM size, 242f31e4b6fSAnirudh Venkataramanan * max_timeout, and blank_nvm_mode 243f31e4b6fSAnirudh Venkataramanan */ 244f31e4b6fSAnirudh Venkataramanan enum ice_status ice_init_nvm(struct ice_hw *hw) 245f31e4b6fSAnirudh Venkataramanan { 246031f2147SMd Fahad Iqbal Polash u16 oem_hi, oem_lo, boot_cfg_tlv, boot_cfg_tlv_len; 247f31e4b6fSAnirudh Venkataramanan struct ice_nvm_info *nvm = &hw->nvm; 248f31e4b6fSAnirudh Venkataramanan u16 eetrack_lo, eetrack_hi; 249031f2147SMd Fahad Iqbal Polash enum ice_status status; 250f31e4b6fSAnirudh Venkataramanan u32 fla, gens_stat; 251f31e4b6fSAnirudh Venkataramanan u8 sr_size; 252f31e4b6fSAnirudh Venkataramanan 253f9867df6SAnirudh Venkataramanan /* The SR size is stored regardless of the NVM programming mode 254f31e4b6fSAnirudh Venkataramanan * as the blank mode may be used in the factory line. 255f31e4b6fSAnirudh Venkataramanan */ 256f31e4b6fSAnirudh Venkataramanan gens_stat = rd32(hw, GLNVM_GENS); 257f31e4b6fSAnirudh Venkataramanan sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S; 258f31e4b6fSAnirudh Venkataramanan 259f31e4b6fSAnirudh Venkataramanan /* Switching to words (sr_size contains power of 2) */ 260f31e4b6fSAnirudh Venkataramanan nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB; 261f31e4b6fSAnirudh Venkataramanan 262f31e4b6fSAnirudh Venkataramanan /* Check if we are in the normal or blank NVM programming mode */ 263f31e4b6fSAnirudh Venkataramanan fla = rd32(hw, GLNVM_FLA); 264f31e4b6fSAnirudh Venkataramanan if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */ 265f31e4b6fSAnirudh Venkataramanan nvm->blank_nvm_mode = false; 266031f2147SMd Fahad Iqbal Polash } else { 267031f2147SMd Fahad Iqbal Polash /* Blank programming mode */ 268f31e4b6fSAnirudh Venkataramanan nvm->blank_nvm_mode = true; 269f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_NVM, 270f31e4b6fSAnirudh Venkataramanan "NVM init error: unsupported blank mode.\n"); 271031f2147SMd Fahad Iqbal Polash return ICE_ERR_NVM_BLANK_MODE; 272f31e4b6fSAnirudh Venkataramanan } 273f31e4b6fSAnirudh Venkataramanan 274031f2147SMd Fahad Iqbal Polash status = ice_read_sr_word(hw, ICE_SR_NVM_DEV_STARTER_VER, &nvm->ver); 275f31e4b6fSAnirudh Venkataramanan if (status) { 276f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, 277f31e4b6fSAnirudh Venkataramanan "Failed to read DEV starter version.\n"); 278f31e4b6fSAnirudh Venkataramanan return status; 279f31e4b6fSAnirudh Venkataramanan } 280f31e4b6fSAnirudh Venkataramanan 281f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_LO, &eetrack_lo); 282f31e4b6fSAnirudh Venkataramanan if (status) { 283f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK lo.\n"); 284f31e4b6fSAnirudh Venkataramanan return status; 285f31e4b6fSAnirudh Venkataramanan } 286f31e4b6fSAnirudh Venkataramanan status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_HI, &eetrack_hi); 287f31e4b6fSAnirudh Venkataramanan if (status) { 288f31e4b6fSAnirudh Venkataramanan ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK hi.\n"); 289f31e4b6fSAnirudh Venkataramanan return status; 290f31e4b6fSAnirudh Venkataramanan } 291f31e4b6fSAnirudh Venkataramanan 292031f2147SMd Fahad Iqbal Polash nvm->eetrack = (eetrack_hi << 16) | eetrack_lo; 293f31e4b6fSAnirudh Venkataramanan 294e36aeec0SBruce Allan switch (hw->device_id) { 2955d9e618cSJacob Keller /* the following devices do not have boot_cfg_tlv yet */ 296e36aeec0SBruce Allan case ICE_DEV_ID_E823C_BACKPLANE: 297e36aeec0SBruce Allan case ICE_DEV_ID_E823C_QSFP: 298e36aeec0SBruce Allan case ICE_DEV_ID_E823C_SFP: 299e36aeec0SBruce Allan case ICE_DEV_ID_E823C_10G_BASE_T: 300e36aeec0SBruce Allan case ICE_DEV_ID_E823C_SGMII: 301e36aeec0SBruce Allan case ICE_DEV_ID_E822C_BACKPLANE: 302e36aeec0SBruce Allan case ICE_DEV_ID_E822C_QSFP: 303e36aeec0SBruce Allan case ICE_DEV_ID_E822C_10G_BASE_T: 304e36aeec0SBruce Allan case ICE_DEV_ID_E822C_SGMII: 305e36aeec0SBruce Allan case ICE_DEV_ID_E822C_SFP: 3062fbfa966SBruce Allan case ICE_DEV_ID_E822L_BACKPLANE: 307e36aeec0SBruce Allan case ICE_DEV_ID_E822L_SFP: 308e36aeec0SBruce Allan case ICE_DEV_ID_E822L_10G_BASE_T: 309e36aeec0SBruce Allan case ICE_DEV_ID_E822L_SGMII: 310e36aeec0SBruce Allan case ICE_DEV_ID_E823L_BACKPLANE: 311e36aeec0SBruce Allan case ICE_DEV_ID_E823L_SFP: 312e36aeec0SBruce Allan case ICE_DEV_ID_E823L_10G_BASE_T: 313e36aeec0SBruce Allan case ICE_DEV_ID_E823L_1GBE: 314e36aeec0SBruce Allan case ICE_DEV_ID_E823L_QSFP: 3155d9e618cSJacob Keller return status; 316e36aeec0SBruce Allan default: 317e36aeec0SBruce Allan break; 318e36aeec0SBruce Allan } 3195d9e618cSJacob Keller 320031f2147SMd Fahad Iqbal Polash status = ice_get_pfa_module_tlv(hw, &boot_cfg_tlv, &boot_cfg_tlv_len, 321031f2147SMd Fahad Iqbal Polash ICE_SR_BOOT_CFG_PTR); 322031f2147SMd Fahad Iqbal Polash if (status) { 323031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, 324031f2147SMd Fahad Iqbal Polash "Failed to read Boot Configuration Block TLV.\n"); 325f31e4b6fSAnirudh Venkataramanan return status; 326f31e4b6fSAnirudh Venkataramanan } 3274c98ab55SBruce Allan 328031f2147SMd Fahad Iqbal Polash /* Boot Configuration Block must have length at least 2 words 329031f2147SMd Fahad Iqbal Polash * (Combo Image Version High and Combo Image Version Low) 330031f2147SMd Fahad Iqbal Polash */ 331031f2147SMd Fahad Iqbal Polash if (boot_cfg_tlv_len < 2) { 332031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, 333031f2147SMd Fahad Iqbal Polash "Invalid Boot Configuration Block TLV size.\n"); 334031f2147SMd Fahad Iqbal Polash return ICE_ERR_INVAL_SIZE; 335031f2147SMd Fahad Iqbal Polash } 336031f2147SMd Fahad Iqbal Polash 337031f2147SMd Fahad Iqbal Polash status = ice_read_sr_word(hw, (boot_cfg_tlv + ICE_NVM_OEM_VER_OFF), 338031f2147SMd Fahad Iqbal Polash &oem_hi); 339031f2147SMd Fahad Iqbal Polash if (status) { 340031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, "Failed to read OEM_VER hi.\n"); 341031f2147SMd Fahad Iqbal Polash return status; 342031f2147SMd Fahad Iqbal Polash } 343031f2147SMd Fahad Iqbal Polash 344031f2147SMd Fahad Iqbal Polash status = ice_read_sr_word(hw, (boot_cfg_tlv + ICE_NVM_OEM_VER_OFF + 1), 345031f2147SMd Fahad Iqbal Polash &oem_lo); 346031f2147SMd Fahad Iqbal Polash if (status) { 347031f2147SMd Fahad Iqbal Polash ice_debug(hw, ICE_DBG_INIT, "Failed to read OEM_VER lo.\n"); 348031f2147SMd Fahad Iqbal Polash return status; 349031f2147SMd Fahad Iqbal Polash } 350031f2147SMd Fahad Iqbal Polash 351031f2147SMd Fahad Iqbal Polash nvm->oem_ver = ((u32)oem_hi << 16) | oem_lo; 352031f2147SMd Fahad Iqbal Polash 353031f2147SMd Fahad Iqbal Polash return 0; 354031f2147SMd Fahad Iqbal Polash } 355031f2147SMd Fahad Iqbal Polash 3564c98ab55SBruce Allan /** 3574c98ab55SBruce Allan * ice_read_sr_buf - Reads Shadow RAM buf and acquire lock if necessary 3584c98ab55SBruce Allan * @hw: pointer to the HW structure 3594c98ab55SBruce Allan * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 3604c98ab55SBruce Allan * @words: (in) number of words to read; (out) number of words actually read 3614c98ab55SBruce Allan * @data: words read from the Shadow RAM 3624c98ab55SBruce Allan * 3634c98ab55SBruce Allan * Reads 16 bit words (data buf) from the SR using the ice_read_nvm_buf_aq 3644c98ab55SBruce Allan * method. The buf read is preceded by the NVM ownership take 3654c98ab55SBruce Allan * and followed by the release. 3664c98ab55SBruce Allan */ 3674c98ab55SBruce Allan enum ice_status 3684c98ab55SBruce Allan ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data) 3694c98ab55SBruce Allan { 3704c98ab55SBruce Allan enum ice_status status; 3714c98ab55SBruce Allan 3724c98ab55SBruce Allan status = ice_acquire_nvm(hw, ICE_RES_READ); 3734c98ab55SBruce Allan if (!status) { 3744c98ab55SBruce Allan status = ice_read_sr_buf_aq(hw, offset, words, data); 3754c98ab55SBruce Allan ice_release_nvm(hw); 3764c98ab55SBruce Allan } 3774c98ab55SBruce Allan 3784c98ab55SBruce Allan return status; 3794c98ab55SBruce Allan } 3800e674aebSAnirudh Venkataramanan 3810e674aebSAnirudh Venkataramanan /** 3820e674aebSAnirudh Venkataramanan * ice_nvm_validate_checksum 3830e674aebSAnirudh Venkataramanan * @hw: pointer to the HW struct 3840e674aebSAnirudh Venkataramanan * 3850e674aebSAnirudh Venkataramanan * Verify NVM PFA checksum validity (0x0706) 3860e674aebSAnirudh Venkataramanan */ 3870e674aebSAnirudh Venkataramanan enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw) 3880e674aebSAnirudh Venkataramanan { 3890e674aebSAnirudh Venkataramanan struct ice_aqc_nvm_checksum *cmd; 3900e674aebSAnirudh Venkataramanan struct ice_aq_desc desc; 3910e674aebSAnirudh Venkataramanan enum ice_status status; 3920e674aebSAnirudh Venkataramanan 3930e674aebSAnirudh Venkataramanan status = ice_acquire_nvm(hw, ICE_RES_READ); 3940e674aebSAnirudh Venkataramanan if (status) 3950e674aebSAnirudh Venkataramanan return status; 3960e674aebSAnirudh Venkataramanan 3970e674aebSAnirudh Venkataramanan cmd = &desc.params.nvm_checksum; 3980e674aebSAnirudh Venkataramanan 3990e674aebSAnirudh Venkataramanan ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_checksum); 4000e674aebSAnirudh Venkataramanan cmd->flags = ICE_AQC_NVM_CHECKSUM_VERIFY; 4010e674aebSAnirudh Venkataramanan 4020e674aebSAnirudh Venkataramanan status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 4030e674aebSAnirudh Venkataramanan ice_release_nvm(hw); 4040e674aebSAnirudh Venkataramanan 4050e674aebSAnirudh Venkataramanan if (!status) 4060e674aebSAnirudh Venkataramanan if (le16_to_cpu(cmd->checksum) != ICE_AQC_NVM_CHECKSUM_CORRECT) 4070e674aebSAnirudh Venkataramanan status = ICE_ERR_NVM_CHECKSUM; 4080e674aebSAnirudh Venkataramanan 4090e674aebSAnirudh Venkataramanan return status; 4100e674aebSAnirudh Venkataramanan } 411