mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 17:01:14 +00:00
net: qed: critical err reporting to management firmware
On various critical errors, notification handler should also report the err information into the management firmware. MFW can interact with server/motherboard backend agents - these are used by server manufacturers to monitor server HW health. Thus, it is important for driver to report on any faulty conditions Signed-off-by: Ariel Elior <ariel.elior@marvell.com> Signed-off-by: Michal Kalderon <michal.kalderon@marvell.com> Signed-off-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2ec276d5b2
commit
d8d6c5a7be
4 changed files with 161 additions and 0 deletions
|
@ -12492,6 +12492,8 @@ struct public_drv_mb {
|
||||||
#define DRV_MSG_CODE_GET_ENGINE_CONFIG 0x00370000
|
#define DRV_MSG_CODE_GET_ENGINE_CONFIG 0x00370000
|
||||||
#define DRV_MSG_CODE_GET_PPFID_BITMAP 0x43000000
|
#define DRV_MSG_CODE_GET_PPFID_BITMAP 0x43000000
|
||||||
|
|
||||||
|
#define DRV_MSG_CODE_DEBUG_DATA_SEND 0xc0040000
|
||||||
|
|
||||||
#define RESOURCE_CMD_REQ_RESC_MASK 0x0000001F
|
#define RESOURCE_CMD_REQ_RESC_MASK 0x0000001F
|
||||||
#define RESOURCE_CMD_REQ_RESC_SHIFT 0
|
#define RESOURCE_CMD_REQ_RESC_SHIFT 0
|
||||||
#define RESOURCE_CMD_REQ_OPCODE_MASK 0x000000E0
|
#define RESOURCE_CMD_REQ_OPCODE_MASK 0x000000E0
|
||||||
|
@ -12626,6 +12628,17 @@ struct public_drv_mb {
|
||||||
#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002
|
#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002
|
||||||
#define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000
|
#define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000
|
||||||
|
|
||||||
|
/* DRV_MSG_CODE_DEBUG_DATA_SEND parameters */
|
||||||
|
#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_OFFSET 0
|
||||||
|
#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_MASK 0xFF
|
||||||
|
|
||||||
|
/* Driver attributes params */
|
||||||
|
#define DRV_MB_PARAM_ATTRIBUTE_KEY_OFFSET 0
|
||||||
|
#define DRV_MB_PARAM_ATTRIBUTE_KEY_MASK 0x00FFFFFF
|
||||||
|
#define DRV_MB_PARAM_ATTRIBUTE_CMD_OFFSET 24
|
||||||
|
#define DRV_MB_PARAM_ATTRIBUTE_CMD_MASK 0xFF000000
|
||||||
|
|
||||||
|
#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_OFFSET 0
|
||||||
#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
|
#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
|
||||||
#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000FFFF
|
#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000FFFF
|
||||||
#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
|
#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
|
||||||
|
@ -12678,6 +12691,12 @@ struct public_drv_mb {
|
||||||
#define FW_MSG_CODE_DRV_CFG_PF_VFS_MSIX_DONE 0x00870000
|
#define FW_MSG_CODE_DRV_CFG_PF_VFS_MSIX_DONE 0x00870000
|
||||||
#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
|
#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
|
||||||
|
|
||||||
|
#define FW_MSG_CODE_DEBUG_DATA_SEND_INV_ARG 0xb0070000
|
||||||
|
#define FW_MSG_CODE_DEBUG_DATA_SEND_BUF_FULL 0xb0080000
|
||||||
|
#define FW_MSG_CODE_DEBUG_DATA_SEND_NO_BUF 0xb0090000
|
||||||
|
#define FW_MSG_CODE_DEBUG_NOT_ENABLED 0xb00a0000
|
||||||
|
#define FW_MSG_CODE_DEBUG_DATA_SEND_OK 0xb00b0000
|
||||||
|
|
||||||
u32 fw_mb_param;
|
u32 fw_mb_param;
|
||||||
#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000
|
#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000
|
||||||
#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
|
#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
|
||||||
|
|
|
@ -868,6 +868,9 @@ void qed_hw_err_notify(struct qed_hwfn *p_hwfn,
|
||||||
}
|
}
|
||||||
|
|
||||||
qed_hw_error_occurred(p_hwfn, err_type);
|
qed_hw_error_occurred(p_hwfn, err_type);
|
||||||
|
|
||||||
|
if (fmt)
|
||||||
|
qed_mcp_send_raw_debug_data(p_hwfn, p_ptt, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
|
int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
|
||||||
|
|
|
@ -3821,3 +3821,127 @@ int qed_mcp_nvm_set_cfg(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
|
||||||
DRV_MSG_CODE_SET_NVM_CFG_OPTION,
|
DRV_MSG_CODE_SET_NVM_CFG_OPTION,
|
||||||
mb_param, &resp, ¶m, len, (u32 *)p_buf);
|
mb_param, &resp, ¶m, len, (u32 *)p_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define QED_MCP_DBG_DATA_MAX_SIZE MCP_DRV_NVM_BUF_LEN
|
||||||
|
#define QED_MCP_DBG_DATA_MAX_HEADER_SIZE sizeof(u32)
|
||||||
|
#define QED_MCP_DBG_DATA_MAX_PAYLOAD_SIZE \
|
||||||
|
(QED_MCP_DBG_DATA_MAX_SIZE - QED_MCP_DBG_DATA_MAX_HEADER_SIZE)
|
||||||
|
|
||||||
|
static int
|
||||||
|
__qed_mcp_send_debug_data(struct qed_hwfn *p_hwfn,
|
||||||
|
struct qed_ptt *p_ptt, u8 *p_buf, u8 size)
|
||||||
|
{
|
||||||
|
struct qed_mcp_mb_params mb_params;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (size > QED_MCP_DBG_DATA_MAX_SIZE) {
|
||||||
|
DP_ERR(p_hwfn,
|
||||||
|
"Debug data size is %d while it should not exceed %d\n",
|
||||||
|
size, QED_MCP_DBG_DATA_MAX_SIZE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&mb_params, 0, sizeof(mb_params));
|
||||||
|
mb_params.cmd = DRV_MSG_CODE_DEBUG_DATA_SEND;
|
||||||
|
SET_MFW_FIELD(mb_params.param, DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE, size);
|
||||||
|
mb_params.p_data_src = p_buf;
|
||||||
|
mb_params.data_src_size = size;
|
||||||
|
rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (mb_params.mcp_resp == FW_MSG_CODE_UNSUPPORTED) {
|
||||||
|
DP_INFO(p_hwfn,
|
||||||
|
"The DEBUG_DATA_SEND command is unsupported by the MFW\n");
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
} else if (mb_params.mcp_resp == (u32)FW_MSG_CODE_DEBUG_NOT_ENABLED) {
|
||||||
|
DP_INFO(p_hwfn, "The DEBUG_DATA_SEND command is not enabled\n");
|
||||||
|
return -EBUSY;
|
||||||
|
} else if (mb_params.mcp_resp != (u32)FW_MSG_CODE_DEBUG_DATA_SEND_OK) {
|
||||||
|
DP_NOTICE(p_hwfn,
|
||||||
|
"Failed to send debug data to the MFW [resp 0x%08x]\n",
|
||||||
|
mb_params.mcp_resp);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum qed_mcp_dbg_data_type {
|
||||||
|
QED_MCP_DBG_DATA_TYPE_RAW,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Header format: [31:28] PFID, [27:20] flags, [19:12] type, [11:0] S/N */
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_SN_OFFSET 0
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_SN_MASK 0x00000fff
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_TYPE_OFFSET 12
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_TYPE_MASK 0x000ff000
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_FLAGS_OFFSET 20
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_FLAGS_MASK 0x0ff00000
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_PF_OFFSET 28
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_PF_MASK 0xf0000000
|
||||||
|
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_FLAGS_FIRST 0x1
|
||||||
|
#define QED_MCP_DBG_DATA_HDR_FLAGS_LAST 0x2
|
||||||
|
|
||||||
|
static int
|
||||||
|
qed_mcp_send_debug_data(struct qed_hwfn *p_hwfn,
|
||||||
|
struct qed_ptt *p_ptt,
|
||||||
|
enum qed_mcp_dbg_data_type type, u8 *p_buf, u32 size)
|
||||||
|
{
|
||||||
|
u8 raw_data[QED_MCP_DBG_DATA_MAX_SIZE], *p_tmp_buf = p_buf;
|
||||||
|
u32 tmp_size = size, *p_header, *p_payload;
|
||||||
|
u8 flags = 0;
|
||||||
|
u16 seq;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
p_header = (u32 *)raw_data;
|
||||||
|
p_payload = (u32 *)(raw_data + QED_MCP_DBG_DATA_MAX_HEADER_SIZE);
|
||||||
|
|
||||||
|
seq = (u16)atomic_inc_return(&p_hwfn->mcp_info->dbg_data_seq);
|
||||||
|
|
||||||
|
/* First chunk is marked as 'first' */
|
||||||
|
flags |= QED_MCP_DBG_DATA_HDR_FLAGS_FIRST;
|
||||||
|
|
||||||
|
*p_header = 0;
|
||||||
|
SET_MFW_FIELD(*p_header, QED_MCP_DBG_DATA_HDR_SN, seq);
|
||||||
|
SET_MFW_FIELD(*p_header, QED_MCP_DBG_DATA_HDR_TYPE, type);
|
||||||
|
SET_MFW_FIELD(*p_header, QED_MCP_DBG_DATA_HDR_FLAGS, flags);
|
||||||
|
SET_MFW_FIELD(*p_header, QED_MCP_DBG_DATA_HDR_PF, p_hwfn->abs_pf_id);
|
||||||
|
|
||||||
|
while (tmp_size > QED_MCP_DBG_DATA_MAX_PAYLOAD_SIZE) {
|
||||||
|
memcpy(p_payload, p_tmp_buf, QED_MCP_DBG_DATA_MAX_PAYLOAD_SIZE);
|
||||||
|
rc = __qed_mcp_send_debug_data(p_hwfn, p_ptt, raw_data,
|
||||||
|
QED_MCP_DBG_DATA_MAX_SIZE);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* Clear the 'first' marking after sending the first chunk */
|
||||||
|
if (p_tmp_buf == p_buf) {
|
||||||
|
flags &= ~QED_MCP_DBG_DATA_HDR_FLAGS_FIRST;
|
||||||
|
SET_MFW_FIELD(*p_header, QED_MCP_DBG_DATA_HDR_FLAGS,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_tmp_buf += QED_MCP_DBG_DATA_MAX_PAYLOAD_SIZE;
|
||||||
|
tmp_size -= QED_MCP_DBG_DATA_MAX_PAYLOAD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last chunk is marked as 'last' */
|
||||||
|
flags |= QED_MCP_DBG_DATA_HDR_FLAGS_LAST;
|
||||||
|
SET_MFW_FIELD(*p_header, QED_MCP_DBG_DATA_HDR_FLAGS, flags);
|
||||||
|
memcpy(p_payload, p_tmp_buf, tmp_size);
|
||||||
|
|
||||||
|
/* Casting the left size to u8 is ok since at this point it is <= 32 */
|
||||||
|
return __qed_mcp_send_debug_data(p_hwfn, p_ptt, raw_data,
|
||||||
|
(u8)(QED_MCP_DBG_DATA_MAX_HEADER_SIZE +
|
||||||
|
tmp_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qed_mcp_send_raw_debug_data(struct qed_hwfn *p_hwfn,
|
||||||
|
struct qed_ptt *p_ptt, u8 *p_buf, u32 size)
|
||||||
|
{
|
||||||
|
return qed_mcp_send_debug_data(p_hwfn, p_ptt,
|
||||||
|
QED_MCP_DBG_DATA_TYPE_RAW, p_buf, size);
|
||||||
|
}
|
||||||
|
|
|
@ -685,6 +685,18 @@ int qed_mcp_bist_nvm_get_image_att(struct qed_hwfn *p_hwfn,
|
||||||
*/
|
*/
|
||||||
int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
|
int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send raw debug data to the MFW
|
||||||
|
*
|
||||||
|
* @param p_hwfn
|
||||||
|
* @param p_ptt
|
||||||
|
* @param p_buf - raw debug data buffer
|
||||||
|
* @param size - buffer size
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qed_mcp_send_raw_debug_data(struct qed_hwfn *p_hwfn,
|
||||||
|
struct qed_ptt *p_ptt, u8 *p_buf, u32 size);
|
||||||
|
|
||||||
/* Using hwfn number (and not pf_num) is required since in CMT mode,
|
/* Using hwfn number (and not pf_num) is required since in CMT mode,
|
||||||
* same pf_num may be used by two different hwfn
|
* same pf_num may be used by two different hwfn
|
||||||
* TODO - this shouldn't really be in .h file, but until all fields
|
* TODO - this shouldn't really be in .h file, but until all fields
|
||||||
|
@ -731,6 +743,9 @@ struct qed_mcp_info {
|
||||||
|
|
||||||
/* Capabilties negotiated with the MFW */
|
/* Capabilties negotiated with the MFW */
|
||||||
u32 capabilities;
|
u32 capabilities;
|
||||||
|
|
||||||
|
/* S/N for debug data mailbox commands */
|
||||||
|
atomic_t dbg_data_seq;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_mcp_mb_params {
|
struct qed_mcp_mb_params {
|
||||||
|
|
Loading…
Reference in a new issue