iwl-4965-ucode.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /******************************************************************************
  2. *
  3. * GPL LICENSE SUMMARY
  4. *
  5. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of version 2 of the GNU General Public License as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  19. * USA
  20. *
  21. * The full GNU General Public License is included in this distribution
  22. * in the file called LICENSE.GPL.
  23. *
  24. * Contact Information:
  25. * Intel Linux Wireless <ilw@linux.intel.com>
  26. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  27. *
  28. *****************************************************************************/
  29. #include <linux/kernel.h>
  30. #include <linux/module.h>
  31. #include <linux/init.h>
  32. #include <linux/sched.h>
  33. #include "iwl-dev.h"
  34. #include "iwl-core.h"
  35. #include "iwl-io.h"
  36. #include "iwl-helpers.h"
  37. #include "iwl-4965-hw.h"
  38. #include "iwl-4965.h"
  39. #include "iwl-4965-calib.h"
  40. #define IWL_AC_UNSET -1
  41. /**
  42. * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
  43. * using sample data 100 bytes apart. If these sample points are good,
  44. * it's a pretty good bet that everything between them is good, too.
  45. */
  46. static int
  47. iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
  48. {
  49. u32 val;
  50. int ret = 0;
  51. u32 errcnt = 0;
  52. u32 i;
  53. IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
  54. for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
  55. /* read data comes through single port, auto-incr addr */
  56. /* NOTE: Use the debugless read so we don't flood kernel log
  57. * if IWL_DL_IO is set */
  58. iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR,
  59. i + IWL4965_RTC_INST_LOWER_BOUND);
  60. val = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT);
  61. if (val != le32_to_cpu(*image)) {
  62. ret = -EIO;
  63. errcnt++;
  64. if (errcnt >= 3)
  65. break;
  66. }
  67. }
  68. return ret;
  69. }
  70. /**
  71. * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host,
  72. * looking at all data.
  73. */
  74. static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image,
  75. u32 len)
  76. {
  77. u32 val;
  78. u32 save_len = len;
  79. int ret = 0;
  80. u32 errcnt;
  81. IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
  82. iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR,
  83. IWL4965_RTC_INST_LOWER_BOUND);
  84. errcnt = 0;
  85. for (; len > 0; len -= sizeof(u32), image++) {
  86. /* read data comes through single port, auto-incr addr */
  87. /* NOTE: Use the debugless read so we don't flood kernel log
  88. * if IWL_DL_IO is set */
  89. val = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT);
  90. if (val != le32_to_cpu(*image)) {
  91. IWL_ERR(priv, "uCode INST section is invalid at "
  92. "offset 0x%x, is 0x%x, s/b 0x%x\n",
  93. save_len - len, val, le32_to_cpu(*image));
  94. ret = -EIO;
  95. errcnt++;
  96. if (errcnt >= 20)
  97. break;
  98. }
  99. }
  100. if (!errcnt)
  101. IWL_DEBUG_INFO(priv,
  102. "ucode image in INSTRUCTION memory is good\n");
  103. return ret;
  104. }
  105. /**
  106. * iwl4965_verify_ucode - determine which instruction image is in SRAM,
  107. * and verify its contents
  108. */
  109. int iwl4965_verify_ucode(struct iwl_priv *priv)
  110. {
  111. __le32 *image;
  112. u32 len;
  113. int ret;
  114. /* Try bootstrap */
  115. image = (__le32 *)priv->ucode_boot.v_addr;
  116. len = priv->ucode_boot.len;
  117. ret = iwl4965_verify_inst_sparse(priv, image, len);
  118. if (!ret) {
  119. IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
  120. return 0;
  121. }
  122. /* Try initialize */
  123. image = (__le32 *)priv->ucode_init.v_addr;
  124. len = priv->ucode_init.len;
  125. ret = iwl4965_verify_inst_sparse(priv, image, len);
  126. if (!ret) {
  127. IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
  128. return 0;
  129. }
  130. /* Try runtime/protocol */
  131. image = (__le32 *)priv->ucode_code.v_addr;
  132. len = priv->ucode_code.len;
  133. ret = iwl4965_verify_inst_sparse(priv, image, len);
  134. if (!ret) {
  135. IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
  136. return 0;
  137. }
  138. IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
  139. /* Since nothing seems to match, show first several data entries in
  140. * instruction SRAM, so maybe visual inspection will give a clue.
  141. * Selection of bootstrap image (vs. other images) is arbitrary. */
  142. image = (__le32 *)priv->ucode_boot.v_addr;
  143. len = priv->ucode_boot.len;
  144. ret = iwl4965_verify_inst_full(priv, image, len);
  145. return ret;
  146. }