igc_nvm.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018 Intel Corporation */
  3. #include "igc_mac.h"
  4. #include "igc_nvm.h"
  5. /**
  6. * igc_poll_eerd_eewr_done - Poll for EEPROM read/write completion
  7. * @hw: pointer to the HW structure
  8. * @ee_reg: EEPROM flag for polling
  9. *
  10. * Polls the EEPROM status bit for either read or write completion based
  11. * upon the value of 'ee_reg'.
  12. */
  13. static s32 igc_poll_eerd_eewr_done(struct igc_hw *hw, int ee_reg)
  14. {
  15. s32 ret_val = -IGC_ERR_NVM;
  16. u32 attempts = 100000;
  17. u32 i, reg = 0;
  18. for (i = 0; i < attempts; i++) {
  19. if (ee_reg == IGC_NVM_POLL_READ)
  20. reg = rd32(IGC_EERD);
  21. else
  22. reg = rd32(IGC_EEWR);
  23. if (reg & IGC_NVM_RW_REG_DONE) {
  24. ret_val = 0;
  25. break;
  26. }
  27. udelay(5);
  28. }
  29. return ret_val;
  30. }
  31. /**
  32. * igc_read_nvm_eerd - Reads EEPROM using EERD register
  33. * @hw: pointer to the HW structure
  34. * @offset: offset of word in the EEPROM to read
  35. * @words: number of words to read
  36. * @data: word read from the EEPROM
  37. *
  38. * Reads a 16 bit word from the EEPROM using the EERD register.
  39. */
  40. s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
  41. {
  42. struct igc_nvm_info *nvm = &hw->nvm;
  43. u32 i, eerd = 0;
  44. s32 ret_val = 0;
  45. /* A check for invalid values: offset too large, too many words,
  46. * and not enough words.
  47. */
  48. if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) ||
  49. words == 0) {
  50. hw_dbg("nvm parameter(s) out of bounds\n");
  51. ret_val = -IGC_ERR_NVM;
  52. goto out;
  53. }
  54. for (i = 0; i < words; i++) {
  55. eerd = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) +
  56. IGC_NVM_RW_REG_START;
  57. wr32(IGC_EERD, eerd);
  58. ret_val = igc_poll_eerd_eewr_done(hw, IGC_NVM_POLL_READ);
  59. if (ret_val)
  60. break;
  61. data[i] = (rd32(IGC_EERD) >> IGC_NVM_RW_REG_DATA);
  62. }
  63. out:
  64. return ret_val;
  65. }
  66. /**
  67. * igc_read_mac_addr - Read device MAC address
  68. * @hw: pointer to the HW structure
  69. */
  70. s32 igc_read_mac_addr(struct igc_hw *hw)
  71. {
  72. u32 rar_high;
  73. u32 rar_low;
  74. u16 i;
  75. rar_high = rd32(IGC_RAH(0));
  76. rar_low = rd32(IGC_RAL(0));
  77. for (i = 0; i < IGC_RAL_MAC_ADDR_LEN; i++)
  78. hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
  79. for (i = 0; i < IGC_RAH_MAC_ADDR_LEN; i++)
  80. hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
  81. for (i = 0; i < ETH_ALEN; i++)
  82. hw->mac.addr[i] = hw->mac.perm_addr[i];
  83. return 0;
  84. }
  85. /**
  86. * igc_validate_nvm_checksum - Validate EEPROM checksum
  87. * @hw: pointer to the HW structure
  88. *
  89. * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
  90. * and then verifies that the sum of the EEPROM is equal to 0xBABA.
  91. */
  92. s32 igc_validate_nvm_checksum(struct igc_hw *hw)
  93. {
  94. u16 checksum = 0;
  95. u16 i, nvm_data;
  96. s32 ret_val = 0;
  97. for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
  98. ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
  99. if (ret_val) {
  100. hw_dbg("NVM Read Error\n");
  101. goto out;
  102. }
  103. checksum += nvm_data;
  104. }
  105. if (checksum != NVM_SUM) {
  106. hw_dbg("NVM Checksum Invalid\n");
  107. ret_val = -IGC_ERR_NVM;
  108. goto out;
  109. }
  110. out:
  111. return ret_val;
  112. }
  113. /**
  114. * igc_update_nvm_checksum - Update EEPROM checksum
  115. * @hw: pointer to the HW structure
  116. *
  117. * Updates the EEPROM checksum by reading/adding each word of the EEPROM
  118. * up to the checksum. Then calculates the EEPROM checksum and writes the
  119. * value to the EEPROM.
  120. */
  121. s32 igc_update_nvm_checksum(struct igc_hw *hw)
  122. {
  123. u16 checksum = 0;
  124. u16 i, nvm_data;
  125. s32 ret_val;
  126. for (i = 0; i < NVM_CHECKSUM_REG; i++) {
  127. ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
  128. if (ret_val) {
  129. hw_dbg("NVM Read Error while updating checksum.\n");
  130. goto out;
  131. }
  132. checksum += nvm_data;
  133. }
  134. checksum = NVM_SUM - checksum;
  135. ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
  136. if (ret_val)
  137. hw_dbg("NVM Write Error while updating checksum.\n");
  138. out:
  139. return ret_val;
  140. }