mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
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
7 changed files with 78 additions and 2 deletions
|
@ -146,6 +146,12 @@ enum hnae3_reset_notify_type {
|
||||||
HNAE3_RESTORE_CLIENT,
|
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 {
|
enum hnae3_reset_type {
|
||||||
HNAE3_VF_RESET,
|
HNAE3_VF_RESET,
|
||||||
HNAE3_VF_FUNC_RESET,
|
HNAE3_VF_FUNC_RESET,
|
||||||
|
@ -210,7 +216,8 @@ struct hnae3_client_ops {
|
||||||
int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
|
int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
|
||||||
int (*reset_notify)(struct hnae3_handle *handle,
|
int (*reset_notify)(struct hnae3_handle *handle,
|
||||||
enum hnae3_reset_notify_type type);
|
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
|
#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);
|
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 = {
|
static const struct hnae3_client_ops client_ops = {
|
||||||
.init_instance = hns3_client_init,
|
.init_instance = hns3_client_init,
|
||||||
.uninit_instance = hns3_client_uninit,
|
.uninit_instance = hns3_client_uninit,
|
||||||
.link_status_change = hns3_link_status_change,
|
.link_status_change = hns3_link_status_change,
|
||||||
.setup_tc = hns3_client_setup_tc,
|
.setup_tc = hns3_client_setup_tc,
|
||||||
.reset_notify = hns3_reset_notify,
|
.reset_notify = hns3_reset_notify,
|
||||||
|
.process_hw_error = hns3_process_hw_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* hns3_init_module - Driver registration routine
|
/* hns3_init_module - Driver registration routine
|
||||||
|
|
|
@ -552,6 +552,11 @@ union l4_hdr_info {
|
||||||
unsigned char *hdr;
|
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)
|
static inline int ring_space(struct hns3_enet_ring *ring)
|
||||||
{
|
{
|
||||||
/* This smp_load_acquire() pairs with smp_store_release() in
|
/* 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 */
|
/* log PPU(RCB) errors */
|
||||||
desc_data = (__le32 *)&desc[3];
|
desc_data = (__le32 *)&desc[3];
|
||||||
status = le32_to_cpu(*desc_data) & HCLGE_PPU_PF_INT_RAS_MASK;
|
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_log_error(dev, "PPU_PF_ABNORMAL_INT_ST0",
|
||||||
&hclge_ppu_pf_abnormal_int[0], status,
|
&hclge_ppu_pf_abnormal_int[0], status,
|
||||||
&ae_dev->hw_err_reset_req);
|
&ae_dev->hw_err_reset_req);
|
||||||
|
hclge_report_hw_error(hdev, HNAE3_PPU_POISON_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/* clear all PF RAS errors */
|
/* clear all PF RAS errors */
|
||||||
hclge_cmd_reuse_desc(&desc[0], false);
|
hclge_cmd_reuse_desc(&desc[0], false);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#define __HCLGE_ERR_H
|
#define __HCLGE_ERR_H
|
||||||
|
|
||||||
#include "hclge_main.h"
|
#include "hclge_main.h"
|
||||||
|
#include "hnae3.h"
|
||||||
|
|
||||||
#define HCLGE_MPF_RAS_INT_MIN_BD_NUM 10
|
#define HCLGE_MPF_RAS_INT_MIN_BD_NUM 10
|
||||||
#define HCLGE_PF_RAS_INT_MIN_BD_NUM 4
|
#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;
|
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)
|
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id)
|
||||||
{
|
{
|
||||||
struct hclge_desc desc;
|
struct hclge_desc desc;
|
||||||
|
@ -3471,6 +3503,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
|
||||||
hdev->rst_stats.flr_rst_cnt++;
|
hdev->rst_stats.flr_rst_cnt++;
|
||||||
break;
|
break;
|
||||||
case HNAE3_IMP_RESET:
|
case HNAE3_IMP_RESET:
|
||||||
|
hclge_handle_imp_error(hdev);
|
||||||
reg_val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
|
reg_val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
|
||||||
hclge_write_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);
|
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_RX_CMDQ_INT_B 1
|
||||||
|
|
||||||
#define HCLGE_VECTOR0_IMP_RESET_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 \
|
#define HCLGE_MAC_DEFAULT_FRAME \
|
||||||
(ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN + ETH_DATA_LEN)
|
(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);
|
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
|
||||||
int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
|
int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
|
||||||
struct hclge_desc *desc);
|
struct hclge_desc *desc);
|
||||||
|
void hclge_report_hw_error(struct hclge_dev *hdev,
|
||||||
|
enum hnae3_hw_error_type type);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue