net: hns3: implement .process_hw_error for hns3 client
When hardware or IMP get specified error it may need the client to take some special operations. This patch implements the hns3 client's process_hw_errorx. Signed-off-by: Weihang Li <liweihang@hisilicon.com> Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> Reviewed-by: Peng Li <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e8df45c281
commit
a83d29618b
@ -146,6 +146,12 @@ enum hnae3_reset_notify_type {
|
||||
HNAE3_RESTORE_CLIENT,
|
||||
};
|
||||
|
||||
enum hnae3_hw_error_type {
|
||||
HNAE3_PPU_POISON_ERROR,
|
||||
HNAE3_CMDQ_ECC_ERROR,
|
||||
HNAE3_IMP_RD_POISON_ERROR,
|
||||
};
|
||||
|
||||
enum hnae3_reset_type {
|
||||
HNAE3_VF_RESET,
|
||||
HNAE3_VF_FUNC_RESET,
|
||||
@ -210,7 +216,8 @@ struct hnae3_client_ops {
|
||||
int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
|
||||
int (*reset_notify)(struct hnae3_handle *handle,
|
||||
enum hnae3_reset_notify_type type);
|
||||
enum hnae3_reset_type (*process_hw_error)(struct hnae3_handle *handle);
|
||||
void (*process_hw_error)(struct hnae3_handle *handle,
|
||||
enum hnae3_hw_error_type);
|
||||
};
|
||||
|
||||
#define HNAE3_CLIENT_NAME_LENGTH 16
|
||||
|
@ -4470,12 +4470,36 @@ int hns3_set_channels(struct net_device *netdev,
|
||||
return hns3_reset_notify(h, HNAE3_UP_CLIENT);
|
||||
}
|
||||
|
||||
static const struct hns3_hw_error_info hns3_hw_err[] = {
|
||||
{ .type = HNAE3_PPU_POISON_ERROR,
|
||||
.msg = "PPU poison" },
|
||||
{ .type = HNAE3_CMDQ_ECC_ERROR,
|
||||
.msg = "IMP CMDQ error" },
|
||||
{ .type = HNAE3_IMP_RD_POISON_ERROR,
|
||||
.msg = "IMP RD poison" },
|
||||
};
|
||||
|
||||
static void hns3_process_hw_error(struct hnae3_handle *handle,
|
||||
enum hnae3_hw_error_type type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hns3_hw_err); i++) {
|
||||
if (hns3_hw_err[i].type == type) {
|
||||
dev_err(&handle->pdev->dev, "Detected %s!\n",
|
||||
hns3_hw_err[i].msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct hnae3_client_ops client_ops = {
|
||||
.init_instance = hns3_client_init,
|
||||
.uninit_instance = hns3_client_uninit,
|
||||
.link_status_change = hns3_link_status_change,
|
||||
.setup_tc = hns3_client_setup_tc,
|
||||
.reset_notify = hns3_reset_notify,
|
||||
.process_hw_error = hns3_process_hw_error,
|
||||
};
|
||||
|
||||
/* hns3_init_module - Driver registration routine
|
||||
|
@ -552,6 +552,11 @@ union l4_hdr_info {
|
||||
unsigned char *hdr;
|
||||
};
|
||||
|
||||
struct hns3_hw_error_info {
|
||||
enum hnae3_hw_error_type type;
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
static inline int ring_space(struct hns3_enet_ring *ring)
|
||||
{
|
||||
/* This smp_load_acquire() pairs with smp_store_release() in
|
||||
|
@ -1325,10 +1325,12 @@ static int hclge_handle_pf_ras_error(struct hclge_dev *hdev,
|
||||
/* log PPU(RCB) errors */
|
||||
desc_data = (__le32 *)&desc[3];
|
||||
status = le32_to_cpu(*desc_data) & HCLGE_PPU_PF_INT_RAS_MASK;
|
||||
if (status)
|
||||
if (status) {
|
||||
hclge_log_error(dev, "PPU_PF_ABNORMAL_INT_ST0",
|
||||
&hclge_ppu_pf_abnormal_int[0], status,
|
||||
&ae_dev->hw_err_reset_req);
|
||||
hclge_report_hw_error(hdev, HNAE3_PPU_POISON_ERROR);
|
||||
}
|
||||
|
||||
/* clear all PF RAS errors */
|
||||
hclge_cmd_reuse_desc(&desc[0], false);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define __HCLGE_ERR_H
|
||||
|
||||
#include "hclge_main.h"
|
||||
#include "hnae3.h"
|
||||
|
||||
#define HCLGE_MPF_RAS_INT_MIN_BD_NUM 10
|
||||
#define HCLGE_PF_RAS_INT_MIN_BD_NUM 4
|
||||
|
@ -3265,6 +3265,38 @@ static int hclge_func_reset_sync_vf(struct hclge_dev *hdev)
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
void hclge_report_hw_error(struct hclge_dev *hdev,
|
||||
enum hnae3_hw_error_type type)
|
||||
{
|
||||
struct hnae3_client *client = hdev->nic_client;
|
||||
u16 i;
|
||||
|
||||
if (!client || !client->ops->process_hw_error ||
|
||||
!test_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state))
|
||||
return;
|
||||
|
||||
for (i = 0; i < hdev->num_vmdq_vport + 1; i++)
|
||||
client->ops->process_hw_error(&hdev->vport[i].nic, type);
|
||||
}
|
||||
|
||||
static void hclge_handle_imp_error(struct hclge_dev *hdev)
|
||||
{
|
||||
u32 reg_val;
|
||||
|
||||
reg_val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
|
||||
if (reg_val & BIT(HCLGE_VECTOR0_IMP_RD_POISON_B)) {
|
||||
hclge_report_hw_error(hdev, HNAE3_IMP_RD_POISON_ERROR);
|
||||
reg_val &= ~BIT(HCLGE_VECTOR0_IMP_RD_POISON_B);
|
||||
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, reg_val);
|
||||
}
|
||||
|
||||
if (reg_val & BIT(HCLGE_VECTOR0_IMP_CMDQ_ERR_B)) {
|
||||
hclge_report_hw_error(hdev, HNAE3_CMDQ_ECC_ERROR);
|
||||
reg_val &= ~BIT(HCLGE_VECTOR0_IMP_CMDQ_ERR_B);
|
||||
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, reg_val);
|
||||
}
|
||||
}
|
||||
|
||||
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id)
|
||||
{
|
||||
struct hclge_desc desc;
|
||||
@ -3471,6 +3503,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
|
||||
hdev->rst_stats.flr_rst_cnt++;
|
||||
break;
|
||||
case HNAE3_IMP_RESET:
|
||||
hclge_handle_imp_error(hdev);
|
||||
reg_val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
|
||||
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG,
|
||||
BIT(HCLGE_VECTOR0_IMP_RESET_INT_B) | reg_val);
|
||||
|
@ -178,6 +178,8 @@ enum HLCGE_PORT_TYPE {
|
||||
#define HCLGE_VECTOR0_RX_CMDQ_INT_B 1
|
||||
|
||||
#define HCLGE_VECTOR0_IMP_RESET_INT_B 1
|
||||
#define HCLGE_VECTOR0_IMP_CMDQ_ERR_B 4U
|
||||
#define HCLGE_VECTOR0_IMP_RD_POISON_B 5U
|
||||
|
||||
#define HCLGE_MAC_DEFAULT_FRAME \
|
||||
(ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN + ETH_DATA_LEN)
|
||||
@ -986,4 +988,6 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
|
||||
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
|
||||
int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
|
||||
struct hclge_desc *desc);
|
||||
void hclge_report_hw_error(struct hclge_dev *hdev,
|
||||
enum hnae3_hw_error_type type);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user