qed_selftest.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <linux/crc32.h>
  2. #include "qed.h"
  3. #include "qed_dev_api.h"
  4. #include "qed_mcp.h"
  5. #include "qed_sp.h"
  6. #include "qed_selftest.h"
  7. int qed_selftest_memory(struct qed_dev *cdev)
  8. {
  9. int rc = 0, i;
  10. for_each_hwfn(cdev, i) {
  11. rc = qed_sp_heartbeat_ramrod(&cdev->hwfns[i]);
  12. if (rc)
  13. return rc;
  14. }
  15. return rc;
  16. }
  17. int qed_selftest_interrupt(struct qed_dev *cdev)
  18. {
  19. int rc = 0, i;
  20. for_each_hwfn(cdev, i) {
  21. rc = qed_sp_heartbeat_ramrod(&cdev->hwfns[i]);
  22. if (rc)
  23. return rc;
  24. }
  25. return rc;
  26. }
  27. int qed_selftest_register(struct qed_dev *cdev)
  28. {
  29. struct qed_hwfn *p_hwfn;
  30. struct qed_ptt *p_ptt;
  31. int rc = 0, i;
  32. /* although performed by MCP, this test is per engine */
  33. for_each_hwfn(cdev, i) {
  34. p_hwfn = &cdev->hwfns[i];
  35. p_ptt = qed_ptt_acquire(p_hwfn);
  36. if (!p_ptt) {
  37. DP_ERR(p_hwfn, "failed to acquire ptt\n");
  38. return -EBUSY;
  39. }
  40. rc = qed_mcp_bist_register_test(p_hwfn, p_ptt);
  41. qed_ptt_release(p_hwfn, p_ptt);
  42. if (rc)
  43. break;
  44. }
  45. return rc;
  46. }
  47. int qed_selftest_clock(struct qed_dev *cdev)
  48. {
  49. struct qed_hwfn *p_hwfn;
  50. struct qed_ptt *p_ptt;
  51. int rc = 0, i;
  52. /* although performed by MCP, this test is per engine */
  53. for_each_hwfn(cdev, i) {
  54. p_hwfn = &cdev->hwfns[i];
  55. p_ptt = qed_ptt_acquire(p_hwfn);
  56. if (!p_ptt) {
  57. DP_ERR(p_hwfn, "failed to acquire ptt\n");
  58. return -EBUSY;
  59. }
  60. rc = qed_mcp_bist_clock_test(p_hwfn, p_ptt);
  61. qed_ptt_release(p_hwfn, p_ptt);
  62. if (rc)
  63. break;
  64. }
  65. return rc;
  66. }
  67. int qed_selftest_nvram(struct qed_dev *cdev)
  68. {
  69. struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
  70. struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
  71. u32 num_images, i, j, nvm_crc, calc_crc;
  72. struct bist_nvm_image_att image_att;
  73. u8 *buf = NULL;
  74. __be32 val;
  75. int rc;
  76. if (!p_ptt) {
  77. DP_ERR(p_hwfn, "failed to acquire ptt\n");
  78. return -EBUSY;
  79. }
  80. /* Acquire from MFW the amount of available images */
  81. rc = qed_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images);
  82. if (rc || !num_images) {
  83. DP_ERR(p_hwfn, "Failed getting number of images\n");
  84. return -EINVAL;
  85. }
  86. /* Iterate over images and validate CRC */
  87. for (i = 0; i < num_images; i++) {
  88. /* This mailbox returns information about the image required for
  89. * reading it.
  90. */
  91. rc = qed_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt,
  92. &image_att, i);
  93. if (rc) {
  94. DP_ERR(p_hwfn,
  95. "Failed getting image index %d attributes\n",
  96. i);
  97. goto err0;
  98. }
  99. /* After MFW crash dump is collected - the image's CRC stops
  100. * being valid.
  101. */
  102. if (image_att.image_type == NVM_TYPE_MDUMP)
  103. continue;
  104. DP_VERBOSE(p_hwfn, QED_MSG_SP, "image index %d, size %x\n",
  105. i, image_att.len);
  106. /* Allocate a buffer for holding the nvram image */
  107. buf = kzalloc(image_att.len, GFP_KERNEL);
  108. if (!buf) {
  109. rc = -ENOMEM;
  110. goto err0;
  111. }
  112. /* Read image into buffer */
  113. rc = qed_mcp_nvm_read(p_hwfn->cdev, image_att.nvm_start_addr,
  114. buf, image_att.len);
  115. if (rc) {
  116. DP_ERR(p_hwfn,
  117. "Failed reading image index %d from nvm.\n", i);
  118. goto err1;
  119. }
  120. /* Convert the buffer into big-endian format (excluding the
  121. * closing 4 bytes of CRC).
  122. */
  123. for (j = 0; j < image_att.len - 4; j += 4) {
  124. val = cpu_to_be32(*(u32 *)&buf[j]);
  125. *(u32 *)&buf[j] = (__force u32)val;
  126. }
  127. /* Calc CRC for the "actual" image buffer, i.e. not including
  128. * the last 4 CRC bytes.
  129. */
  130. nvm_crc = *(u32 *)(buf + image_att.len - 4);
  131. calc_crc = crc32(0xffffffff, buf, image_att.len - 4);
  132. calc_crc = (__force u32)~cpu_to_be32(calc_crc);
  133. DP_VERBOSE(p_hwfn, QED_MSG_SP,
  134. "nvm crc 0x%x, calc_crc 0x%x\n", nvm_crc, calc_crc);
  135. if (calc_crc != nvm_crc) {
  136. rc = -EINVAL;
  137. goto err1;
  138. }
  139. /* Done with this image; Free to prevent double release
  140. * on subsequent failure.
  141. */
  142. kfree(buf);
  143. buf = NULL;
  144. }
  145. qed_ptt_release(p_hwfn, p_ptt);
  146. return 0;
  147. err1:
  148. kfree(buf);
  149. err0:
  150. qed_ptt_release(p_hwfn, p_ptt);
  151. return rc;
  152. }