提交 b48dd469 编写于 作者: L liweihang 提交者: Xie XiuQi

net: hns3: trigger VF reset if a VF has an over_8bd_nfe_err

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

We trigger PF reset when a RAS error of NIC named over_8bd_nfe_err
occurred before. But it is possible that a VF causes that error, it's
reasonable to trigger VF reset instead of PF reset in this case.
This patch add detection of vf_id if a over_8bd_nfe_err occurs, if
vf_id is 0, we trigger PF reset. Otherwise, we will trigger VF reset
on the VF with error.

Feature or Bugfix: Bugfix
Signed-off-by: Nliweihang <liweihang@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 c3f76fb7
...@@ -193,6 +193,9 @@ enum hclge_opcode_type { ...@@ -193,6 +193,9 @@ enum hclge_opcode_type {
HCLGE_OPC_CFG_COM_TQP_QUEUE = 0x0B20, HCLGE_OPC_CFG_COM_TQP_QUEUE = 0x0B20,
HCLGE_OPC_RESET_TQP_QUEUE = 0x0B22, HCLGE_OPC_RESET_TQP_QUEUE = 0x0B22,
/* PPU commands */
HCLGE_OPC_PPU_PF_OTHER_INT_DFX = 0x0B4A,
/* TSO command */ /* TSO command */
HCLGE_OPC_TSO_GENERIC_CONFIG = 0x0C01, HCLGE_OPC_TSO_GENERIC_CONFIG = 0x0C01,
HCLGE_OPC_GRO_GENERIC_CONFIG = 0x0C10, HCLGE_OPC_GRO_GENERIC_CONFIG = 0x0C10,
...@@ -1009,6 +1012,20 @@ struct hclge_fd_ad_config_cmd { ...@@ -1009,6 +1012,20 @@ struct hclge_fd_ad_config_cmd {
u8 rsv2[8]; u8 rsv2[8];
}; };
struct hclge_query_ppu_pf_other_int_dfx_cmd {
__le16 over_8bd_no_fe_qid;
__le16 over_8bd_no_fe_vf_id;
__le16 tso_mss_cmp_min_err_qid;
__le16 tso_mss_cmp_min_err_vf_id;
__le16 tso_mss_cmp_max_err_qid;
__le16 tso_mss_cmp_max_err_vf_id;
__le16 tx_rd_fbd_poison_qid;
__le16 tx_rd_fbd_poison_vf_id;
__le16 rx_rd_fbd_poison_qid;
__le16 rx_rd_fbd_poison_vf_id;
u8 rsv[4];
};
int hclge_cmd_init(struct hclge_dev *hdev); int hclge_cmd_init(struct hclge_dev *hdev);
static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value) static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value)
{ {
......
...@@ -1674,6 +1674,81 @@ static int hclge_clear_hw_msix_error(struct hclge_dev *hdev, ...@@ -1674,6 +1674,81 @@ static int hclge_clear_hw_msix_error(struct hclge_dev *hdev,
return hclge_cmd_send(&hdev->hw, &desc[0], bd_num); return hclge_cmd_send(&hdev->hw, &desc[0], bd_num);
} }
/* hclge_query_8bd_info: query information about over_8bd_nfe_err
* @hdev: pointer to struct hclge_dev
* @vf_id: Index of the virtual function with error
* @q_id: Physical index of the queue with error
*
* This function get specific index of queue and function which causes
* over_8bd_nfe_err by using command. If vf_id is 0, it means error is
* caused by PF instead of VF.
*/
static int hclge_query_over_8bd_err_info(struct hclge_dev *hdev, u16 *vf_id,
u16 *q_id)
{
struct hclge_query_ppu_pf_other_int_dfx_cmd *req;
struct hclge_desc desc;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PPU_PF_OTHER_INT_DFX, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
return ret;
req = (struct hclge_query_ppu_pf_other_int_dfx_cmd *)desc.data;
*vf_id = le16_to_cpu(req->over_8bd_no_fe_vf_id);
*q_id = le16_to_cpu(req->over_8bd_no_fe_qid);
return 0;
}
/* hclge_handle_over_8bd_err: handle MSI-X error named over_8bd_nfe_err
* @hdev: pointer to struct hclge_dev
* @reset_requests: reset level that we need to trigger later
*
* over_8bd_nfe_err is a special MSI-X because it may caused by a VF, in
* that case, we need to trigger VF reset. Otherwise, a PF reset is needed.
*/
static void hclge_handle_over_8bd_err(struct hclge_dev *hdev,
unsigned long *reset_requests)
{
struct device *dev = &hdev->pdev->dev;
u16 vf_id;
u16 q_id;
int ret;
ret = hclge_query_over_8bd_err_info(hdev, &vf_id, &q_id);
if (ret) {
dev_err(dev, "fail(%d) to query over_8bd_no_fe info\n",
ret);
return;
}
dev_warn(dev, "PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found, vf_id(%d), queue_id(%d)\n",
vf_id, q_id);
if (vf_id) {
if (vf_id >= hdev->num_alloc_vport) {
dev_err(dev, "invalid vf id(%d)\n", vf_id);
return;
}
/* If we need to trigger other reset whose level is higher
* than HNAE3_VF_FUNC_RESET, no need to trigger a VF reset
* here.
*/
if (*reset_requests != 0)
return;
ret = hclge_inform_reset_assert_to_vf(&hdev->vport[vf_id]);
if (ret)
dev_warn(dev, "inform reset to vf(%d) failed %d!\n",
hdev->vport->vport_id, ret);
} else {
set_bit(HNAE3_FUNC_RESET, reset_requests);
}
}
/* hclge_handle_mpf_msix_error: handle all main PF MSI-X errors /* hclge_handle_mpf_msix_error: handle all main PF MSI-X errors
* @hdev: pointer to struct hclge_dev * @hdev: pointer to struct hclge_dev
* @desc: descriptor for describing the command * @desc: descriptor for describing the command
...@@ -1719,12 +1794,10 @@ static int hclge_handle_mpf_msix_error(struct hclge_dev *hdev, ...@@ -1719,12 +1794,10 @@ static int hclge_handle_mpf_msix_error(struct hclge_dev *hdev,
/* clear all main PF MSIx errors */ /* clear all main PF MSIx errors */
ret = hclge_clear_hw_msix_error(hdev, desc, true, mpf_bd_num); ret = hclge_clear_hw_msix_error(hdev, desc, true, mpf_bd_num);
if (ret) { if (ret)
dev_err(dev, "clear all mpf msix int cmd failed (%d)\n", ret); dev_err(dev, "clear all mpf msix int cmd failed (%d)\n", ret);
return ret;
}
return 0; return ret;
} }
/* hclge_handle_pf_msix_error: handle all PF MSI-X errors /* hclge_handle_pf_msix_error: handle all PF MSI-X errors
...@@ -1778,14 +1851,16 @@ static int hclge_handle_pf_msix_error(struct hclge_dev *hdev, ...@@ -1778,14 +1851,16 @@ static int hclge_handle_pf_msix_error(struct hclge_dev *hdev,
&hclge_ppu_pf_abnormal_int[0], &hclge_ppu_pf_abnormal_int[0],
status, reset_requests); status, reset_requests);
status = le32_to_cpu(*desc_data) & HCLGE_PPU_PF_OVER_8BD_ERR_MASK;
if (status)
hclge_handle_over_8bd_err(hdev, reset_requests);
/* clear all PF MSIx errors */ /* clear all PF MSIx errors */
ret = hclge_clear_hw_msix_error(hdev, desc, false, pf_bd_num); ret = hclge_clear_hw_msix_error(hdev, desc, false, pf_bd_num);
if (ret) { if (ret)
dev_err(dev, "clear all pf msix int cmd failed (%d)\n", ret); dev_err(dev, "clear all pf msix int cmd failed (%d)\n", ret);
return ret;
}
return 0; return ret;
} }
static int hclge_handle_all_hw_msix_error(struct hclge_dev *hdev, static int hclge_handle_all_hw_msix_error(struct hclge_dev *hdev,
......
...@@ -83,7 +83,8 @@ ...@@ -83,7 +83,8 @@
#define HCLGE_PPU_MPF_INT_ST3_MASK GENMASK(7, 0) #define HCLGE_PPU_MPF_INT_ST3_MASK GENMASK(7, 0)
#define HCLGE_PPU_MPF_INT_ST2_MSIX_MASK BIT(29) #define HCLGE_PPU_MPF_INT_ST2_MSIX_MASK BIT(29)
#define HCLGE_PPU_PF_INT_RAS_MASK 0x18 #define HCLGE_PPU_PF_INT_RAS_MASK 0x18
#define HCLGE_PPU_PF_INT_MSIX_MASK 0x27 #define HCLGE_PPU_PF_INT_MSIX_MASK 0x26
#define HCLGE_PPU_PF_OVER_8BD_ERR_MASK 0x01
#define HCLGE_QCN_FIFO_INT_MASK GENMASK(17, 0) #define HCLGE_QCN_FIFO_INT_MASK GENMASK(17, 0)
#define HCLGE_QCN_ECC_INT_MASK GENMASK(21, 0) #define HCLGE_QCN_ECC_INT_MASK GENMASK(21, 0)
#define HCLGE_NCSI_ECC_INT_MASK GENMASK(1, 0) #define HCLGE_NCSI_ECC_INT_MASK GENMASK(1, 0)
......
...@@ -125,7 +125,7 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) ...@@ -125,7 +125,7 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
else if (hdev->reset_type == HNAE3_FLR_RESET) else if (hdev->reset_type == HNAE3_FLR_RESET)
reset_type = HNAE3_VF_FULL_RESET; reset_type = HNAE3_VF_FULL_RESET;
else else
return -EINVAL; reset_type = HNAE3_VF_FUNC_RESET;
memcpy(&msg_data[0], &reset_type, sizeof(u16)); memcpy(&msg_data[0], &reset_type, sizeof(u16));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册