#include "bcm_osal.h"
#include "ecore.h"
#include "ecore_sp_commands.h"
#include "ecore_dev_api.h"
#include "ecore_mcp.h"
#include "nvm_map.h"
#include "ecore_selftest_api.h"
enum _ecore_status_t ecore_selftest_memory(struct ecore_dev *p_dev)
{
enum _ecore_status_t rc = ECORE_SUCCESS;
int i;
for_each_hwfn(p_dev, i) {
rc = ecore_sp_heartbeat_ramrod(&p_dev->hwfns[i]);
if (rc != ECORE_SUCCESS)
return rc;
}
return rc;
}
enum _ecore_status_t ecore_selftest_interrupt(struct ecore_dev *p_dev)
{
enum _ecore_status_t rc = ECORE_SUCCESS;
int i;
for_each_hwfn(p_dev, i) {
rc = ecore_sp_heartbeat_ramrod(&p_dev->hwfns[i]);
if (rc != ECORE_SUCCESS)
return rc;
}
return rc;
}
enum _ecore_status_t ecore_selftest_register(struct ecore_dev *p_dev)
{
struct ecore_hwfn *p_hwfn;
struct ecore_ptt *p_ptt;
enum _ecore_status_t rc = ECORE_SUCCESS;
int i;
for_each_hwfn(p_dev, i) {
p_hwfn = &p_dev->hwfns[i];
p_ptt = ecore_ptt_acquire(p_hwfn);
if (!p_ptt) {
DP_ERR(p_hwfn, "failed to acquire ptt\n");
return ECORE_BUSY;
}
rc = ecore_mcp_bist_register_test(p_hwfn, p_ptt);
ecore_ptt_release(p_hwfn, p_ptt);
if (rc != ECORE_SUCCESS)
break;
}
return rc;
}
enum _ecore_status_t ecore_selftest_clock(struct ecore_dev *p_dev)
{
struct ecore_hwfn *p_hwfn;
struct ecore_ptt *p_ptt;
enum _ecore_status_t rc = ECORE_SUCCESS;
int i;
for_each_hwfn(p_dev, i) {
p_hwfn = &p_dev->hwfns[i];
p_ptt = ecore_ptt_acquire(p_hwfn);
if (!p_ptt) {
DP_ERR(p_hwfn, "failed to acquire ptt\n");
return ECORE_BUSY;
}
rc = ecore_mcp_bist_clock_test(p_hwfn, p_ptt);
ecore_ptt_release(p_hwfn, p_ptt);
if (rc != ECORE_SUCCESS)
break;
}
return rc;
}
enum _ecore_status_t ecore_selftest_nvram(struct ecore_dev *p_dev)
{
struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(p_dev);
struct ecore_ptt *p_ptt = ecore_ptt_acquire(p_hwfn);
u32 num_images, i, j, nvm_crc, calc_crc;
struct bist_nvm_image_att image_att;
u8 *buf = OSAL_NULL;
OSAL_BE32 val;
enum _ecore_status_t rc;
if (!p_ptt) {
DP_ERR(p_hwfn, "failed to acquire ptt\n");
return ECORE_BUSY;
}
rc = ecore_mcp_bist_nvm_test_get_num_images(p_hwfn, p_ptt, &num_images);
if ((rc != ECORE_SUCCESS) || (num_images == 0)) {
DP_ERR(p_hwfn, "Failed getting number of images\n");
return ECORE_INVAL;
}
for (i = 0; i < num_images; i++) {
rc = ecore_mcp_bist_nvm_test_get_image_att(p_hwfn, p_ptt,
&image_att, i);
if (rc != ECORE_SUCCESS) {
DP_ERR(p_hwfn,
"Failed getting image index %d attributes\n",
i);
goto err0;
}
if (image_att.image_type == NVM_TYPE_MDUMP)
continue;
DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "image index %d, size %x\n", i,
image_att.len);
buf = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, image_att.len);
if (!buf) {
DP_ERR(p_hwfn,
"Failed allocating memory for image index %d.\n",
i);
rc = ECORE_NOMEM;
goto err0;
}
rc = ecore_mcp_nvm_read(p_hwfn->p_dev, image_att.nvm_start_addr,
buf, image_att.len);
if (rc != ECORE_SUCCESS) {
DP_ERR(p_hwfn,
"Failed reading image index %d from nvm.\n", i);
goto err1;
}
for (j = 0; j < image_att.len - 4; j += 4) {
val = OSAL_CPU_TO_BE32(*(u32 *)&buf[j]);
*(u32 *)&buf[j] = val;
}
nvm_crc = *(u32 *)(buf + image_att.len - 4);
calc_crc = OSAL_CRC32(0xffffffff , buf, image_att.len - 4);
calc_crc = ~OSAL_CPU_TO_BE32(calc_crc);
DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
"nvm crc 0x%x, calc_crc 0x%x\n", nvm_crc, calc_crc);
if (calc_crc != nvm_crc) {
rc = ECORE_UNKNOWN_ERROR;
goto err1;
}
OSAL_FREE(p_hwfn->p_dev, buf);
buf = OSAL_NULL;
}
ecore_ptt_release(p_hwfn, p_ptt);
return ECORE_SUCCESS;
err1:
OSAL_FREE(p_hwfn->p_dev, buf);
err0:
ecore_ptt_release(p_hwfn, p_ptt);
return rc;
}