ice_nvm.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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
  116. ice_status ice_acquire_nvm(struct ice_hw *hw,
  117. enum ice_aq_res_access_type access)
  118. {
  119. if (hw->nvm.blank_nvm_mode)
  120. return 0;
  121. return ice_acquire_res(hw, ICE_NVM_RES_ID, access);
  122. }
  123. /**
  124. * ice_release_nvm - Generic request for releasing the NVM ownership
  125. * @hw: pointer to the HW structure
  126. *
  127. * This function will release NVM ownership.
  128. */
  129. static void ice_release_nvm(struct ice_hw *hw)
  130. {
  131. if (hw->nvm.blank_nvm_mode)
  132. return;
  133. ice_release_res(hw, ICE_NVM_RES_ID);
  134. }
  135. /**
  136. * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary
  137. * @hw: pointer to the HW structure
  138. * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  139. * @data: word read from the Shadow RAM
  140. *
  141. * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq.
  142. */
  143. static enum ice_status
  144. ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
  145. {
  146. enum ice_status status;
  147. status = ice_acquire_nvm(hw, ICE_RES_READ);
  148. if (!status) {
  149. status = ice_read_sr_word_aq(hw, offset, data);
  150. ice_release_nvm(hw);
  151. }
  152. return status;
  153. }
  154. /**
  155. * ice_init_nvm - initializes NVM setting
  156. * @hw: pointer to the hw struct
  157. *
  158. * This function reads and populates NVM settings such as Shadow RAM size,
  159. * max_timeout, and blank_nvm_mode
  160. */
  161. enum ice_status ice_init_nvm(struct ice_hw *hw)
  162. {
  163. struct ice_nvm_info *nvm = &hw->nvm;
  164. u16 eetrack_lo, eetrack_hi;
  165. enum ice_status status = 0;
  166. u32 fla, gens_stat;
  167. u8 sr_size;
  168. /* The SR size is stored regardless of the nvm programming mode
  169. * as the blank mode may be used in the factory line.
  170. */
  171. gens_stat = rd32(hw, GLNVM_GENS);
  172. sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
  173. /* Switching to words (sr_size contains power of 2) */
  174. nvm->sr_words = BIT(sr_size) * ICE_SR_WORDS_IN_1KB;
  175. /* Check if we are in the normal or blank NVM programming mode */
  176. fla = rd32(hw, GLNVM_FLA);
  177. if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
  178. nvm->blank_nvm_mode = false;
  179. } else { /* Blank programming mode */
  180. nvm->blank_nvm_mode = true;
  181. status = ICE_ERR_NVM_BLANK_MODE;
  182. ice_debug(hw, ICE_DBG_NVM,
  183. "NVM init error: unsupported blank mode.\n");
  184. return status;
  185. }
  186. status = ice_read_sr_word(hw, ICE_SR_NVM_DEV_STARTER_VER, &hw->nvm.ver);
  187. if (status) {
  188. ice_debug(hw, ICE_DBG_INIT,
  189. "Failed to read DEV starter version.\n");
  190. return status;
  191. }
  192. status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_LO, &eetrack_lo);
  193. if (status) {
  194. ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK lo.\n");
  195. return status;
  196. }
  197. status = ice_read_sr_word(hw, ICE_SR_NVM_EETRACK_HI, &eetrack_hi);
  198. if (status) {
  199. ice_debug(hw, ICE_DBG_INIT, "Failed to read EETRACK hi.\n");
  200. return status;
  201. }
  202. hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
  203. return status;
  204. }