qed: Add APIs for flash access.

This patch adds APIs for flash access.

Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Sudarsana Reddy Kalluru 2018-03-28 05:14:21 -07:00 committed by David S. Miller
parent d8bf47af24
commit 62e4d4386a
4 changed files with 168 additions and 1 deletions

View File

@ -81,6 +81,13 @@ enum qed_coalescing_mode {
QED_COAL_MODE_ENABLE
};
enum qed_nvm_cmd {
QED_PUT_FILE_BEGIN = DRV_MSG_CODE_NVM_PUT_FILE_BEGIN,
QED_PUT_FILE_DATA = DRV_MSG_CODE_NVM_PUT_FILE_DATA,
QED_NVM_WRITE_NVRAM = DRV_MSG_CODE_NVM_WRITE_NVRAM,
QED_GET_MCP_NVM_RESP = 0xFFFFFF00
};
struct qed_eth_cb_ops;
struct qed_dev_info;
union qed_mcp_protocol_stats;

View File

@ -12268,8 +12268,11 @@ struct public_drv_mb {
#define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000
#define DRV_MSG_CODE_CFG_VF_MSIX 0xc0010000
#define DRV_MSG_CODE_CFG_PF_VFS_MSIX 0xc0020000
#define DRV_MSG_CODE_NVM_PUT_FILE_BEGIN 0x00010000
#define DRV_MSG_CODE_NVM_PUT_FILE_DATA 0x00020000
#define DRV_MSG_CODE_NVM_GET_FILE_ATT 0x00030000
#define DRV_MSG_CODE_NVM_READ_NVRAM 0x00050000
#define DRV_MSG_CODE_NVM_WRITE_NVRAM 0x00060000
#define DRV_MSG_CODE_MCP_RESET 0x00090000
#define DRV_MSG_CODE_SET_VERSION 0x000f0000
#define DRV_MSG_CODE_MCP_HALT 0x00100000
@ -12323,7 +12326,6 @@ struct public_drv_mb {
#define DRV_MSG_CODE_FEATURE_SUPPORT 0x00300000
#define DRV_MSG_CODE_GET_MFW_FEATURE_SUPPORT 0x00310000
#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
u32 drv_mb_param;
@ -12435,7 +12437,10 @@ struct public_drv_mb {
#define FW_MSG_CODE_DRV_CFG_VF_MSIX_DONE 0xb0010000
#define FW_MSG_CODE_NVM_OK 0x00010000
#define FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK 0x00400000
#define FW_MSG_CODE_PHY_OK 0x00110000
#define FW_MSG_CODE_OK 0x00160000
#define FW_MSG_CODE_ERROR 0x00170000
#define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000
#define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000

View File

@ -569,6 +569,31 @@ int qed_mcp_cmd(struct qed_hwfn *p_hwfn,
return 0;
}
int qed_mcp_nvm_wr_cmd(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 cmd,
u32 param,
u32 *o_mcp_resp,
u32 *o_mcp_param, u32 i_txn_size, u32 *i_buf)
{
struct qed_mcp_mb_params mb_params;
int rc;
memset(&mb_params, 0, sizeof(mb_params));
mb_params.cmd = cmd;
mb_params.param = param;
mb_params.p_data_src = i_buf;
mb_params.data_src_size = (u8)i_txn_size;
rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
if (rc)
return rc;
*o_mcp_resp = mb_params.mcp_resp;
*o_mcp_param = mb_params.mcp_param;
return 0;
}
int qed_mcp_nvm_rd_cmd(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 cmd,
@ -2261,6 +2286,102 @@ int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len)
return rc;
}
int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf)
{
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_ptt *p_ptt;
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt)
return -EBUSY;
memcpy(p_buf, &cdev->mcp_nvm_resp, sizeof(cdev->mcp_nvm_resp));
qed_ptt_release(p_hwfn, p_ptt);
return 0;
}
int qed_mcp_nvm_put_file_begin(struct qed_dev *cdev, u32 addr)
{
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_ptt *p_ptt;
u32 resp, param;
int rc;
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt)
return -EBUSY;
rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_NVM_PUT_FILE_BEGIN, addr,
&resp, &param);
cdev->mcp_nvm_resp = resp;
qed_ptt_release(p_hwfn, p_ptt);
return rc;
}
int qed_mcp_nvm_write(struct qed_dev *cdev,
u32 cmd, u32 addr, u8 *p_buf, u32 len)
{
u32 buf_idx = 0, buf_size, nvm_cmd, nvm_offset, resp = 0, param;
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_ptt *p_ptt;
int rc = -EINVAL;
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt)
return -EBUSY;
switch (cmd) {
case QED_PUT_FILE_DATA:
nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA;
break;
case QED_NVM_WRITE_NVRAM:
nvm_cmd = DRV_MSG_CODE_NVM_WRITE_NVRAM;
break;
default:
DP_NOTICE(p_hwfn, "Invalid nvm write command 0x%x\n", cmd);
rc = -EINVAL;
goto out;
}
while (buf_idx < len) {
buf_size = min_t(u32, (len - buf_idx), MCP_DRV_NVM_BUF_LEN);
nvm_offset = ((buf_size << DRV_MB_PARAM_NVM_LEN_OFFSET) |
addr) + buf_idx;
rc = qed_mcp_nvm_wr_cmd(p_hwfn, p_ptt, nvm_cmd, nvm_offset,
&resp, &param, buf_size,
(u32 *)&p_buf[buf_idx]);
if (rc) {
DP_NOTICE(cdev, "nvm write failed, rc = %d\n", rc);
resp = FW_MSG_CODE_ERROR;
break;
}
if (resp != FW_MSG_CODE_OK &&
resp != FW_MSG_CODE_NVM_OK &&
resp != FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK) {
DP_NOTICE(cdev,
"nvm write failed, resp = 0x%08x\n", resp);
rc = -EINVAL;
break;
}
/* This can be a lengthy process, and it's possible scheduler
* isn't pre-emptable. Sleep a bit to prevent CPU hogging.
*/
if (buf_idx % 0x1000 > (buf_idx + buf_size) % 0x1000)
usleep_range(1000, 2000);
buf_idx += buf_size;
}
cdev->mcp_nvm_resp = resp;
out:
qed_ptt_release(p_hwfn, p_ptt);
return rc;
}
int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
u32 drv_mb_param = 0, rsp, param;

View File

@ -443,6 +443,40 @@ int qed_mcp_set_led(struct qed_hwfn *p_hwfn,
*/
int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len);
/**
* @brief Write to nvm
*
* @param cdev
* @param addr - nvm offset
* @param cmd - nvm command
* @param p_buf - nvm write buffer
* @param len - buffer len
*
* @return int - 0 - operation was successful.
*/
int qed_mcp_nvm_write(struct qed_dev *cdev,
u32 cmd, u32 addr, u8 *p_buf, u32 len);
/**
* @brief Put file begin
*
* @param cdev
* @param addr - nvm offset
*
* @return int - 0 - operation was successful.
*/
int qed_mcp_nvm_put_file_begin(struct qed_dev *cdev, u32 addr);
/**
* @brief Check latest response
*
* @param cdev
* @param p_buf - nvm write buffer
*
* @return int - 0 - operation was successful.
*/
int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf);
struct qed_nvm_image_att {
u32 start_addr;
u32 length;