diff options
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3')
13 files changed, 621 insertions, 483 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h index d87158acdf6f..948e67ef30fd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h @@ -7,8 +7,6 @@ #include <linux/mutex.h> #include <linux/types.h> -#define HCLGE_MBX_VF_MSG_DATA_NUM 16 - enum HCLGE_MBX_OPCODE { HCLGE_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ HCLGE_MBX_ASSERTING_RESET, /* (PF -> VF) PF is asserting reset*/ @@ -72,10 +70,15 @@ enum hclge_mbx_vlan_cfg_subcode { HCLGE_MBX_GET_PORT_BASE_VLAN_STATE, /* get port based vlan state */ }; -#define HCLGE_MBX_MAX_MSG_SIZE 16 +#define HCLGE_MBX_MAX_MSG_SIZE 14 #define HCLGE_MBX_MAX_RESP_DATA_SIZE 8U -#define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM 3 -#define HCLGE_MBX_RING_NODE_VARIABLE_NUM 3 +#define HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM 4 + +struct hclge_ring_chain_param { + u8 ring_type; + u8 tqp_index; + u8 int_gl_index; +}; struct hclgevf_mbx_resp_status { struct mutex mbx_mutex; /* protects against contending sync cmd resp */ @@ -85,6 +88,41 @@ struct hclgevf_mbx_resp_status { u8 additional_info[HCLGE_MBX_MAX_RESP_DATA_SIZE]; }; +struct hclge_respond_to_vf_msg { + int status; + u8 data[HCLGE_MBX_MAX_RESP_DATA_SIZE]; + u16 len; +}; + +struct hclge_vf_to_pf_msg { + u8 code; + union { + struct { + u8 subcode; + u8 data[HCLGE_MBX_MAX_MSG_SIZE]; + }; + struct { + u8 en_bc; + u8 en_uc; + u8 en_mc; + }; + struct { + u8 vector_id; + u8 ring_num; + struct hclge_ring_chain_param + param[HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM]; + }; + }; +}; + +struct hclge_pf_to_vf_msg { + u16 code; + u16 vf_mbx_msg_code; + u16 vf_mbx_msg_subcode; + u16 resp_status; + u8 resp_data[HCLGE_MBX_MAX_RESP_DATA_SIZE]; +}; + struct hclge_mbx_vf_to_pf_cmd { u8 rsv; u8 mbx_src_vfid; /* Auto filled by IMP */ @@ -92,17 +130,17 @@ struct hclge_mbx_vf_to_pf_cmd { u8 rsv1[1]; u8 msg_len; u8 rsv2[3]; - u8 msg[HCLGE_MBX_MAX_MSG_SIZE]; + struct hclge_vf_to_pf_msg msg; }; -#define HCLGE_MBX_NEED_RESP_BIT BIT(0) +#define HCLGE_MBX_NEED_RESP_B 0 struct hclge_mbx_pf_to_vf_cmd { u8 dest_vfid; u8 rsv[3]; u8 msg_len; u8 rsv1[3]; - u16 msg[8]; + struct hclge_pf_to_vf_msg msg; }; struct hclge_vf_rst_cmd { diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index a3e4081b84ba..5587605d6deb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -78,6 +78,7 @@ enum hns_desc_type { DESC_TYPE_SKB, + DESC_TYPE_FRAGLIST_SKB, DESC_TYPE_PAGE, }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index 1d4ffc5f408a..e1d88095a77e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -260,6 +260,8 @@ static void hns3_dbg_help(struct hnae3_handle *h) dev_info(&h->pdev->dev, "dump m7 info\n"); dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n"); dev_info(&h->pdev->dev, "dump mac tnl status\n"); + dev_info(&h->pdev->dev, "dump loopback\n"); + dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); memset(printf_buf, 0, HNS3_DBG_BUF_LEN); strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]", diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index a7f40aa1a0ea..da98fd7c8eca 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1107,6 +1107,10 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, return ret; dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); + } else if (type == DESC_TYPE_FRAGLIST_SKB) { + struct sk_buff *skb = (struct sk_buff *)priv; + + dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); } else { frag = (skb_frag_t *)priv; dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE); @@ -1144,8 +1148,9 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */ desc_cb->priv = priv; desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k; - desc_cb->type = (type == DESC_TYPE_SKB && !k) ? - DESC_TYPE_SKB : DESC_TYPE_PAGE; + desc_cb->type = ((type == DESC_TYPE_FRAGLIST_SKB || + type == DESC_TYPE_SKB) && !k) ? + type : DESC_TYPE_PAGE; /* now, fill the descriptor */ desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k); @@ -1354,7 +1359,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) ring_ptr_move_bw(ring, next_to_use); /* unmap the descriptor dma address */ - if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB) + if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB || + ring->desc_cb[ring->next_to_use].type == + DESC_TYPE_FRAGLIST_SKB) dma_unmap_single(dev, ring->desc_cb[ring->next_to_use].dma, ring->desc_cb[ring->next_to_use].length, @@ -1447,7 +1454,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) goto out; skb_walk_frags(skb, frag_skb) { - ret = hns3_fill_skb_to_desc(ring, frag_skb, DESC_TYPE_PAGE); + ret = hns3_fill_skb_to_desc(ring, frag_skb, + DESC_TYPE_FRAGLIST_SKB); if (unlikely(ret < 0)) goto fill_err; @@ -2228,7 +2236,7 @@ static void hns3_reset_prepare(struct pci_dev *pdev) { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); - dev_info(&pdev->dev, "hns3 flr prepare\n"); + dev_info(&pdev->dev, "FLR prepare\n"); if (ae_dev && ae_dev->ops && ae_dev->ops->flr_prepare) ae_dev->ops->flr_prepare(ae_dev); } @@ -2237,7 +2245,7 @@ static void hns3_reset_done(struct pci_dev *pdev) { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); - dev_info(&pdev->dev, "hns3 flr done\n"); + dev_info(&pdev->dev, "FLR done\n"); if (ae_dev && ae_dev->ops && ae_dev->ops->flr_done) ae_dev->ops->flr_done(ae_dev); } @@ -2356,7 +2364,7 @@ static int hns3_map_buffer(struct hns3_enet_ring *ring, struct hns3_desc_cb *cb) static void hns3_unmap_buffer(struct hns3_enet_ring *ring, struct hns3_desc_cb *cb) { - if (cb->type == DESC_TYPE_SKB) + if (cb->type == DESC_TYPE_SKB || cb->type == DESC_TYPE_FRAGLIST_SKB) dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length, ring_to_dma_dir(ring)); else if (cb->length) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index c03856e63320..28b81f24afa1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -736,7 +736,7 @@ static int hns3_check_ksettings_param(const struct net_device *netdev, if (ops->get_media_type) ops->get_media_type(handle, &media_type, &module_type); - if (cmd->base.duplex != DUPLEX_FULL && + if (cmd->base.duplex == DUPLEX_HALF && media_type != HNAE3_MEDIA_TYPE_COPPER) { netdev_err(netdev, "only copper port supports half duplex!"); @@ -1390,7 +1390,13 @@ static int hns3_set_fecparam(struct net_device *netdev, return ops->set_fec(handle, fec_mode); } +#define HNS3_ETHTOOL_COALESCE (ETHTOOL_COALESCE_USECS | \ + ETHTOOL_COALESCE_USE_ADAPTIVE | \ + ETHTOOL_COALESCE_RX_USECS_HIGH | \ + ETHTOOL_COALESCE_TX_USECS_HIGH) + static const struct ethtool_ops hns3vf_ethtool_ops = { + .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, .get_drvinfo = hns3_get_drvinfo, .get_ringparam = hns3_get_ringparam, .set_ringparam = hns3_set_ringparam, @@ -1416,6 +1422,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = { }; static const struct ethtool_ops hns3_ethtool_ops = { + .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, .self_test = hns3_self_test, .get_drvinfo = hns3_get_drvinfo, .get_link = hns3_get_link, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 67fad80035d3..17228288d4df 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -87,7 +87,7 @@ static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset) entries_per_desc = ARRAY_SIZE(desc[0].data); index = offset % entries_per_desc; - return (int)desc[offset / entries_per_desc].data[index]; + return le32_to_cpu(desc[offset / entries_per_desc].data[index]); } static int hclge_dbg_cmd_send(struct hclge_dev *hdev, @@ -145,10 +145,8 @@ static void hclge_dbg_dump_reg_common(struct hclge_dev *hdev, buf_len = sizeof(struct hclge_desc) * bd_num; desc_src = kzalloc(buf_len, GFP_KERNEL); - if (!desc_src) { - dev_err(&hdev->pdev->dev, "call kzalloc failed\n"); + if (!desc_src) return; - } desc = desc_src; ret = hclge_dbg_cmd_send(hdev, desc, index, bd_num, reg_msg->cmd); @@ -179,6 +177,7 @@ static void hclge_dbg_dump_dcb(struct hclge_dev *hdev, const char *cmd_buf) { struct device *dev = &hdev->pdev->dev; struct hclge_dbg_bitmap_cmd *bitmap; + enum hclge_opcode_type cmd; int rq_id, pri_id, qset_id; int port_id, nq_id, pg_id; struct hclge_desc desc[2]; @@ -193,10 +192,10 @@ static void hclge_dbg_dump_dcb(struct hclge_dev *hdev, const char *cmd_buf) return; } - ret = hclge_dbg_cmd_send(hdev, desc, qset_id, 1, - HCLGE_OPC_QSET_DFX_STS); + cmd = HCLGE_OPC_QSET_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, qset_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "roce_qset_mask: 0x%x\n", bitmap->bit0); @@ -204,48 +203,53 @@ static void hclge_dbg_dump_dcb(struct hclge_dev *hdev, const char *cmd_buf) dev_info(dev, "qs_shaping_pass: 0x%x\n", bitmap->bit2); dev_info(dev, "qs_bp_sts: 0x%x\n", bitmap->bit3); - ret = hclge_dbg_cmd_send(hdev, desc, pri_id, 1, HCLGE_OPC_PRI_DFX_STS); + cmd = HCLGE_OPC_PRI_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, pri_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "pri_mask: 0x%x\n", bitmap->bit0); dev_info(dev, "pri_cshaping_pass: 0x%x\n", bitmap->bit1); dev_info(dev, "pri_pshaping_pass: 0x%x\n", bitmap->bit2); - ret = hclge_dbg_cmd_send(hdev, desc, pg_id, 1, HCLGE_OPC_PG_DFX_STS); + cmd = HCLGE_OPC_PG_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, pg_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "pg_mask: 0x%x\n", bitmap->bit0); dev_info(dev, "pg_cshaping_pass: 0x%x\n", bitmap->bit1); dev_info(dev, "pg_pshaping_pass: 0x%x\n", bitmap->bit2); - ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, - HCLGE_OPC_PORT_DFX_STS); + cmd = HCLGE_OPC_PORT_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "port_mask: 0x%x\n", bitmap->bit0); dev_info(dev, "port_shaping_pass: 0x%x\n", bitmap->bit1); - ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, HCLGE_OPC_SCH_NQ_CNT); + cmd = HCLGE_OPC_SCH_NQ_CNT; + ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; dev_info(dev, "sch_nq_cnt: 0x%x\n", le32_to_cpu(desc[0].data[1])); - ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, HCLGE_OPC_SCH_RQ_CNT); + cmd = HCLGE_OPC_SCH_RQ_CNT; + ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; dev_info(dev, "sch_rq_cnt: 0x%x\n", le32_to_cpu(desc[0].data[1])); - ret = hclge_dbg_cmd_send(hdev, desc, 0, 2, HCLGE_OPC_TM_INTERNAL_STS); + cmd = HCLGE_OPC_TM_INTERNAL_STS; + ret = hclge_dbg_cmd_send(hdev, desc, 0, 2, cmd); if (ret) - return; + goto err_dcb_cmd_send; dev_info(dev, "pri_bp: 0x%x\n", le32_to_cpu(desc[0].data[1])); dev_info(dev, "fifo_dfx_info: 0x%x\n", le32_to_cpu(desc[0].data[2])); @@ -257,18 +261,18 @@ static void hclge_dbg_dump_dcb(struct hclge_dev *hdev, const char *cmd_buf) dev_info(dev, "SSU_TM_BYPASS_EN: 0x%x\n", le32_to_cpu(desc[1].data[0])); dev_info(dev, "SSU_RESERVE_CFG: 0x%x\n", le32_to_cpu(desc[1].data[1])); - ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, - HCLGE_OPC_TM_INTERNAL_CNT); + cmd = HCLGE_OPC_TM_INTERNAL_CNT; + ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; dev_info(dev, "SCH_NIC_NUM: 0x%x\n", le32_to_cpu(desc[0].data[1])); dev_info(dev, "SCH_ROCE_NUM: 0x%x\n", le32_to_cpu(desc[0].data[2])); - ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, - HCLGE_OPC_TM_INTERNAL_STS_1); + cmd = HCLGE_OPC_TM_INTERNAL_STS_1; + ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; dev_info(dev, "TC_MAP_SEL: 0x%x\n", le32_to_cpu(desc[0].data[1])); dev_info(dev, "IGU_PFC_PRI_EN: 0x%x\n", le32_to_cpu(desc[0].data[2])); @@ -277,6 +281,12 @@ static void hclge_dbg_dump_dcb(struct hclge_dev *hdev, const char *cmd_buf) le32_to_cpu(desc[0].data[4])); dev_info(dev, "IGU_TX_PRI_MAP_TC_CFG: 0x%x\n", le32_to_cpu(desc[0].data[5])); + return; + +err_dcb_cmd_send: + dev_err(&hdev->pdev->dev, + "failed to dump dcb dfx, cmd = %#x, ret = %d\n", + cmd, ret); } static void hclge_dbg_dump_reg_cmd(struct hclge_dev *hdev, const char *cmd_buf) @@ -310,8 +320,9 @@ static void hclge_title_idx_print(struct hclge_dev *hdev, bool flag, int index, char *false_buf) { if (flag) - dev_info(&hdev->pdev->dev, "%s(%d): %s\n", title_buf, index, - true_buf); + dev_info(&hdev->pdev->dev, "%s(%d): %s weight: %u\n", + title_buf, index, true_buf, + hdev->tm_info.pg_info[0].tc_dwrr[index]); else dev_info(&hdev->pdev->dev, "%s(%d): %s\n", title_buf, index, false_buf); @@ -339,7 +350,8 @@ static void hclge_dbg_dump_tc(struct hclge_dev *hdev) ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data; - dev_info(&hdev->pdev->dev, "dump tc\n"); + dev_info(&hdev->pdev->dev, "dump tc: %u tc enabled\n", + hdev->tm_info.num_tc); dev_info(&hdev->pdev->dev, "weight_offset: %u\n", ets_weight->weight_offset); @@ -581,7 +593,7 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) goto err_tm_map_cmd_send; - qset_id = nq_to_qs_map->qset_id & 0x3FF; + qset_id = le16_to_cpu(nq_to_qs_map->qset_id) & 0x3FF; cmd = HCLGE_OPC_TM_QS_TO_PRI_LINK; map = (struct hclge_qs_to_pri_link_cmd *)desc.data; @@ -621,7 +633,8 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, if (ret) goto err_tm_map_cmd_send; - qset_maping[group_id] = bp_to_qs_map_cmd->qs_bit_map; + qset_maping[group_id] = + le32_to_cpu(bp_to_qs_map_cmd->qs_bit_map); } dev_info(&hdev->pdev->dev, "index | tm bp qset maping:\n"); @@ -824,6 +837,7 @@ static void hclge_dbg_dump_mng_table(struct hclge_dev *hdev) struct hclge_mac_ethertype_idx_rd_cmd *req0; char printf_buf[HCLGE_DBG_BUF_LEN]; struct hclge_desc desc; + u32 msg_egress_port; int ret, i; dev_info(&hdev->pdev->dev, "mng tab:\n"); @@ -865,20 +879,21 @@ static void hclge_dbg_dump_mng_table(struct hclge_dev *hdev) HCLGE_DBG_BUF_LEN - strlen(printf_buf), "%x |%04x |%x |%04x|%x |%02x |%02x |", !!(req0->flags & HCLGE_DBG_MNG_MAC_MASK_B), - req0->ethter_type, + le16_to_cpu(req0->ethter_type), !!(req0->flags & HCLGE_DBG_MNG_ETHER_MASK_B), - req0->vlan_tag & HCLGE_DBG_MNG_VLAN_TAG, + le16_to_cpu(req0->vlan_tag) & HCLGE_DBG_MNG_VLAN_TAG, !!(req0->flags & HCLGE_DBG_MNG_VLAN_MASK_B), req0->i_port_bitmap, req0->i_port_direction); + msg_egress_port = le16_to_cpu(req0->egress_port); snprintf(printf_buf + strlen(printf_buf), HCLGE_DBG_BUF_LEN - strlen(printf_buf), - "%d |%d |%02d |%04d|%x\n", - !!(req0->egress_port & HCLGE_DBG_MNG_E_TYPE_B), - req0->egress_port & HCLGE_DBG_MNG_PF_ID, - (req0->egress_port >> 3) & HCLGE_DBG_MNG_VF_ID, - req0->egress_queue, - !!(req0->egress_port & HCLGE_DBG_MNG_DROP_B)); + "%x |%x |%02x |%04x|%x\n", + !!(msg_egress_port & HCLGE_DBG_MNG_E_TYPE_B), + msg_egress_port & HCLGE_DBG_MNG_PF_ID, + (msg_egress_port >> 3) & HCLGE_DBG_MNG_VF_ID, + le16_to_cpu(req0->egress_queue), + !!(msg_egress_port & HCLGE_DBG_MNG_DROP_B)); dev_info(&hdev->pdev->dev, "%s", printf_buf); } @@ -1065,11 +1080,8 @@ static void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev) buf_len = sizeof(struct hclge_desc) * bd_num; desc_src = kzalloc(buf_len, GFP_KERNEL); - if (!desc_src) { - dev_err(&hdev->pdev->dev, - "allocate desc for get_m7_stats failed\n"); + if (!desc_src) return; - } desc_tmp = desc_src; ret = hclge_dbg_cmd_send(hdev, desc_tmp, 0, bd_num, @@ -1132,7 +1144,7 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev, const char *cmd_buf) { #define HCLGE_MAX_NCL_CONFIG_OFFSET 4096 -#define HCLGE_MAX_NCL_CONFIG_LENGTH (20 + 24 * 4) +#define HCLGE_NCL_CONFIG_LENGTH_IN_EACH_CMD (20 + 24 * 4) struct hclge_desc desc[HCLGE_CMD_NCL_CONFIG_BD_NUM]; int bd_num = HCLGE_CMD_NCL_CONFIG_BD_NUM; @@ -1156,8 +1168,8 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev, while (length > 0) { data0 = offset; - if (length >= HCLGE_MAX_NCL_CONFIG_LENGTH) - data0 |= HCLGE_MAX_NCL_CONFIG_LENGTH << 16; + if (length >= HCLGE_NCL_CONFIG_LENGTH_IN_EACH_CMD) + data0 |= HCLGE_NCL_CONFIG_LENGTH_IN_EACH_CMD << 16; else data0 |= length << 16; ret = hclge_dbg_cmd_send(hdev, desc, data0, bd_num, @@ -1169,6 +1181,57 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev, } } +static void hclge_dbg_dump_loopback(struct hclge_dev *hdev, + const char *cmd_buf) +{ + struct phy_device *phydev = hdev->hw.mac.phydev; + struct hclge_config_mac_mode_cmd *req_app; + struct hclge_serdes_lb_cmd *req_serdes; + struct hclge_desc desc; + u8 loopback_en; + int ret; + + req_app = (struct hclge_config_mac_mode_cmd *)desc.data; + req_serdes = (struct hclge_serdes_lb_cmd *)desc.data; + + dev_info(&hdev->pdev->dev, "mac id: %u\n", hdev->hw.mac.mac_id); + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAC_MODE, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to dump app loopback status, ret = %d\n", ret); + return; + } + + loopback_en = hnae3_get_bit(le32_to_cpu(req_app->txrx_pad_fcs_loop_en), + HCLGE_MAC_APP_LP_B); + dev_info(&hdev->pdev->dev, "app loopback: %s\n", + loopback_en ? "on" : "off"); + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to dump serdes loopback status, ret = %d\n", + ret); + return; + } + + loopback_en = req_serdes->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B; + dev_info(&hdev->pdev->dev, "serdes serial loopback: %s\n", + loopback_en ? "on" : "off"); + + loopback_en = req_serdes->enable & + HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B; + dev_info(&hdev->pdev->dev, "serdes parallel loopback: %s\n", + loopback_en ? "on" : "off"); + + if (phydev) + dev_info(&hdev->pdev->dev, "phy loopback: %s\n", + phydev->loopback_enabled ? "on" : "off"); +} + /* hclge_dbg_dump_mac_tnl_status: print message about mac tnl interrupt * @hdev: pointer to struct hclge_dev */ @@ -1269,6 +1332,7 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) { #define DUMP_REG "dump reg" #define DUMP_TM_MAP "dump tm map" +#define DUMP_LOOPBACK "dump loopback" struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -1302,6 +1366,9 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) &cmd_buf[sizeof("dump ncl_config")]); } else if (strncmp(cmd_buf, "dump mac tnl status", 19) == 0) { hclge_dbg_dump_mac_tnl_status(hdev); + } else if (strncmp(cmd_buf, DUMP_LOOPBACK, + strlen(DUMP_LOOPBACK)) == 0) { + hclge_dbg_dump_loopback(hdev, &cmd_buf[sizeof(DUMP_LOOPBACK)]); } else if (strncmp(cmd_buf, "dump qs shaper", 14) == 0) { hclge_dbg_dump_qs_shaper(hdev, &cmd_buf[sizeof("dump qs shaper")]); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c index c85b72dc44d2..50d5ef71756b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c @@ -1667,9 +1667,6 @@ pci_ers_result_t hclge_handle_hw_ras_error(struct hnae3_ae_dev *ae_dev) hclge_handle_rocee_ras_error(ae_dev); } - if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) - goto out; - if (ae_dev->hw_err_reset_req) return PCI_ERS_RESULT_NEED_RESET; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index d3b0cd74ecd2..a758f9ae32be 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -824,6 +824,8 @@ static void hclge_get_mac_stat(struct hnae3_handle *handle, static int hclge_parse_func_status(struct hclge_dev *hdev, struct hclge_func_status_cmd *status) { +#define HCLGE_MAC_ID_MASK 0xF + if (!(status->pf_state & HCLGE_PF_STATE_DONE)) return -EINVAL; @@ -833,6 +835,7 @@ static int hclge_parse_func_status(struct hclge_dev *hdev, else hdev->flag &= ~HCLGE_FLAG_MAIN; + hdev->hw.mac.mac_id = status->mac_id & HCLGE_MAC_ID_MASK; return 0; } @@ -3441,7 +3444,7 @@ static void hclge_do_reset(struct hclge_dev *hdev) u32 val; if (hclge_get_hw_reset_stat(handle)) { - dev_info(&pdev->dev, "Hardware reset not finish\n"); + dev_info(&pdev->dev, "hardware reset not finish\n"); dev_info(&pdev->dev, "func_rst_reg:0x%x, global_rst_reg:0x%x\n", hclge_read_dev(&hdev->hw, HCLGE_FUN_RST_ING), hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG)); @@ -3450,20 +3453,20 @@ static void hclge_do_reset(struct hclge_dev *hdev) switch (hdev->reset_type) { case HNAE3_GLOBAL_RESET: + dev_info(&pdev->dev, "global reset requested\n"); val = hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG); hnae3_set_bit(val, HCLGE_GLOBAL_RESET_BIT, 1); hclge_write_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG, val); - dev_info(&pdev->dev, "Global Reset requested\n"); break; case HNAE3_FUNC_RESET: - dev_info(&pdev->dev, "PF Reset requested\n"); + dev_info(&pdev->dev, "PF reset requested\n"); /* schedule again to check later */ set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending); hclge_reset_task_schedule(hdev); break; default: dev_warn(&pdev->dev, - "Unsupported reset type: %d\n", hdev->reset_type); + "unsupported reset type: %d\n", hdev->reset_type); break; } } @@ -6765,7 +6768,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable) struct hclge_dev *hdev = vport->back; if (enable) { - hclge_task_schedule(hdev, round_jiffies_relative(HZ)); + hclge_task_schedule(hdev, 0); } else { /* Set the DOWN flag here to disable link updating */ set_bit(HCLGE_STATE_DOWN, &hdev->state); @@ -7353,7 +7356,6 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport, return -EINVAL; } memset(&req, 0, sizeof(req)); - hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hclge_prepare_mac_addr(&req, addr, true); status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true); if (status) { @@ -7398,7 +7400,6 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport, } memset(&req, 0, sizeof(req)); - hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hclge_prepare_mac_addr(&req, addr, true); status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true); if (!status) { @@ -7618,11 +7619,17 @@ static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf, } ether_addr_copy(vport->vf_info.mac, mac_addr); - dev_info(&hdev->pdev->dev, - "MAC of VF %d has been set to %pM, and it will be reinitialized!\n", - vf, mac_addr); - return hclge_inform_reset_assert_to_vf(vport); + if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { + dev_info(&hdev->pdev->dev, + "MAC of VF %d has been set to %pM, and it will be reinitialized!\n", + vf, mac_addr); + return hclge_inform_reset_assert_to_vf(vport); + } + + dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %pM\n", + vf, mac_addr); + return 0; } static int hclge_add_mgr_tbl(struct hclge_dev *hdev, @@ -8979,6 +8986,12 @@ static void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; + /* When nic is down, the service task is not running, doesn't update + * the port information per second. Query the port information before + * return the media type, ensure getting the correct media information. + */ + hclge_update_port_info(hdev); + if (media_type) *media_type = hdev->hw.mac.media_type; @@ -9109,8 +9122,8 @@ init_nic_err: static int hclge_init_roce_client_instance(struct hnae3_ae_dev *ae_dev, struct hclge_vport *vport) { - struct hnae3_client *client = vport->roce.client; struct hclge_dev *hdev = ae_dev->priv; + struct hnae3_client *client; int rst_cnt; int ret; @@ -10286,8 +10299,9 @@ static int hclge_dfx_reg_fetch_data(struct hclge_desc *desc_src, int bd_num, static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len) { u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list); - int data_len_per_desc, data_len, bd_num, i; + int data_len_per_desc, bd_num, i; int bd_num_list[BD_LIST_MAX_NUM]; + u32 data_len; int ret; ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num); @@ -10666,7 +10680,7 @@ static int hclge_init(void) { pr_info("%s is initializing\n", HCLGE_NAME); - hclge_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, HCLGE_NAME); + hclge_wq = alloc_workqueue("%s", 0, 0, HCLGE_NAME); if (!hclge_wq) { pr_err("%s: failed to create workqueue\n", HCLGE_NAME); return -ENOMEM; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index f78cbb4cc85e..71df23d5f1b4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -249,6 +249,7 @@ enum HCLGE_MAC_DUPLEX { #define QUERY_ACTIVE_SPEED 1 struct hclge_mac { + u8 mac_id; u8 phy_addr; u8 flag; u8 media_type; /* port media type, e.g. fibre/copper/backplane */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 3d850f6b1e37..7f24fcb4f96a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -5,6 +5,11 @@ #include "hclge_mbx.h" #include "hnae3.h" +static u16 hclge_errno_to_resp(int errno) +{ + return abs(errno); +} + /* hclge_gen_resp_to_vf: used to generate a synchronous response to VF when PF * receives a mailbox message from VF. * @vport: pointer to struct hclge_vport @@ -14,25 +19,25 @@ */ static int hclge_gen_resp_to_vf(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *vf_to_pf_req, - int resp_status, - u8 *resp_data, u16 resp_data_len) + struct hclge_respond_to_vf_msg *resp_msg) { struct hclge_mbx_pf_to_vf_cmd *resp_pf_to_vf; struct hclge_dev *hdev = vport->back; enum hclge_cmd_status status; struct hclge_desc desc; + u16 resp; resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; - if (resp_data_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { + if (resp_msg->len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { dev_err(&hdev->pdev->dev, "PF fail to gen resp to VF len %u exceeds max len %u\n", - resp_data_len, + resp_msg->len, HCLGE_MBX_MAX_RESP_DATA_SIZE); - /* If resp_data_len is too long, set the value to max length + /* If resp_msg->len is too long, set the value to max length * and return the msg to VF */ - resp_data_len = HCLGE_MBX_MAX_RESP_DATA_SIZE; + resp_msg->len = HCLGE_MBX_MAX_RESP_DATA_SIZE; } hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); @@ -40,18 +45,29 @@ static int hclge_gen_resp_to_vf(struct hclge_vport *vport, resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; - resp_pf_to_vf->msg[0] = HCLGE_MBX_PF_VF_RESP; - resp_pf_to_vf->msg[1] = vf_to_pf_req->msg[0]; - resp_pf_to_vf->msg[2] = vf_to_pf_req->msg[1]; - resp_pf_to_vf->msg[3] = (resp_status == 0) ? 0 : 1; + resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; + resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; + resp_pf_to_vf->msg.vf_mbx_msg_subcode = vf_to_pf_req->msg.subcode; + resp = hclge_errno_to_resp(resp_msg->status); + if (resp < SHRT_MAX) { + resp_pf_to_vf->msg.resp_status = resp; + } else { + dev_warn(&hdev->pdev->dev, + "failed to send response to VF, response status %d is out-of-bound\n", + resp); + resp_pf_to_vf->msg.resp_status = EIO; + } - if (resp_data && resp_data_len > 0) - memcpy(&resp_pf_to_vf->msg[4], resp_data, resp_data_len); + if (resp_msg->len > 0) + memcpy(resp_pf_to_vf->msg.resp_data, resp_msg->data, + resp_msg->len); status = hclge_cmd_send(&hdev->hw, &desc, 1); if (status) dev_err(&hdev->pdev->dev, - "PF failed(=%d) to send response to VF\n", status); + "failed to send response to VF, status: %d, vfid: %u, code: %u, subcode: %u.\n", + status, vf_to_pf_req->mbx_src_vfid, + vf_to_pf_req->msg.code, vf_to_pf_req->msg.subcode); return status; } @@ -70,15 +86,15 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, resp_pf_to_vf->dest_vfid = dest_vfid; resp_pf_to_vf->msg_len = msg_len; - resp_pf_to_vf->msg[0] = mbx_opcode; + resp_pf_to_vf->msg.code = mbx_opcode; - memcpy(&resp_pf_to_vf->msg[1], msg, msg_len); + memcpy(&resp_pf_to_vf->msg.vf_mbx_msg_code, msg, msg_len); status = hclge_cmd_send(&hdev->hw, &desc, 1); if (status) dev_err(&hdev->pdev->dev, - "PF failed(=%d) to send mailbox message to VF\n", - status); + "failed to send mailbox to VF, status: %d, vfid: %u, opcode: %u\n", + status, dest_vfid, mbx_opcode); return status; } @@ -138,21 +154,20 @@ static int hclge_get_ring_chain_from_mbx( { struct hnae3_ring_chain_node *cur_chain, *new_chain; int ring_num; - int i; + int i = 0; - ring_num = req->msg[2]; + ring_num = req->msg.ring_num; - if (ring_num > ((HCLGE_MBX_VF_MSG_DATA_NUM - - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) / - HCLGE_MBX_RING_NODE_VARIABLE_NUM)) + if (ring_num > HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM) return -ENOMEM; - hnae3_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]); + hnae3_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, + req->msg.param[i].ring_type); ring_chain->tqp_index = - hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]); + hclge_get_queue_id(vport->nic.kinfo.tqp + [req->msg.param[i].tqp_index]); hnae3_set_field(ring_chain->int_gl_idx, HNAE3_RING_GL_IDX_M, - HNAE3_RING_GL_IDX_S, - req->msg[5]); + HNAE3_RING_GL_IDX_S, req->msg.param[i].int_gl_index); cur_chain = ring_chain; @@ -162,18 +177,15 @@ static int hclge_get_ring_chain_from_mbx( goto err; hnae3_set_bit(new_chain->flag, HNAE3_RING_TYPE_B, - req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i + - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM]); + req->msg.param[i].ring_type); new_chain->tqp_index = hclge_get_queue_id(vport->nic.kinfo.tqp - [req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i + - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 1]]); + [req->msg.param[i].tqp_index]); hnae3_set_field(new_chain->int_gl_idx, HNAE3_RING_GL_IDX_M, HNAE3_RING_GL_IDX_S, - req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i + - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 2]); + req->msg.param[i].int_gl_index); cur_chain->next = new_chain; cur_chain = new_chain; @@ -189,7 +201,7 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en, struct hclge_mbx_vf_to_pf_cmd *req) { struct hnae3_ring_chain_node ring_chain; - int vector_id = req->msg[1]; + int vector_id = req->msg.vector_id; int ret; memset(&ring_chain, 0, sizeof(ring_chain)); @@ -207,13 +219,9 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en, static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *req) { -#define HCLGE_MBX_BC_INDEX 1 -#define HCLGE_MBX_UC_INDEX 2 -#define HCLGE_MBX_MC_INDEX 3 - - bool en_bc = req->msg[HCLGE_MBX_BC_INDEX] ? true : false; - bool en_uc = req->msg[HCLGE_MBX_UC_INDEX] ? true : false; - bool en_mc = req->msg[HCLGE_MBX_MC_INDEX] ? true : false; + bool en_bc = req->msg.en_bc ? true : false; + bool en_uc = req->msg.en_uc ? true : false; + bool en_mc = req->msg.en_mc ? true : false; int ret; if (!vport->vf_info.trusted) { @@ -222,8 +230,6 @@ static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, } ret = hclge_set_vport_promisc_mode(vport, en_uc, en_mc, en_bc); - if (req->mbx_need_resp) - hclge_gen_resp_to_vf(vport, req, ret, NULL, 0); vport->vf_info.promisc_enable = (en_uc || en_mc) ? 1 : 0; @@ -244,26 +250,25 @@ void hclge_inform_vf_promisc_info(struct hclge_vport *vport) static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *mbx_req) { - const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); +#define HCLGE_MBX_VF_OLD_MAC_ADDR_OFFSET 6 + + const u8 *mac_addr = (const u8 *)(mbx_req->msg.data); struct hclge_dev *hdev = vport->back; int status; - if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { - const u8 *old_addr = (const u8 *)(&mbx_req->msg[8]); + if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { + const u8 *old_addr = (const u8 *) + (&mbx_req->msg.data[HCLGE_MBX_VF_OLD_MAC_ADDR_OFFSET]); /* If VF MAC has been configured by the host then it * cannot be overridden by the MAC specified by the VM. */ if (!is_zero_ether_addr(vport->vf_info.mac) && - !ether_addr_equal(mac_addr, vport->vf_info.mac)) { - status = -EPERM; - goto out; - } + !ether_addr_equal(mac_addr, vport->vf_info.mac)) + return -EPERM; - if (!is_valid_ether_addr(mac_addr)) { - status = -EINVAL; - goto out; - } + if (!is_valid_ether_addr(mac_addr)) + return -EINVAL; hclge_rm_uc_addr_common(vport, old_addr); status = hclge_add_uc_addr_common(vport, mac_addr); @@ -275,12 +280,12 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, hclge_add_vport_mac_table(vport, mac_addr, HCLGE_MAC_ADDR_UC); } - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) { + } else if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_UC_ADD) { status = hclge_add_uc_addr_common(vport, mac_addr); if (!status) hclge_add_vport_mac_table(vport, mac_addr, HCLGE_MAC_ADDR_UC); - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { + } else if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { status = hclge_rm_uc_addr_common(vport, mac_addr); if (!status) hclge_rm_vport_mac_table(vport, mac_addr, @@ -288,33 +293,26 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, } else { dev_err(&hdev->pdev->dev, "failed to set unicast mac addr, unknown subcode %u\n", - mbx_req->msg[1]); + mbx_req->msg.subcode); return -EIO; } -out: - if (mbx_req->mbx_need_resp & HCLGE_MBX_NEED_RESP_BIT) - hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); - - return 0; + return status; } static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req, - bool gen_resp) + struct hclge_mbx_vf_to_pf_cmd *mbx_req) { - const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); + const u8 *mac_addr = (const u8 *)(mbx_req->msg.data); struct hclge_dev *hdev = vport->back; - u8 resp_len = 0; - u8 resp_data; int status; - if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_ADD) { + if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_MC_ADD) { status = hclge_add_mc_addr_common(vport, mac_addr); if (!status) hclge_add_vport_mac_table(vport, mac_addr, HCLGE_MAC_ADDR_MC); - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_REMOVE) { + } else if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_MC_REMOVE) { status = hclge_rm_mc_addr_common(vport, mac_addr); if (!status) hclge_rm_vport_mac_table(vport, mac_addr, @@ -322,15 +320,11 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, } else { dev_err(&hdev->pdev->dev, "failed to set mcast mac addr, unknown subcode %u\n", - mbx_req->msg[1]); + mbx_req->msg.subcode); return -EIO; } - if (gen_resp) - hclge_gen_resp_to_vf(vport, mbx_req, status, - &resp_data, resp_len); - - return 0; + return status; } int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, @@ -351,12 +345,16 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, } static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + struct hclge_respond_to_vf_msg *resp_msg) { +#define HCLGE_MBX_VLAN_STATE_OFFSET 0 +#define HCLGE_MBX_VLAN_INFO_OFFSET 2 + struct hclge_vf_vlan_cfg *msg_cmd; int status = 0; - msg_cmd = (struct hclge_vf_vlan_cfg *)mbx_req->msg; + msg_cmd = (struct hclge_vf_vlan_cfg *)&mbx_req->msg; if (msg_cmd->subcode == HCLGE_MBX_VLAN_FILTER) { struct hnae3_handle *handle = &vport->nic; u16 vlan, proto; @@ -367,38 +365,32 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, proto = msg_cmd->proto; status = hclge_set_vlan_filter(handle, cpu_to_be16(proto), vlan, is_kill); - if (mbx_req->mbx_need_resp) - return hclge_gen_resp_to_vf(vport, mbx_req, status, - NULL, 0); } else if (msg_cmd->subcode == HCLGE_MBX_VLAN_RX_OFF_CFG) { struct hnae3_handle *handle = &vport->nic; bool en = msg_cmd->is_kill ? true : false; status = hclge_en_hw_strip_rxvtag(handle, en); - } else if (mbx_req->msg[1] == HCLGE_MBX_PORT_BASE_VLAN_CFG) { + } else if (msg_cmd->subcode == HCLGE_MBX_PORT_BASE_VLAN_CFG) { struct hclge_vlan_info *vlan_info; u16 *state; - state = (u16 *)&mbx_req->msg[2]; - vlan_info = (struct hclge_vlan_info *)&mbx_req->msg[4]; + state = (u16 *)&mbx_req->msg.data[HCLGE_MBX_VLAN_STATE_OFFSET]; + vlan_info = (struct hclge_vlan_info *) + &mbx_req->msg.data[HCLGE_MBX_VLAN_INFO_OFFSET]; status = hclge_update_port_base_vlan_cfg(vport, *state, vlan_info); - } else if (mbx_req->msg[1] == HCLGE_MBX_GET_PORT_BASE_VLAN_STATE) { - u8 state; - - state = vport->port_base_vlan_cfg.state; - status = hclge_gen_resp_to_vf(vport, mbx_req, 0, &state, - sizeof(u8)); + } else if (msg_cmd->subcode == HCLGE_MBX_GET_PORT_BASE_VLAN_STATE) { + resp_msg->data[0] = vport->port_base_vlan_cfg.state; + resp_msg->len = sizeof(u8); } return status; } static int hclge_set_vf_alive(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req, - bool gen_resp) + struct hclge_mbx_vf_to_pf_cmd *mbx_req) { - bool alive = !!mbx_req->msg[2]; + bool alive = !!mbx_req->msg.data[0]; int ret = 0; if (alive) @@ -409,73 +401,76 @@ static int hclge_set_vf_alive(struct hclge_vport *vport, return ret; } -static int hclge_get_vf_tcinfo(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req, - bool gen_resp) +static void hclge_get_vf_tcinfo(struct hclge_vport *vport, + struct hclge_respond_to_vf_msg *resp_msg) { struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; - u8 vf_tc_map = 0; unsigned int i; - int ret; for (i = 0; i < kinfo->num_tc; i++) - vf_tc_map |= BIT(i); - - ret = hclge_gen_resp_to_vf(vport, mbx_req, 0, &vf_tc_map, - sizeof(vf_tc_map)); + resp_msg->data[0] |= BIT(i); - return ret; + resp_msg->len = sizeof(u8); } -static int hclge_get_vf_queue_info(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req, - bool gen_resp) +static void hclge_get_vf_queue_info(struct hclge_vport *vport, + struct hclge_respond_to_vf_msg *resp_msg) { #define HCLGE_TQPS_RSS_INFO_LEN 6 - u8 resp_data[HCLGE_TQPS_RSS_INFO_LEN]; +#define HCLGE_TQPS_ALLOC_OFFSET 0 +#define HCLGE_TQPS_RSS_SIZE_OFFSET 2 +#define HCLGE_TQPS_RX_BUFFER_LEN_OFFSET 4 + struct hclge_dev *hdev = vport->back; /* get the queue related info */ - memcpy(&resp_data[0], &vport->alloc_tqps, sizeof(u16)); - memcpy(&resp_data[2], &vport->nic.kinfo.rss_size, sizeof(u16)); - memcpy(&resp_data[4], &hdev->rx_buf_len, sizeof(u16)); - - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, - HCLGE_TQPS_RSS_INFO_LEN); + memcpy(&resp_msg->data[HCLGE_TQPS_ALLOC_OFFSET], + &vport->alloc_tqps, sizeof(u16)); + memcpy(&resp_msg->data[HCLGE_TQPS_RSS_SIZE_OFFSET], + &vport->nic.kinfo.rss_size, sizeof(u16)); + memcpy(&resp_msg->data[HCLGE_TQPS_RX_BUFFER_LEN_OFFSET], + &hdev->rx_buf_len, sizeof(u16)); + resp_msg->len = HCLGE_TQPS_RSS_INFO_LEN; } -static int hclge_get_vf_mac_addr(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) +static void hclge_get_vf_mac_addr(struct hclge_vport *vport, + struct hclge_respond_to_vf_msg *resp_msg) { - return hclge_gen_resp_to_vf(vport, mbx_req, 0, vport->vf_info.mac, - ETH_ALEN); + ether_addr_copy(resp_msg->data, vport->vf_info.mac); + resp_msg->len = ETH_ALEN; } -static int hclge_get_vf_queue_depth(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req, - bool gen_resp) +static void hclge_get_vf_queue_depth(struct hclge_vport *vport, + struct hclge_respond_to_vf_msg *resp_msg) { #define HCLGE_TQPS_DEPTH_INFO_LEN 4 - u8 resp_data[HCLGE_TQPS_DEPTH_INFO_LEN]; +#define HCLGE_TQPS_NUM_TX_DESC_OFFSET 0 +#define HCLGE_TQPS_NUM_RX_DESC_OFFSET 2 + struct hclge_dev *hdev = vport->back; /* get the queue depth info */ - memcpy(&resp_data[0], &hdev->num_tx_desc, sizeof(u16)); - memcpy(&resp_data[2], &hdev->num_rx_desc, sizeof(u16)); - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, - HCLGE_TQPS_DEPTH_INFO_LEN); + memcpy(&resp_msg->data[HCLGE_TQPS_NUM_TX_DESC_OFFSET], + &hdev->num_tx_desc, sizeof(u16)); + memcpy(&resp_msg->data[HCLGE_TQPS_NUM_RX_DESC_OFFSET], + &hdev->num_rx_desc, sizeof(u16)); + resp_msg->len = HCLGE_TQPS_DEPTH_INFO_LEN; } -static int hclge_get_vf_media_type(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) +static void hclge_get_vf_media_type(struct hclge_vport *vport, + struct hclge_respond_to_vf_msg *resp_msg) { +#define HCLGE_VF_MEDIA_TYPE_OFFSET 0 +#define HCLGE_VF_MODULE_TYPE_OFFSET 1 +#define HCLGE_VF_MEDIA_TYPE_LENGTH 2 + struct hclge_dev *hdev = vport->back; - u8 resp_data[2]; - resp_data[0] = hdev->hw.mac.media_type; - resp_data[1] = hdev->hw.mac.module_type; - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, - sizeof(resp_data)); + resp_msg->data[HCLGE_VF_MEDIA_TYPE_OFFSET] = + hdev->hw.mac.media_type; + resp_msg->data[HCLGE_VF_MODULE_TYPE_OFFSET] = + hdev->hw.mac.module_type; + resp_msg->len = HCLGE_VF_MEDIA_TYPE_LENGTH; } static int hclge_get_link_info(struct hclge_vport *vport, @@ -529,7 +524,7 @@ static void hclge_get_link_mode(struct hclge_vport *vport, advertising = hdev->hw.mac.advertising[0]; supported = hdev->hw.mac.supported[0]; dest_vfid = mbx_req->mbx_src_vfid; - msg_data[0] = mbx_req->msg[2]; + msg_data[0] = mbx_req->msg.data[0]; send_data = msg_data[0] == HCLGE_SUPPORTED ? supported : advertising; @@ -543,29 +538,22 @@ static void hclge_mbx_reset_vf_queue(struct hclge_vport *vport, { u16 queue_id; - memcpy(&queue_id, &mbx_req->msg[2], sizeof(queue_id)); + memcpy(&queue_id, mbx_req->msg.data, sizeof(queue_id)); hclge_reset_vf_queue(vport, queue_id); - - /* send response msg to VF after queue reset complete */ - hclge_gen_resp_to_vf(vport, mbx_req, 0, NULL, 0); } -static void hclge_reset_vf(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) +static int hclge_reset_vf(struct hclge_vport *vport) { struct hclge_dev *hdev = vport->back; - int ret; dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %u!", vport->vport_id); - ret = hclge_func_reset_cmd(hdev, vport->vport_id); - hclge_gen_resp_to_vf(vport, mbx_req, ret, NULL, 0); + return hclge_func_reset_cmd(hdev, vport->vport_id); } -static void hclge_vf_keep_alive(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) +static void hclge_vf_keep_alive(struct hclge_vport *vport) { vport->last_active_jiffies = jiffies; } @@ -573,45 +561,39 @@ static void hclge_vf_keep_alive(struct hclge_vport *vport, static int hclge_set_vf_mtu(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *mbx_req) { - int ret; u32 mtu; - memcpy(&mtu, &mbx_req->msg[2], sizeof(mtu)); - ret = hclge_set_vport_mtu(vport, mtu); + memcpy(&mtu, mbx_req->msg.data, sizeof(mtu)); - return hclge_gen_resp_to_vf(vport, mbx_req, ret, NULL, 0); + return hclge_set_vport_mtu(vport, mtu); } -static int hclge_get_queue_id_in_pf(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) +static void hclge_get_queue_id_in_pf(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + struct hclge_respond_to_vf_msg *resp_msg) { u16 queue_id, qid_in_pf; - u8 resp_data[2]; - memcpy(&queue_id, &mbx_req->msg[2], sizeof(queue_id)); + memcpy(&queue_id, mbx_req->msg.data, sizeof(queue_id)); qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id); - memcpy(resp_data, &qid_in_pf, sizeof(qid_in_pf)); - - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, - sizeof(resp_data)); + memcpy(resp_msg->data, &qid_in_pf, sizeof(qid_in_pf)); + resp_msg->len = sizeof(qid_in_pf); } -static int hclge_get_rss_key(struct hclge_vport *vport, - struct hclge_mbx_vf_to_pf_cmd *mbx_req) +static void hclge_get_rss_key(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + struct hclge_respond_to_vf_msg *resp_msg) { #define HCLGE_RSS_MBX_RESP_LEN 8 - u8 resp_data[HCLGE_RSS_MBX_RESP_LEN]; struct hclge_dev *hdev = vport->back; u8 index; - index = mbx_req->msg[2]; + index = mbx_req->msg.data[0]; - memcpy(&resp_data[0], + memcpy(resp_msg->data, &hdev->vport[0].rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN], HCLGE_RSS_MBX_RESP_LEN); - - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, - HCLGE_RSS_MBX_RESP_LEN); + resp_msg->len = HCLGE_RSS_MBX_RESP_LEN; } static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code) @@ -634,13 +616,10 @@ static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code) static void hclge_handle_link_change_event(struct hclge_dev *hdev, struct hclge_mbx_vf_to_pf_cmd *req) { -#define LINK_STATUS_OFFSET 1 -#define LINK_FAIL_CODE_OFFSET 2 - hclge_task_schedule(hdev, 0); - if (!req->msg[LINK_STATUS_OFFSET]) - hclge_link_fail_parse(hdev, req->msg[LINK_FAIL_CODE_OFFSET]); + if (!req->msg.subcode) + hclge_link_fail_parse(hdev, req->msg.data[0]); } static bool hclge_cmd_crq_empty(struct hclge_hw *hw) @@ -662,12 +641,14 @@ static void hclge_handle_ncsi_error(struct hclge_dev *hdev) void hclge_mbx_handler(struct hclge_dev *hdev) { struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq; + struct hclge_respond_to_vf_msg resp_msg; struct hclge_mbx_vf_to_pf_cmd *req; struct hclge_vport *vport; struct hclge_desc *desc; unsigned int flag; - int ret; + int ret = 0; + memset(&resp_msg, 0, sizeof(resp_msg)); /* handle all the mailbox requests in the queue */ while (!hclge_cmd_crq_empty(&hdev->hw)) { if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state)) { @@ -683,7 +664,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev) if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B))) { dev_warn(&hdev->pdev->dev, "dropped invalid mailbox message, code = %u\n", - req->msg[0]); + req->msg.code); /* dropping/not processing this invalid message */ crq->desc[crq->next_to_use].flag = 0; @@ -693,7 +674,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev) vport = &hdev->vport[req->mbx_src_vfid]; - switch (req->msg[0]) { + switch (req->msg.code) { case HCLGE_MBX_MAP_RING_TO_VECTOR: ret = hclge_map_unmap_ring_to_vf_vector(vport, true, req); @@ -717,47 +698,34 @@ void hclge_mbx_handler(struct hclge_dev *hdev) ret); break; case HCLGE_MBX_SET_MULTICAST: - ret = hclge_set_vf_mc_mac_addr(vport, req, false); + ret = hclge_set_vf_mc_mac_addr(vport, req); if (ret) dev_err(&hdev->pdev->dev, "PF fail(%d) to set VF MC MAC Addr\n", ret); break; case HCLGE_MBX_SET_VLAN: - ret = hclge_set_vf_vlan_cfg(vport, req); + ret = hclge_set_vf_vlan_cfg(vport, req, &resp_msg); if (ret) dev_err(&hdev->pdev->dev, "PF failed(%d) to config VF's VLAN\n", ret); break; case HCLGE_MBX_SET_ALIVE: - ret = hclge_set_vf_alive(vport, req, false); + ret = hclge_set_vf_alive(vport, req); if (ret) dev_err(&hdev->pdev->dev, "PF failed(%d) to set VF's ALIVE\n", ret); break; case HCLGE_MBX_GET_QINFO: - ret = hclge_get_vf_queue_info(vport, req, true); - if (ret) - dev_err(&hdev->pdev->dev, - "PF failed(%d) to get Q info for VF\n", - ret); + hclge_get_vf_queue_info(vport, &resp_msg); break; case HCLGE_MBX_GET_QDEPTH: - ret = hclge_get_vf_queue_depth(vport, req, true); - if (ret) - dev_err(&hdev->pdev->dev, - "PF failed(%d) to get Q depth for VF\n", - ret); + hclge_get_vf_queue_depth(vport, &resp_msg); break; - case HCLGE_MBX_GET_TCINFO: - ret = hclge_get_vf_tcinfo(vport, req, true); - if (ret) - dev_err(&hdev->pdev->dev, - "PF failed(%d) to get TC info for VF\n", - ret); + hclge_get_vf_tcinfo(vport, &resp_msg); break; case HCLGE_MBX_GET_LINK_STATUS: ret = hclge_get_link_info(vport, req); @@ -770,10 +738,10 @@ void hclge_mbx_handler(struct hclge_dev *hdev) hclge_mbx_reset_vf_queue(vport, req); break; case HCLGE_MBX_RESET: - hclge_reset_vf(vport, req); + ret = hclge_reset_vf(vport); break; case HCLGE_MBX_KEEP_ALIVE: - hclge_vf_keep_alive(vport, req); + hclge_vf_keep_alive(vport); break; case HCLGE_MBX_SET_MTU: ret = hclge_set_vf_mtu(vport, req); @@ -782,18 +750,10 @@ void hclge_mbx_handler(struct hclge_dev *hdev) "VF fail(%d) to set mtu\n", ret); break; case HCLGE_MBX_GET_QID_IN_PF: - ret = hclge_get_queue_id_in_pf(vport, req); - if (ret) - dev_err(&hdev->pdev->dev, - "PF failed(%d) to get qid for VF\n", - ret); + hclge_get_queue_id_in_pf(vport, req, &resp_msg); break; case HCLGE_MBX_GET_RSS_KEY: - ret = hclge_get_rss_key(vport, req); - if (ret) - dev_err(&hdev->pdev->dev, - "PF fail(%d) to get rss key for VF\n", - ret); + hclge_get_rss_key(vport, req, &resp_msg); break; case HCLGE_MBX_GET_LINK_MODE: hclge_get_link_mode(vport, req); @@ -807,21 +767,13 @@ void hclge_mbx_handler(struct hclge_dev *hdev) hclge_rm_vport_all_vlan_table(vport, true); break; case HCLGE_MBX_GET_MEDIA_TYPE: - ret = hclge_get_vf_media_type(vport, req); - if (ret) - dev_err(&hdev->pdev->dev, - "PF fail(%d) to media type for VF\n", - ret); + hclge_get_vf_media_type(vport, &resp_msg); break; case HCLGE_MBX_PUSH_LINK_STATUS: hclge_handle_link_change_event(hdev, req); break; case HCLGE_MBX_GET_MAC_ADDR: - ret = hclge_get_vf_mac_addr(vport, req); - if (ret) - dev_err(&hdev->pdev->dev, - "PF failed(%d) to get MAC for VF\n", - ret); + hclge_get_vf_mac_addr(vport, &resp_msg); break; case HCLGE_MBX_NCSI_ERROR: hclge_handle_ncsi_error(hdev); @@ -829,11 +781,22 @@ void hclge_mbx_handler(struct hclge_dev *hdev) default: dev_err(&hdev->pdev->dev, "un-supported mailbox message, code = %u\n", - req->msg[0]); + req->msg.code); break; } + + /* PF driver should not reply IMP */ + if (hnae3_get_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) && + req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) { + resp_msg.status = ret; + hclge_gen_resp_to_vf(vport, req, &resp_msg); + } + crq->desc[crq->next_to_use].flag = 0; hclge_mbx_ring_ptr_move_crq(crq); + + /* reinitialize ret after complete the mbx message processing */ + ret = 0; } /* Write back CMDQ_RQ header pointer, M7 need this pointer */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 0510d85a7f6a..e02d427131ee 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -229,13 +229,25 @@ static void hclgevf_get_stats(struct hnae3_handle *handle, u64 *data) hclgevf_tqps_get_stats(handle, data); } +static void hclgevf_build_send_msg(struct hclge_vf_to_pf_msg *msg, u8 code, + u8 subcode) +{ + if (msg) { + memset(msg, 0, sizeof(struct hclge_vf_to_pf_msg)); + msg->code = code; + msg->subcode = subcode; + } +} + static int hclgevf_get_tc_info(struct hclgevf_dev *hdev) { + struct hclge_vf_to_pf_msg send_msg; u8 resp_msg; int status; - status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_TCINFO, 0, NULL, 0, - true, &resp_msg, sizeof(resp_msg)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_TCINFO, 0); + status = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg, + sizeof(resp_msg)); if (status) { dev_err(&hdev->pdev->dev, "VF request to get TC info from PF failed %d", @@ -251,12 +263,14 @@ static int hclgevf_get_tc_info(struct hclgevf_dev *hdev) static int hclgevf_get_port_base_vlan_filter_state(struct hclgevf_dev *hdev) { struct hnae3_handle *nic = &hdev->nic; + struct hclge_vf_to_pf_msg send_msg; u8 resp_msg; int ret; - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, - HCLGE_MBX_GET_PORT_BASE_VLAN_STATE, - NULL, 0, true, &resp_msg, sizeof(u8)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, + HCLGE_MBX_GET_PORT_BASE_VLAN_STATE); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg, + sizeof(u8)); if (ret) { dev_err(&hdev->pdev->dev, "VF request to get port based vlan state failed %d", @@ -272,11 +286,16 @@ static int hclgevf_get_port_base_vlan_filter_state(struct hclgevf_dev *hdev) static int hclgevf_get_queue_info(struct hclgevf_dev *hdev) { #define HCLGEVF_TQPS_RSS_INFO_LEN 6 +#define HCLGEVF_TQPS_ALLOC_OFFSET 0 +#define HCLGEVF_TQPS_RSS_SIZE_OFFSET 2 +#define HCLGEVF_TQPS_RX_BUFFER_LEN_OFFSET 4 + u8 resp_msg[HCLGEVF_TQPS_RSS_INFO_LEN]; + struct hclge_vf_to_pf_msg send_msg; int status; - status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QINFO, 0, NULL, 0, - true, resp_msg, + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QINFO, 0); + status = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, HCLGEVF_TQPS_RSS_INFO_LEN); if (status) { dev_err(&hdev->pdev->dev, @@ -285,9 +304,12 @@ static int hclgevf_get_queue_info(struct hclgevf_dev *hdev) return status; } - memcpy(&hdev->num_tqps, &resp_msg[0], sizeof(u16)); - memcpy(&hdev->rss_size_max, &resp_msg[2], sizeof(u16)); - memcpy(&hdev->rx_buf_len, &resp_msg[4], sizeof(u16)); + memcpy(&hdev->num_tqps, &resp_msg[HCLGEVF_TQPS_ALLOC_OFFSET], + sizeof(u16)); + memcpy(&hdev->rss_size_max, &resp_msg[HCLGEVF_TQPS_RSS_SIZE_OFFSET], + sizeof(u16)); + memcpy(&hdev->rx_buf_len, &resp_msg[HCLGEVF_TQPS_RX_BUFFER_LEN_OFFSET], + sizeof(u16)); return 0; } @@ -295,11 +317,15 @@ static int hclgevf_get_queue_info(struct hclgevf_dev *hdev) static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev) { #define HCLGEVF_TQPS_DEPTH_INFO_LEN 4 +#define HCLGEVF_TQPS_NUM_TX_DESC_OFFSET 0 +#define HCLGEVF_TQPS_NUM_RX_DESC_OFFSET 2 + u8 resp_msg[HCLGEVF_TQPS_DEPTH_INFO_LEN]; + struct hclge_vf_to_pf_msg send_msg; int ret; - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QDEPTH, 0, NULL, 0, - true, resp_msg, + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QDEPTH, 0); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, HCLGEVF_TQPS_DEPTH_INFO_LEN); if (ret) { dev_err(&hdev->pdev->dev, @@ -308,8 +334,10 @@ static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev) return ret; } - memcpy(&hdev->num_tx_desc, &resp_msg[0], sizeof(u16)); - memcpy(&hdev->num_rx_desc, &resp_msg[2], sizeof(u16)); + memcpy(&hdev->num_tx_desc, &resp_msg[HCLGEVF_TQPS_NUM_TX_DESC_OFFSET], + sizeof(u16)); + memcpy(&hdev->num_rx_desc, &resp_msg[HCLGEVF_TQPS_NUM_RX_DESC_OFFSET], + sizeof(u16)); return 0; } @@ -317,14 +345,14 @@ static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev) static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - u8 msg_data[2], resp_data[2]; + struct hclge_vf_to_pf_msg send_msg; u16 qid_in_pf = 0; + u8 resp_data[2]; int ret; - memcpy(&msg_data[0], &queue_id, sizeof(queue_id)); - - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QID_IN_PF, 0, msg_data, - sizeof(msg_data), true, resp_data, + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QID_IN_PF, 0); + memcpy(send_msg.data, &queue_id, sizeof(queue_id)); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_data, sizeof(resp_data)); if (!ret) qid_in_pf = *(u16 *)resp_data; @@ -334,11 +362,13 @@ static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id) static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev) { + struct hclge_vf_to_pf_msg send_msg; u8 resp_msg[2]; int ret; - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MEDIA_TYPE, 0, NULL, 0, - true, resp_msg, sizeof(resp_msg)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_MEDIA_TYPE, 0); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, + sizeof(resp_msg)); if (ret) { dev_err(&hdev->pdev->dev, "VF request to get the pf port media type failed %d", @@ -425,11 +455,11 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev) static void hclgevf_request_link_info(struct hclgevf_dev *hdev) { + struct hclge_vf_to_pf_msg send_msg; int status; - u8 resp_msg; - status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_STATUS, 0, NULL, - 0, false, &resp_msg, sizeof(resp_msg)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_LINK_STATUS, 0); + status = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); if (status) dev_err(&hdev->pdev->dev, "VF failed to fetch link status(%d) from PF", status); @@ -463,19 +493,16 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state) static void hclgevf_update_link_mode(struct hclgevf_dev *hdev) { -#define HCLGEVF_ADVERTISING 0 -#define HCLGEVF_SUPPORTED 1 - u8 send_msg; - u8 resp_msg; +#define HCLGEVF_ADVERTISING 0 +#define HCLGEVF_SUPPORTED 1 - send_msg = HCLGEVF_ADVERTISING; - hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0, - &send_msg, sizeof(send_msg), false, - &resp_msg, sizeof(resp_msg)); - send_msg = HCLGEVF_SUPPORTED; - hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0, - &send_msg, sizeof(send_msg), false, - &resp_msg, sizeof(resp_msg)); + struct hclge_vf_to_pf_msg send_msg; + + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_LINK_MODE, 0); + send_msg.data[0] = HCLGEVF_ADVERTISING; + hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); + send_msg.data[0] = HCLGEVF_SUPPORTED; + hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_set_handle_info(struct hclgevf_dev *hdev) @@ -677,19 +704,19 @@ static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size) static int hclgevf_get_rss_hash_key(struct hclgevf_dev *hdev) { #define HCLGEVF_RSS_MBX_RESP_LEN 8 - struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; u8 resp_msg[HCLGEVF_RSS_MBX_RESP_LEN]; + struct hclge_vf_to_pf_msg send_msg; u16 msg_num, hash_key_index; u8 index; int ret; + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_RSS_KEY, 0); msg_num = (HCLGEVF_RSS_KEY_SIZE + HCLGEVF_RSS_MBX_RESP_LEN - 1) / HCLGEVF_RSS_MBX_RESP_LEN; for (index = 0; index < msg_num; index++) { - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_RSS_KEY, 0, - &index, sizeof(index), - true, resp_msg, + send_msg.data[0] = index; + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, HCLGEVF_RSS_MBX_RESP_LEN); if (ret) { dev_err(&hdev->pdev->dev, @@ -1001,44 +1028,32 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, struct hnae3_ring_chain_node *ring_chain) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; struct hnae3_ring_chain_node *node; - struct hclge_mbx_vf_to_pf_cmd *req; - struct hclgevf_desc desc; - int i = 0; int status; - u8 type; + int i = 0; - req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; - type = en ? HCLGE_MBX_MAP_RING_TO_VECTOR : + memset(&send_msg, 0, sizeof(send_msg)); + send_msg.code = en ? HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR; + send_msg.vector_id = vector_id; for (node = ring_chain; node; node = node->next) { - int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + - HCLGE_MBX_RING_NODE_VARIABLE_NUM * i; - - if (i == 0) { - hclgevf_cmd_setup_basic_desc(&desc, - HCLGEVF_OPC_MBX_VF_TO_PF, - false); - req->msg[0] = type; - req->msg[1] = vector_id; - } - - req->msg[idx_offset] = + send_msg.param[i].ring_type = hnae3_get_bit(node->flag, HNAE3_RING_TYPE_B); - req->msg[idx_offset + 1] = node->tqp_index; - req->msg[idx_offset + 2] = hnae3_get_field(node->int_gl_idx, - HNAE3_RING_GL_IDX_M, - HNAE3_RING_GL_IDX_S); + + send_msg.param[i].tqp_index = node->tqp_index; + send_msg.param[i].int_gl_index = + hnae3_get_field(node->int_gl_idx, + HNAE3_RING_GL_IDX_M, + HNAE3_RING_GL_IDX_S); i++; - if ((i == (HCLGE_MBX_VF_MSG_DATA_NUM - - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) / - HCLGE_MBX_RING_NODE_VARIABLE_NUM) || - !node->next) { - req->msg[2] = i; + if (i == HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM || !node->next) { + send_msg.ring_num = i; - status = hclgevf_cmd_send(&hdev->hw, &desc, 1); + status = hclgevf_send_mbx_msg(hdev, &send_msg, false, + NULL, 0); if (status) { dev_err(&hdev->pdev->dev, "Map TQP fail, status is %d.\n", @@ -1046,11 +1061,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, return status; } i = 0; - hclgevf_cmd_setup_basic_desc(&desc, - HCLGEVF_OPC_MBX_VF_TO_PF, - false); - req->msg[0] = type; - req->msg[1] = vector_id; } } @@ -1123,18 +1133,17 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, bool en_uc_pmc, bool en_mc_pmc, bool en_bc_pmc) { - struct hclge_mbx_vf_to_pf_cmd *req; - struct hclgevf_desc desc; + struct hclge_vf_to_pf_msg send_msg; int ret; - req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; - hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); - req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; - req->msg[1] = en_bc_pmc ? 1 : 0; - req->msg[2] = en_uc_pmc ? 1 : 0; - req->msg[3] = en_mc_pmc ? 1 : 0; + memset(&send_msg, 0, sizeof(send_msg)); + send_msg.code = HCLGE_MBX_SET_PROMISC_MODE; + send_msg.en_bc = en_bc_pmc ? 1 : 0; + send_msg.en_uc = en_uc_pmc ? 1 : 0; + send_msg.en_mc = en_mc_pmc ? 1 : 0; + + ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); - ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); if (ret) dev_err(&hdev->pdev->dev, "Set promisc mode fail, status is %d.\n", ret); @@ -1193,11 +1202,13 @@ static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) static int hclgevf_get_host_mac_addr(struct hclgevf_dev *hdev, u8 *p) { + struct hclge_vf_to_pf_msg send_msg; u8 host_mac[ETH_ALEN]; int status; - status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MAC_ADDR, 0, NULL, 0, - true, host_mac, ETH_ALEN); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_MAC_ADDR, 0); + status = hclgevf_send_mbx_msg(hdev, &send_msg, true, host_mac, + ETH_ALEN); if (status) { dev_err(&hdev->pdev->dev, "fail to get VF MAC from host %d", status); @@ -1229,20 +1240,16 @@ static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p, { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; + struct hclge_vf_to_pf_msg send_msg; u8 *new_mac_addr = (u8 *)p; - u8 msg_data[ETH_ALEN * 2]; - u16 subcode; int status; - ether_addr_copy(msg_data, new_mac_addr); - ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); - - subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD : + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST, 0); + send_msg.subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD : HCLGE_MBX_MAC_VLAN_UC_MODIFY; - - status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, - subcode, msg_data, sizeof(msg_data), - true, NULL, 0); + ether_addr_copy(send_msg.data, new_mac_addr); + ether_addr_copy(&send_msg.data[ETH_ALEN], old_mac_addr); + status = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); if (!status) ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); @@ -1253,49 +1260,60 @@ static int hclgevf_add_uc_addr(struct hnae3_handle *handle, const unsigned char *addr) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, - HCLGE_MBX_MAC_VLAN_UC_ADD, - addr, ETH_ALEN, false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST, + HCLGE_MBX_MAC_VLAN_UC_ADD); + ether_addr_copy(send_msg.data, addr); + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_rm_uc_addr(struct hnae3_handle *handle, const unsigned char *addr) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, - HCLGE_MBX_MAC_VLAN_UC_REMOVE, - addr, ETH_ALEN, false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST, + HCLGE_MBX_MAC_VLAN_UC_REMOVE); + ether_addr_copy(send_msg.data, addr); + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_add_mc_addr(struct hnae3_handle *handle, const unsigned char *addr) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, - HCLGE_MBX_MAC_VLAN_MC_ADD, - addr, ETH_ALEN, false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MULTICAST, + HCLGE_MBX_MAC_VLAN_MC_ADD); + ether_addr_copy(send_msg.data, addr); + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_rm_mc_addr(struct hnae3_handle *handle, const unsigned char *addr) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, - HCLGE_MBX_MAC_VLAN_MC_REMOVE, - addr, ETH_ALEN, false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MULTICAST, + HCLGE_MBX_MAC_VLAN_MC_REMOVE); + ether_addr_copy(send_msg.data, addr); + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, u16 vlan_id, bool is_kill) { -#define HCLGEVF_VLAN_MBX_MSG_LEN 5 +#define HCLGEVF_VLAN_MBX_IS_KILL_OFFSET 0 +#define HCLGEVF_VLAN_MBX_VLAN_ID_OFFSET 1 +#define HCLGEVF_VLAN_MBX_PROTO_OFFSET 3 + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - u8 msg_data[HCLGEVF_VLAN_MBX_MSG_LEN]; + struct hclge_vf_to_pf_msg send_msg; int ret; if (vlan_id > HCLGEVF_MAX_VLAN_ID) @@ -1313,16 +1331,18 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, return -EBUSY; } - msg_data[0] = is_kill; - memcpy(&msg_data[1], &vlan_id, sizeof(vlan_id)); - memcpy(&msg_data[3], &proto, sizeof(proto)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, + HCLGE_MBX_VLAN_FILTER); + send_msg.data[HCLGEVF_VLAN_MBX_IS_KILL_OFFSET] = is_kill; + memcpy(&send_msg.data[HCLGEVF_VLAN_MBX_VLAN_ID_OFFSET], &vlan_id, + sizeof(vlan_id)); + memcpy(&send_msg.data[HCLGEVF_VLAN_MBX_PROTO_OFFSET], &proto, + sizeof(proto)); /* when remove hw vlan filter failed, record the vlan id, * and try to remove it from hw later, to be consistence * with stack. */ - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, - HCLGE_MBX_VLAN_FILTER, msg_data, - HCLGEVF_VLAN_MBX_MSG_LEN, true, NULL, 0); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); if (is_kill && ret) set_bit(vlan_id, hdev->vlan_del_fail_bmap); @@ -1355,37 +1375,38 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - u8 msg_data; + struct hclge_vf_to_pf_msg send_msg; - msg_data = enable ? 1 : 0; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, - HCLGE_MBX_VLAN_RX_OFF_CFG, &msg_data, - 1, false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, + HCLGE_MBX_VLAN_RX_OFF_CFG); + send_msg.data[0] = enable ? 1 : 0; + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - u8 msg_data[2]; + struct hclge_vf_to_pf_msg send_msg; int ret; - memcpy(msg_data, &queue_id, sizeof(queue_id)); - /* disable vf queue before send queue reset msg to PF */ ret = hclgevf_tqp_enable(hdev, queue_id, 0, false); if (ret) return ret; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data, - sizeof(msg_data), true, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_QUEUE_RESET, 0); + memcpy(send_msg.data, &queue_id, sizeof(queue_id)); + return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); } static int hclgevf_set_mtu(struct hnae3_handle *handle, int new_mtu) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclge_vf_to_pf_msg send_msg; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MTU, 0, (u8 *)&new_mtu, - sizeof(new_mtu), true, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MTU, 0); + memcpy(send_msg.data, &new_mtu, sizeof(new_mtu)); + return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); } static int hclgevf_notify_client(struct hclgevf_dev *hdev, @@ -1500,11 +1521,12 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) { #define HCLGEVF_RESET_SYNC_TIME 100 + struct hclge_vf_to_pf_msg send_msg; int ret = 0; if (hdev->reset_type == HNAE3_VF_FUNC_RESET) { - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL, - 0, true, NULL, sizeof(u8)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_RESET, 0); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); hdev->rst_stats.vf_func_rst_cnt++; } @@ -1881,14 +1903,14 @@ static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev) static void hclgevf_keep_alive(struct hclgevf_dev *hdev) { - u8 respmsg; + struct hclge_vf_to_pf_msg send_msg; int ret; if (test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state)) return; - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_KEEP_ALIVE, 0, NULL, - 0, false, &respmsg, sizeof(respmsg)); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_KEEP_ALIVE, 0); + ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); if (ret) dev_err(&hdev->pdev->dev, "VF sends keep alive cmd failed(=%d)\n", ret); @@ -2002,7 +2024,10 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, return HCLGEVF_VECTOR0_EVENT_MBX; } - dev_dbg(&hdev->pdev->dev, "vector 0 interrupt from unknown source\n"); + /* print other vector0 event source */ + dev_info(&hdev->pdev->dev, + "vector 0 interrupt from unknown source, cmdq_src = %#x\n", + cmdq_stat_reg); return HCLGEVF_VECTOR0_EVENT_OTHER; } @@ -2124,50 +2149,51 @@ static int hclgevf_config_gro(struct hclgevf_dev *hdev, bool en) return ret; } -static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) +static void hclgevf_rss_init_cfg(struct hclgevf_dev *hdev) { struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; - int ret; + struct hclgevf_rss_tuple_cfg *tuple_sets; u32 i; + rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ; rss_cfg->rss_size = hdev->nic.kinfo.rss_size; - + tuple_sets = &rss_cfg->rss_tuple_sets; if (hdev->pdev->revision >= 0x21) { rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_SIMPLE; memcpy(rss_cfg->rss_hash_key, hclgevf_hash_key, HCLGEVF_RSS_KEY_SIZE); + tuple_sets->ipv4_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; + tuple_sets->ipv4_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; + tuple_sets->ipv4_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP; + tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; + tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; + tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; + tuple_sets->ipv6_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP; + tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; + } + + /* Initialize RSS indirect table */ + for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) + rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size; +} + +static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) +{ + struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; + int ret; + + if (hdev->pdev->revision >= 0x21) { ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo, rss_cfg->rss_hash_key); if (ret) return ret; - rss_cfg->rss_tuple_sets.ipv4_tcp_en = - HCLGEVF_RSS_INPUT_TUPLE_OTHER; - rss_cfg->rss_tuple_sets.ipv4_udp_en = - HCLGEVF_RSS_INPUT_TUPLE_OTHER; - rss_cfg->rss_tuple_sets.ipv4_sctp_en = - HCLGEVF_RSS_INPUT_TUPLE_SCTP; - rss_cfg->rss_tuple_sets.ipv4_fragment_en = - HCLGEVF_RSS_INPUT_TUPLE_OTHER; - rss_cfg->rss_tuple_sets.ipv6_tcp_en = - HCLGEVF_RSS_INPUT_TUPLE_OTHER; - rss_cfg->rss_tuple_sets.ipv6_udp_en = - HCLGEVF_RSS_INPUT_TUPLE_OTHER; - rss_cfg->rss_tuple_sets.ipv6_sctp_en = - HCLGEVF_RSS_INPUT_TUPLE_SCTP; - rss_cfg->rss_tuple_sets.ipv6_fragment_en = - HCLGEVF_RSS_INPUT_TUPLE_OTHER; - ret = hclgevf_set_rss_input_tuple(hdev, rss_cfg); if (ret) return ret; } - /* Initialize RSS indirect table */ - for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) - rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size; - ret = hclgevf_set_rss_indir_table(hdev); if (ret) return ret; @@ -2242,12 +2268,16 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle) static int hclgevf_set_alive(struct hnae3_handle *handle, bool alive) { +#define HCLGEVF_STATE_ALIVE 1 +#define HCLGEVF_STATE_NOT_ALIVE 0 + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - u8 msg_data; + struct hclge_vf_to_pf_msg send_msg; - msg_data = alive ? 1 : 0; - return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_ALIVE, - 0, &msg_data, 1, false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_ALIVE, 0); + send_msg.data[0] = alive ? HCLGEVF_STATE_ALIVE : + HCLGEVF_STATE_NOT_ALIVE; + return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); } static int hclgevf_client_start(struct hnae3_handle *handle) @@ -2764,6 +2794,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) goto err_config; /* Initialize RSS for this VF */ + hclgevf_rss_init_cfg(hdev); ret = hclgevf_rss_init_hw(hdev); if (ret) { dev_err(&hdev->pdev->dev, @@ -2801,10 +2832,12 @@ err_cmd_queue_init: static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev) { + struct hclge_vf_to_pf_msg send_msg; + hclgevf_state_uninit(hdev); - hclgevf_send_mbx_msg(hdev, HCLGE_MBX_VF_UNINIT, 0, NULL, 0, - false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_VF_UNINIT, 0); + hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { hclgevf_misc_irq_uninit(hdev); @@ -2936,6 +2969,8 @@ static int hclgevf_set_channels(struct hnae3_handle *handle, u32 new_tqps_num, for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) rss_indir[i] = i % kinfo->rss_size; + hdev->rss_cfg.rss_size = kinfo->rss_size; + ret = hclgevf_set_rss(handle, rss_indir, NULL, 0); if (ret) dev_err(&hdev->pdev->dev, "set rss indir table fail, ret=%d\n", @@ -3101,16 +3136,17 @@ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state, u8 *port_base_vlan_info, u8 data_size) { struct hnae3_handle *nic = &hdev->nic; + struct hclge_vf_to_pf_msg send_msg; rtnl_lock(); hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); rtnl_unlock(); /* send msg to PF and wait update port based vlan info */ - hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, - HCLGE_MBX_PORT_BASE_VLAN_CFG, - port_base_vlan_info, data_size, - false, NULL, 0); + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, + HCLGE_MBX_PORT_BASE_VLAN_CFG); + memcpy(send_msg.data, port_base_vlan_info, data_size); + hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); if (state == HNAE3_PORT_BASE_VLAN_DISABLE) nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_DISABLE; @@ -3188,7 +3224,7 @@ static int hclgevf_init(void) { pr_info("%s is initializing\n", HCLGEVF_NAME); - hclgevf_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, HCLGEVF_NAME); + hclgevf_wq = alloc_workqueue("%s", 0, 0, HCLGEVF_NAME); if (!hclgevf_wq) { pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME); return -ENOMEM; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index fee8d97f323c..3b88d866facc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -305,8 +305,8 @@ static inline bool hclgevf_is_reset_pending(struct hclgevf_dev *hdev) return !!hdev->reset_pending; } -int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode, - const u8 *msg_data, u8 msg_len, bool need_resp, +int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, + struct hclge_vf_to_pf_msg *send_msg, bool need_resp, u8 *resp_data, u16 resp_len); void hclgevf_mbx_handler(struct hclgevf_dev *hdev); void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c index 7cbd715d5e7a..9b8154955f91 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c @@ -5,6 +5,11 @@ #include "hclgevf_main.h" #include "hnae3.h" +static int hclgevf_resp_to_errno(u16 resp_code) +{ + return resp_code ? -resp_code : 0; +} + static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev) { /* this function should be called with mbx_resp.mbx_mutex held @@ -79,8 +84,8 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, return 0; } -int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode, - const u8 *msg_data, u8 msg_len, bool need_resp, +int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, + struct hclge_vf_to_pf_msg *send_msg, bool need_resp, u8 *resp_data, u16 resp_len) { struct hclge_mbx_vf_to_pf_cmd *req; @@ -89,21 +94,17 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode, req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; - /* first two bytes are reserved for code & subcode */ - if (msg_len > (HCLGE_MBX_MAX_MSG_SIZE - 2)) { + if (!send_msg) { dev_err(&hdev->pdev->dev, - "VF send mbx msg fail, msg len %d exceeds max len %d\n", - msg_len, HCLGE_MBX_MAX_MSG_SIZE); + "failed to send mbx, msg is NULL\n"); return -EINVAL; } hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); - req->mbx_need_resp |= need_resp ? HCLGE_MBX_NEED_RESP_BIT : - ~HCLGE_MBX_NEED_RESP_BIT; - req->msg[0] = code; - req->msg[1] = subcode; - if (msg_data) - memcpy(&req->msg[2], msg_data, msg_len); + if (need_resp) + hnae3_set_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B, 1); + + memcpy(&req->msg, send_msg, sizeof(struct hclge_vf_to_pf_msg)); /* synchronous send */ if (need_resp) { @@ -118,7 +119,8 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode, return status; } - status = hclgevf_get_mbx_resp(hdev, code, subcode, resp_data, + status = hclgevf_get_mbx_resp(hdev, send_msg->code, + send_msg->subcode, resp_data, resp_len); mutex_unlock(&hdev->mbx_resp.mbx_mutex); } else { @@ -169,7 +171,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) if (unlikely(!hnae3_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B))) { dev_warn(&hdev->pdev->dev, "dropped invalid mailbox message, code = %u\n", - req->msg[0]); + req->msg.code); /* dropping/not processing this invalid message */ crq->desc[crq->next_to_use].flag = 0; @@ -183,19 +185,21 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) * timeout and simultaneously queue the async messages for later * prcessing in context of mailbox task i.e. the slow path. */ - switch (req->msg[0]) { + switch (req->msg.code) { case HCLGE_MBX_PF_VF_RESP: if (resp->received_resp) dev_warn(&hdev->pdev->dev, "VF mbx resp flag not clear(%u)\n", - req->msg[1]); + req->msg.vf_mbx_msg_code); resp->received_resp = true; - resp->origin_mbx_msg = (req->msg[1] << 16); - resp->origin_mbx_msg |= req->msg[2]; - resp->resp_status = req->msg[3]; + resp->origin_mbx_msg = + (req->msg.vf_mbx_msg_code << 16); + resp->origin_mbx_msg |= req->msg.vf_mbx_msg_subcode; + resp->resp_status = + hclgevf_resp_to_errno(req->msg.resp_status); - temp = (u8 *)&req->msg[4]; + temp = (u8 *)req->msg.resp_data; for (i = 0; i < HCLGE_MBX_MAX_RESP_DATA_SIZE; i++) { resp->additional_info[i] = *temp; temp++; @@ -220,13 +224,13 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) HCLGE_MBX_MAX_ARQ_MSG_NUM) { dev_warn(&hdev->pdev->dev, "Async Q full, dropping msg(%u)\n", - req->msg[1]); + req->msg.code); break; } /* tail the async message in arq */ msg_q = hdev->arq.msg_q[hdev->arq.tail]; - memcpy(&msg_q[0], req->msg, + memcpy(&msg_q[0], &req->msg, HCLGE_MBX_MAX_ARQ_MSG_SIZE * sizeof(u16)); hclge_mbx_tail_ptr_move_arq(hdev->arq); atomic_inc(&hdev->arq.count); @@ -237,7 +241,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) default: dev_err(&hdev->pdev->dev, "VF received unsupported(%u) mbx msg from PF\n", - req->msg[0]); + req->msg.code); break; } crq->desc[crq->next_to_use].flag = 0; |