ice_nvm.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018, Intel Corporation. */
  3. #include "ice_common.h"
  4. /**
  5. * ice_aq_read_nvm
  6. * @hw: pointer to the hw struct
  7. * @module_typeid: module pointer location in words from the NVM beginning
  8. * @offset: byte offset from the module beginning
  9. * @length: length of the section to be read (in bytes from the offset)
  10. * @data: command buffer (size [bytes] = length)
  11. * @last_command: tells if this is the last command in a series
  12. * @cd: pointer to command details structure or NULL
  13. *
  14. * Read the NVM using the admin queue commands (0x0701)
  15. */
  16. static enum ice_status
  17. ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
  18. void *data, bool last_command, struct ice_sq_cd *cd)
  19. {
  20. struct ice_aq_desc desc;
  21. struct ice_aqc_nvm *cmd;
  22. cmd = &desc.params.nvm;
  23. /* In offset the highest byte must be zeroed. */
  24. if (offset & 0xFF000000)
  25. return ICE_ERR_PARAM;
  26. ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
  27. /* If this is the last command in a series, set the proper flag. */
  28. if (last_command)
  29. cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
  30. cmd->module_typeid = cpu_to_le16(module_typeid);
  31. cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
  32. cmd->offset_high = (offset >> 16) & 0xFF;
  33. cmd->length = cpu_to_le16(length);
  34. return ice_aq_send_cmd(hw, &desc, data, length, cd);
  35. }
  36. /**
  37. * ice_check_sr_access_params - verify params for Shadow RAM R/W operations.
  38. * @hw: pointer to the HW structure
  39. * @offset: offset in words from module start
  40. * @words: number of words to access
  41. */
  42. static enum ice_status
  43. ice_check_sr_access_params(struct ice_hw *hw, u32 offset, u16 words)
  44. {
  45. if ((offset + words) > hw->nvm.sr_words) {
  46. ice_debug(hw, ICE_DBG_NVM,
  47. "NVM error: offset beyond SR lmt.\n");
  48. return ICE_ERR_PARAM;
  49. }
  50. if (words > ICE_SR_SECTOR_SIZE_IN_WORDS) {
  51. /* We can access only up to 4KB (one sector), in one AQ write */
  52. ice_debug(hw, ICE_DBG_NVM,
  53. "NVM error: tried to access %d words, limit is %d.\n",
  54. words, ICE_SR_SECTOR_SIZE_IN_WORDS);
  55. return ICE_ERR_PARAM;
  56. }
  57. if (((offset + (words - 1)) / ICE_SR_SECTOR_SIZE_IN_WORDS) !=
  58. (offset / ICE_SR_SECTOR_SIZE_IN_WORDS)) {
  59. /* A single access cannot spread over two sectors */
  60. ice_debug(hw, ICE_DBG_NVM,
  61. "NVM error: cannot spread over two sectors.\n");
  62. return ICE_ERR_PARAM;
  63. }
  64. return 0;
  65. }
  66. /**
  67. * ice_read_sr_aq - Read Shadow RAM.
  68. * @hw: pointer to the HW structure
  69. * @offset: offset in words from module start
  70. * @words: number of words to read
  71. * @data: buffer for words reads from Shadow RAM
  72. * @last_command: tells the AdminQ that this is the last command
  73. *
  74. * Reads 16-bit word buffers from the Shadow RAM using the admin command.
  75. */
  76. static enum ice_status
  77. ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, u16 *data,
  78. bool last_command)
  79. {
  80. enum ice_status status;
  81. status = ice_check_sr_access_params(hw, offset, words);
  82. /* values in "offset" and "words" parameters are sized as words
  83. * (16 bits) but ice_aq_read_nvm expects these values in bytes.
  84. * So do this conversion while calling ice_aq_read_nvm.
  85. */
  86. if (!status)
  87. status = ice_aq_read_nvm(hw, 0, 2 * offset, 2 * words, data,
  88. last_command, NULL);
  89. return status;
  90. }
  91. /**
  92. * ice_read_sr_word_aq - Reads Shadow RAM via AQ
  93. * @hw: pointer to the HW structure
  94. * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  95. * @data: word read from the Shadow RAM
  96. *
  97. * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_aq method.
  98. */
  99. static enum ice_status
  100. ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
  101. {
  102. enum ice_status status;
  103. status = ice_read_sr_aq(hw, offset, 1, data, true);
  104. if (!status)
  105. *data = le16_to_cpu(*(__le16 *)data);
  106. return status;
  107. }
  108. /**
  109. * ice_acquire_nvm - Generic request for acquiring the NVM ownership
  110. * @hw: pointer to the HW structure
  111. * @access: NVM access type (read or write)
  112. *
  113. * This function will request NVM ownership.
  114. */
  115. static enum ice_status
  116. ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
  117. {
  118. if (hw->nvm.blank_nvm_mode)
  119. return 0;
  120. return ice_acquire_res(hw, ICE_NVM_RES_ID, access);
  121. }
  122. /**
  123. * ice_release_nvm - Generic request for releasing the NVM ownership
  124. * @hw: pointer to the HW structure
  125. *
  126. * This function will release NVM ownership.
  127. */
  128. static void ice_release_nvm(struct ice_hw *hw)
  129. {
  130. if (hw->nvm.blank_nvm_mode)
  131. return;
  132. ice_release_res(hw, ICE_NVM_RES_ID);
  133. }
  134. /**
  135. * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
  136. * @hw: pointer to the HW structure
  137. * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  138. * @data: word read from the Shadow RAM
  139. *
  140. * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
  141. */
  142. static enum ice_status
  143. ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
  144. {
  145. enum ice_status status;
  146. status = ice_acquire_nvm(hw, ICE_RES_READ);
  147. if (!status) {
  148. status = ice_read_sr_word_aq(hw, offset, data);
  149. ice_release_nvm(hw);
  150. }
  151. return status;
  152. }
  153. /**
  154. * ice_init_nvm - initializes NVM setting
  155. * @hw: pointer to the hw struct
  156. *
  157. * This function reads and populates NVM settings such as Shadow RAM size,
  158. * max_timeout, and blank_nvm_mode
  159. */
  160. enum ice_status ice_init_nvm(struct ice_hw *hw)
  161. {
  162. struct ice_nvm_info *nvm = &hw->nvm;
  163. u16 eetrack_lo, eetrack_hi;
  164. enum ice_status status = 0;
  165. u32 fla, gens_stat;
  166. u8 sr_size;
  167. /* The SR size is stored regardless of the nvm programming mode
  168. * as the blank mode may be used in the factory line.
  169. */
  170. gens_stat = rd32(hw, GLNVM_GENS);
  171. sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
  172. /* Switching to words (sr_size contains power of 2) */
  173. nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
  174. /* Check if we are in the normal or blank NVM programming mode */
  175. fla = rd32(hw, GLNVM_FLA);
  176. if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
  177. nvm->blank_nvm_mode = false;
  178. } else { /* Blank programming mode */
  179. nvm->blank_nvm_mode = true;
  180. status = ICE_ERR_NVM_BLANK_MODE;
  181. ice_debug(hw, ICE_DBG_NVM,
  182. "NVM init error: unsupported blank mode.\n");
  183. return status;
  184. }
  185. status = ice_read_sr_word(hw, ICE_SR_NVM_DEV_STARTER_VER, &hw->nvm.ver);
  186. if (status) {
  187. ice_debug(hw, ICE_DBG_INIT,
  188. "Failed to read DEV starter version.\n");
  189. return status;
  190. }
  191. status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
  192. if (status) {
  193. ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK lo.\n");
  194. return status;
  195. }
  196. status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
  197. if (status) {
  198. ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK hi.\n");
  199. return status;
  200. }
  201. hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
  202. return status;
  203. }