0001
0002
0003
0004
0005
0006
0007 #include <linux/crc32.h>
0008 #include "qed.h"
0009 #include "qed_dev_api.h"
0010 #include "qed_mcp.h"
0011 #include "qed_sp.h"
0012 #include "qed_selftest.h"
0013
0014 int qed_selftest_memory(struct qed_dev *cdev)
0015 {
0016 int rc = 0, i;
0017
0018 for_each_hwfn(cdev, i) {
0019 rc = qed_sp_heartbeat_ramrod(&cdev->hwfns[i]);
0020 if (rc)
0021 return rc;
0022 }
0023
0024 return rc;
0025 }
0026
0027 int qed_selftest_interrupt(struct qed_dev *cdev)
0028 {
0029 int rc = 0, i;
0030
0031 for_each_hwfn(cdev, i) {
0032 rc = qed_sp_heartbeat_ramrod(&cdev->hwfns[i]);
0033 if (rc)
0034 return rc;
0035 }
0036
0037 return rc;
0038 }
0039
0040 int qed_selftest_register(struct qed_dev *cdev)
0041 {
0042 struct qed_hwfn *p_hwfn;
0043 struct qed_ptt *p_ptt;
0044 int rc = 0, i;
0045
0046
0047 for_each_hwfn(cdev, i) {
0048 p_hwfn = &cdev->hwfns[i];
0049 p_ptt = qed_ptt_acquire(p_hwfn);
0050 if (!p_ptt) {
0051 DP_ERR(p_hwfn, "failed to acquire ptt\n");
0052 return -EBUSY;
0053 }
0054 rc = qed_mcp_bist_register_test(p_hwfn, p_ptt);
0055 qed_ptt_release(p_hwfn, p_ptt);
0056 if (rc)
0057 break;
0058 }
0059
0060 return rc;
0061 }
0062
0063 int qed_selftest_clock(struct qed_dev *cdev)
0064 {
0065 struct qed_hwfn *p_hwfn;
0066 struct qed_ptt *p_ptt;
0067 int rc = 0, i;
0068
0069
0070 for_each_hwfn(cdev, i) {
0071 p_hwfn = &cdev->hwfns[i];
0072 p_ptt = qed_ptt_acquire(p_hwfn);
0073 if (!p_ptt) {
0074 DP_ERR(p_hwfn, "failed to acquire ptt\n");
0075 return -EBUSY;
0076 }
0077 rc = qed_mcp_bist_clock_test(p_hwfn, p_ptt);
0078 qed_ptt_release(p_hwfn, p_ptt);
0079 if (rc)
0080 break;
0081 }
0082
0083 return rc;
0084 }
0085
0086 int qed_selftest_nvram(struct qed_dev *cdev)
0087 {
0088 struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
0089 struct qed_ptt *p_ptt = qed_ptt_acquire(p_hwfn);
0090 u32 num_images, i, j, nvm_crc, calc_crc;
0091 struct bist_nvm_image_att image_att;
0092 u8 *buf = NULL;
0093 __be32 val;
0094 int rc;
0095
0096 if (!p_ptt) {
0097 DP_ERR(p_hwfn, "failed to acquire ptt\n");
0098 return -EBUSY;
0099 }
0100
0101
0102 rc = qed_mcp_bist_nvm_get_num_images(p_hwfn, p_ptt, &num_images);
0103 if (rc || !num_images) {
0104 DP_ERR(p_hwfn, "Failed getting number of images\n");
0105 rc = -EINVAL;
0106 goto err0;
0107 }
0108
0109
0110 for (i = 0; i < num_images; i++) {
0111
0112
0113
0114 rc = qed_mcp_bist_nvm_get_image_att(p_hwfn, p_ptt,
0115 &image_att, i);
0116 if (rc) {
0117 DP_ERR(p_hwfn,
0118 "Failed getting image index %d attributes\n",
0119 i);
0120 goto err0;
0121 }
0122
0123
0124
0125
0126 if (image_att.image_type == NVM_TYPE_MDUMP)
0127 continue;
0128
0129 DP_VERBOSE(p_hwfn, QED_MSG_SP, "image index %d, size %x\n",
0130 i, image_att.len);
0131
0132
0133 buf = kzalloc(image_att.len, GFP_KERNEL);
0134 if (!buf) {
0135 rc = -ENOMEM;
0136 goto err0;
0137 }
0138
0139
0140 rc = qed_mcp_nvm_read(p_hwfn->cdev, image_att.nvm_start_addr,
0141 buf, image_att.len);
0142 if (rc) {
0143 DP_ERR(p_hwfn,
0144 "Failed reading image index %d from nvm.\n", i);
0145 goto err1;
0146 }
0147
0148
0149
0150
0151 for (j = 0; j < image_att.len - 4; j += 4) {
0152 val = cpu_to_be32(*(u32 *)&buf[j]);
0153 *(u32 *)&buf[j] = (__force u32)val;
0154 }
0155
0156
0157
0158
0159 nvm_crc = *(u32 *)(buf + image_att.len - 4);
0160 calc_crc = crc32(0xffffffff, buf, image_att.len - 4);
0161 calc_crc = (__force u32)~cpu_to_be32(calc_crc);
0162 DP_VERBOSE(p_hwfn, QED_MSG_SP,
0163 "nvm crc 0x%x, calc_crc 0x%x\n", nvm_crc, calc_crc);
0164
0165 if (calc_crc != nvm_crc) {
0166 rc = -EINVAL;
0167 goto err1;
0168 }
0169
0170
0171
0172
0173 kfree(buf);
0174 buf = NULL;
0175 }
0176
0177 qed_ptt_release(p_hwfn, p_ptt);
0178 return 0;
0179
0180 err1:
0181 kfree(buf);
0182 err0:
0183 qed_ptt_release(p_hwfn, p_ptt);
0184 return rc;
0185 }