Commit 057d2b19 authored by Sudarsana Reddy Kalluru's avatar Sudarsana Reddy Kalluru Committed by David S. Miller

qed: Add support for MBI upgrade over MFW.

The patch adds driver support for MBI image update through MFW.
Signed-off-by: default avatarSudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: default avatarAriel Elior <Ariel.Elior@cavium.com>
Signed-off-by: default avatarMichal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f04e48db
...@@ -12655,6 +12655,7 @@ struct public_drv_mb { ...@@ -12655,6 +12655,7 @@ struct public_drv_mb {
#define DRV_MB_PARAM_DCBX_NOTIFY_MASK 0x000000FF #define DRV_MB_PARAM_DCBX_NOTIFY_MASK 0x000000FF
#define DRV_MB_PARAM_DCBX_NOTIFY_SHIFT 3 #define DRV_MB_PARAM_DCBX_NOTIFY_SHIFT 3
#define DRV_MB_PARAM_NVM_PUT_FILE_BEGIN_MBI 0x3
#define DRV_MB_PARAM_NVM_LEN_OFFSET 24 #define DRV_MB_PARAM_NVM_LEN_OFFSET 24
#define DRV_MB_PARAM_CFG_VF_MSIX_VF_ID_SHIFT 0 #define DRV_MB_PARAM_CFG_VF_MSIX_VF_ID_SHIFT 0
...@@ -12814,6 +12815,11 @@ struct public_drv_mb { ...@@ -12814,6 +12815,11 @@ struct public_drv_mb {
union drv_union_data union_data; union drv_union_data union_data;
}; };
#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_MASK 0x00ffffff
#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_SHIFT 0
#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_MASK 0xff000000
#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_SHIFT 24
enum MFW_DRV_MSG_TYPE { enum MFW_DRV_MSG_TYPE {
MFW_DRV_MSG_LINK_CHANGE, MFW_DRV_MSG_LINK_CHANGE,
MFW_DRV_MSG_FLR_FW_ACK_FAILED, MFW_DRV_MSG_FLR_FW_ACK_FAILED,
......
...@@ -1939,21 +1939,30 @@ static int qed_nvm_flash_image_access(struct qed_dev *cdev, const u8 **data, ...@@ -1939,21 +1939,30 @@ static int qed_nvm_flash_image_access(struct qed_dev *cdev, const u8 **data,
* 0B | 0x3 [command index] | * 0B | 0x3 [command index] |
* 4B | b'0: check_response? | b'1-31 reserved | * 4B | b'0: check_response? | b'1-31 reserved |
* 8B | File-type | reserved | * 8B | File-type | reserved |
* 12B | Image length in bytes |
* \----------------------------------------------------------------------/ * \----------------------------------------------------------------------/
* Start a new file of the provided type * Start a new file of the provided type
*/ */
static int qed_nvm_flash_image_file_start(struct qed_dev *cdev, static int qed_nvm_flash_image_file_start(struct qed_dev *cdev,
const u8 **data, bool *check_resp) const u8 **data, bool *check_resp)
{ {
u32 file_type, file_size = 0;
int rc; int rc;
*data += 4; *data += 4;
*check_resp = !!(**data & BIT(0)); *check_resp = !!(**data & BIT(0));
*data += 4; *data += 4;
file_type = **data;
DP_VERBOSE(cdev, NETIF_MSG_DRV, DP_VERBOSE(cdev, NETIF_MSG_DRV,
"About to start a new file of type %02x\n", **data); "About to start a new file of type %02x\n", file_type);
rc = qed_mcp_nvm_put_file_begin(cdev, **data); if (file_type == DRV_MB_PARAM_NVM_PUT_FILE_BEGIN_MBI) {
*data += 4;
file_size = *((u32 *)(*data));
}
rc = qed_mcp_nvm_write(cdev, QED_PUT_FILE_BEGIN, file_type,
(u8 *)(&file_size), 4);
*data += 4; *data += 4;
return rc; return rc;
......
...@@ -2745,24 +2745,6 @@ int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf) ...@@ -2745,24 +2745,6 @@ int qed_mcp_nvm_resp(struct qed_dev *cdev, u8 *p_buf)
return 0; 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, int qed_mcp_nvm_write(struct qed_dev *cdev,
u32 cmd, u32 addr, u8 *p_buf, u32 len) u32 cmd, u32 addr, u8 *p_buf, u32 len)
{ {
...@@ -2776,6 +2758,9 @@ int qed_mcp_nvm_write(struct qed_dev *cdev, ...@@ -2776,6 +2758,9 @@ int qed_mcp_nvm_write(struct qed_dev *cdev,
return -EBUSY; return -EBUSY;
switch (cmd) { switch (cmd) {
case QED_PUT_FILE_BEGIN:
nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_BEGIN;
break;
case QED_PUT_FILE_DATA: case QED_PUT_FILE_DATA:
nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA; nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA;
break; break;
...@@ -2788,10 +2773,14 @@ int qed_mcp_nvm_write(struct qed_dev *cdev, ...@@ -2788,10 +2773,14 @@ int qed_mcp_nvm_write(struct qed_dev *cdev,
goto out; goto out;
} }
while (buf_idx < len) {
buf_size = min_t(u32, (len - buf_idx), MCP_DRV_NVM_BUF_LEN); buf_size = min_t(u32, (len - buf_idx), MCP_DRV_NVM_BUF_LEN);
nvm_offset = ((buf_size << DRV_MB_PARAM_NVM_LEN_OFFSET) | while (buf_idx < len) {
addr) + buf_idx; if (cmd == QED_PUT_FILE_BEGIN)
nvm_offset = addr;
else
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, rc = qed_mcp_nvm_wr_cmd(p_hwfn, p_ptt, nvm_cmd, nvm_offset,
&resp, &param, buf_size, &resp, &param, buf_size,
(u32 *)&p_buf[buf_idx]); (u32 *)&p_buf[buf_idx]);
...@@ -2816,7 +2805,19 @@ int qed_mcp_nvm_write(struct qed_dev *cdev, ...@@ -2816,7 +2805,19 @@ int qed_mcp_nvm_write(struct qed_dev *cdev,
if (buf_idx % 0x1000 > (buf_idx + buf_size) % 0x1000) if (buf_idx % 0x1000 > (buf_idx + buf_size) % 0x1000)
usleep_range(1000, 2000); usleep_range(1000, 2000);
/* For MBI upgrade, MFW response includes the next buffer offset
* to be delivered to MFW.
*/
if (param && cmd == QED_PUT_FILE_DATA) {
buf_idx = QED_MFW_GET_FIELD(param,
FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET);
buf_size = QED_MFW_GET_FIELD(param,
FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE);
} else {
buf_idx += buf_size; buf_idx += buf_size;
buf_size = min_t(u32, (len - buf_idx),
MCP_DRV_NVM_BUF_LEN);
}
} }
cdev->mcp_nvm_resp = resp; cdev->mcp_nvm_resp = resp;
......
...@@ -542,16 +542,6 @@ int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len); ...@@ -542,16 +542,6 @@ int qed_mcp_nvm_read(struct qed_dev *cdev, u32 addr, u8 *p_buf, u32 len);
int qed_mcp_nvm_write(struct qed_dev *cdev, int qed_mcp_nvm_write(struct qed_dev *cdev,
u32 cmd, u32 addr, u8 *p_buf, u32 len); 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 * @brief Check latest response
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment