1e2cb1decSSalil Mehta // SPDX-License-Identifier: GPL-2.0+ 2e2cb1decSSalil Mehta // Copyright (c) 2016-2017 Hisilicon Limited. 3e2cb1decSSalil Mehta 4e2cb1decSSalil Mehta #include <linux/etherdevice.h> 5aa5c4f17SHuazhong Tan #include <linux/iopoll.h> 66988eb2aSSalil Mehta #include <net/rtnetlink.h> 7e2cb1decSSalil Mehta #include "hclgevf_cmd.h" 8e2cb1decSSalil Mehta #include "hclgevf_main.h" 9e2cb1decSSalil Mehta #include "hclge_mbx.h" 10e2cb1decSSalil Mehta #include "hnae3.h" 11e2cb1decSSalil Mehta 12e2cb1decSSalil Mehta #define HCLGEVF_NAME "hclgevf" 13e2cb1decSSalil Mehta 14bbe6540eSHuazhong Tan #define HCLGEVF_RESET_MAX_FAIL_CNT 5 15bbe6540eSHuazhong Tan 169c6f7085SHuazhong Tan static int hclgevf_reset_hdev(struct hclgevf_dev *hdev); 175e7414cdSJian Shen static void hclgevf_task_schedule(struct hclgevf_dev *hdev, 185e7414cdSJian Shen unsigned long delay); 195e7414cdSJian Shen 20e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf; 21e2cb1decSSalil Mehta 220ea68902SYunsheng Lin static struct workqueue_struct *hclgevf_wq; 230ea68902SYunsheng Lin 24e2cb1decSSalil Mehta static const struct pci_device_id ae_algovf_pci_tbl[] = { 25c155e22bSGuangbin Huang {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_VF), 0}, 26c155e22bSGuangbin Huang {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_RDMA_DCB_PFC_VF), 27c155e22bSGuangbin Huang HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, 28e2cb1decSSalil Mehta /* required last entry */ 29e2cb1decSSalil Mehta {0, } 30e2cb1decSSalil Mehta }; 31e2cb1decSSalil Mehta 32472d7eceSJian Shen static const u8 hclgevf_hash_key[] = { 33472d7eceSJian Shen 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 34472d7eceSJian Shen 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0, 35472d7eceSJian Shen 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, 36472d7eceSJian Shen 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 37472d7eceSJian Shen 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA 38472d7eceSJian Shen }; 39472d7eceSJian Shen 402f550a46SYunsheng Lin MODULE_DEVICE_TABLE(pci, ae_algovf_pci_tbl); 412f550a46SYunsheng Lin 421600c3e5SJian Shen static const u32 cmdq_reg_addr_list[] = {HCLGEVF_CMDQ_TX_ADDR_L_REG, 431600c3e5SJian Shen HCLGEVF_CMDQ_TX_ADDR_H_REG, 441600c3e5SJian Shen HCLGEVF_CMDQ_TX_DEPTH_REG, 451600c3e5SJian Shen HCLGEVF_CMDQ_TX_TAIL_REG, 461600c3e5SJian Shen HCLGEVF_CMDQ_TX_HEAD_REG, 471600c3e5SJian Shen HCLGEVF_CMDQ_RX_ADDR_L_REG, 481600c3e5SJian Shen HCLGEVF_CMDQ_RX_ADDR_H_REG, 491600c3e5SJian Shen HCLGEVF_CMDQ_RX_DEPTH_REG, 501600c3e5SJian Shen HCLGEVF_CMDQ_RX_TAIL_REG, 511600c3e5SJian Shen HCLGEVF_CMDQ_RX_HEAD_REG, 521600c3e5SJian Shen HCLGEVF_VECTOR0_CMDQ_SRC_REG, 539cee2e8dSHuazhong Tan HCLGEVF_VECTOR0_CMDQ_STATE_REG, 541600c3e5SJian Shen HCLGEVF_CMDQ_INTR_EN_REG, 551600c3e5SJian Shen HCLGEVF_CMDQ_INTR_GEN_REG}; 561600c3e5SJian Shen 571600c3e5SJian Shen static const u32 common_reg_addr_list[] = {HCLGEVF_MISC_VECTOR_REG_BASE, 581600c3e5SJian Shen HCLGEVF_RST_ING, 591600c3e5SJian Shen HCLGEVF_GRO_EN_REG}; 601600c3e5SJian Shen 611600c3e5SJian Shen static const u32 ring_reg_addr_list[] = {HCLGEVF_RING_RX_ADDR_L_REG, 621600c3e5SJian Shen HCLGEVF_RING_RX_ADDR_H_REG, 631600c3e5SJian Shen HCLGEVF_RING_RX_BD_NUM_REG, 641600c3e5SJian Shen HCLGEVF_RING_RX_BD_LENGTH_REG, 651600c3e5SJian Shen HCLGEVF_RING_RX_MERGE_EN_REG, 661600c3e5SJian Shen HCLGEVF_RING_RX_TAIL_REG, 671600c3e5SJian Shen HCLGEVF_RING_RX_HEAD_REG, 681600c3e5SJian Shen HCLGEVF_RING_RX_FBD_NUM_REG, 691600c3e5SJian Shen HCLGEVF_RING_RX_OFFSET_REG, 701600c3e5SJian Shen HCLGEVF_RING_RX_FBD_OFFSET_REG, 711600c3e5SJian Shen HCLGEVF_RING_RX_STASH_REG, 721600c3e5SJian Shen HCLGEVF_RING_RX_BD_ERR_REG, 731600c3e5SJian Shen HCLGEVF_RING_TX_ADDR_L_REG, 741600c3e5SJian Shen HCLGEVF_RING_TX_ADDR_H_REG, 751600c3e5SJian Shen HCLGEVF_RING_TX_BD_NUM_REG, 761600c3e5SJian Shen HCLGEVF_RING_TX_PRIORITY_REG, 771600c3e5SJian Shen HCLGEVF_RING_TX_TC_REG, 781600c3e5SJian Shen HCLGEVF_RING_TX_MERGE_EN_REG, 791600c3e5SJian Shen HCLGEVF_RING_TX_TAIL_REG, 801600c3e5SJian Shen HCLGEVF_RING_TX_HEAD_REG, 811600c3e5SJian Shen HCLGEVF_RING_TX_FBD_NUM_REG, 821600c3e5SJian Shen HCLGEVF_RING_TX_OFFSET_REG, 831600c3e5SJian Shen HCLGEVF_RING_TX_EBD_NUM_REG, 841600c3e5SJian Shen HCLGEVF_RING_TX_EBD_OFFSET_REG, 851600c3e5SJian Shen HCLGEVF_RING_TX_BD_ERR_REG, 861600c3e5SJian Shen HCLGEVF_RING_EN_REG}; 871600c3e5SJian Shen 881600c3e5SJian Shen static const u32 tqp_intr_reg_addr_list[] = {HCLGEVF_TQP_INTR_CTRL_REG, 891600c3e5SJian Shen HCLGEVF_TQP_INTR_GL0_REG, 901600c3e5SJian Shen HCLGEVF_TQP_INTR_GL1_REG, 911600c3e5SJian Shen HCLGEVF_TQP_INTR_GL2_REG, 921600c3e5SJian Shen HCLGEVF_TQP_INTR_RL_REG}; 931600c3e5SJian Shen 949b2f3477SWeihang Li static struct hclgevf_dev *hclgevf_ae_get_hdev(struct hnae3_handle *handle) 95e2cb1decSSalil Mehta { 96eed9535fSPeng Li if (!handle->client) 97eed9535fSPeng Li return container_of(handle, struct hclgevf_dev, nic); 98eed9535fSPeng Li else if (handle->client->type == HNAE3_CLIENT_ROCE) 99eed9535fSPeng Li return container_of(handle, struct hclgevf_dev, roce); 100eed9535fSPeng Li else 101e2cb1decSSalil Mehta return container_of(handle, struct hclgevf_dev, nic); 102e2cb1decSSalil Mehta } 103e2cb1decSSalil Mehta 104e2cb1decSSalil Mehta static int hclgevf_tqps_update_stats(struct hnae3_handle *handle) 105e2cb1decSSalil Mehta { 106b4f1d303SJian Shen struct hnae3_knic_private_info *kinfo = &handle->kinfo; 107e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 108e2cb1decSSalil Mehta struct hclgevf_desc desc; 109e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 110e2cb1decSSalil Mehta int status; 111e2cb1decSSalil Mehta int i; 112e2cb1decSSalil Mehta 113b4f1d303SJian Shen for (i = 0; i < kinfo->num_tqps; i++) { 114b4f1d303SJian Shen tqp = container_of(kinfo->tqp[i], struct hclgevf_tqp, q); 115e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 116e2cb1decSSalil Mehta HCLGEVF_OPC_QUERY_RX_STATUS, 117e2cb1decSSalil Mehta true); 118e2cb1decSSalil Mehta 119e2cb1decSSalil Mehta desc.data[0] = cpu_to_le32(tqp->index & 0x1ff); 120e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 121e2cb1decSSalil Mehta if (status) { 122e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 123e2cb1decSSalil Mehta "Query tqp stat fail, status = %d,queue = %d\n", 124e2cb1decSSalil Mehta status, i); 125e2cb1decSSalil Mehta return status; 126e2cb1decSSalil Mehta } 127e2cb1decSSalil Mehta tqp->tqp_stats.rcb_rx_ring_pktnum_rcd += 128cf72fa63SJian Shen le32_to_cpu(desc.data[1]); 129e2cb1decSSalil Mehta 130e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_QUERY_TX_STATUS, 131e2cb1decSSalil Mehta true); 132e2cb1decSSalil Mehta 133e2cb1decSSalil Mehta desc.data[0] = cpu_to_le32(tqp->index & 0x1ff); 134e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 135e2cb1decSSalil Mehta if (status) { 136e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 137e2cb1decSSalil Mehta "Query tqp stat fail, status = %d,queue = %d\n", 138e2cb1decSSalil Mehta status, i); 139e2cb1decSSalil Mehta return status; 140e2cb1decSSalil Mehta } 141e2cb1decSSalil Mehta tqp->tqp_stats.rcb_tx_ring_pktnum_rcd += 142cf72fa63SJian Shen le32_to_cpu(desc.data[1]); 143e2cb1decSSalil Mehta } 144e2cb1decSSalil Mehta 145e2cb1decSSalil Mehta return 0; 146e2cb1decSSalil Mehta } 147e2cb1decSSalil Mehta 148e2cb1decSSalil Mehta static u64 *hclgevf_tqps_get_stats(struct hnae3_handle *handle, u64 *data) 149e2cb1decSSalil Mehta { 150e2cb1decSSalil Mehta struct hnae3_knic_private_info *kinfo = &handle->kinfo; 151e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 152e2cb1decSSalil Mehta u64 *buff = data; 153e2cb1decSSalil Mehta int i; 154e2cb1decSSalil Mehta 155b4f1d303SJian Shen for (i = 0; i < kinfo->num_tqps; i++) { 156b4f1d303SJian Shen tqp = container_of(kinfo->tqp[i], struct hclgevf_tqp, q); 157e2cb1decSSalil Mehta *buff++ = tqp->tqp_stats.rcb_tx_ring_pktnum_rcd; 158e2cb1decSSalil Mehta } 159e2cb1decSSalil Mehta for (i = 0; i < kinfo->num_tqps; i++) { 160b4f1d303SJian Shen tqp = container_of(kinfo->tqp[i], struct hclgevf_tqp, q); 161e2cb1decSSalil Mehta *buff++ = tqp->tqp_stats.rcb_rx_ring_pktnum_rcd; 162e2cb1decSSalil Mehta } 163e2cb1decSSalil Mehta 164e2cb1decSSalil Mehta return buff; 165e2cb1decSSalil Mehta } 166e2cb1decSSalil Mehta 167e2cb1decSSalil Mehta static int hclgevf_tqps_get_sset_count(struct hnae3_handle *handle, int strset) 168e2cb1decSSalil Mehta { 169b4f1d303SJian Shen struct hnae3_knic_private_info *kinfo = &handle->kinfo; 170e2cb1decSSalil Mehta 171b4f1d303SJian Shen return kinfo->num_tqps * 2; 172e2cb1decSSalil Mehta } 173e2cb1decSSalil Mehta 174e2cb1decSSalil Mehta static u8 *hclgevf_tqps_get_strings(struct hnae3_handle *handle, u8 *data) 175e2cb1decSSalil Mehta { 176b4f1d303SJian Shen struct hnae3_knic_private_info *kinfo = &handle->kinfo; 177e2cb1decSSalil Mehta u8 *buff = data; 1789d8d5a36SYufeng Mo int i; 179e2cb1decSSalil Mehta 180b4f1d303SJian Shen for (i = 0; i < kinfo->num_tqps; i++) { 181b4f1d303SJian Shen struct hclgevf_tqp *tqp = container_of(kinfo->tqp[i], 182e2cb1decSSalil Mehta struct hclgevf_tqp, q); 1830c218123SJian Shen snprintf(buff, ETH_GSTRING_LEN, "txq%d_pktnum_rcd", 184e2cb1decSSalil Mehta tqp->index); 185e2cb1decSSalil Mehta buff += ETH_GSTRING_LEN; 186e2cb1decSSalil Mehta } 187e2cb1decSSalil Mehta 188b4f1d303SJian Shen for (i = 0; i < kinfo->num_tqps; i++) { 189b4f1d303SJian Shen struct hclgevf_tqp *tqp = container_of(kinfo->tqp[i], 190e2cb1decSSalil Mehta struct hclgevf_tqp, q); 1910c218123SJian Shen snprintf(buff, ETH_GSTRING_LEN, "rxq%d_pktnum_rcd", 192e2cb1decSSalil Mehta tqp->index); 193e2cb1decSSalil Mehta buff += ETH_GSTRING_LEN; 194e2cb1decSSalil Mehta } 195e2cb1decSSalil Mehta 196e2cb1decSSalil Mehta return buff; 197e2cb1decSSalil Mehta } 198e2cb1decSSalil Mehta 199e2cb1decSSalil Mehta static void hclgevf_update_stats(struct hnae3_handle *handle, 200e2cb1decSSalil Mehta struct net_device_stats *net_stats) 201e2cb1decSSalil Mehta { 202e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 203e2cb1decSSalil Mehta int status; 204e2cb1decSSalil Mehta 205e2cb1decSSalil Mehta status = hclgevf_tqps_update_stats(handle); 206e2cb1decSSalil Mehta if (status) 207e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 208e2cb1decSSalil Mehta "VF update of TQPS stats fail, status = %d.\n", 209e2cb1decSSalil Mehta status); 210e2cb1decSSalil Mehta } 211e2cb1decSSalil Mehta 212e2cb1decSSalil Mehta static int hclgevf_get_sset_count(struct hnae3_handle *handle, int strset) 213e2cb1decSSalil Mehta { 214e2cb1decSSalil Mehta if (strset == ETH_SS_TEST) 215e2cb1decSSalil Mehta return -EOPNOTSUPP; 216e2cb1decSSalil Mehta else if (strset == ETH_SS_STATS) 217e2cb1decSSalil Mehta return hclgevf_tqps_get_sset_count(handle, strset); 218e2cb1decSSalil Mehta 219e2cb1decSSalil Mehta return 0; 220e2cb1decSSalil Mehta } 221e2cb1decSSalil Mehta 222e2cb1decSSalil Mehta static void hclgevf_get_strings(struct hnae3_handle *handle, u32 strset, 223e2cb1decSSalil Mehta u8 *data) 224e2cb1decSSalil Mehta { 225e2cb1decSSalil Mehta u8 *p = (char *)data; 226e2cb1decSSalil Mehta 227e2cb1decSSalil Mehta if (strset == ETH_SS_STATS) 228e2cb1decSSalil Mehta p = hclgevf_tqps_get_strings(handle, p); 229e2cb1decSSalil Mehta } 230e2cb1decSSalil Mehta 231e2cb1decSSalil Mehta static void hclgevf_get_stats(struct hnae3_handle *handle, u64 *data) 232e2cb1decSSalil Mehta { 233e2cb1decSSalil Mehta hclgevf_tqps_get_stats(handle, data); 234e2cb1decSSalil Mehta } 235e2cb1decSSalil Mehta 236d3410018SYufeng Mo static void hclgevf_build_send_msg(struct hclge_vf_to_pf_msg *msg, u8 code, 237d3410018SYufeng Mo u8 subcode) 238d3410018SYufeng Mo { 239d3410018SYufeng Mo if (msg) { 240d3410018SYufeng Mo memset(msg, 0, sizeof(struct hclge_vf_to_pf_msg)); 241d3410018SYufeng Mo msg->code = code; 242d3410018SYufeng Mo msg->subcode = subcode; 243d3410018SYufeng Mo } 244d3410018SYufeng Mo } 245d3410018SYufeng Mo 246e2cb1decSSalil Mehta static int hclgevf_get_tc_info(struct hclgevf_dev *hdev) 247e2cb1decSSalil Mehta { 248d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 249e2cb1decSSalil Mehta u8 resp_msg; 250e2cb1decSSalil Mehta int status; 251e2cb1decSSalil Mehta 252d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_TCINFO, 0); 253d3410018SYufeng Mo status = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg, 254d3410018SYufeng Mo sizeof(resp_msg)); 255e2cb1decSSalil Mehta if (status) { 256e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 257e2cb1decSSalil Mehta "VF request to get TC info from PF failed %d", 258e2cb1decSSalil Mehta status); 259e2cb1decSSalil Mehta return status; 260e2cb1decSSalil Mehta } 261e2cb1decSSalil Mehta 262e2cb1decSSalil Mehta hdev->hw_tc_map = resp_msg; 263e2cb1decSSalil Mehta 264e2cb1decSSalil Mehta return 0; 265e2cb1decSSalil Mehta } 266e2cb1decSSalil Mehta 26792f11ea1SJian Shen static int hclgevf_get_port_base_vlan_filter_state(struct hclgevf_dev *hdev) 26892f11ea1SJian Shen { 26992f11ea1SJian Shen struct hnae3_handle *nic = &hdev->nic; 270d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 27192f11ea1SJian Shen u8 resp_msg; 27292f11ea1SJian Shen int ret; 27392f11ea1SJian Shen 274d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, 275d3410018SYufeng Mo HCLGE_MBX_GET_PORT_BASE_VLAN_STATE); 276d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg, 277d3410018SYufeng Mo sizeof(u8)); 27892f11ea1SJian Shen if (ret) { 27992f11ea1SJian Shen dev_err(&hdev->pdev->dev, 28092f11ea1SJian Shen "VF request to get port based vlan state failed %d", 28192f11ea1SJian Shen ret); 28292f11ea1SJian Shen return ret; 28392f11ea1SJian Shen } 28492f11ea1SJian Shen 28592f11ea1SJian Shen nic->port_base_vlan_state = resp_msg; 28692f11ea1SJian Shen 28792f11ea1SJian Shen return 0; 28892f11ea1SJian Shen } 28992f11ea1SJian Shen 2906cee6fc3SJian Shen static int hclgevf_get_queue_info(struct hclgevf_dev *hdev) 291e2cb1decSSalil Mehta { 292c0425944SPeng Li #define HCLGEVF_TQPS_RSS_INFO_LEN 6 293d3410018SYufeng Mo #define HCLGEVF_TQPS_ALLOC_OFFSET 0 294d3410018SYufeng Mo #define HCLGEVF_TQPS_RSS_SIZE_OFFSET 2 295d3410018SYufeng Mo #define HCLGEVF_TQPS_RX_BUFFER_LEN_OFFSET 4 296d3410018SYufeng Mo 297e2cb1decSSalil Mehta u8 resp_msg[HCLGEVF_TQPS_RSS_INFO_LEN]; 298d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 299e2cb1decSSalil Mehta int status; 300e2cb1decSSalil Mehta 301d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QINFO, 0); 302d3410018SYufeng Mo status = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, 303e2cb1decSSalil Mehta HCLGEVF_TQPS_RSS_INFO_LEN); 304e2cb1decSSalil Mehta if (status) { 305e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 306e2cb1decSSalil Mehta "VF request to get tqp info from PF failed %d", 307e2cb1decSSalil Mehta status); 308e2cb1decSSalil Mehta return status; 309e2cb1decSSalil Mehta } 310e2cb1decSSalil Mehta 311d3410018SYufeng Mo memcpy(&hdev->num_tqps, &resp_msg[HCLGEVF_TQPS_ALLOC_OFFSET], 312d3410018SYufeng Mo sizeof(u16)); 313d3410018SYufeng Mo memcpy(&hdev->rss_size_max, &resp_msg[HCLGEVF_TQPS_RSS_SIZE_OFFSET], 314d3410018SYufeng Mo sizeof(u16)); 315d3410018SYufeng Mo memcpy(&hdev->rx_buf_len, &resp_msg[HCLGEVF_TQPS_RX_BUFFER_LEN_OFFSET], 316d3410018SYufeng Mo sizeof(u16)); 317c0425944SPeng Li 318c0425944SPeng Li return 0; 319c0425944SPeng Li } 320c0425944SPeng Li 321c0425944SPeng Li static int hclgevf_get_queue_depth(struct hclgevf_dev *hdev) 322c0425944SPeng Li { 323c0425944SPeng Li #define HCLGEVF_TQPS_DEPTH_INFO_LEN 4 324d3410018SYufeng Mo #define HCLGEVF_TQPS_NUM_TX_DESC_OFFSET 0 325d3410018SYufeng Mo #define HCLGEVF_TQPS_NUM_RX_DESC_OFFSET 2 326d3410018SYufeng Mo 327c0425944SPeng Li u8 resp_msg[HCLGEVF_TQPS_DEPTH_INFO_LEN]; 328d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 329c0425944SPeng Li int ret; 330c0425944SPeng Li 331d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QDEPTH, 0); 332d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, 333c0425944SPeng Li HCLGEVF_TQPS_DEPTH_INFO_LEN); 334c0425944SPeng Li if (ret) { 335c0425944SPeng Li dev_err(&hdev->pdev->dev, 336c0425944SPeng Li "VF request to get tqp depth info from PF failed %d", 337c0425944SPeng Li ret); 338c0425944SPeng Li return ret; 339c0425944SPeng Li } 340c0425944SPeng Li 341d3410018SYufeng Mo memcpy(&hdev->num_tx_desc, &resp_msg[HCLGEVF_TQPS_NUM_TX_DESC_OFFSET], 342d3410018SYufeng Mo sizeof(u16)); 343d3410018SYufeng Mo memcpy(&hdev->num_rx_desc, &resp_msg[HCLGEVF_TQPS_NUM_RX_DESC_OFFSET], 344d3410018SYufeng Mo sizeof(u16)); 345e2cb1decSSalil Mehta 346e2cb1decSSalil Mehta return 0; 347e2cb1decSSalil Mehta } 348e2cb1decSSalil Mehta 3490c29d191Sliuzhongzhu static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id) 3500c29d191Sliuzhongzhu { 3510c29d191Sliuzhongzhu struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 352d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 3530c29d191Sliuzhongzhu u16 qid_in_pf = 0; 354d3410018SYufeng Mo u8 resp_data[2]; 3550c29d191Sliuzhongzhu int ret; 3560c29d191Sliuzhongzhu 357d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_QID_IN_PF, 0); 358d3410018SYufeng Mo memcpy(send_msg.data, &queue_id, sizeof(queue_id)); 359d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_data, 36063cbf7a9SYufeng Mo sizeof(resp_data)); 3610c29d191Sliuzhongzhu if (!ret) 3620c29d191Sliuzhongzhu qid_in_pf = *(u16 *)resp_data; 3630c29d191Sliuzhongzhu 3640c29d191Sliuzhongzhu return qid_in_pf; 3650c29d191Sliuzhongzhu } 3660c29d191Sliuzhongzhu 3679c3e7130Sliuzhongzhu static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev) 3689c3e7130Sliuzhongzhu { 369d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 37088d10bd6SJian Shen u8 resp_msg[2]; 3719c3e7130Sliuzhongzhu int ret; 3729c3e7130Sliuzhongzhu 373d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_MEDIA_TYPE, 0); 374d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, 375d3410018SYufeng Mo sizeof(resp_msg)); 3769c3e7130Sliuzhongzhu if (ret) { 3779c3e7130Sliuzhongzhu dev_err(&hdev->pdev->dev, 3789c3e7130Sliuzhongzhu "VF request to get the pf port media type failed %d", 3799c3e7130Sliuzhongzhu ret); 3809c3e7130Sliuzhongzhu return ret; 3819c3e7130Sliuzhongzhu } 3829c3e7130Sliuzhongzhu 38388d10bd6SJian Shen hdev->hw.mac.media_type = resp_msg[0]; 38488d10bd6SJian Shen hdev->hw.mac.module_type = resp_msg[1]; 3859c3e7130Sliuzhongzhu 3869c3e7130Sliuzhongzhu return 0; 3879c3e7130Sliuzhongzhu } 3889c3e7130Sliuzhongzhu 389e2cb1decSSalil Mehta static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev) 390e2cb1decSSalil Mehta { 391e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 392e2cb1decSSalil Mehta int i; 393e2cb1decSSalil Mehta 394e2cb1decSSalil Mehta hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, 395e2cb1decSSalil Mehta sizeof(struct hclgevf_tqp), GFP_KERNEL); 396e2cb1decSSalil Mehta if (!hdev->htqp) 397e2cb1decSSalil Mehta return -ENOMEM; 398e2cb1decSSalil Mehta 399e2cb1decSSalil Mehta tqp = hdev->htqp; 400e2cb1decSSalil Mehta 401e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 402e2cb1decSSalil Mehta tqp->dev = &hdev->pdev->dev; 403e2cb1decSSalil Mehta tqp->index = i; 404e2cb1decSSalil Mehta 405e2cb1decSSalil Mehta tqp->q.ae_algo = &ae_algovf; 406e2cb1decSSalil Mehta tqp->q.buf_size = hdev->rx_buf_len; 407c0425944SPeng Li tqp->q.tx_desc_num = hdev->num_tx_desc; 408c0425944SPeng Li tqp->q.rx_desc_num = hdev->num_rx_desc; 4099a5ef4aaSYonglong Liu 4109a5ef4aaSYonglong Liu /* need an extended offset to configure queues >= 4119a5ef4aaSYonglong Liu * HCLGEVF_TQP_MAX_SIZE_DEV_V2. 4129a5ef4aaSYonglong Liu */ 4139a5ef4aaSYonglong Liu if (i < HCLGEVF_TQP_MAX_SIZE_DEV_V2) 4149a5ef4aaSYonglong Liu tqp->q.io_base = hdev->hw.io_base + 4159a5ef4aaSYonglong Liu HCLGEVF_TQP_REG_OFFSET + 416e2cb1decSSalil Mehta i * HCLGEVF_TQP_REG_SIZE; 4179a5ef4aaSYonglong Liu else 4189a5ef4aaSYonglong Liu tqp->q.io_base = hdev->hw.io_base + 4199a5ef4aaSYonglong Liu HCLGEVF_TQP_REG_OFFSET + 4209a5ef4aaSYonglong Liu HCLGEVF_TQP_EXT_REG_OFFSET + 4219a5ef4aaSYonglong Liu (i - HCLGEVF_TQP_MAX_SIZE_DEV_V2) * 4229a5ef4aaSYonglong Liu HCLGEVF_TQP_REG_SIZE; 423e2cb1decSSalil Mehta 424e2cb1decSSalil Mehta tqp++; 425e2cb1decSSalil Mehta } 426e2cb1decSSalil Mehta 427e2cb1decSSalil Mehta return 0; 428e2cb1decSSalil Mehta } 429e2cb1decSSalil Mehta 430e2cb1decSSalil Mehta static int hclgevf_knic_setup(struct hclgevf_dev *hdev) 431e2cb1decSSalil Mehta { 432e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 433e2cb1decSSalil Mehta struct hnae3_knic_private_info *kinfo; 434e2cb1decSSalil Mehta u16 new_tqps = hdev->num_tqps; 435ebaf1908SWeihang Li unsigned int i; 43635244430SJian Shen u8 num_tc = 0; 437e2cb1decSSalil Mehta 438e2cb1decSSalil Mehta kinfo = &nic->kinfo; 439c0425944SPeng Li kinfo->num_tx_desc = hdev->num_tx_desc; 440c0425944SPeng Li kinfo->num_rx_desc = hdev->num_rx_desc; 441e2cb1decSSalil Mehta kinfo->rx_buf_len = hdev->rx_buf_len; 442e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) 443e2cb1decSSalil Mehta if (hdev->hw_tc_map & BIT(i)) 44435244430SJian Shen num_tc++; 445e2cb1decSSalil Mehta 44635244430SJian Shen num_tc = num_tc ? num_tc : 1; 44735244430SJian Shen kinfo->tc_info.num_tc = num_tc; 44835244430SJian Shen kinfo->rss_size = min_t(u16, hdev->rss_size_max, new_tqps / num_tc); 44935244430SJian Shen new_tqps = kinfo->rss_size * num_tc; 450e2cb1decSSalil Mehta kinfo->num_tqps = min(new_tqps, hdev->num_tqps); 451e2cb1decSSalil Mehta 452e2cb1decSSalil Mehta kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, 453e2cb1decSSalil Mehta sizeof(struct hnae3_queue *), GFP_KERNEL); 454e2cb1decSSalil Mehta if (!kinfo->tqp) 455e2cb1decSSalil Mehta return -ENOMEM; 456e2cb1decSSalil Mehta 457e2cb1decSSalil Mehta for (i = 0; i < kinfo->num_tqps; i++) { 458e2cb1decSSalil Mehta hdev->htqp[i].q.handle = &hdev->nic; 459e2cb1decSSalil Mehta hdev->htqp[i].q.tqp_index = i; 460e2cb1decSSalil Mehta kinfo->tqp[i] = &hdev->htqp[i].q; 461e2cb1decSSalil Mehta } 462e2cb1decSSalil Mehta 463580a05f9SYonglong Liu /* after init the max rss_size and tqps, adjust the default tqp numbers 464580a05f9SYonglong Liu * and rss size with the actual vector numbers 465580a05f9SYonglong Liu */ 466580a05f9SYonglong Liu kinfo->num_tqps = min_t(u16, hdev->num_nic_msix - 1, kinfo->num_tqps); 46735244430SJian Shen kinfo->rss_size = min_t(u16, kinfo->num_tqps / num_tc, 468580a05f9SYonglong Liu kinfo->rss_size); 469580a05f9SYonglong Liu 470e2cb1decSSalil Mehta return 0; 471e2cb1decSSalil Mehta } 472e2cb1decSSalil Mehta 473e2cb1decSSalil Mehta static void hclgevf_request_link_info(struct hclgevf_dev *hdev) 474e2cb1decSSalil Mehta { 475d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 476e2cb1decSSalil Mehta int status; 477e2cb1decSSalil Mehta 478d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_LINK_STATUS, 0); 479d3410018SYufeng Mo status = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 480e2cb1decSSalil Mehta if (status) 481e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 482e2cb1decSSalil Mehta "VF failed to fetch link status(%d) from PF", status); 483e2cb1decSSalil Mehta } 484e2cb1decSSalil Mehta 485e2cb1decSSalil Mehta void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state) 486e2cb1decSSalil Mehta { 48745e92b7eSPeng Li struct hnae3_handle *rhandle = &hdev->roce; 488e2cb1decSSalil Mehta struct hnae3_handle *handle = &hdev->nic; 48945e92b7eSPeng Li struct hnae3_client *rclient; 490e2cb1decSSalil Mehta struct hnae3_client *client; 491e2cb1decSSalil Mehta 492ff200099SYunsheng Lin if (test_and_set_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state)) 493ff200099SYunsheng Lin return; 494ff200099SYunsheng Lin 495e2cb1decSSalil Mehta client = handle->client; 49645e92b7eSPeng Li rclient = hdev->roce_client; 497e2cb1decSSalil Mehta 498582d37bbSPeng Li link_state = 499582d37bbSPeng Li test_bit(HCLGEVF_STATE_DOWN, &hdev->state) ? 0 : link_state; 500582d37bbSPeng Li 501e2cb1decSSalil Mehta if (link_state != hdev->hw.mac.link) { 502e2cb1decSSalil Mehta client->ops->link_status_change(handle, !!link_state); 50345e92b7eSPeng Li if (rclient && rclient->ops->link_status_change) 50445e92b7eSPeng Li rclient->ops->link_status_change(rhandle, !!link_state); 505e2cb1decSSalil Mehta hdev->hw.mac.link = link_state; 506e2cb1decSSalil Mehta } 507ff200099SYunsheng Lin 508ff200099SYunsheng Lin clear_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state); 509e2cb1decSSalil Mehta } 510e2cb1decSSalil Mehta 511538abaf3SYueHaibing static void hclgevf_update_link_mode(struct hclgevf_dev *hdev) 5129194d18bSliuzhongzhu { 5139194d18bSliuzhongzhu #define HCLGEVF_ADVERTISING 0 5149194d18bSliuzhongzhu #define HCLGEVF_SUPPORTED 1 5159194d18bSliuzhongzhu 516d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 517d3410018SYufeng Mo 518d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_LINK_MODE, 0); 519d3410018SYufeng Mo send_msg.data[0] = HCLGEVF_ADVERTISING; 520d3410018SYufeng Mo hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 521d3410018SYufeng Mo send_msg.data[0] = HCLGEVF_SUPPORTED; 522d3410018SYufeng Mo hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 5239194d18bSliuzhongzhu } 5249194d18bSliuzhongzhu 525e2cb1decSSalil Mehta static int hclgevf_set_handle_info(struct hclgevf_dev *hdev) 526e2cb1decSSalil Mehta { 527e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 528e2cb1decSSalil Mehta int ret; 529e2cb1decSSalil Mehta 530e2cb1decSSalil Mehta nic->ae_algo = &ae_algovf; 531e2cb1decSSalil Mehta nic->pdev = hdev->pdev; 532e2cb1decSSalil Mehta nic->numa_node_mask = hdev->numa_node_mask; 533424eb834SSalil Mehta nic->flags |= HNAE3_SUPPORT_VF; 534e2cb1decSSalil Mehta 535e2cb1decSSalil Mehta ret = hclgevf_knic_setup(hdev); 536e2cb1decSSalil Mehta if (ret) 537e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF knic setup failed %d\n", 538e2cb1decSSalil Mehta ret); 539e2cb1decSSalil Mehta return ret; 540e2cb1decSSalil Mehta } 541e2cb1decSSalil Mehta 542e2cb1decSSalil Mehta static void hclgevf_free_vector(struct hclgevf_dev *hdev, int vector_id) 543e2cb1decSSalil Mehta { 54436cbbdf6SPeng Li if (hdev->vector_status[vector_id] == HCLGEVF_INVALID_VPORT) { 54536cbbdf6SPeng Li dev_warn(&hdev->pdev->dev, 54636cbbdf6SPeng Li "vector(vector_id %d) has been freed.\n", vector_id); 54736cbbdf6SPeng Li return; 54836cbbdf6SPeng Li } 54936cbbdf6SPeng Li 550e2cb1decSSalil Mehta hdev->vector_status[vector_id] = HCLGEVF_INVALID_VPORT; 551e2cb1decSSalil Mehta hdev->num_msi_left += 1; 552e2cb1decSSalil Mehta hdev->num_msi_used -= 1; 553e2cb1decSSalil Mehta } 554e2cb1decSSalil Mehta 555e2cb1decSSalil Mehta static int hclgevf_get_vector(struct hnae3_handle *handle, u16 vector_num, 556e2cb1decSSalil Mehta struct hnae3_vector_info *vector_info) 557e2cb1decSSalil Mehta { 558e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 559e2cb1decSSalil Mehta struct hnae3_vector_info *vector = vector_info; 560e2cb1decSSalil Mehta int alloc = 0; 561e2cb1decSSalil Mehta int i, j; 562e2cb1decSSalil Mehta 563580a05f9SYonglong Liu vector_num = min_t(u16, hdev->num_nic_msix - 1, vector_num); 564e2cb1decSSalil Mehta vector_num = min(hdev->num_msi_left, vector_num); 565e2cb1decSSalil Mehta 566e2cb1decSSalil Mehta for (j = 0; j < vector_num; j++) { 567e2cb1decSSalil Mehta for (i = HCLGEVF_MISC_VECTOR_NUM + 1; i < hdev->num_msi; i++) { 568e2cb1decSSalil Mehta if (hdev->vector_status[i] == HCLGEVF_INVALID_VPORT) { 569e2cb1decSSalil Mehta vector->vector = pci_irq_vector(hdev->pdev, i); 570e2cb1decSSalil Mehta vector->io_addr = hdev->hw.io_base + 571e2cb1decSSalil Mehta HCLGEVF_VECTOR_REG_BASE + 572e2cb1decSSalil Mehta (i - 1) * HCLGEVF_VECTOR_REG_OFFSET; 573e2cb1decSSalil Mehta hdev->vector_status[i] = 0; 574e2cb1decSSalil Mehta hdev->vector_irq[i] = vector->vector; 575e2cb1decSSalil Mehta 576e2cb1decSSalil Mehta vector++; 577e2cb1decSSalil Mehta alloc++; 578e2cb1decSSalil Mehta 579e2cb1decSSalil Mehta break; 580e2cb1decSSalil Mehta } 581e2cb1decSSalil Mehta } 582e2cb1decSSalil Mehta } 583e2cb1decSSalil Mehta hdev->num_msi_left -= alloc; 584e2cb1decSSalil Mehta hdev->num_msi_used += alloc; 585e2cb1decSSalil Mehta 586e2cb1decSSalil Mehta return alloc; 587e2cb1decSSalil Mehta } 588e2cb1decSSalil Mehta 589e2cb1decSSalil Mehta static int hclgevf_get_vector_index(struct hclgevf_dev *hdev, int vector) 590e2cb1decSSalil Mehta { 591e2cb1decSSalil Mehta int i; 592e2cb1decSSalil Mehta 593e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 594e2cb1decSSalil Mehta if (vector == hdev->vector_irq[i]) 595e2cb1decSSalil Mehta return i; 596e2cb1decSSalil Mehta 597e2cb1decSSalil Mehta return -EINVAL; 598e2cb1decSSalil Mehta } 599e2cb1decSSalil Mehta 600374ad291SJian Shen static int hclgevf_set_rss_algo_key(struct hclgevf_dev *hdev, 601374ad291SJian Shen const u8 hfunc, const u8 *key) 602374ad291SJian Shen { 603374ad291SJian Shen struct hclgevf_rss_config_cmd *req; 604ebaf1908SWeihang Li unsigned int key_offset = 0; 605374ad291SJian Shen struct hclgevf_desc desc; 6063caf772bSYufeng Mo int key_counts; 607374ad291SJian Shen int key_size; 608374ad291SJian Shen int ret; 609374ad291SJian Shen 6103caf772bSYufeng Mo key_counts = HCLGEVF_RSS_KEY_SIZE; 611374ad291SJian Shen req = (struct hclgevf_rss_config_cmd *)desc.data; 612374ad291SJian Shen 6133caf772bSYufeng Mo while (key_counts) { 614374ad291SJian Shen hclgevf_cmd_setup_basic_desc(&desc, 615374ad291SJian Shen HCLGEVF_OPC_RSS_GENERIC_CONFIG, 616374ad291SJian Shen false); 617374ad291SJian Shen 618374ad291SJian Shen req->hash_config |= (hfunc & HCLGEVF_RSS_HASH_ALGO_MASK); 619374ad291SJian Shen req->hash_config |= 620374ad291SJian Shen (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET_B); 621374ad291SJian Shen 6223caf772bSYufeng Mo key_size = min(HCLGEVF_RSS_HASH_KEY_NUM, key_counts); 623374ad291SJian Shen memcpy(req->hash_key, 624374ad291SJian Shen key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, key_size); 625374ad291SJian Shen 6263caf772bSYufeng Mo key_counts -= key_size; 6273caf772bSYufeng Mo key_offset++; 628374ad291SJian Shen ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); 629374ad291SJian Shen if (ret) { 630374ad291SJian Shen dev_err(&hdev->pdev->dev, 631374ad291SJian Shen "Configure RSS config fail, status = %d\n", 632374ad291SJian Shen ret); 633374ad291SJian Shen return ret; 634374ad291SJian Shen } 635374ad291SJian Shen } 636374ad291SJian Shen 637374ad291SJian Shen return 0; 638374ad291SJian Shen } 639374ad291SJian Shen 640e2cb1decSSalil Mehta static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle) 641e2cb1decSSalil Mehta { 642e2cb1decSSalil Mehta return HCLGEVF_RSS_KEY_SIZE; 643e2cb1decSSalil Mehta } 644e2cb1decSSalil Mehta 645e2cb1decSSalil Mehta static int hclgevf_set_rss_indir_table(struct hclgevf_dev *hdev) 646e2cb1decSSalil Mehta { 647e2cb1decSSalil Mehta const u8 *indir = hdev->rss_cfg.rss_indirection_tbl; 648e2cb1decSSalil Mehta struct hclgevf_rss_indirection_table_cmd *req; 649e2cb1decSSalil Mehta struct hclgevf_desc desc; 65087ce161eSGuangbin Huang int rss_cfg_tbl_num; 651e2cb1decSSalil Mehta int status; 652e2cb1decSSalil Mehta int i, j; 653e2cb1decSSalil Mehta 654e2cb1decSSalil Mehta req = (struct hclgevf_rss_indirection_table_cmd *)desc.data; 65587ce161eSGuangbin Huang rss_cfg_tbl_num = hdev->ae_dev->dev_specs.rss_ind_tbl_size / 65687ce161eSGuangbin Huang HCLGEVF_RSS_CFG_TBL_SIZE; 657e2cb1decSSalil Mehta 65887ce161eSGuangbin Huang for (i = 0; i < rss_cfg_tbl_num; i++) { 659e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_INDIR_TABLE, 660e2cb1decSSalil Mehta false); 661e2cb1decSSalil Mehta req->start_table_index = i * HCLGEVF_RSS_CFG_TBL_SIZE; 662e2cb1decSSalil Mehta req->rss_set_bitmap = HCLGEVF_RSS_SET_BITMAP_MSK; 663e2cb1decSSalil Mehta for (j = 0; j < HCLGEVF_RSS_CFG_TBL_SIZE; j++) 664e2cb1decSSalil Mehta req->rss_result[j] = 665e2cb1decSSalil Mehta indir[i * HCLGEVF_RSS_CFG_TBL_SIZE + j]; 666e2cb1decSSalil Mehta 667e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 668e2cb1decSSalil Mehta if (status) { 669e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 670e2cb1decSSalil Mehta "VF failed(=%d) to set RSS indirection table\n", 671e2cb1decSSalil Mehta status); 672e2cb1decSSalil Mehta return status; 673e2cb1decSSalil Mehta } 674e2cb1decSSalil Mehta } 675e2cb1decSSalil Mehta 676e2cb1decSSalil Mehta return 0; 677e2cb1decSSalil Mehta } 678e2cb1decSSalil Mehta 679e2cb1decSSalil Mehta static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size) 680e2cb1decSSalil Mehta { 681e2cb1decSSalil Mehta struct hclgevf_rss_tc_mode_cmd *req; 682e2cb1decSSalil Mehta u16 tc_offset[HCLGEVF_MAX_TC_NUM]; 683e2cb1decSSalil Mehta u16 tc_valid[HCLGEVF_MAX_TC_NUM]; 684e2cb1decSSalil Mehta u16 tc_size[HCLGEVF_MAX_TC_NUM]; 685e2cb1decSSalil Mehta struct hclgevf_desc desc; 686e2cb1decSSalil Mehta u16 roundup_size; 687ebaf1908SWeihang Li unsigned int i; 6882adb8187SHuazhong Tan int status; 689e2cb1decSSalil Mehta 690e2cb1decSSalil Mehta req = (struct hclgevf_rss_tc_mode_cmd *)desc.data; 691e2cb1decSSalil Mehta 692e2cb1decSSalil Mehta roundup_size = roundup_pow_of_two(rss_size); 693e2cb1decSSalil Mehta roundup_size = ilog2(roundup_size); 694e2cb1decSSalil Mehta 695e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 696e2cb1decSSalil Mehta tc_valid[i] = !!(hdev->hw_tc_map & BIT(i)); 697e2cb1decSSalil Mehta tc_size[i] = roundup_size; 698e2cb1decSSalil Mehta tc_offset[i] = rss_size * i; 699e2cb1decSSalil Mehta } 700e2cb1decSSalil Mehta 701e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false); 702e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 703e4e87715SPeng Li hnae3_set_bit(req->rss_tc_mode[i], HCLGEVF_RSS_TC_VALID_B, 704e2cb1decSSalil Mehta (tc_valid[i] & 0x1)); 705e4e87715SPeng Li hnae3_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_SIZE_M, 706e2cb1decSSalil Mehta HCLGEVF_RSS_TC_SIZE_S, tc_size[i]); 707e4e87715SPeng Li hnae3_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_OFFSET_M, 708e2cb1decSSalil Mehta HCLGEVF_RSS_TC_OFFSET_S, tc_offset[i]); 709e2cb1decSSalil Mehta } 710e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 711e2cb1decSSalil Mehta if (status) 712e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 713e2cb1decSSalil Mehta "VF failed(=%d) to set rss tc mode\n", status); 714e2cb1decSSalil Mehta 715e2cb1decSSalil Mehta return status; 716e2cb1decSSalil Mehta } 717e2cb1decSSalil Mehta 718a638b1d8SJian Shen /* for revision 0x20, vf shared the same rss config with pf */ 719a638b1d8SJian Shen static int hclgevf_get_rss_hash_key(struct hclgevf_dev *hdev) 720a638b1d8SJian Shen { 721a638b1d8SJian Shen #define HCLGEVF_RSS_MBX_RESP_LEN 8 722a638b1d8SJian Shen struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 723a638b1d8SJian Shen u8 resp_msg[HCLGEVF_RSS_MBX_RESP_LEN]; 724d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 725a638b1d8SJian Shen u16 msg_num, hash_key_index; 726a638b1d8SJian Shen u8 index; 727a638b1d8SJian Shen int ret; 728a638b1d8SJian Shen 729d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_RSS_KEY, 0); 730a638b1d8SJian Shen msg_num = (HCLGEVF_RSS_KEY_SIZE + HCLGEVF_RSS_MBX_RESP_LEN - 1) / 731a638b1d8SJian Shen HCLGEVF_RSS_MBX_RESP_LEN; 732a638b1d8SJian Shen for (index = 0; index < msg_num; index++) { 733d3410018SYufeng Mo send_msg.data[0] = index; 734d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg, 735a638b1d8SJian Shen HCLGEVF_RSS_MBX_RESP_LEN); 736a638b1d8SJian Shen if (ret) { 737a638b1d8SJian Shen dev_err(&hdev->pdev->dev, 738a638b1d8SJian Shen "VF get rss hash key from PF failed, ret=%d", 739a638b1d8SJian Shen ret); 740a638b1d8SJian Shen return ret; 741a638b1d8SJian Shen } 742a638b1d8SJian Shen 743a638b1d8SJian Shen hash_key_index = HCLGEVF_RSS_MBX_RESP_LEN * index; 744a638b1d8SJian Shen if (index == msg_num - 1) 745a638b1d8SJian Shen memcpy(&rss_cfg->rss_hash_key[hash_key_index], 746a638b1d8SJian Shen &resp_msg[0], 747a638b1d8SJian Shen HCLGEVF_RSS_KEY_SIZE - hash_key_index); 748a638b1d8SJian Shen else 749a638b1d8SJian Shen memcpy(&rss_cfg->rss_hash_key[hash_key_index], 750a638b1d8SJian Shen &resp_msg[0], HCLGEVF_RSS_MBX_RESP_LEN); 751a638b1d8SJian Shen } 752a638b1d8SJian Shen 753a638b1d8SJian Shen return 0; 754a638b1d8SJian Shen } 755a638b1d8SJian Shen 756e2cb1decSSalil Mehta static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key, 757e2cb1decSSalil Mehta u8 *hfunc) 758e2cb1decSSalil Mehta { 759e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 760e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 761a638b1d8SJian Shen int i, ret; 762e2cb1decSSalil Mehta 763295ba232SGuangbin Huang if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { 764374ad291SJian Shen /* Get hash algorithm */ 765374ad291SJian Shen if (hfunc) { 766374ad291SJian Shen switch (rss_cfg->hash_algo) { 767374ad291SJian Shen case HCLGEVF_RSS_HASH_ALGO_TOEPLITZ: 768374ad291SJian Shen *hfunc = ETH_RSS_HASH_TOP; 769374ad291SJian Shen break; 770374ad291SJian Shen case HCLGEVF_RSS_HASH_ALGO_SIMPLE: 771374ad291SJian Shen *hfunc = ETH_RSS_HASH_XOR; 772374ad291SJian Shen break; 773374ad291SJian Shen default: 774374ad291SJian Shen *hfunc = ETH_RSS_HASH_UNKNOWN; 775374ad291SJian Shen break; 776374ad291SJian Shen } 777374ad291SJian Shen } 778374ad291SJian Shen 779374ad291SJian Shen /* Get the RSS Key required by the user */ 780374ad291SJian Shen if (key) 781374ad291SJian Shen memcpy(key, rss_cfg->rss_hash_key, 782374ad291SJian Shen HCLGEVF_RSS_KEY_SIZE); 783a638b1d8SJian Shen } else { 784a638b1d8SJian Shen if (hfunc) 785a638b1d8SJian Shen *hfunc = ETH_RSS_HASH_TOP; 786a638b1d8SJian Shen if (key) { 787a638b1d8SJian Shen ret = hclgevf_get_rss_hash_key(hdev); 788a638b1d8SJian Shen if (ret) 789a638b1d8SJian Shen return ret; 790a638b1d8SJian Shen memcpy(key, rss_cfg->rss_hash_key, 791a638b1d8SJian Shen HCLGEVF_RSS_KEY_SIZE); 792a638b1d8SJian Shen } 793374ad291SJian Shen } 794374ad291SJian Shen 795e2cb1decSSalil Mehta if (indir) 79687ce161eSGuangbin Huang for (i = 0; i < hdev->ae_dev->dev_specs.rss_ind_tbl_size; i++) 797e2cb1decSSalil Mehta indir[i] = rss_cfg->rss_indirection_tbl[i]; 798e2cb1decSSalil Mehta 799374ad291SJian Shen return 0; 800e2cb1decSSalil Mehta } 801e2cb1decSSalil Mehta 802e2cb1decSSalil Mehta static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, 803e2cb1decSSalil Mehta const u8 *key, const u8 hfunc) 804e2cb1decSSalil Mehta { 805e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 806e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 807374ad291SJian Shen int ret, i; 808374ad291SJian Shen 809295ba232SGuangbin Huang if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { 810374ad291SJian Shen /* Set the RSS Hash Key if specififed by the user */ 811374ad291SJian Shen if (key) { 812374ad291SJian Shen switch (hfunc) { 813374ad291SJian Shen case ETH_RSS_HASH_TOP: 814374ad291SJian Shen rss_cfg->hash_algo = 815374ad291SJian Shen HCLGEVF_RSS_HASH_ALGO_TOEPLITZ; 816374ad291SJian Shen break; 817374ad291SJian Shen case ETH_RSS_HASH_XOR: 818374ad291SJian Shen rss_cfg->hash_algo = 819374ad291SJian Shen HCLGEVF_RSS_HASH_ALGO_SIMPLE; 820374ad291SJian Shen break; 821374ad291SJian Shen case ETH_RSS_HASH_NO_CHANGE: 822374ad291SJian Shen break; 823374ad291SJian Shen default: 824374ad291SJian Shen return -EINVAL; 825374ad291SJian Shen } 826374ad291SJian Shen 827374ad291SJian Shen ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo, 828374ad291SJian Shen key); 829374ad291SJian Shen if (ret) 830374ad291SJian Shen return ret; 831374ad291SJian Shen 832374ad291SJian Shen /* Update the shadow RSS key with user specified qids */ 833374ad291SJian Shen memcpy(rss_cfg->rss_hash_key, key, 834374ad291SJian Shen HCLGEVF_RSS_KEY_SIZE); 835374ad291SJian Shen } 836374ad291SJian Shen } 837e2cb1decSSalil Mehta 838e2cb1decSSalil Mehta /* update the shadow RSS table with user specified qids */ 83987ce161eSGuangbin Huang for (i = 0; i < hdev->ae_dev->dev_specs.rss_ind_tbl_size; i++) 840e2cb1decSSalil Mehta rss_cfg->rss_indirection_tbl[i] = indir[i]; 841e2cb1decSSalil Mehta 842e2cb1decSSalil Mehta /* update the hardware */ 843e2cb1decSSalil Mehta return hclgevf_set_rss_indir_table(hdev); 844e2cb1decSSalil Mehta } 845e2cb1decSSalil Mehta 846d97b3072SJian Shen static u8 hclgevf_get_rss_hash_bits(struct ethtool_rxnfc *nfc) 847d97b3072SJian Shen { 848d97b3072SJian Shen u8 hash_sets = nfc->data & RXH_L4_B_0_1 ? HCLGEVF_S_PORT_BIT : 0; 849d97b3072SJian Shen 850d97b3072SJian Shen if (nfc->data & RXH_L4_B_2_3) 851d97b3072SJian Shen hash_sets |= HCLGEVF_D_PORT_BIT; 852d97b3072SJian Shen else 853d97b3072SJian Shen hash_sets &= ~HCLGEVF_D_PORT_BIT; 854d97b3072SJian Shen 855d97b3072SJian Shen if (nfc->data & RXH_IP_SRC) 856d97b3072SJian Shen hash_sets |= HCLGEVF_S_IP_BIT; 857d97b3072SJian Shen else 858d97b3072SJian Shen hash_sets &= ~HCLGEVF_S_IP_BIT; 859d97b3072SJian Shen 860d97b3072SJian Shen if (nfc->data & RXH_IP_DST) 861d97b3072SJian Shen hash_sets |= HCLGEVF_D_IP_BIT; 862d97b3072SJian Shen else 863d97b3072SJian Shen hash_sets &= ~HCLGEVF_D_IP_BIT; 864d97b3072SJian Shen 865d97b3072SJian Shen if (nfc->flow_type == SCTP_V4_FLOW || nfc->flow_type == SCTP_V6_FLOW) 866d97b3072SJian Shen hash_sets |= HCLGEVF_V_TAG_BIT; 867d97b3072SJian Shen 868d97b3072SJian Shen return hash_sets; 869d97b3072SJian Shen } 870d97b3072SJian Shen 871d97b3072SJian Shen static int hclgevf_set_rss_tuple(struct hnae3_handle *handle, 872d97b3072SJian Shen struct ethtool_rxnfc *nfc) 873d97b3072SJian Shen { 874d97b3072SJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 875d97b3072SJian Shen struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 876d97b3072SJian Shen struct hclgevf_rss_input_tuple_cmd *req; 877d97b3072SJian Shen struct hclgevf_desc desc; 878d97b3072SJian Shen u8 tuple_sets; 879d97b3072SJian Shen int ret; 880d97b3072SJian Shen 881295ba232SGuangbin Huang if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) 882d97b3072SJian Shen return -EOPNOTSUPP; 883d97b3072SJian Shen 884d97b3072SJian Shen if (nfc->data & 885d97b3072SJian Shen ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)) 886d97b3072SJian Shen return -EINVAL; 887d97b3072SJian Shen 888d97b3072SJian Shen req = (struct hclgevf_rss_input_tuple_cmd *)desc.data; 889d97b3072SJian Shen hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_INPUT_TUPLE, false); 890d97b3072SJian Shen 891d97b3072SJian Shen req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en; 892d97b3072SJian Shen req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en; 893d97b3072SJian Shen req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en; 894d97b3072SJian Shen req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en; 895d97b3072SJian Shen req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en; 896d97b3072SJian Shen req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en; 897d97b3072SJian Shen req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en; 898d97b3072SJian Shen req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en; 899d97b3072SJian Shen 900d97b3072SJian Shen tuple_sets = hclgevf_get_rss_hash_bits(nfc); 901d97b3072SJian Shen switch (nfc->flow_type) { 902d97b3072SJian Shen case TCP_V4_FLOW: 903d97b3072SJian Shen req->ipv4_tcp_en = tuple_sets; 904d97b3072SJian Shen break; 905d97b3072SJian Shen case TCP_V6_FLOW: 906d97b3072SJian Shen req->ipv6_tcp_en = tuple_sets; 907d97b3072SJian Shen break; 908d97b3072SJian Shen case UDP_V4_FLOW: 909d97b3072SJian Shen req->ipv4_udp_en = tuple_sets; 910d97b3072SJian Shen break; 911d97b3072SJian Shen case UDP_V6_FLOW: 912d97b3072SJian Shen req->ipv6_udp_en = tuple_sets; 913d97b3072SJian Shen break; 914d97b3072SJian Shen case SCTP_V4_FLOW: 915d97b3072SJian Shen req->ipv4_sctp_en = tuple_sets; 916d97b3072SJian Shen break; 917d97b3072SJian Shen case SCTP_V6_FLOW: 918ab6e32d2SJian Shen if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 && 919ab6e32d2SJian Shen (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))) 920d97b3072SJian Shen return -EINVAL; 921d97b3072SJian Shen 922d97b3072SJian Shen req->ipv6_sctp_en = tuple_sets; 923d97b3072SJian Shen break; 924d97b3072SJian Shen case IPV4_FLOW: 925d97b3072SJian Shen req->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 926d97b3072SJian Shen break; 927d97b3072SJian Shen case IPV6_FLOW: 928d97b3072SJian Shen req->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 929d97b3072SJian Shen break; 930d97b3072SJian Shen default: 931d97b3072SJian Shen return -EINVAL; 932d97b3072SJian Shen } 933d97b3072SJian Shen 934d97b3072SJian Shen ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); 935d97b3072SJian Shen if (ret) { 936d97b3072SJian Shen dev_err(&hdev->pdev->dev, 937d97b3072SJian Shen "Set rss tuple fail, status = %d\n", ret); 938d97b3072SJian Shen return ret; 939d97b3072SJian Shen } 940d97b3072SJian Shen 941d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv4_tcp_en = req->ipv4_tcp_en; 942d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv4_udp_en = req->ipv4_udp_en; 943d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv4_sctp_en = req->ipv4_sctp_en; 944d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv4_fragment_en = req->ipv4_fragment_en; 945d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv6_tcp_en = req->ipv6_tcp_en; 946d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en; 947d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en; 948d97b3072SJian Shen rss_cfg->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en; 949d97b3072SJian Shen return 0; 950d97b3072SJian Shen } 951d97b3072SJian Shen 952d97b3072SJian Shen static int hclgevf_get_rss_tuple(struct hnae3_handle *handle, 953d97b3072SJian Shen struct ethtool_rxnfc *nfc) 954d97b3072SJian Shen { 955d97b3072SJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 956d97b3072SJian Shen struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 957d97b3072SJian Shen u8 tuple_sets; 958d97b3072SJian Shen 959295ba232SGuangbin Huang if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2) 960d97b3072SJian Shen return -EOPNOTSUPP; 961d97b3072SJian Shen 962d97b3072SJian Shen nfc->data = 0; 963d97b3072SJian Shen 964d97b3072SJian Shen switch (nfc->flow_type) { 965d97b3072SJian Shen case TCP_V4_FLOW: 966d97b3072SJian Shen tuple_sets = rss_cfg->rss_tuple_sets.ipv4_tcp_en; 967d97b3072SJian Shen break; 968d97b3072SJian Shen case UDP_V4_FLOW: 969d97b3072SJian Shen tuple_sets = rss_cfg->rss_tuple_sets.ipv4_udp_en; 970d97b3072SJian Shen break; 971d97b3072SJian Shen case TCP_V6_FLOW: 972d97b3072SJian Shen tuple_sets = rss_cfg->rss_tuple_sets.ipv6_tcp_en; 973d97b3072SJian Shen break; 974d97b3072SJian Shen case UDP_V6_FLOW: 975d97b3072SJian Shen tuple_sets = rss_cfg->rss_tuple_sets.ipv6_udp_en; 976d97b3072SJian Shen break; 977d97b3072SJian Shen case SCTP_V4_FLOW: 978d97b3072SJian Shen tuple_sets = rss_cfg->rss_tuple_sets.ipv4_sctp_en; 979d97b3072SJian Shen break; 980d97b3072SJian Shen case SCTP_V6_FLOW: 981d97b3072SJian Shen tuple_sets = rss_cfg->rss_tuple_sets.ipv6_sctp_en; 982d97b3072SJian Shen break; 983d97b3072SJian Shen case IPV4_FLOW: 984d97b3072SJian Shen case IPV6_FLOW: 985d97b3072SJian Shen tuple_sets = HCLGEVF_S_IP_BIT | HCLGEVF_D_IP_BIT; 986d97b3072SJian Shen break; 987d97b3072SJian Shen default: 988d97b3072SJian Shen return -EINVAL; 989d97b3072SJian Shen } 990d97b3072SJian Shen 991d97b3072SJian Shen if (!tuple_sets) 992d97b3072SJian Shen return 0; 993d97b3072SJian Shen 994d97b3072SJian Shen if (tuple_sets & HCLGEVF_D_PORT_BIT) 995d97b3072SJian Shen nfc->data |= RXH_L4_B_2_3; 996d97b3072SJian Shen if (tuple_sets & HCLGEVF_S_PORT_BIT) 997d97b3072SJian Shen nfc->data |= RXH_L4_B_0_1; 998d97b3072SJian Shen if (tuple_sets & HCLGEVF_D_IP_BIT) 999d97b3072SJian Shen nfc->data |= RXH_IP_DST; 1000d97b3072SJian Shen if (tuple_sets & HCLGEVF_S_IP_BIT) 1001d97b3072SJian Shen nfc->data |= RXH_IP_SRC; 1002d97b3072SJian Shen 1003d97b3072SJian Shen return 0; 1004d97b3072SJian Shen } 1005d97b3072SJian Shen 1006d97b3072SJian Shen static int hclgevf_set_rss_input_tuple(struct hclgevf_dev *hdev, 1007d97b3072SJian Shen struct hclgevf_rss_cfg *rss_cfg) 1008d97b3072SJian Shen { 1009d97b3072SJian Shen struct hclgevf_rss_input_tuple_cmd *req; 1010d97b3072SJian Shen struct hclgevf_desc desc; 1011d97b3072SJian Shen int ret; 1012d97b3072SJian Shen 1013d97b3072SJian Shen hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_INPUT_TUPLE, false); 1014d97b3072SJian Shen 1015d97b3072SJian Shen req = (struct hclgevf_rss_input_tuple_cmd *)desc.data; 1016d97b3072SJian Shen 1017d97b3072SJian Shen req->ipv4_tcp_en = rss_cfg->rss_tuple_sets.ipv4_tcp_en; 1018d97b3072SJian Shen req->ipv4_udp_en = rss_cfg->rss_tuple_sets.ipv4_udp_en; 1019d97b3072SJian Shen req->ipv4_sctp_en = rss_cfg->rss_tuple_sets.ipv4_sctp_en; 1020d97b3072SJian Shen req->ipv4_fragment_en = rss_cfg->rss_tuple_sets.ipv4_fragment_en; 1021d97b3072SJian Shen req->ipv6_tcp_en = rss_cfg->rss_tuple_sets.ipv6_tcp_en; 1022d97b3072SJian Shen req->ipv6_udp_en = rss_cfg->rss_tuple_sets.ipv6_udp_en; 1023d97b3072SJian Shen req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en; 1024d97b3072SJian Shen req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en; 1025d97b3072SJian Shen 1026d97b3072SJian Shen ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); 1027d97b3072SJian Shen if (ret) 1028d97b3072SJian Shen dev_err(&hdev->pdev->dev, 1029d97b3072SJian Shen "Configure rss input fail, status = %d\n", ret); 1030d97b3072SJian Shen return ret; 1031d97b3072SJian Shen } 1032d97b3072SJian Shen 1033e2cb1decSSalil Mehta static int hclgevf_get_tc_size(struct hnae3_handle *handle) 1034e2cb1decSSalil Mehta { 1035e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1036e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 1037e2cb1decSSalil Mehta 1038e2cb1decSSalil Mehta return rss_cfg->rss_size; 1039e2cb1decSSalil Mehta } 1040e2cb1decSSalil Mehta 1041e2cb1decSSalil Mehta static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, 1042b204bc74SPeng Li int vector_id, 1043e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 1044e2cb1decSSalil Mehta { 1045e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1046d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 1047e2cb1decSSalil Mehta struct hnae3_ring_chain_node *node; 1048e2cb1decSSalil Mehta int status; 1049d3410018SYufeng Mo int i = 0; 1050e2cb1decSSalil Mehta 1051d3410018SYufeng Mo memset(&send_msg, 0, sizeof(send_msg)); 1052d3410018SYufeng Mo send_msg.code = en ? HCLGE_MBX_MAP_RING_TO_VECTOR : 1053c09ba484SPeng Li HCLGE_MBX_UNMAP_RING_TO_VECTOR; 1054d3410018SYufeng Mo send_msg.vector_id = vector_id; 1055e2cb1decSSalil Mehta 1056e2cb1decSSalil Mehta for (node = ring_chain; node; node = node->next) { 1057d3410018SYufeng Mo send_msg.param[i].ring_type = 1058e4e87715SPeng Li hnae3_get_bit(node->flag, HNAE3_RING_TYPE_B); 1059d3410018SYufeng Mo 1060d3410018SYufeng Mo send_msg.param[i].tqp_index = node->tqp_index; 1061d3410018SYufeng Mo send_msg.param[i].int_gl_index = 1062d3410018SYufeng Mo hnae3_get_field(node->int_gl_idx, 106379eee410SFuyun Liang HNAE3_RING_GL_IDX_M, 106479eee410SFuyun Liang HNAE3_RING_GL_IDX_S); 106579eee410SFuyun Liang 10665d02a58dSYunsheng Lin i++; 1067d3410018SYufeng Mo if (i == HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM || !node->next) { 1068d3410018SYufeng Mo send_msg.ring_num = i; 1069e2cb1decSSalil Mehta 1070d3410018SYufeng Mo status = hclgevf_send_mbx_msg(hdev, &send_msg, false, 1071d3410018SYufeng Mo NULL, 0); 1072e2cb1decSSalil Mehta if (status) { 1073e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1074e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", 1075e2cb1decSSalil Mehta status); 1076e2cb1decSSalil Mehta return status; 1077e2cb1decSSalil Mehta } 1078e2cb1decSSalil Mehta i = 0; 1079e2cb1decSSalil Mehta } 1080e2cb1decSSalil Mehta } 1081e2cb1decSSalil Mehta 1082e2cb1decSSalil Mehta return 0; 1083e2cb1decSSalil Mehta } 1084e2cb1decSSalil Mehta 1085e2cb1decSSalil Mehta static int hclgevf_map_ring_to_vector(struct hnae3_handle *handle, int vector, 1086e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 1087e2cb1decSSalil Mehta { 1088b204bc74SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1089b204bc74SPeng Li int vector_id; 1090b204bc74SPeng Li 1091b204bc74SPeng Li vector_id = hclgevf_get_vector_index(hdev, vector); 1092b204bc74SPeng Li if (vector_id < 0) { 1093b204bc74SPeng Li dev_err(&handle->pdev->dev, 1094b204bc74SPeng Li "Get vector index fail. ret =%d\n", vector_id); 1095b204bc74SPeng Li return vector_id; 1096b204bc74SPeng Li } 1097b204bc74SPeng Li 1098b204bc74SPeng Li return hclgevf_bind_ring_to_vector(handle, true, vector_id, ring_chain); 1099e2cb1decSSalil Mehta } 1100e2cb1decSSalil Mehta 1101e2cb1decSSalil Mehta static int hclgevf_unmap_ring_from_vector( 1102e2cb1decSSalil Mehta struct hnae3_handle *handle, 1103e2cb1decSSalil Mehta int vector, 1104e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 1105e2cb1decSSalil Mehta { 1106e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1107e2cb1decSSalil Mehta int ret, vector_id; 1108e2cb1decSSalil Mehta 1109dea846e8SHuazhong Tan if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) 1110dea846e8SHuazhong Tan return 0; 1111dea846e8SHuazhong Tan 1112e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 1113e2cb1decSSalil Mehta if (vector_id < 0) { 1114e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 1115e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 1116e2cb1decSSalil Mehta return vector_id; 1117e2cb1decSSalil Mehta } 1118e2cb1decSSalil Mehta 1119b204bc74SPeng Li ret = hclgevf_bind_ring_to_vector(handle, false, vector_id, ring_chain); 11200d3e6631SYunsheng Lin if (ret) 1121e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 1122e2cb1decSSalil Mehta "Unmap ring from vector fail. vector=%d, ret =%d\n", 1123e2cb1decSSalil Mehta vector_id, 1124e2cb1decSSalil Mehta ret); 11250d3e6631SYunsheng Lin 1126e2cb1decSSalil Mehta return ret; 1127e2cb1decSSalil Mehta } 1128e2cb1decSSalil Mehta 11290d3e6631SYunsheng Lin static int hclgevf_put_vector(struct hnae3_handle *handle, int vector) 11300d3e6631SYunsheng Lin { 11310d3e6631SYunsheng Lin struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 113203718db9SYunsheng Lin int vector_id; 11330d3e6631SYunsheng Lin 113403718db9SYunsheng Lin vector_id = hclgevf_get_vector_index(hdev, vector); 113503718db9SYunsheng Lin if (vector_id < 0) { 113603718db9SYunsheng Lin dev_err(&handle->pdev->dev, 113703718db9SYunsheng Lin "hclgevf_put_vector get vector index fail. ret =%d\n", 113803718db9SYunsheng Lin vector_id); 113903718db9SYunsheng Lin return vector_id; 114003718db9SYunsheng Lin } 114103718db9SYunsheng Lin 114203718db9SYunsheng Lin hclgevf_free_vector(hdev, vector_id); 1143e2cb1decSSalil Mehta 1144e2cb1decSSalil Mehta return 0; 1145e2cb1decSSalil Mehta } 1146e2cb1decSSalil Mehta 11473b75c3dfSPeng Li static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, 1148e196ec75SJian Shen bool en_uc_pmc, bool en_mc_pmc, 1149f01f5559SJian Shen bool en_bc_pmc) 1150e2cb1decSSalil Mehta { 11515e7414cdSJian Shen struct hnae3_handle *handle = &hdev->nic; 1152d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 1153f01f5559SJian Shen int ret; 1154e2cb1decSSalil Mehta 1155d3410018SYufeng Mo memset(&send_msg, 0, sizeof(send_msg)); 1156d3410018SYufeng Mo send_msg.code = HCLGE_MBX_SET_PROMISC_MODE; 1157d3410018SYufeng Mo send_msg.en_bc = en_bc_pmc ? 1 : 0; 1158d3410018SYufeng Mo send_msg.en_uc = en_uc_pmc ? 1 : 0; 1159d3410018SYufeng Mo send_msg.en_mc = en_mc_pmc ? 1 : 0; 11605e7414cdSJian Shen send_msg.en_limit_promisc = test_bit(HNAE3_PFLAG_LIMIT_PROMISC, 11615e7414cdSJian Shen &handle->priv_flags) ? 1 : 0; 1162e2cb1decSSalil Mehta 1163d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 1164f01f5559SJian Shen if (ret) 1165e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1166f01f5559SJian Shen "Set promisc mode fail, status is %d.\n", ret); 1167e2cb1decSSalil Mehta 1168f01f5559SJian Shen return ret; 1169e2cb1decSSalil Mehta } 1170e2cb1decSSalil Mehta 1171e196ec75SJian Shen static int hclgevf_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, 1172e196ec75SJian Shen bool en_mc_pmc) 1173e2cb1decSSalil Mehta { 1174e196ec75SJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1175e196ec75SJian Shen bool en_bc_pmc; 1176e196ec75SJian Shen 1177295ba232SGuangbin Huang en_bc_pmc = hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2; 1178e196ec75SJian Shen 1179e196ec75SJian Shen return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc, 1180e196ec75SJian Shen en_bc_pmc); 1181e2cb1decSSalil Mehta } 1182e2cb1decSSalil Mehta 1183c631c696SJian Shen static void hclgevf_request_update_promisc_mode(struct hnae3_handle *handle) 1184c631c696SJian Shen { 1185c631c696SJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1186c631c696SJian Shen 1187c631c696SJian Shen set_bit(HCLGEVF_STATE_PROMISC_CHANGED, &hdev->state); 11885e7414cdSJian Shen hclgevf_task_schedule(hdev, 0); 1189c631c696SJian Shen } 1190c631c696SJian Shen 1191c631c696SJian Shen static void hclgevf_sync_promisc_mode(struct hclgevf_dev *hdev) 1192c631c696SJian Shen { 1193c631c696SJian Shen struct hnae3_handle *handle = &hdev->nic; 1194c631c696SJian Shen bool en_uc_pmc = handle->netdev_flags & HNAE3_UPE; 1195c631c696SJian Shen bool en_mc_pmc = handle->netdev_flags & HNAE3_MPE; 1196c631c696SJian Shen int ret; 1197c631c696SJian Shen 1198c631c696SJian Shen if (test_bit(HCLGEVF_STATE_PROMISC_CHANGED, &hdev->state)) { 1199c631c696SJian Shen ret = hclgevf_set_promisc_mode(handle, en_uc_pmc, en_mc_pmc); 1200c631c696SJian Shen if (!ret) 1201c631c696SJian Shen clear_bit(HCLGEVF_STATE_PROMISC_CHANGED, &hdev->state); 1202c631c696SJian Shen } 1203c631c696SJian Shen } 1204c631c696SJian Shen 1205ebaf1908SWeihang Li static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, unsigned int tqp_id, 1206e2cb1decSSalil Mehta int stream_id, bool enable) 1207e2cb1decSSalil Mehta { 1208e2cb1decSSalil Mehta struct hclgevf_cfg_com_tqp_queue_cmd *req; 1209e2cb1decSSalil Mehta struct hclgevf_desc desc; 1210e2cb1decSSalil Mehta int status; 1211e2cb1decSSalil Mehta 1212e2cb1decSSalil Mehta req = (struct hclgevf_cfg_com_tqp_queue_cmd *)desc.data; 1213e2cb1decSSalil Mehta 1214e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_CFG_COM_TQP_QUEUE, 1215e2cb1decSSalil Mehta false); 1216e2cb1decSSalil Mehta req->tqp_id = cpu_to_le16(tqp_id & HCLGEVF_RING_ID_MASK); 1217e2cb1decSSalil Mehta req->stream_id = cpu_to_le16(stream_id); 1218ebaf1908SWeihang Li if (enable) 1219ebaf1908SWeihang Li req->enable |= 1U << HCLGEVF_TQP_ENABLE_B; 1220e2cb1decSSalil Mehta 1221e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 1222e2cb1decSSalil Mehta if (status) 1223e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1224e2cb1decSSalil Mehta "TQP enable fail, status =%d.\n", status); 1225e2cb1decSSalil Mehta 1226e2cb1decSSalil Mehta return status; 1227e2cb1decSSalil Mehta } 1228e2cb1decSSalil Mehta 1229e2cb1decSSalil Mehta static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) 1230e2cb1decSSalil Mehta { 1231b4f1d303SJian Shen struct hnae3_knic_private_info *kinfo = &handle->kinfo; 1232e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 1233e2cb1decSSalil Mehta int i; 1234e2cb1decSSalil Mehta 1235b4f1d303SJian Shen for (i = 0; i < kinfo->num_tqps; i++) { 1236b4f1d303SJian Shen tqp = container_of(kinfo->tqp[i], struct hclgevf_tqp, q); 1237e2cb1decSSalil Mehta memset(&tqp->tqp_stats, 0, sizeof(tqp->tqp_stats)); 1238e2cb1decSSalil Mehta } 1239e2cb1decSSalil Mehta } 1240e2cb1decSSalil Mehta 12418e6de441SHuazhong Tan static int hclgevf_get_host_mac_addr(struct hclgevf_dev *hdev, u8 *p) 12428e6de441SHuazhong Tan { 1243d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 12448e6de441SHuazhong Tan u8 host_mac[ETH_ALEN]; 12458e6de441SHuazhong Tan int status; 12468e6de441SHuazhong Tan 1247d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_MAC_ADDR, 0); 1248d3410018SYufeng Mo status = hclgevf_send_mbx_msg(hdev, &send_msg, true, host_mac, 1249d3410018SYufeng Mo ETH_ALEN); 12508e6de441SHuazhong Tan if (status) { 12518e6de441SHuazhong Tan dev_err(&hdev->pdev->dev, 12528e6de441SHuazhong Tan "fail to get VF MAC from host %d", status); 12538e6de441SHuazhong Tan return status; 12548e6de441SHuazhong Tan } 12558e6de441SHuazhong Tan 12568e6de441SHuazhong Tan ether_addr_copy(p, host_mac); 12578e6de441SHuazhong Tan 12588e6de441SHuazhong Tan return 0; 12598e6de441SHuazhong Tan } 12608e6de441SHuazhong Tan 1261e2cb1decSSalil Mehta static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) 1262e2cb1decSSalil Mehta { 1263e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 12648e6de441SHuazhong Tan u8 host_mac_addr[ETH_ALEN]; 1265e2cb1decSSalil Mehta 12668e6de441SHuazhong Tan if (hclgevf_get_host_mac_addr(hdev, host_mac_addr)) 12678e6de441SHuazhong Tan return; 12688e6de441SHuazhong Tan 12698e6de441SHuazhong Tan hdev->has_pf_mac = !is_zero_ether_addr(host_mac_addr); 12708e6de441SHuazhong Tan if (hdev->has_pf_mac) 12718e6de441SHuazhong Tan ether_addr_copy(p, host_mac_addr); 12728e6de441SHuazhong Tan else 1273e2cb1decSSalil Mehta ether_addr_copy(p, hdev->hw.mac.mac_addr); 1274e2cb1decSSalil Mehta } 1275e2cb1decSSalil Mehta 127659098055SFuyun Liang static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p, 127759098055SFuyun Liang bool is_first) 1278e2cb1decSSalil Mehta { 1279e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1280e2cb1decSSalil Mehta u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; 1281d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 1282e2cb1decSSalil Mehta u8 *new_mac_addr = (u8 *)p; 1283e2cb1decSSalil Mehta int status; 1284e2cb1decSSalil Mehta 1285d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_UNICAST, 0); 1286ee4bcd3bSJian Shen send_msg.subcode = HCLGE_MBX_MAC_VLAN_UC_MODIFY; 1287d3410018SYufeng Mo ether_addr_copy(send_msg.data, new_mac_addr); 1288ee4bcd3bSJian Shen if (is_first && !hdev->has_pf_mac) 1289ee4bcd3bSJian Shen eth_zero_addr(&send_msg.data[ETH_ALEN]); 1290ee4bcd3bSJian Shen else 1291d3410018SYufeng Mo ether_addr_copy(&send_msg.data[ETH_ALEN], old_mac_addr); 1292d3410018SYufeng Mo status = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); 1293e2cb1decSSalil Mehta if (!status) 1294e2cb1decSSalil Mehta ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); 1295e2cb1decSSalil Mehta 1296e2cb1decSSalil Mehta return status; 1297e2cb1decSSalil Mehta } 1298e2cb1decSSalil Mehta 1299ee4bcd3bSJian Shen static struct hclgevf_mac_addr_node * 1300ee4bcd3bSJian Shen hclgevf_find_mac_node(struct list_head *list, const u8 *mac_addr) 1301ee4bcd3bSJian Shen { 1302ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, *tmp; 1303ee4bcd3bSJian Shen 1304ee4bcd3bSJian Shen list_for_each_entry_safe(mac_node, tmp, list, node) 1305ee4bcd3bSJian Shen if (ether_addr_equal(mac_addr, mac_node->mac_addr)) 1306ee4bcd3bSJian Shen return mac_node; 1307ee4bcd3bSJian Shen 1308ee4bcd3bSJian Shen return NULL; 1309ee4bcd3bSJian Shen } 1310ee4bcd3bSJian Shen 1311ee4bcd3bSJian Shen static void hclgevf_update_mac_node(struct hclgevf_mac_addr_node *mac_node, 1312ee4bcd3bSJian Shen enum HCLGEVF_MAC_NODE_STATE state) 1313ee4bcd3bSJian Shen { 1314ee4bcd3bSJian Shen switch (state) { 1315ee4bcd3bSJian Shen /* from set_rx_mode or tmp_add_list */ 1316ee4bcd3bSJian Shen case HCLGEVF_MAC_TO_ADD: 1317ee4bcd3bSJian Shen if (mac_node->state == HCLGEVF_MAC_TO_DEL) 1318ee4bcd3bSJian Shen mac_node->state = HCLGEVF_MAC_ACTIVE; 1319ee4bcd3bSJian Shen break; 1320ee4bcd3bSJian Shen /* only from set_rx_mode */ 1321ee4bcd3bSJian Shen case HCLGEVF_MAC_TO_DEL: 1322ee4bcd3bSJian Shen if (mac_node->state == HCLGEVF_MAC_TO_ADD) { 1323ee4bcd3bSJian Shen list_del(&mac_node->node); 1324ee4bcd3bSJian Shen kfree(mac_node); 1325ee4bcd3bSJian Shen } else { 1326ee4bcd3bSJian Shen mac_node->state = HCLGEVF_MAC_TO_DEL; 1327ee4bcd3bSJian Shen } 1328ee4bcd3bSJian Shen break; 1329ee4bcd3bSJian Shen /* only from tmp_add_list, the mac_node->state won't be 1330ee4bcd3bSJian Shen * HCLGEVF_MAC_ACTIVE 1331ee4bcd3bSJian Shen */ 1332ee4bcd3bSJian Shen case HCLGEVF_MAC_ACTIVE: 1333ee4bcd3bSJian Shen if (mac_node->state == HCLGEVF_MAC_TO_ADD) 1334ee4bcd3bSJian Shen mac_node->state = HCLGEVF_MAC_ACTIVE; 1335ee4bcd3bSJian Shen break; 1336ee4bcd3bSJian Shen } 1337ee4bcd3bSJian Shen } 1338ee4bcd3bSJian Shen 1339ee4bcd3bSJian Shen static int hclgevf_update_mac_list(struct hnae3_handle *handle, 1340ee4bcd3bSJian Shen enum HCLGEVF_MAC_NODE_STATE state, 1341ee4bcd3bSJian Shen enum HCLGEVF_MAC_ADDR_TYPE mac_type, 1342e2cb1decSSalil Mehta const unsigned char *addr) 1343e2cb1decSSalil Mehta { 1344e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1345ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node; 1346ee4bcd3bSJian Shen struct list_head *list; 1347e2cb1decSSalil Mehta 1348ee4bcd3bSJian Shen list = (mac_type == HCLGEVF_MAC_ADDR_UC) ? 1349ee4bcd3bSJian Shen &hdev->mac_table.uc_mac_list : &hdev->mac_table.mc_mac_list; 1350ee4bcd3bSJian Shen 1351ee4bcd3bSJian Shen spin_lock_bh(&hdev->mac_table.mac_list_lock); 1352ee4bcd3bSJian Shen 1353ee4bcd3bSJian Shen /* if the mac addr is already in the mac list, no need to add a new 1354ee4bcd3bSJian Shen * one into it, just check the mac addr state, convert it to a new 1355ee4bcd3bSJian Shen * new state, or just remove it, or do nothing. 1356ee4bcd3bSJian Shen */ 1357ee4bcd3bSJian Shen mac_node = hclgevf_find_mac_node(list, addr); 1358ee4bcd3bSJian Shen if (mac_node) { 1359ee4bcd3bSJian Shen hclgevf_update_mac_node(mac_node, state); 1360ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1361ee4bcd3bSJian Shen return 0; 1362ee4bcd3bSJian Shen } 1363ee4bcd3bSJian Shen /* if this address is never added, unnecessary to delete */ 1364ee4bcd3bSJian Shen if (state == HCLGEVF_MAC_TO_DEL) { 1365ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1366ee4bcd3bSJian Shen return -ENOENT; 1367ee4bcd3bSJian Shen } 1368ee4bcd3bSJian Shen 1369ee4bcd3bSJian Shen mac_node = kzalloc(sizeof(*mac_node), GFP_ATOMIC); 1370ee4bcd3bSJian Shen if (!mac_node) { 1371ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1372ee4bcd3bSJian Shen return -ENOMEM; 1373ee4bcd3bSJian Shen } 1374ee4bcd3bSJian Shen 1375ee4bcd3bSJian Shen mac_node->state = state; 1376ee4bcd3bSJian Shen ether_addr_copy(mac_node->mac_addr, addr); 1377ee4bcd3bSJian Shen list_add_tail(&mac_node->node, list); 1378ee4bcd3bSJian Shen 1379ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1380ee4bcd3bSJian Shen return 0; 1381ee4bcd3bSJian Shen } 1382ee4bcd3bSJian Shen 1383ee4bcd3bSJian Shen static int hclgevf_add_uc_addr(struct hnae3_handle *handle, 1384ee4bcd3bSJian Shen const unsigned char *addr) 1385ee4bcd3bSJian Shen { 1386ee4bcd3bSJian Shen return hclgevf_update_mac_list(handle, HCLGEVF_MAC_TO_ADD, 1387ee4bcd3bSJian Shen HCLGEVF_MAC_ADDR_UC, addr); 1388e2cb1decSSalil Mehta } 1389e2cb1decSSalil Mehta 1390e2cb1decSSalil Mehta static int hclgevf_rm_uc_addr(struct hnae3_handle *handle, 1391e2cb1decSSalil Mehta const unsigned char *addr) 1392e2cb1decSSalil Mehta { 1393ee4bcd3bSJian Shen return hclgevf_update_mac_list(handle, HCLGEVF_MAC_TO_DEL, 1394ee4bcd3bSJian Shen HCLGEVF_MAC_ADDR_UC, addr); 1395e2cb1decSSalil Mehta } 1396e2cb1decSSalil Mehta 1397e2cb1decSSalil Mehta static int hclgevf_add_mc_addr(struct hnae3_handle *handle, 1398e2cb1decSSalil Mehta const unsigned char *addr) 1399e2cb1decSSalil Mehta { 1400ee4bcd3bSJian Shen return hclgevf_update_mac_list(handle, HCLGEVF_MAC_TO_ADD, 1401ee4bcd3bSJian Shen HCLGEVF_MAC_ADDR_MC, addr); 1402e2cb1decSSalil Mehta } 1403e2cb1decSSalil Mehta 1404e2cb1decSSalil Mehta static int hclgevf_rm_mc_addr(struct hnae3_handle *handle, 1405e2cb1decSSalil Mehta const unsigned char *addr) 1406e2cb1decSSalil Mehta { 1407ee4bcd3bSJian Shen return hclgevf_update_mac_list(handle, HCLGEVF_MAC_TO_DEL, 1408ee4bcd3bSJian Shen HCLGEVF_MAC_ADDR_MC, addr); 1409ee4bcd3bSJian Shen } 1410e2cb1decSSalil Mehta 1411ee4bcd3bSJian Shen static int hclgevf_add_del_mac_addr(struct hclgevf_dev *hdev, 1412ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, 1413ee4bcd3bSJian Shen enum HCLGEVF_MAC_ADDR_TYPE mac_type) 1414ee4bcd3bSJian Shen { 1415ee4bcd3bSJian Shen struct hclge_vf_to_pf_msg send_msg; 1416ee4bcd3bSJian Shen u8 code, subcode; 1417ee4bcd3bSJian Shen 1418ee4bcd3bSJian Shen if (mac_type == HCLGEVF_MAC_ADDR_UC) { 1419ee4bcd3bSJian Shen code = HCLGE_MBX_SET_UNICAST; 1420ee4bcd3bSJian Shen if (mac_node->state == HCLGEVF_MAC_TO_ADD) 1421ee4bcd3bSJian Shen subcode = HCLGE_MBX_MAC_VLAN_UC_ADD; 1422ee4bcd3bSJian Shen else 1423ee4bcd3bSJian Shen subcode = HCLGE_MBX_MAC_VLAN_UC_REMOVE; 1424ee4bcd3bSJian Shen } else { 1425ee4bcd3bSJian Shen code = HCLGE_MBX_SET_MULTICAST; 1426ee4bcd3bSJian Shen if (mac_node->state == HCLGEVF_MAC_TO_ADD) 1427ee4bcd3bSJian Shen subcode = HCLGE_MBX_MAC_VLAN_MC_ADD; 1428ee4bcd3bSJian Shen else 1429ee4bcd3bSJian Shen subcode = HCLGE_MBX_MAC_VLAN_MC_REMOVE; 1430ee4bcd3bSJian Shen } 1431ee4bcd3bSJian Shen 1432ee4bcd3bSJian Shen hclgevf_build_send_msg(&send_msg, code, subcode); 1433ee4bcd3bSJian Shen ether_addr_copy(send_msg.data, mac_node->mac_addr); 1434d3410018SYufeng Mo return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 1435e2cb1decSSalil Mehta } 1436e2cb1decSSalil Mehta 1437ee4bcd3bSJian Shen static void hclgevf_config_mac_list(struct hclgevf_dev *hdev, 1438ee4bcd3bSJian Shen struct list_head *list, 1439ee4bcd3bSJian Shen enum HCLGEVF_MAC_ADDR_TYPE mac_type) 1440ee4bcd3bSJian Shen { 1441ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, *tmp; 1442ee4bcd3bSJian Shen int ret; 1443ee4bcd3bSJian Shen 1444ee4bcd3bSJian Shen list_for_each_entry_safe(mac_node, tmp, list, node) { 1445ee4bcd3bSJian Shen ret = hclgevf_add_del_mac_addr(hdev, mac_node, mac_type); 1446ee4bcd3bSJian Shen if (ret) { 1447ee4bcd3bSJian Shen dev_err(&hdev->pdev->dev, 1448ee4bcd3bSJian Shen "failed to configure mac %pM, state = %d, ret = %d\n", 1449ee4bcd3bSJian Shen mac_node->mac_addr, mac_node->state, ret); 1450ee4bcd3bSJian Shen return; 1451ee4bcd3bSJian Shen } 1452ee4bcd3bSJian Shen if (mac_node->state == HCLGEVF_MAC_TO_ADD) { 1453ee4bcd3bSJian Shen mac_node->state = HCLGEVF_MAC_ACTIVE; 1454ee4bcd3bSJian Shen } else { 1455ee4bcd3bSJian Shen list_del(&mac_node->node); 1456ee4bcd3bSJian Shen kfree(mac_node); 1457ee4bcd3bSJian Shen } 1458ee4bcd3bSJian Shen } 1459ee4bcd3bSJian Shen } 1460ee4bcd3bSJian Shen 1461ee4bcd3bSJian Shen static void hclgevf_sync_from_add_list(struct list_head *add_list, 1462ee4bcd3bSJian Shen struct list_head *mac_list) 1463ee4bcd3bSJian Shen { 1464ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, *tmp, *new_node; 1465ee4bcd3bSJian Shen 1466ee4bcd3bSJian Shen list_for_each_entry_safe(mac_node, tmp, add_list, node) { 1467ee4bcd3bSJian Shen /* if the mac address from tmp_add_list is not in the 1468ee4bcd3bSJian Shen * uc/mc_mac_list, it means have received a TO_DEL request 1469ee4bcd3bSJian Shen * during the time window of sending mac config request to PF 1470ee4bcd3bSJian Shen * If mac_node state is ACTIVE, then change its state to TO_DEL, 1471ee4bcd3bSJian Shen * then it will be removed at next time. If is TO_ADD, it means 1472ee4bcd3bSJian Shen * send TO_ADD request failed, so just remove the mac node. 1473ee4bcd3bSJian Shen */ 1474ee4bcd3bSJian Shen new_node = hclgevf_find_mac_node(mac_list, mac_node->mac_addr); 1475ee4bcd3bSJian Shen if (new_node) { 1476ee4bcd3bSJian Shen hclgevf_update_mac_node(new_node, mac_node->state); 1477ee4bcd3bSJian Shen list_del(&mac_node->node); 1478ee4bcd3bSJian Shen kfree(mac_node); 1479ee4bcd3bSJian Shen } else if (mac_node->state == HCLGEVF_MAC_ACTIVE) { 1480ee4bcd3bSJian Shen mac_node->state = HCLGEVF_MAC_TO_DEL; 1481ee4bcd3bSJian Shen list_del(&mac_node->node); 1482ee4bcd3bSJian Shen list_add_tail(&mac_node->node, mac_list); 1483ee4bcd3bSJian Shen } else { 1484ee4bcd3bSJian Shen list_del(&mac_node->node); 1485ee4bcd3bSJian Shen kfree(mac_node); 1486ee4bcd3bSJian Shen } 1487ee4bcd3bSJian Shen } 1488ee4bcd3bSJian Shen } 1489ee4bcd3bSJian Shen 1490ee4bcd3bSJian Shen static void hclgevf_sync_from_del_list(struct list_head *del_list, 1491ee4bcd3bSJian Shen struct list_head *mac_list) 1492ee4bcd3bSJian Shen { 1493ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, *tmp, *new_node; 1494ee4bcd3bSJian Shen 1495ee4bcd3bSJian Shen list_for_each_entry_safe(mac_node, tmp, del_list, node) { 1496ee4bcd3bSJian Shen new_node = hclgevf_find_mac_node(mac_list, mac_node->mac_addr); 1497ee4bcd3bSJian Shen if (new_node) { 1498ee4bcd3bSJian Shen /* If the mac addr is exist in the mac list, it means 1499ee4bcd3bSJian Shen * received a new request TO_ADD during the time window 1500ee4bcd3bSJian Shen * of sending mac addr configurrequest to PF, so just 1501ee4bcd3bSJian Shen * change the mac state to ACTIVE. 1502ee4bcd3bSJian Shen */ 1503ee4bcd3bSJian Shen new_node->state = HCLGEVF_MAC_ACTIVE; 1504ee4bcd3bSJian Shen list_del(&mac_node->node); 1505ee4bcd3bSJian Shen kfree(mac_node); 1506ee4bcd3bSJian Shen } else { 1507ee4bcd3bSJian Shen list_del(&mac_node->node); 1508ee4bcd3bSJian Shen list_add_tail(&mac_node->node, mac_list); 1509ee4bcd3bSJian Shen } 1510ee4bcd3bSJian Shen } 1511ee4bcd3bSJian Shen } 1512ee4bcd3bSJian Shen 1513ee4bcd3bSJian Shen static void hclgevf_clear_list(struct list_head *list) 1514ee4bcd3bSJian Shen { 1515ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, *tmp; 1516ee4bcd3bSJian Shen 1517ee4bcd3bSJian Shen list_for_each_entry_safe(mac_node, tmp, list, node) { 1518ee4bcd3bSJian Shen list_del(&mac_node->node); 1519ee4bcd3bSJian Shen kfree(mac_node); 1520ee4bcd3bSJian Shen } 1521ee4bcd3bSJian Shen } 1522ee4bcd3bSJian Shen 1523ee4bcd3bSJian Shen static void hclgevf_sync_mac_list(struct hclgevf_dev *hdev, 1524ee4bcd3bSJian Shen enum HCLGEVF_MAC_ADDR_TYPE mac_type) 1525ee4bcd3bSJian Shen { 1526ee4bcd3bSJian Shen struct hclgevf_mac_addr_node *mac_node, *tmp, *new_node; 1527ee4bcd3bSJian Shen struct list_head tmp_add_list, tmp_del_list; 1528ee4bcd3bSJian Shen struct list_head *list; 1529ee4bcd3bSJian Shen 1530ee4bcd3bSJian Shen INIT_LIST_HEAD(&tmp_add_list); 1531ee4bcd3bSJian Shen INIT_LIST_HEAD(&tmp_del_list); 1532ee4bcd3bSJian Shen 1533ee4bcd3bSJian Shen /* move the mac addr to the tmp_add_list and tmp_del_list, then 1534ee4bcd3bSJian Shen * we can add/delete these mac addr outside the spin lock 1535ee4bcd3bSJian Shen */ 1536ee4bcd3bSJian Shen list = (mac_type == HCLGEVF_MAC_ADDR_UC) ? 1537ee4bcd3bSJian Shen &hdev->mac_table.uc_mac_list : &hdev->mac_table.mc_mac_list; 1538ee4bcd3bSJian Shen 1539ee4bcd3bSJian Shen spin_lock_bh(&hdev->mac_table.mac_list_lock); 1540ee4bcd3bSJian Shen 1541ee4bcd3bSJian Shen list_for_each_entry_safe(mac_node, tmp, list, node) { 1542ee4bcd3bSJian Shen switch (mac_node->state) { 1543ee4bcd3bSJian Shen case HCLGEVF_MAC_TO_DEL: 1544ee4bcd3bSJian Shen list_del(&mac_node->node); 1545ee4bcd3bSJian Shen list_add_tail(&mac_node->node, &tmp_del_list); 1546ee4bcd3bSJian Shen break; 1547ee4bcd3bSJian Shen case HCLGEVF_MAC_TO_ADD: 1548ee4bcd3bSJian Shen new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); 1549ee4bcd3bSJian Shen if (!new_node) 1550ee4bcd3bSJian Shen goto stop_traverse; 1551ee4bcd3bSJian Shen 1552ee4bcd3bSJian Shen ether_addr_copy(new_node->mac_addr, mac_node->mac_addr); 1553ee4bcd3bSJian Shen new_node->state = mac_node->state; 1554ee4bcd3bSJian Shen list_add_tail(&new_node->node, &tmp_add_list); 1555ee4bcd3bSJian Shen break; 1556ee4bcd3bSJian Shen default: 1557ee4bcd3bSJian Shen break; 1558ee4bcd3bSJian Shen } 1559ee4bcd3bSJian Shen } 1560ee4bcd3bSJian Shen 1561ee4bcd3bSJian Shen stop_traverse: 1562ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1563ee4bcd3bSJian Shen 1564ee4bcd3bSJian Shen /* delete first, in order to get max mac table space for adding */ 1565ee4bcd3bSJian Shen hclgevf_config_mac_list(hdev, &tmp_del_list, mac_type); 1566ee4bcd3bSJian Shen hclgevf_config_mac_list(hdev, &tmp_add_list, mac_type); 1567ee4bcd3bSJian Shen 1568ee4bcd3bSJian Shen /* if some mac addresses were added/deleted fail, move back to the 1569ee4bcd3bSJian Shen * mac_list, and retry at next time. 1570ee4bcd3bSJian Shen */ 1571ee4bcd3bSJian Shen spin_lock_bh(&hdev->mac_table.mac_list_lock); 1572ee4bcd3bSJian Shen 1573ee4bcd3bSJian Shen hclgevf_sync_from_del_list(&tmp_del_list, list); 1574ee4bcd3bSJian Shen hclgevf_sync_from_add_list(&tmp_add_list, list); 1575ee4bcd3bSJian Shen 1576ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1577ee4bcd3bSJian Shen } 1578ee4bcd3bSJian Shen 1579ee4bcd3bSJian Shen static void hclgevf_sync_mac_table(struct hclgevf_dev *hdev) 1580ee4bcd3bSJian Shen { 1581ee4bcd3bSJian Shen hclgevf_sync_mac_list(hdev, HCLGEVF_MAC_ADDR_UC); 1582ee4bcd3bSJian Shen hclgevf_sync_mac_list(hdev, HCLGEVF_MAC_ADDR_MC); 1583ee4bcd3bSJian Shen } 1584ee4bcd3bSJian Shen 1585ee4bcd3bSJian Shen static void hclgevf_uninit_mac_list(struct hclgevf_dev *hdev) 1586ee4bcd3bSJian Shen { 1587ee4bcd3bSJian Shen spin_lock_bh(&hdev->mac_table.mac_list_lock); 1588ee4bcd3bSJian Shen 1589ee4bcd3bSJian Shen hclgevf_clear_list(&hdev->mac_table.uc_mac_list); 1590ee4bcd3bSJian Shen hclgevf_clear_list(&hdev->mac_table.mc_mac_list); 1591ee4bcd3bSJian Shen 1592ee4bcd3bSJian Shen spin_unlock_bh(&hdev->mac_table.mac_list_lock); 1593ee4bcd3bSJian Shen } 1594ee4bcd3bSJian Shen 1595e2cb1decSSalil Mehta static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, 1596e2cb1decSSalil Mehta __be16 proto, u16 vlan_id, 1597e2cb1decSSalil Mehta bool is_kill) 1598e2cb1decSSalil Mehta { 1599d3410018SYufeng Mo #define HCLGEVF_VLAN_MBX_IS_KILL_OFFSET 0 1600d3410018SYufeng Mo #define HCLGEVF_VLAN_MBX_VLAN_ID_OFFSET 1 1601d3410018SYufeng Mo #define HCLGEVF_VLAN_MBX_PROTO_OFFSET 3 1602d3410018SYufeng Mo 1603e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1604d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 1605fe4144d4SJian Shen int ret; 1606e2cb1decSSalil Mehta 1607b37ce587SYufeng Mo if (vlan_id > HCLGEVF_MAX_VLAN_ID) 1608e2cb1decSSalil Mehta return -EINVAL; 1609e2cb1decSSalil Mehta 1610e2cb1decSSalil Mehta if (proto != htons(ETH_P_8021Q)) 1611e2cb1decSSalil Mehta return -EPROTONOSUPPORT; 1612e2cb1decSSalil Mehta 1613b7b5d25bSGuojia Liao /* When device is resetting or reset failed, firmware is unable to 1614b7b5d25bSGuojia Liao * handle mailbox. Just record the vlan id, and remove it after 1615fe4144d4SJian Shen * reset finished. 1616fe4144d4SJian Shen */ 1617b7b5d25bSGuojia Liao if ((test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state) || 1618b7b5d25bSGuojia Liao test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) { 1619fe4144d4SJian Shen set_bit(vlan_id, hdev->vlan_del_fail_bmap); 1620fe4144d4SJian Shen return -EBUSY; 1621fe4144d4SJian Shen } 1622fe4144d4SJian Shen 1623d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, 1624d3410018SYufeng Mo HCLGE_MBX_VLAN_FILTER); 1625d3410018SYufeng Mo send_msg.data[HCLGEVF_VLAN_MBX_IS_KILL_OFFSET] = is_kill; 1626d3410018SYufeng Mo memcpy(&send_msg.data[HCLGEVF_VLAN_MBX_VLAN_ID_OFFSET], &vlan_id, 1627d3410018SYufeng Mo sizeof(vlan_id)); 1628d3410018SYufeng Mo memcpy(&send_msg.data[HCLGEVF_VLAN_MBX_PROTO_OFFSET], &proto, 1629d3410018SYufeng Mo sizeof(proto)); 163046ee7350SGuojia Liao /* when remove hw vlan filter failed, record the vlan id, 1631fe4144d4SJian Shen * and try to remove it from hw later, to be consistence 1632fe4144d4SJian Shen * with stack. 1633fe4144d4SJian Shen */ 1634d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); 1635fe4144d4SJian Shen if (is_kill && ret) 1636fe4144d4SJian Shen set_bit(vlan_id, hdev->vlan_del_fail_bmap); 1637fe4144d4SJian Shen 1638fe4144d4SJian Shen return ret; 1639fe4144d4SJian Shen } 1640fe4144d4SJian Shen 1641fe4144d4SJian Shen static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) 1642fe4144d4SJian Shen { 1643fe4144d4SJian Shen #define HCLGEVF_MAX_SYNC_COUNT 60 1644fe4144d4SJian Shen struct hnae3_handle *handle = &hdev->nic; 1645fe4144d4SJian Shen int ret, sync_cnt = 0; 1646fe4144d4SJian Shen u16 vlan_id; 1647fe4144d4SJian Shen 1648fe4144d4SJian Shen vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); 1649fe4144d4SJian Shen while (vlan_id != VLAN_N_VID) { 1650fe4144d4SJian Shen ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q), 1651fe4144d4SJian Shen vlan_id, true); 1652fe4144d4SJian Shen if (ret) 1653fe4144d4SJian Shen return; 1654fe4144d4SJian Shen 1655fe4144d4SJian Shen clear_bit(vlan_id, hdev->vlan_del_fail_bmap); 1656fe4144d4SJian Shen sync_cnt++; 1657fe4144d4SJian Shen if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT) 1658fe4144d4SJian Shen return; 1659fe4144d4SJian Shen 1660fe4144d4SJian Shen vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); 1661fe4144d4SJian Shen } 1662e2cb1decSSalil Mehta } 1663e2cb1decSSalil Mehta 1664b2641e2aSYunsheng Lin static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) 1665b2641e2aSYunsheng Lin { 1666b2641e2aSYunsheng Lin struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1667d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 1668b2641e2aSYunsheng Lin 1669d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, 1670d3410018SYufeng Mo HCLGE_MBX_VLAN_RX_OFF_CFG); 1671d3410018SYufeng Mo send_msg.data[0] = enable ? 1 : 0; 1672d3410018SYufeng Mo return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 1673b2641e2aSYunsheng Lin } 1674b2641e2aSYunsheng Lin 16757fa6be4fSHuazhong Tan static int hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 1676e2cb1decSSalil Mehta { 1677e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1678d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 16791a426f8bSPeng Li int ret; 1680e2cb1decSSalil Mehta 16811a426f8bSPeng Li /* disable vf queue before send queue reset msg to PF */ 16821a426f8bSPeng Li ret = hclgevf_tqp_enable(hdev, queue_id, 0, false); 16831a426f8bSPeng Li if (ret) 16847fa6be4fSHuazhong Tan return ret; 16851a426f8bSPeng Li 1686d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_QUEUE_RESET, 0); 1687d3410018SYufeng Mo memcpy(send_msg.data, &queue_id, sizeof(queue_id)); 1688d3410018SYufeng Mo return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); 1689e2cb1decSSalil Mehta } 1690e2cb1decSSalil Mehta 1691818f1675SYunsheng Lin static int hclgevf_set_mtu(struct hnae3_handle *handle, int new_mtu) 1692818f1675SYunsheng Lin { 1693818f1675SYunsheng Lin struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1694d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 1695818f1675SYunsheng Lin 1696d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_MTU, 0); 1697d3410018SYufeng Mo memcpy(send_msg.data, &new_mtu, sizeof(new_mtu)); 1698d3410018SYufeng Mo return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); 1699818f1675SYunsheng Lin } 1700818f1675SYunsheng Lin 17016988eb2aSSalil Mehta static int hclgevf_notify_client(struct hclgevf_dev *hdev, 17026988eb2aSSalil Mehta enum hnae3_reset_notify_type type) 17036988eb2aSSalil Mehta { 17046988eb2aSSalil Mehta struct hnae3_client *client = hdev->nic_client; 17056988eb2aSSalil Mehta struct hnae3_handle *handle = &hdev->nic; 17066a5f6fa3SHuazhong Tan int ret; 17076988eb2aSSalil Mehta 170825d1817cSHuazhong Tan if (!test_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state) || 170925d1817cSHuazhong Tan !client) 171025d1817cSHuazhong Tan return 0; 171125d1817cSHuazhong Tan 17126988eb2aSSalil Mehta if (!client->ops->reset_notify) 17136988eb2aSSalil Mehta return -EOPNOTSUPP; 17146988eb2aSSalil Mehta 17156a5f6fa3SHuazhong Tan ret = client->ops->reset_notify(handle, type); 17166a5f6fa3SHuazhong Tan if (ret) 17176a5f6fa3SHuazhong Tan dev_err(&hdev->pdev->dev, "notify nic client failed %d(%d)\n", 17186a5f6fa3SHuazhong Tan type, ret); 17196a5f6fa3SHuazhong Tan 17206a5f6fa3SHuazhong Tan return ret; 17216988eb2aSSalil Mehta } 17226988eb2aSSalil Mehta 1723fe735c84SHuazhong Tan static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev, 1724fe735c84SHuazhong Tan enum hnae3_reset_notify_type type) 1725fe735c84SHuazhong Tan { 1726fe735c84SHuazhong Tan struct hnae3_client *client = hdev->roce_client; 1727fe735c84SHuazhong Tan struct hnae3_handle *handle = &hdev->roce; 1728fe735c84SHuazhong Tan int ret; 1729fe735c84SHuazhong Tan 1730fe735c84SHuazhong Tan if (!test_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state) || !client) 1731fe735c84SHuazhong Tan return 0; 1732fe735c84SHuazhong Tan 1733fe735c84SHuazhong Tan if (!client->ops->reset_notify) 1734fe735c84SHuazhong Tan return -EOPNOTSUPP; 1735fe735c84SHuazhong Tan 1736fe735c84SHuazhong Tan ret = client->ops->reset_notify(handle, type); 1737fe735c84SHuazhong Tan if (ret) 1738fe735c84SHuazhong Tan dev_err(&hdev->pdev->dev, "notify roce client failed %d(%d)", 1739fe735c84SHuazhong Tan type, ret); 1740fe735c84SHuazhong Tan return ret; 1741fe735c84SHuazhong Tan } 1742fe735c84SHuazhong Tan 17436988eb2aSSalil Mehta static int hclgevf_reset_wait(struct hclgevf_dev *hdev) 17446988eb2aSSalil Mehta { 1745aa5c4f17SHuazhong Tan #define HCLGEVF_RESET_WAIT_US 20000 1746aa5c4f17SHuazhong Tan #define HCLGEVF_RESET_WAIT_CNT 2000 1747aa5c4f17SHuazhong Tan #define HCLGEVF_RESET_WAIT_TIMEOUT_US \ 1748aa5c4f17SHuazhong Tan (HCLGEVF_RESET_WAIT_US * HCLGEVF_RESET_WAIT_CNT) 1749aa5c4f17SHuazhong Tan 1750aa5c4f17SHuazhong Tan u32 val; 1751aa5c4f17SHuazhong Tan int ret; 17526988eb2aSSalil Mehta 1753f28368bbSHuazhong Tan if (hdev->reset_type == HNAE3_VF_RESET) 175472e2fb07SHuazhong Tan ret = readl_poll_timeout(hdev->hw.io_base + 175572e2fb07SHuazhong Tan HCLGEVF_VF_RST_ING, val, 175672e2fb07SHuazhong Tan !(val & HCLGEVF_VF_RST_ING_BIT), 175772e2fb07SHuazhong Tan HCLGEVF_RESET_WAIT_US, 175872e2fb07SHuazhong Tan HCLGEVF_RESET_WAIT_TIMEOUT_US); 175972e2fb07SHuazhong Tan else 176072e2fb07SHuazhong Tan ret = readl_poll_timeout(hdev->hw.io_base + 176172e2fb07SHuazhong Tan HCLGEVF_RST_ING, val, 1762aa5c4f17SHuazhong Tan !(val & HCLGEVF_RST_ING_BITS), 1763aa5c4f17SHuazhong Tan HCLGEVF_RESET_WAIT_US, 1764aa5c4f17SHuazhong Tan HCLGEVF_RESET_WAIT_TIMEOUT_US); 17656988eb2aSSalil Mehta 17666988eb2aSSalil Mehta /* hardware completion status should be available by this time */ 1767aa5c4f17SHuazhong Tan if (ret) { 1768aa5c4f17SHuazhong Tan dev_err(&hdev->pdev->dev, 17698912fd6aSColin Ian King "couldn't get reset done status from h/w, timeout!\n"); 1770aa5c4f17SHuazhong Tan return ret; 17716988eb2aSSalil Mehta } 17726988eb2aSSalil Mehta 17736988eb2aSSalil Mehta /* we will wait a bit more to let reset of the stack to complete. This 17746988eb2aSSalil Mehta * might happen in case reset assertion was made by PF. Yes, this also 17756988eb2aSSalil Mehta * means we might end up waiting bit more even for VF reset. 17766988eb2aSSalil Mehta */ 17776988eb2aSSalil Mehta msleep(5000); 17786988eb2aSSalil Mehta 17796988eb2aSSalil Mehta return 0; 17806988eb2aSSalil Mehta } 17816988eb2aSSalil Mehta 17826b428b4fSHuazhong Tan static void hclgevf_reset_handshake(struct hclgevf_dev *hdev, bool enable) 17836b428b4fSHuazhong Tan { 17846b428b4fSHuazhong Tan u32 reg_val; 17856b428b4fSHuazhong Tan 17866b428b4fSHuazhong Tan reg_val = hclgevf_read_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG); 17876b428b4fSHuazhong Tan if (enable) 17886b428b4fSHuazhong Tan reg_val |= HCLGEVF_NIC_SW_RST_RDY; 17896b428b4fSHuazhong Tan else 17906b428b4fSHuazhong Tan reg_val &= ~HCLGEVF_NIC_SW_RST_RDY; 17916b428b4fSHuazhong Tan 17926b428b4fSHuazhong Tan hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG, 17936b428b4fSHuazhong Tan reg_val); 17946b428b4fSHuazhong Tan } 17956b428b4fSHuazhong Tan 17966988eb2aSSalil Mehta static int hclgevf_reset_stack(struct hclgevf_dev *hdev) 17976988eb2aSSalil Mehta { 17987a01c897SSalil Mehta int ret; 17997a01c897SSalil Mehta 18006988eb2aSSalil Mehta /* uninitialize the nic client */ 18016a5f6fa3SHuazhong Tan ret = hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT); 18026a5f6fa3SHuazhong Tan if (ret) 18036a5f6fa3SHuazhong Tan return ret; 18046988eb2aSSalil Mehta 18057a01c897SSalil Mehta /* re-initialize the hclge device */ 18069c6f7085SHuazhong Tan ret = hclgevf_reset_hdev(hdev); 18077a01c897SSalil Mehta if (ret) { 18087a01c897SSalil Mehta dev_err(&hdev->pdev->dev, 18097a01c897SSalil Mehta "hclge device re-init failed, VF is disabled!\n"); 18107a01c897SSalil Mehta return ret; 18117a01c897SSalil Mehta } 18126988eb2aSSalil Mehta 18136988eb2aSSalil Mehta /* bring up the nic client again */ 18146a5f6fa3SHuazhong Tan ret = hclgevf_notify_client(hdev, HNAE3_INIT_CLIENT); 18156a5f6fa3SHuazhong Tan if (ret) 18166a5f6fa3SHuazhong Tan return ret; 18176988eb2aSSalil Mehta 18186b428b4fSHuazhong Tan /* clear handshake status with IMP */ 18196b428b4fSHuazhong Tan hclgevf_reset_handshake(hdev, false); 18206b428b4fSHuazhong Tan 18211cc9bc6eSHuazhong Tan /* bring up the nic to enable TX/RX again */ 18221cc9bc6eSHuazhong Tan return hclgevf_notify_client(hdev, HNAE3_UP_CLIENT); 18236988eb2aSSalil Mehta } 18246988eb2aSSalil Mehta 1825dea846e8SHuazhong Tan static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) 1826dea846e8SHuazhong Tan { 1827ada13ee3SHuazhong Tan #define HCLGEVF_RESET_SYNC_TIME 100 1828ada13ee3SHuazhong Tan 1829f28368bbSHuazhong Tan if (hdev->reset_type == HNAE3_VF_FUNC_RESET) { 1830d41884eeSHuazhong Tan struct hclge_vf_to_pf_msg send_msg; 1831d41884eeSHuazhong Tan int ret; 1832d41884eeSHuazhong Tan 1833d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_RESET, 0); 1834d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0); 1835cddd5648SHuazhong Tan if (ret) { 1836cddd5648SHuazhong Tan dev_err(&hdev->pdev->dev, 1837cddd5648SHuazhong Tan "failed to assert VF reset, ret = %d\n", ret); 1838cddd5648SHuazhong Tan return ret; 1839cddd5648SHuazhong Tan } 1840c88a6e7dSHuazhong Tan hdev->rst_stats.vf_func_rst_cnt++; 1841dea846e8SHuazhong Tan } 1842dea846e8SHuazhong Tan 1843ef5f8e50SHuazhong Tan set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); 1844ada13ee3SHuazhong Tan /* inform hardware that preparatory work is done */ 1845ada13ee3SHuazhong Tan msleep(HCLGEVF_RESET_SYNC_TIME); 18466b428b4fSHuazhong Tan hclgevf_reset_handshake(hdev, true); 1847d41884eeSHuazhong Tan dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done\n", 1848d41884eeSHuazhong Tan hdev->reset_type); 1849dea846e8SHuazhong Tan 1850d41884eeSHuazhong Tan return 0; 1851dea846e8SHuazhong Tan } 1852dea846e8SHuazhong Tan 18533d77d0cbSHuazhong Tan static void hclgevf_dump_rst_info(struct hclgevf_dev *hdev) 18543d77d0cbSHuazhong Tan { 18553d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "VF function reset count: %u\n", 18563d77d0cbSHuazhong Tan hdev->rst_stats.vf_func_rst_cnt); 18573d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "FLR reset count: %u\n", 18583d77d0cbSHuazhong Tan hdev->rst_stats.flr_rst_cnt); 18593d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "VF reset count: %u\n", 18603d77d0cbSHuazhong Tan hdev->rst_stats.vf_rst_cnt); 18613d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "reset done count: %u\n", 18623d77d0cbSHuazhong Tan hdev->rst_stats.rst_done_cnt); 18633d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "HW reset done count: %u\n", 18643d77d0cbSHuazhong Tan hdev->rst_stats.hw_rst_done_cnt); 18653d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "reset count: %u\n", 18663d77d0cbSHuazhong Tan hdev->rst_stats.rst_cnt); 18673d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "reset fail count: %u\n", 18683d77d0cbSHuazhong Tan hdev->rst_stats.rst_fail_cnt); 18693d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "vector0 interrupt enable status: 0x%x\n", 18703d77d0cbSHuazhong Tan hclgevf_read_dev(&hdev->hw, HCLGEVF_MISC_VECTOR_REG_BASE)); 18713d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "vector0 interrupt status: 0x%x\n", 18729cee2e8dSHuazhong Tan hclgevf_read_dev(&hdev->hw, HCLGEVF_VECTOR0_CMDQ_STATE_REG)); 18733d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "handshake status: 0x%x\n", 18743d77d0cbSHuazhong Tan hclgevf_read_dev(&hdev->hw, HCLGEVF_CMDQ_TX_DEPTH_REG)); 18753d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "function reset status: 0x%x\n", 18763d77d0cbSHuazhong Tan hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING)); 18773d77d0cbSHuazhong Tan dev_info(&hdev->pdev->dev, "hdev state: 0x%lx\n", hdev->state); 18783d77d0cbSHuazhong Tan } 18793d77d0cbSHuazhong Tan 1880bbe6540eSHuazhong Tan static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) 1881bbe6540eSHuazhong Tan { 18826b428b4fSHuazhong Tan /* recover handshake status with IMP when reset fail */ 18836b428b4fSHuazhong Tan hclgevf_reset_handshake(hdev, true); 1884bbe6540eSHuazhong Tan hdev->rst_stats.rst_fail_cnt++; 1885adcf738bSGuojia Liao dev_err(&hdev->pdev->dev, "failed to reset VF(%u)\n", 1886bbe6540eSHuazhong Tan hdev->rst_stats.rst_fail_cnt); 1887bbe6540eSHuazhong Tan 1888bbe6540eSHuazhong Tan if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT) 1889bbe6540eSHuazhong Tan set_bit(hdev->reset_type, &hdev->reset_pending); 1890bbe6540eSHuazhong Tan 1891bbe6540eSHuazhong Tan if (hclgevf_is_reset_pending(hdev)) { 1892bbe6540eSHuazhong Tan set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); 1893bbe6540eSHuazhong Tan hclgevf_reset_task_schedule(hdev); 18943d77d0cbSHuazhong Tan } else { 1895d5432455SGuojia Liao set_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); 18963d77d0cbSHuazhong Tan hclgevf_dump_rst_info(hdev); 1897bbe6540eSHuazhong Tan } 1898bbe6540eSHuazhong Tan } 1899bbe6540eSHuazhong Tan 19001cc9bc6eSHuazhong Tan static int hclgevf_reset_prepare(struct hclgevf_dev *hdev) 19016988eb2aSSalil Mehta { 19026988eb2aSSalil Mehta int ret; 19036988eb2aSSalil Mehta 1904c88a6e7dSHuazhong Tan hdev->rst_stats.rst_cnt++; 19056988eb2aSSalil Mehta 1906fe735c84SHuazhong Tan /* perform reset of the stack & ae device for a client */ 1907fe735c84SHuazhong Tan ret = hclgevf_notify_roce_client(hdev, HNAE3_DOWN_CLIENT); 1908fe735c84SHuazhong Tan if (ret) 1909fe735c84SHuazhong Tan return ret; 1910fe735c84SHuazhong Tan 19111cc9bc6eSHuazhong Tan rtnl_lock(); 19126988eb2aSSalil Mehta /* bring down the nic to stop any ongoing TX/RX */ 19136a5f6fa3SHuazhong Tan ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); 191429118ab9SHuazhong Tan rtnl_unlock(); 19156a5f6fa3SHuazhong Tan if (ret) 19161cc9bc6eSHuazhong Tan return ret; 1917dea846e8SHuazhong Tan 19181cc9bc6eSHuazhong Tan return hclgevf_reset_prepare_wait(hdev); 19196988eb2aSSalil Mehta } 19206988eb2aSSalil Mehta 19211cc9bc6eSHuazhong Tan static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev) 19221cc9bc6eSHuazhong Tan { 19231cc9bc6eSHuazhong Tan int ret; 19241cc9bc6eSHuazhong Tan 1925c88a6e7dSHuazhong Tan hdev->rst_stats.hw_rst_done_cnt++; 1926fe735c84SHuazhong Tan ret = hclgevf_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT); 1927fe735c84SHuazhong Tan if (ret) 1928fe735c84SHuazhong Tan return ret; 1929c88a6e7dSHuazhong Tan 193029118ab9SHuazhong Tan rtnl_lock(); 19316988eb2aSSalil Mehta /* now, re-initialize the nic client and ae device */ 19326988eb2aSSalil Mehta ret = hclgevf_reset_stack(hdev); 19331cc9bc6eSHuazhong Tan rtnl_unlock(); 19346a5f6fa3SHuazhong Tan if (ret) { 19356988eb2aSSalil Mehta dev_err(&hdev->pdev->dev, "failed to reset VF stack\n"); 19361cc9bc6eSHuazhong Tan return ret; 19376a5f6fa3SHuazhong Tan } 19386988eb2aSSalil Mehta 1939fe735c84SHuazhong Tan ret = hclgevf_notify_roce_client(hdev, HNAE3_INIT_CLIENT); 1940fe735c84SHuazhong Tan /* ignore RoCE notify error if it fails HCLGEVF_RESET_MAX_FAIL_CNT - 1 1941fe735c84SHuazhong Tan * times 1942fe735c84SHuazhong Tan */ 1943fe735c84SHuazhong Tan if (ret && 1944fe735c84SHuazhong Tan hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT - 1) 1945fe735c84SHuazhong Tan return ret; 1946fe735c84SHuazhong Tan 1947fe735c84SHuazhong Tan ret = hclgevf_notify_roce_client(hdev, HNAE3_UP_CLIENT); 1948fe735c84SHuazhong Tan if (ret) 1949fe735c84SHuazhong Tan return ret; 1950fe735c84SHuazhong Tan 1951b644a8d4SHuazhong Tan hdev->last_reset_time = jiffies; 1952c88a6e7dSHuazhong Tan hdev->rst_stats.rst_done_cnt++; 1953bbe6540eSHuazhong Tan hdev->rst_stats.rst_fail_cnt = 0; 1954d5432455SGuojia Liao clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); 1955b644a8d4SHuazhong Tan 19561cc9bc6eSHuazhong Tan return 0; 19571cc9bc6eSHuazhong Tan } 19581cc9bc6eSHuazhong Tan 19591cc9bc6eSHuazhong Tan static void hclgevf_reset(struct hclgevf_dev *hdev) 19601cc9bc6eSHuazhong Tan { 19611cc9bc6eSHuazhong Tan if (hclgevf_reset_prepare(hdev)) 19621cc9bc6eSHuazhong Tan goto err_reset; 19631cc9bc6eSHuazhong Tan 19641cc9bc6eSHuazhong Tan /* check if VF could successfully fetch the hardware reset completion 19651cc9bc6eSHuazhong Tan * status from the hardware 19661cc9bc6eSHuazhong Tan */ 19671cc9bc6eSHuazhong Tan if (hclgevf_reset_wait(hdev)) { 19681cc9bc6eSHuazhong Tan /* can't do much in this situation, will disable VF */ 19691cc9bc6eSHuazhong Tan dev_err(&hdev->pdev->dev, 19701cc9bc6eSHuazhong Tan "failed to fetch H/W reset completion status\n"); 19711cc9bc6eSHuazhong Tan goto err_reset; 19721cc9bc6eSHuazhong Tan } 19731cc9bc6eSHuazhong Tan 19741cc9bc6eSHuazhong Tan if (hclgevf_reset_rebuild(hdev)) 19751cc9bc6eSHuazhong Tan goto err_reset; 19761cc9bc6eSHuazhong Tan 19771cc9bc6eSHuazhong Tan return; 19781cc9bc6eSHuazhong Tan 19796a5f6fa3SHuazhong Tan err_reset: 1980bbe6540eSHuazhong Tan hclgevf_reset_err_handle(hdev); 19816988eb2aSSalil Mehta } 19826988eb2aSSalil Mehta 1983720bd583SHuazhong Tan static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev, 1984720bd583SHuazhong Tan unsigned long *addr) 1985720bd583SHuazhong Tan { 1986720bd583SHuazhong Tan enum hnae3_reset_type rst_level = HNAE3_NONE_RESET; 1987720bd583SHuazhong Tan 1988dea846e8SHuazhong Tan /* return the highest priority reset level amongst all */ 1989b90fcc5bSHuazhong Tan if (test_bit(HNAE3_VF_RESET, addr)) { 1990b90fcc5bSHuazhong Tan rst_level = HNAE3_VF_RESET; 1991b90fcc5bSHuazhong Tan clear_bit(HNAE3_VF_RESET, addr); 1992b90fcc5bSHuazhong Tan clear_bit(HNAE3_VF_PF_FUNC_RESET, addr); 1993b90fcc5bSHuazhong Tan clear_bit(HNAE3_VF_FUNC_RESET, addr); 1994b90fcc5bSHuazhong Tan } else if (test_bit(HNAE3_VF_FULL_RESET, addr)) { 1995dea846e8SHuazhong Tan rst_level = HNAE3_VF_FULL_RESET; 1996dea846e8SHuazhong Tan clear_bit(HNAE3_VF_FULL_RESET, addr); 1997dea846e8SHuazhong Tan clear_bit(HNAE3_VF_FUNC_RESET, addr); 1998aa5c4f17SHuazhong Tan } else if (test_bit(HNAE3_VF_PF_FUNC_RESET, addr)) { 1999aa5c4f17SHuazhong Tan rst_level = HNAE3_VF_PF_FUNC_RESET; 2000aa5c4f17SHuazhong Tan clear_bit(HNAE3_VF_PF_FUNC_RESET, addr); 2001aa5c4f17SHuazhong Tan clear_bit(HNAE3_VF_FUNC_RESET, addr); 2002dea846e8SHuazhong Tan } else if (test_bit(HNAE3_VF_FUNC_RESET, addr)) { 2003dea846e8SHuazhong Tan rst_level = HNAE3_VF_FUNC_RESET; 2004dea846e8SHuazhong Tan clear_bit(HNAE3_VF_FUNC_RESET, addr); 20056ff3cf07SHuazhong Tan } else if (test_bit(HNAE3_FLR_RESET, addr)) { 20066ff3cf07SHuazhong Tan rst_level = HNAE3_FLR_RESET; 20076ff3cf07SHuazhong Tan clear_bit(HNAE3_FLR_RESET, addr); 2008720bd583SHuazhong Tan } 2009720bd583SHuazhong Tan 2010720bd583SHuazhong Tan return rst_level; 2011720bd583SHuazhong Tan } 2012720bd583SHuazhong Tan 20136ae4e733SShiju Jose static void hclgevf_reset_event(struct pci_dev *pdev, 20146ae4e733SShiju Jose struct hnae3_handle *handle) 20156d4c3981SSalil Mehta { 20166ff3cf07SHuazhong Tan struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); 20176ff3cf07SHuazhong Tan struct hclgevf_dev *hdev = ae_dev->priv; 20186d4c3981SSalil Mehta 20196d4c3981SSalil Mehta dev_info(&hdev->pdev->dev, "received reset request from VF enet\n"); 20206d4c3981SSalil Mehta 20216ff3cf07SHuazhong Tan if (hdev->default_reset_request) 20220742ed7cSHuazhong Tan hdev->reset_level = 2023720bd583SHuazhong Tan hclgevf_get_reset_level(hdev, 2024720bd583SHuazhong Tan &hdev->default_reset_request); 2025720bd583SHuazhong Tan else 2026dea846e8SHuazhong Tan hdev->reset_level = HNAE3_VF_FUNC_RESET; 20276d4c3981SSalil Mehta 2028436667d2SSalil Mehta /* reset of this VF requested */ 2029436667d2SSalil Mehta set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); 2030436667d2SSalil Mehta hclgevf_reset_task_schedule(hdev); 20316d4c3981SSalil Mehta 20320742ed7cSHuazhong Tan hdev->last_reset_time = jiffies; 20336d4c3981SSalil Mehta } 20346d4c3981SSalil Mehta 2035720bd583SHuazhong Tan static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, 2036720bd583SHuazhong Tan enum hnae3_reset_type rst_type) 2037720bd583SHuazhong Tan { 2038720bd583SHuazhong Tan struct hclgevf_dev *hdev = ae_dev->priv; 2039720bd583SHuazhong Tan 2040720bd583SHuazhong Tan set_bit(rst_type, &hdev->default_reset_request); 2041720bd583SHuazhong Tan } 2042720bd583SHuazhong Tan 2043f28368bbSHuazhong Tan static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en) 2044f28368bbSHuazhong Tan { 2045f28368bbSHuazhong Tan writel(en ? 1 : 0, vector->addr); 2046f28368bbSHuazhong Tan } 2047f28368bbSHuazhong Tan 20486ff3cf07SHuazhong Tan static void hclgevf_flr_prepare(struct hnae3_ae_dev *ae_dev) 20496ff3cf07SHuazhong Tan { 2050f28368bbSHuazhong Tan #define HCLGEVF_FLR_RETRY_WAIT_MS 500 2051f28368bbSHuazhong Tan #define HCLGEVF_FLR_RETRY_CNT 5 2052f28368bbSHuazhong Tan 20536ff3cf07SHuazhong Tan struct hclgevf_dev *hdev = ae_dev->priv; 2054f28368bbSHuazhong Tan int retry_cnt = 0; 2055f28368bbSHuazhong Tan int ret; 20566ff3cf07SHuazhong Tan 2057f28368bbSHuazhong Tan retry: 2058f28368bbSHuazhong Tan down(&hdev->reset_sem); 2059f28368bbSHuazhong Tan set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 2060f28368bbSHuazhong Tan hdev->reset_type = HNAE3_FLR_RESET; 2061f28368bbSHuazhong Tan ret = hclgevf_reset_prepare(hdev); 2062f28368bbSHuazhong Tan if (ret) { 2063f28368bbSHuazhong Tan dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n", 2064f28368bbSHuazhong Tan ret); 2065f28368bbSHuazhong Tan if (hdev->reset_pending || 2066f28368bbSHuazhong Tan retry_cnt++ < HCLGEVF_FLR_RETRY_CNT) { 20676ff3cf07SHuazhong Tan dev_err(&hdev->pdev->dev, 2068f28368bbSHuazhong Tan "reset_pending:0x%lx, retry_cnt:%d\n", 2069f28368bbSHuazhong Tan hdev->reset_pending, retry_cnt); 2070f28368bbSHuazhong Tan clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 2071f28368bbSHuazhong Tan up(&hdev->reset_sem); 2072f28368bbSHuazhong Tan msleep(HCLGEVF_FLR_RETRY_WAIT_MS); 2073f28368bbSHuazhong Tan goto retry; 2074f28368bbSHuazhong Tan } 2075f28368bbSHuazhong Tan } 2076f28368bbSHuazhong Tan 2077f28368bbSHuazhong Tan /* disable misc vector before FLR done */ 2078f28368bbSHuazhong Tan hclgevf_enable_vector(&hdev->misc_vector, false); 2079f28368bbSHuazhong Tan hdev->rst_stats.flr_rst_cnt++; 2080f28368bbSHuazhong Tan } 2081f28368bbSHuazhong Tan 2082f28368bbSHuazhong Tan static void hclgevf_flr_done(struct hnae3_ae_dev *ae_dev) 2083f28368bbSHuazhong Tan { 2084f28368bbSHuazhong Tan struct hclgevf_dev *hdev = ae_dev->priv; 2085f28368bbSHuazhong Tan int ret; 2086f28368bbSHuazhong Tan 2087f28368bbSHuazhong Tan hclgevf_enable_vector(&hdev->misc_vector, true); 2088f28368bbSHuazhong Tan 2089f28368bbSHuazhong Tan ret = hclgevf_reset_rebuild(hdev); 2090f28368bbSHuazhong Tan if (ret) 2091f28368bbSHuazhong Tan dev_warn(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", 2092f28368bbSHuazhong Tan ret); 2093f28368bbSHuazhong Tan 2094f28368bbSHuazhong Tan hdev->reset_type = HNAE3_NONE_RESET; 2095f28368bbSHuazhong Tan clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 2096f28368bbSHuazhong Tan up(&hdev->reset_sem); 20976ff3cf07SHuazhong Tan } 20986ff3cf07SHuazhong Tan 2099e2cb1decSSalil Mehta static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) 2100e2cb1decSSalil Mehta { 2101e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 2102e2cb1decSSalil Mehta 2103e2cb1decSSalil Mehta return hdev->fw_version; 2104e2cb1decSSalil Mehta } 2105e2cb1decSSalil Mehta 2106e2cb1decSSalil Mehta static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev) 2107e2cb1decSSalil Mehta { 2108e2cb1decSSalil Mehta struct hclgevf_misc_vector *vector = &hdev->misc_vector; 2109e2cb1decSSalil Mehta 2110e2cb1decSSalil Mehta vector->vector_irq = pci_irq_vector(hdev->pdev, 2111e2cb1decSSalil Mehta HCLGEVF_MISC_VECTOR_NUM); 2112e2cb1decSSalil Mehta vector->addr = hdev->hw.io_base + HCLGEVF_MISC_VECTOR_REG_BASE; 2113e2cb1decSSalil Mehta /* vector status always valid for Vector 0 */ 2114e2cb1decSSalil Mehta hdev->vector_status[HCLGEVF_MISC_VECTOR_NUM] = 0; 2115e2cb1decSSalil Mehta hdev->vector_irq[HCLGEVF_MISC_VECTOR_NUM] = vector->vector_irq; 2116e2cb1decSSalil Mehta 2117e2cb1decSSalil Mehta hdev->num_msi_left -= 1; 2118e2cb1decSSalil Mehta hdev->num_msi_used += 1; 2119e2cb1decSSalil Mehta } 2120e2cb1decSSalil Mehta 212135a1e503SSalil Mehta void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev) 212235a1e503SSalil Mehta { 2123ff200099SYunsheng Lin if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) && 2124ff200099SYunsheng Lin !test_and_set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, 2125ff200099SYunsheng Lin &hdev->state)) 21260ea68902SYunsheng Lin mod_delayed_work(hclgevf_wq, &hdev->service_task, 0); 212735a1e503SSalil Mehta } 212835a1e503SSalil Mehta 212907a0556aSSalil Mehta void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) 2130e2cb1decSSalil Mehta { 2131ff200099SYunsheng Lin if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) && 2132ff200099SYunsheng Lin !test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, 2133ff200099SYunsheng Lin &hdev->state)) 21340ea68902SYunsheng Lin mod_delayed_work(hclgevf_wq, &hdev->service_task, 0); 213507a0556aSSalil Mehta } 2136e2cb1decSSalil Mehta 2137ff200099SYunsheng Lin static void hclgevf_task_schedule(struct hclgevf_dev *hdev, 2138ff200099SYunsheng Lin unsigned long delay) 2139e2cb1decSSalil Mehta { 2140d5432455SGuojia Liao if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) && 2141d5432455SGuojia Liao !test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) 21420ea68902SYunsheng Lin mod_delayed_work(hclgevf_wq, &hdev->service_task, delay); 2143e2cb1decSSalil Mehta } 2144e2cb1decSSalil Mehta 2145ff200099SYunsheng Lin static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) 214635a1e503SSalil Mehta { 2147d6ad7c53SGuojia Liao #define HCLGEVF_MAX_RESET_ATTEMPTS_CNT 3 2148d6ad7c53SGuojia Liao 2149ff200099SYunsheng Lin if (!test_and_clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state)) 2150ff200099SYunsheng Lin return; 2151ff200099SYunsheng Lin 2152f28368bbSHuazhong Tan down(&hdev->reset_sem); 2153f28368bbSHuazhong Tan set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 215435a1e503SSalil Mehta 2155436667d2SSalil Mehta if (test_and_clear_bit(HCLGEVF_RESET_PENDING, 2156436667d2SSalil Mehta &hdev->reset_state)) { 2157436667d2SSalil Mehta /* PF has initmated that it is about to reset the hardware. 21589b2f3477SWeihang Li * We now have to poll & check if hardware has actually 21599b2f3477SWeihang Li * completed the reset sequence. On hardware reset completion, 21609b2f3477SWeihang Li * VF needs to reset the client and ae device. 216135a1e503SSalil Mehta */ 2162436667d2SSalil Mehta hdev->reset_attempts = 0; 2163436667d2SSalil Mehta 2164dea846e8SHuazhong Tan hdev->last_reset_time = jiffies; 2165dea846e8SHuazhong Tan while ((hdev->reset_type = 2166dea846e8SHuazhong Tan hclgevf_get_reset_level(hdev, &hdev->reset_pending)) 21671cc9bc6eSHuazhong Tan != HNAE3_NONE_RESET) 21681cc9bc6eSHuazhong Tan hclgevf_reset(hdev); 2169436667d2SSalil Mehta } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED, 2170436667d2SSalil Mehta &hdev->reset_state)) { 2171436667d2SSalil Mehta /* we could be here when either of below happens: 21729b2f3477SWeihang Li * 1. reset was initiated due to watchdog timeout caused by 2173436667d2SSalil Mehta * a. IMP was earlier reset and our TX got choked down and 2174436667d2SSalil Mehta * which resulted in watchdog reacting and inducing VF 2175436667d2SSalil Mehta * reset. This also means our cmdq would be unreliable. 2176436667d2SSalil Mehta * b. problem in TX due to other lower layer(example link 2177436667d2SSalil Mehta * layer not functioning properly etc.) 2178436667d2SSalil Mehta * 2. VF reset might have been initiated due to some config 2179436667d2SSalil Mehta * change. 2180436667d2SSalil Mehta * 2181436667d2SSalil Mehta * NOTE: Theres no clear way to detect above cases than to react 2182436667d2SSalil Mehta * to the response of PF for this reset request. PF will ack the 2183436667d2SSalil Mehta * 1b and 2. cases but we will not get any intimation about 1a 2184436667d2SSalil Mehta * from PF as cmdq would be in unreliable state i.e. mailbox 2185436667d2SSalil Mehta * communication between PF and VF would be broken. 218646ee7350SGuojia Liao * 218746ee7350SGuojia Liao * if we are never geting into pending state it means either: 2188436667d2SSalil Mehta * 1. PF is not receiving our request which could be due to IMP 2189436667d2SSalil Mehta * reset 2190436667d2SSalil Mehta * 2. PF is screwed 2191436667d2SSalil Mehta * We cannot do much for 2. but to check first we can try reset 2192436667d2SSalil Mehta * our PCIe + stack and see if it alleviates the problem. 2193436667d2SSalil Mehta */ 2194d6ad7c53SGuojia Liao if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { 2195436667d2SSalil Mehta /* prepare for full reset of stack + pcie interface */ 2196dea846e8SHuazhong Tan set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending); 2197436667d2SSalil Mehta 2198436667d2SSalil Mehta /* "defer" schedule the reset task again */ 2199436667d2SSalil Mehta set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); 2200436667d2SSalil Mehta } else { 2201436667d2SSalil Mehta hdev->reset_attempts++; 2202436667d2SSalil Mehta 2203dea846e8SHuazhong Tan set_bit(hdev->reset_level, &hdev->reset_pending); 2204dea846e8SHuazhong Tan set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); 2205436667d2SSalil Mehta } 2206dea846e8SHuazhong Tan hclgevf_reset_task_schedule(hdev); 2207436667d2SSalil Mehta } 220835a1e503SSalil Mehta 2209afb6afdbSHuazhong Tan hdev->reset_type = HNAE3_NONE_RESET; 221035a1e503SSalil Mehta clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 2211f28368bbSHuazhong Tan up(&hdev->reset_sem); 221235a1e503SSalil Mehta } 221335a1e503SSalil Mehta 2214ff200099SYunsheng Lin static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev) 2215e2cb1decSSalil Mehta { 2216ff200099SYunsheng Lin if (!test_and_clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) 2217ff200099SYunsheng Lin return; 2218e2cb1decSSalil Mehta 2219e2cb1decSSalil Mehta if (test_and_set_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) 2220e2cb1decSSalil Mehta return; 2221e2cb1decSSalil Mehta 222207a0556aSSalil Mehta hclgevf_mbx_async_handler(hdev); 2223e2cb1decSSalil Mehta 2224e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 2225e2cb1decSSalil Mehta } 2226e2cb1decSSalil Mehta 2227ff200099SYunsheng Lin static void hclgevf_keep_alive(struct hclgevf_dev *hdev) 2228a6d818e3SYunsheng Lin { 2229d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 2230a6d818e3SYunsheng Lin int ret; 2231a6d818e3SYunsheng Lin 22321416d333SHuazhong Tan if (test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state)) 2233c59a85c0SJian Shen return; 2234c59a85c0SJian Shen 2235d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_KEEP_ALIVE, 0); 2236d3410018SYufeng Mo ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 2237a6d818e3SYunsheng Lin if (ret) 2238a6d818e3SYunsheng Lin dev_err(&hdev->pdev->dev, 2239a6d818e3SYunsheng Lin "VF sends keep alive cmd failed(=%d)\n", ret); 2240a6d818e3SYunsheng Lin } 2241a6d818e3SYunsheng Lin 2242ff200099SYunsheng Lin static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev) 2243e2cb1decSSalil Mehta { 2244ff200099SYunsheng Lin unsigned long delta = round_jiffies_relative(HZ); 2245ff200099SYunsheng Lin struct hnae3_handle *handle = &hdev->nic; 2246e2cb1decSSalil Mehta 2247e6394363SGuangbin Huang if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) 2248e6394363SGuangbin Huang return; 2249e6394363SGuangbin Huang 2250ff200099SYunsheng Lin if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { 2251ff200099SYunsheng Lin delta = jiffies - hdev->last_serv_processed; 2252db01afebSliuzhongzhu 2253ff200099SYunsheng Lin if (delta < round_jiffies_relative(HZ)) { 2254ff200099SYunsheng Lin delta = round_jiffies_relative(HZ) - delta; 2255ff200099SYunsheng Lin goto out; 2256db01afebSliuzhongzhu } 2257ff200099SYunsheng Lin } 2258ff200099SYunsheng Lin 2259ff200099SYunsheng Lin hdev->serv_processed_cnt++; 2260ff200099SYunsheng Lin if (!(hdev->serv_processed_cnt % HCLGEVF_KEEP_ALIVE_TASK_INTERVAL)) 2261ff200099SYunsheng Lin hclgevf_keep_alive(hdev); 2262ff200099SYunsheng Lin 2263ff200099SYunsheng Lin if (test_bit(HCLGEVF_STATE_DOWN, &hdev->state)) { 2264ff200099SYunsheng Lin hdev->last_serv_processed = jiffies; 2265ff200099SYunsheng Lin goto out; 2266ff200099SYunsheng Lin } 2267ff200099SYunsheng Lin 2268ff200099SYunsheng Lin if (!(hdev->serv_processed_cnt % HCLGEVF_STATS_TIMER_INTERVAL)) 2269ff200099SYunsheng Lin hclgevf_tqps_update_stats(handle); 2270e2cb1decSSalil Mehta 2271e2cb1decSSalil Mehta /* request the link status from the PF. PF would be able to tell VF 2272e2cb1decSSalil Mehta * about such updates in future so we might remove this later 2273e2cb1decSSalil Mehta */ 2274e2cb1decSSalil Mehta hclgevf_request_link_info(hdev); 2275e2cb1decSSalil Mehta 22769194d18bSliuzhongzhu hclgevf_update_link_mode(hdev); 22779194d18bSliuzhongzhu 2278fe4144d4SJian Shen hclgevf_sync_vlan_filter(hdev); 2279fe4144d4SJian Shen 2280ee4bcd3bSJian Shen hclgevf_sync_mac_table(hdev); 2281ee4bcd3bSJian Shen 2282c631c696SJian Shen hclgevf_sync_promisc_mode(hdev); 2283c631c696SJian Shen 2284ff200099SYunsheng Lin hdev->last_serv_processed = jiffies; 2285436667d2SSalil Mehta 2286ff200099SYunsheng Lin out: 2287ff200099SYunsheng Lin hclgevf_task_schedule(hdev, delta); 2288ff200099SYunsheng Lin } 2289b3c3fe8eSYunsheng Lin 2290ff200099SYunsheng Lin static void hclgevf_service_task(struct work_struct *work) 2291ff200099SYunsheng Lin { 2292ff200099SYunsheng Lin struct hclgevf_dev *hdev = container_of(work, struct hclgevf_dev, 2293ff200099SYunsheng Lin service_task.work); 2294ff200099SYunsheng Lin 2295ff200099SYunsheng Lin hclgevf_reset_service_task(hdev); 2296ff200099SYunsheng Lin hclgevf_mailbox_service_task(hdev); 2297ff200099SYunsheng Lin hclgevf_periodic_service_task(hdev); 2298ff200099SYunsheng Lin 2299ff200099SYunsheng Lin /* Handle reset and mbx again in case periodical task delays the 2300ff200099SYunsheng Lin * handling by calling hclgevf_task_schedule() in 2301ff200099SYunsheng Lin * hclgevf_periodic_service_task() 2302ff200099SYunsheng Lin */ 2303ff200099SYunsheng Lin hclgevf_reset_service_task(hdev); 2304ff200099SYunsheng Lin hclgevf_mailbox_service_task(hdev); 2305e2cb1decSSalil Mehta } 2306e2cb1decSSalil Mehta 2307e2cb1decSSalil Mehta static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr) 2308e2cb1decSSalil Mehta { 2309e2cb1decSSalil Mehta hclgevf_write_dev(&hdev->hw, HCLGEVF_VECTOR0_CMDQ_SRC_REG, regclr); 2310e2cb1decSSalil Mehta } 2311e2cb1decSSalil Mehta 2312b90fcc5bSHuazhong Tan static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, 2313b90fcc5bSHuazhong Tan u32 *clearval) 2314e2cb1decSSalil Mehta { 231513050921SHuazhong Tan u32 val, cmdq_stat_reg, rst_ing_reg; 2316e2cb1decSSalil Mehta 2317e2cb1decSSalil Mehta /* fetch the events from their corresponding regs */ 231813050921SHuazhong Tan cmdq_stat_reg = hclgevf_read_dev(&hdev->hw, 23199cee2e8dSHuazhong Tan HCLGEVF_VECTOR0_CMDQ_STATE_REG); 2320e2cb1decSSalil Mehta 232113050921SHuazhong Tan if (BIT(HCLGEVF_VECTOR0_RST_INT_B) & cmdq_stat_reg) { 2322b90fcc5bSHuazhong Tan rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); 2323b90fcc5bSHuazhong Tan dev_info(&hdev->pdev->dev, 2324b90fcc5bSHuazhong Tan "receive reset interrupt 0x%x!\n", rst_ing_reg); 2325b90fcc5bSHuazhong Tan set_bit(HNAE3_VF_RESET, &hdev->reset_pending); 2326b90fcc5bSHuazhong Tan set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); 2327ef5f8e50SHuazhong Tan set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); 232813050921SHuazhong Tan *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B); 2329c88a6e7dSHuazhong Tan hdev->rst_stats.vf_rst_cnt++; 233072e2fb07SHuazhong Tan /* set up VF hardware reset status, its PF will clear 233172e2fb07SHuazhong Tan * this status when PF has initialized done. 233272e2fb07SHuazhong Tan */ 233372e2fb07SHuazhong Tan val = hclgevf_read_dev(&hdev->hw, HCLGEVF_VF_RST_ING); 233472e2fb07SHuazhong Tan hclgevf_write_dev(&hdev->hw, HCLGEVF_VF_RST_ING, 233572e2fb07SHuazhong Tan val | HCLGEVF_VF_RST_ING_BIT); 2336b90fcc5bSHuazhong Tan return HCLGEVF_VECTOR0_EVENT_RST; 2337b90fcc5bSHuazhong Tan } 2338b90fcc5bSHuazhong Tan 2339e2cb1decSSalil Mehta /* check for vector0 mailbox(=CMDQ RX) event source */ 234013050921SHuazhong Tan if (BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B) & cmdq_stat_reg) { 234113050921SHuazhong Tan /* for revision 0x21, clearing interrupt is writing bit 0 234213050921SHuazhong Tan * to the clear register, writing bit 1 means to keep the 234313050921SHuazhong Tan * old value. 234413050921SHuazhong Tan * for revision 0x20, the clear register is a read & write 234513050921SHuazhong Tan * register, so we should just write 0 to the bit we are 234613050921SHuazhong Tan * handling, and keep other bits as cmdq_stat_reg. 234713050921SHuazhong Tan */ 2348295ba232SGuangbin Huang if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) 234913050921SHuazhong Tan *clearval = ~(1U << HCLGEVF_VECTOR0_RX_CMDQ_INT_B); 235013050921SHuazhong Tan else 235113050921SHuazhong Tan *clearval = cmdq_stat_reg & 235213050921SHuazhong Tan ~BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B); 235313050921SHuazhong Tan 2354b90fcc5bSHuazhong Tan return HCLGEVF_VECTOR0_EVENT_MBX; 2355e2cb1decSSalil Mehta } 2356e2cb1decSSalil Mehta 2357e45afb39SHuazhong Tan /* print other vector0 event source */ 2358e45afb39SHuazhong Tan dev_info(&hdev->pdev->dev, 2359e45afb39SHuazhong Tan "vector 0 interrupt from unknown source, cmdq_src = %#x\n", 2360e45afb39SHuazhong Tan cmdq_stat_reg); 2361e2cb1decSSalil Mehta 2362b90fcc5bSHuazhong Tan return HCLGEVF_VECTOR0_EVENT_OTHER; 2363e2cb1decSSalil Mehta } 2364e2cb1decSSalil Mehta 2365e2cb1decSSalil Mehta static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) 2366e2cb1decSSalil Mehta { 2367b90fcc5bSHuazhong Tan enum hclgevf_evt_cause event_cause; 2368e2cb1decSSalil Mehta struct hclgevf_dev *hdev = data; 2369e2cb1decSSalil Mehta u32 clearval; 2370e2cb1decSSalil Mehta 2371e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 2372b90fcc5bSHuazhong Tan event_cause = hclgevf_check_evt_cause(hdev, &clearval); 2373e2cb1decSSalil Mehta 2374b90fcc5bSHuazhong Tan switch (event_cause) { 2375b90fcc5bSHuazhong Tan case HCLGEVF_VECTOR0_EVENT_RST: 2376b90fcc5bSHuazhong Tan hclgevf_reset_task_schedule(hdev); 2377b90fcc5bSHuazhong Tan break; 2378b90fcc5bSHuazhong Tan case HCLGEVF_VECTOR0_EVENT_MBX: 237907a0556aSSalil Mehta hclgevf_mbx_handler(hdev); 2380b90fcc5bSHuazhong Tan break; 2381b90fcc5bSHuazhong Tan default: 2382b90fcc5bSHuazhong Tan break; 2383b90fcc5bSHuazhong Tan } 2384e2cb1decSSalil Mehta 2385b90fcc5bSHuazhong Tan if (event_cause != HCLGEVF_VECTOR0_EVENT_OTHER) { 2386e2cb1decSSalil Mehta hclgevf_clear_event_cause(hdev, clearval); 2387e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 2388b90fcc5bSHuazhong Tan } 2389e2cb1decSSalil Mehta 2390e2cb1decSSalil Mehta return IRQ_HANDLED; 2391e2cb1decSSalil Mehta } 2392e2cb1decSSalil Mehta 2393e2cb1decSSalil Mehta static int hclgevf_configure(struct hclgevf_dev *hdev) 2394e2cb1decSSalil Mehta { 2395e2cb1decSSalil Mehta int ret; 2396e2cb1decSSalil Mehta 239792f11ea1SJian Shen /* get current port based vlan state from PF */ 239892f11ea1SJian Shen ret = hclgevf_get_port_base_vlan_filter_state(hdev); 239992f11ea1SJian Shen if (ret) 240092f11ea1SJian Shen return ret; 240192f11ea1SJian Shen 2402e2cb1decSSalil Mehta /* get queue configuration from PF */ 24036cee6fc3SJian Shen ret = hclgevf_get_queue_info(hdev); 2404e2cb1decSSalil Mehta if (ret) 2405e2cb1decSSalil Mehta return ret; 2406c0425944SPeng Li 2407c0425944SPeng Li /* get queue depth info from PF */ 2408c0425944SPeng Li ret = hclgevf_get_queue_depth(hdev); 2409c0425944SPeng Li if (ret) 2410c0425944SPeng Li return ret; 2411c0425944SPeng Li 24129c3e7130Sliuzhongzhu ret = hclgevf_get_pf_media_type(hdev); 24139c3e7130Sliuzhongzhu if (ret) 24149c3e7130Sliuzhongzhu return ret; 24159c3e7130Sliuzhongzhu 2416e2cb1decSSalil Mehta /* get tc configuration from PF */ 2417e2cb1decSSalil Mehta return hclgevf_get_tc_info(hdev); 2418e2cb1decSSalil Mehta } 2419e2cb1decSSalil Mehta 24207a01c897SSalil Mehta static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev) 24217a01c897SSalil Mehta { 24227a01c897SSalil Mehta struct pci_dev *pdev = ae_dev->pdev; 24231154bb26SPeng Li struct hclgevf_dev *hdev; 24247a01c897SSalil Mehta 24257a01c897SSalil Mehta hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); 24267a01c897SSalil Mehta if (!hdev) 24277a01c897SSalil Mehta return -ENOMEM; 24287a01c897SSalil Mehta 24297a01c897SSalil Mehta hdev->pdev = pdev; 24307a01c897SSalil Mehta hdev->ae_dev = ae_dev; 24317a01c897SSalil Mehta ae_dev->priv = hdev; 24327a01c897SSalil Mehta 24337a01c897SSalil Mehta return 0; 24347a01c897SSalil Mehta } 24357a01c897SSalil Mehta 2436e2cb1decSSalil Mehta static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) 2437e2cb1decSSalil Mehta { 2438e2cb1decSSalil Mehta struct hnae3_handle *roce = &hdev->roce; 2439e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 2440e2cb1decSSalil Mehta 244107acf909SJian Shen roce->rinfo.num_vectors = hdev->num_roce_msix; 2442e2cb1decSSalil Mehta 2443e2cb1decSSalil Mehta if (hdev->num_msi_left < roce->rinfo.num_vectors || 2444e2cb1decSSalil Mehta hdev->num_msi_left == 0) 2445e2cb1decSSalil Mehta return -EINVAL; 2446e2cb1decSSalil Mehta 244707acf909SJian Shen roce->rinfo.base_vector = hdev->roce_base_vector; 2448e2cb1decSSalil Mehta 2449e2cb1decSSalil Mehta roce->rinfo.netdev = nic->kinfo.netdev; 2450e2cb1decSSalil Mehta roce->rinfo.roce_io_base = hdev->hw.io_base; 245130ae7f8aSHuazhong Tan roce->rinfo.roce_mem_base = hdev->hw.mem_base; 2452e2cb1decSSalil Mehta 2453e2cb1decSSalil Mehta roce->pdev = nic->pdev; 2454e2cb1decSSalil Mehta roce->ae_algo = nic->ae_algo; 2455e2cb1decSSalil Mehta roce->numa_node_mask = nic->numa_node_mask; 2456e2cb1decSSalil Mehta 2457e2cb1decSSalil Mehta return 0; 2458e2cb1decSSalil Mehta } 2459e2cb1decSSalil Mehta 2460b26a6feaSPeng Li static int hclgevf_config_gro(struct hclgevf_dev *hdev, bool en) 2461b26a6feaSPeng Li { 2462b26a6feaSPeng Li struct hclgevf_cfg_gro_status_cmd *req; 2463b26a6feaSPeng Li struct hclgevf_desc desc; 2464b26a6feaSPeng Li int ret; 2465b26a6feaSPeng Li 2466b26a6feaSPeng Li if (!hnae3_dev_gro_supported(hdev)) 2467b26a6feaSPeng Li return 0; 2468b26a6feaSPeng Li 2469b26a6feaSPeng Li hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_GRO_GENERIC_CONFIG, 2470b26a6feaSPeng Li false); 2471b26a6feaSPeng Li req = (struct hclgevf_cfg_gro_status_cmd *)desc.data; 2472b26a6feaSPeng Li 2473fb9e44d6SHuazhong Tan req->gro_en = en ? 1 : 0; 2474b26a6feaSPeng Li 2475b26a6feaSPeng Li ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); 2476b26a6feaSPeng Li if (ret) 2477b26a6feaSPeng Li dev_err(&hdev->pdev->dev, 2478b26a6feaSPeng Li "VF GRO hardware config cmd failed, ret = %d.\n", ret); 2479b26a6feaSPeng Li 2480b26a6feaSPeng Li return ret; 2481b26a6feaSPeng Li } 2482b26a6feaSPeng Li 248387ce161eSGuangbin Huang static int hclgevf_rss_init_cfg(struct hclgevf_dev *hdev) 2484e2cb1decSSalil Mehta { 248587ce161eSGuangbin Huang u16 rss_ind_tbl_size = hdev->ae_dev->dev_specs.rss_ind_tbl_size; 2486e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 2487944de484SGuojia Liao struct hclgevf_rss_tuple_cfg *tuple_sets; 24884093d1a2SGuangbin Huang u32 i; 2489e2cb1decSSalil Mehta 2490944de484SGuojia Liao rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ; 24914093d1a2SGuangbin Huang rss_cfg->rss_size = hdev->nic.kinfo.rss_size; 2492944de484SGuojia Liao tuple_sets = &rss_cfg->rss_tuple_sets; 2493295ba232SGuangbin Huang if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { 249487ce161eSGuangbin Huang u8 *rss_ind_tbl; 249587ce161eSGuangbin Huang 2496472d7eceSJian Shen rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_SIMPLE; 249787ce161eSGuangbin Huang 249887ce161eSGuangbin Huang rss_ind_tbl = devm_kcalloc(&hdev->pdev->dev, rss_ind_tbl_size, 249987ce161eSGuangbin Huang sizeof(*rss_ind_tbl), GFP_KERNEL); 250087ce161eSGuangbin Huang if (!rss_ind_tbl) 250187ce161eSGuangbin Huang return -ENOMEM; 250287ce161eSGuangbin Huang 250387ce161eSGuangbin Huang rss_cfg->rss_indirection_tbl = rss_ind_tbl; 2504472d7eceSJian Shen memcpy(rss_cfg->rss_hash_key, hclgevf_hash_key, 2505374ad291SJian Shen HCLGEVF_RSS_KEY_SIZE); 2506374ad291SJian Shen 2507944de484SGuojia Liao tuple_sets->ipv4_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 2508944de484SGuojia Liao tuple_sets->ipv4_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 2509944de484SGuojia Liao tuple_sets->ipv4_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP; 2510944de484SGuojia Liao tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 2511944de484SGuojia Liao tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 2512944de484SGuojia Liao tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 2513ab6e32d2SJian Shen tuple_sets->ipv6_sctp_en = 2514ab6e32d2SJian Shen hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 ? 2515ab6e32d2SJian Shen HCLGEVF_RSS_INPUT_TUPLE_SCTP_NO_PORT : 2516ab6e32d2SJian Shen HCLGEVF_RSS_INPUT_TUPLE_SCTP; 2517944de484SGuojia Liao tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER; 2518374ad291SJian Shen } 2519374ad291SJian Shen 25209b2f3477SWeihang Li /* Initialize RSS indirect table */ 252187ce161eSGuangbin Huang for (i = 0; i < rss_ind_tbl_size; i++) 25224093d1a2SGuangbin Huang rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size; 252387ce161eSGuangbin Huang 252487ce161eSGuangbin Huang return 0; 2525944de484SGuojia Liao } 2526944de484SGuojia Liao 2527944de484SGuojia Liao static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) 2528944de484SGuojia Liao { 2529944de484SGuojia Liao struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 2530944de484SGuojia Liao int ret; 2531944de484SGuojia Liao 2532295ba232SGuangbin Huang if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { 2533944de484SGuojia Liao ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo, 2534944de484SGuojia Liao rss_cfg->rss_hash_key); 2535944de484SGuojia Liao if (ret) 2536944de484SGuojia Liao return ret; 2537944de484SGuojia Liao 2538944de484SGuojia Liao ret = hclgevf_set_rss_input_tuple(hdev, rss_cfg); 2539944de484SGuojia Liao if (ret) 2540944de484SGuojia Liao return ret; 2541944de484SGuojia Liao } 2542e2cb1decSSalil Mehta 2543e2cb1decSSalil Mehta ret = hclgevf_set_rss_indir_table(hdev); 2544e2cb1decSSalil Mehta if (ret) 2545e2cb1decSSalil Mehta return ret; 2546e2cb1decSSalil Mehta 25474093d1a2SGuangbin Huang return hclgevf_set_rss_tc_mode(hdev, rss_cfg->rss_size); 2548e2cb1decSSalil Mehta } 2549e2cb1decSSalil Mehta 2550e2cb1decSSalil Mehta static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) 2551e2cb1decSSalil Mehta { 2552e2cb1decSSalil Mehta return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, 2553e2cb1decSSalil Mehta false); 2554e2cb1decSSalil Mehta } 2555e2cb1decSSalil Mehta 2556ff200099SYunsheng Lin static void hclgevf_flush_link_update(struct hclgevf_dev *hdev) 2557ff200099SYunsheng Lin { 2558ff200099SYunsheng Lin #define HCLGEVF_FLUSH_LINK_TIMEOUT 100000 2559ff200099SYunsheng Lin 2560ff200099SYunsheng Lin unsigned long last = hdev->serv_processed_cnt; 2561ff200099SYunsheng Lin int i = 0; 2562ff200099SYunsheng Lin 2563ff200099SYunsheng Lin while (test_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state) && 2564ff200099SYunsheng Lin i++ < HCLGEVF_FLUSH_LINK_TIMEOUT && 2565ff200099SYunsheng Lin last == hdev->serv_processed_cnt) 2566ff200099SYunsheng Lin usleep_range(1, 1); 2567ff200099SYunsheng Lin } 2568ff200099SYunsheng Lin 25698cdb992fSJian Shen static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable) 25708cdb992fSJian Shen { 25718cdb992fSJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 25728cdb992fSJian Shen 25738cdb992fSJian Shen if (enable) { 2574ff200099SYunsheng Lin hclgevf_task_schedule(hdev, 0); 25758cdb992fSJian Shen } else { 2576b3c3fe8eSYunsheng Lin set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 2577ff200099SYunsheng Lin 2578ff200099SYunsheng Lin /* flush memory to make sure DOWN is seen by service task */ 2579ff200099SYunsheng Lin smp_mb__before_atomic(); 2580ff200099SYunsheng Lin hclgevf_flush_link_update(hdev); 25818cdb992fSJian Shen } 25828cdb992fSJian Shen } 25838cdb992fSJian Shen 2584e2cb1decSSalil Mehta static int hclgevf_ae_start(struct hnae3_handle *handle) 2585e2cb1decSSalil Mehta { 2586e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 2587e2cb1decSSalil Mehta 2588e2cb1decSSalil Mehta hclgevf_reset_tqp_stats(handle); 2589e2cb1decSSalil Mehta 2590e2cb1decSSalil Mehta hclgevf_request_link_info(hdev); 2591e2cb1decSSalil Mehta 25929194d18bSliuzhongzhu hclgevf_update_link_mode(hdev); 25939194d18bSliuzhongzhu 2594e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); 2595e2cb1decSSalil Mehta 2596e2cb1decSSalil Mehta return 0; 2597e2cb1decSSalil Mehta } 2598e2cb1decSSalil Mehta 2599e2cb1decSSalil Mehta static void hclgevf_ae_stop(struct hnae3_handle *handle) 2600e2cb1decSSalil Mehta { 2601e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 260239cfbc9cSHuazhong Tan int i; 2603e2cb1decSSalil Mehta 26042f7e4896SFuyun Liang set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 26052f7e4896SFuyun Liang 2606146e92c1SHuazhong Tan if (hdev->reset_type != HNAE3_VF_RESET) 260739cfbc9cSHuazhong Tan for (i = 0; i < handle->kinfo.num_tqps; i++) 2608146e92c1SHuazhong Tan if (hclgevf_reset_tqp(handle, i)) 2609146e92c1SHuazhong Tan break; 261039cfbc9cSHuazhong Tan 2611e2cb1decSSalil Mehta hclgevf_reset_tqp_stats(handle); 26128cc6c1f7SFuyun Liang hclgevf_update_link_status(hdev, 0); 2613e2cb1decSSalil Mehta } 2614e2cb1decSSalil Mehta 2615a6d818e3SYunsheng Lin static int hclgevf_set_alive(struct hnae3_handle *handle, bool alive) 2616a6d818e3SYunsheng Lin { 2617d3410018SYufeng Mo #define HCLGEVF_STATE_ALIVE 1 2618d3410018SYufeng Mo #define HCLGEVF_STATE_NOT_ALIVE 0 2619a6d818e3SYunsheng Lin 2620d3410018SYufeng Mo struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 2621d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 2622d3410018SYufeng Mo 2623d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_ALIVE, 0); 2624d3410018SYufeng Mo send_msg.data[0] = alive ? HCLGEVF_STATE_ALIVE : 2625d3410018SYufeng Mo HCLGEVF_STATE_NOT_ALIVE; 2626d3410018SYufeng Mo return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 2627a6d818e3SYunsheng Lin } 2628a6d818e3SYunsheng Lin 2629a6d818e3SYunsheng Lin static int hclgevf_client_start(struct hnae3_handle *handle) 2630a6d818e3SYunsheng Lin { 2631f621df96SQinglang Miao return hclgevf_set_alive(handle, true); 2632a6d818e3SYunsheng Lin } 2633a6d818e3SYunsheng Lin 2634a6d818e3SYunsheng Lin static void hclgevf_client_stop(struct hnae3_handle *handle) 2635a6d818e3SYunsheng Lin { 2636a6d818e3SYunsheng Lin struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 2637a6d818e3SYunsheng Lin int ret; 2638a6d818e3SYunsheng Lin 2639a6d818e3SYunsheng Lin ret = hclgevf_set_alive(handle, false); 2640a6d818e3SYunsheng Lin if (ret) 2641a6d818e3SYunsheng Lin dev_warn(&hdev->pdev->dev, 2642a6d818e3SYunsheng Lin "%s failed %d\n", __func__, ret); 2643a6d818e3SYunsheng Lin } 2644a6d818e3SYunsheng Lin 2645e2cb1decSSalil Mehta static void hclgevf_state_init(struct hclgevf_dev *hdev) 2646e2cb1decSSalil Mehta { 2647e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 2648e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 2649d5432455SGuojia Liao clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); 2650e2cb1decSSalil Mehta 2651b3c3fe8eSYunsheng Lin INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); 265235a1e503SSalil Mehta 2653e2cb1decSSalil Mehta mutex_init(&hdev->mbx_resp.mbx_mutex); 2654f28368bbSHuazhong Tan sema_init(&hdev->reset_sem, 1); 2655e2cb1decSSalil Mehta 2656ee4bcd3bSJian Shen spin_lock_init(&hdev->mac_table.mac_list_lock); 2657ee4bcd3bSJian Shen INIT_LIST_HEAD(&hdev->mac_table.uc_mac_list); 2658ee4bcd3bSJian Shen INIT_LIST_HEAD(&hdev->mac_table.mc_mac_list); 2659ee4bcd3bSJian Shen 2660e2cb1decSSalil Mehta /* bring the device down */ 2661e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 2662e2cb1decSSalil Mehta } 2663e2cb1decSSalil Mehta 2664e2cb1decSSalil Mehta static void hclgevf_state_uninit(struct hclgevf_dev *hdev) 2665e2cb1decSSalil Mehta { 2666e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 2667acfc3d55SHuazhong Tan set_bit(HCLGEVF_STATE_REMOVING, &hdev->state); 2668e2cb1decSSalil Mehta 2669b3c3fe8eSYunsheng Lin if (hdev->service_task.work.func) 2670b3c3fe8eSYunsheng Lin cancel_delayed_work_sync(&hdev->service_task); 2671e2cb1decSSalil Mehta 2672e2cb1decSSalil Mehta mutex_destroy(&hdev->mbx_resp.mbx_mutex); 2673e2cb1decSSalil Mehta } 2674e2cb1decSSalil Mehta 2675e2cb1decSSalil Mehta static int hclgevf_init_msi(struct hclgevf_dev *hdev) 2676e2cb1decSSalil Mehta { 2677e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 2678e2cb1decSSalil Mehta int vectors; 2679e2cb1decSSalil Mehta int i; 2680e2cb1decSSalil Mehta 2681580a05f9SYonglong Liu if (hnae3_dev_roce_supported(hdev)) 268207acf909SJian Shen vectors = pci_alloc_irq_vectors(pdev, 268307acf909SJian Shen hdev->roce_base_msix_offset + 1, 268407acf909SJian Shen hdev->num_msi, 268507acf909SJian Shen PCI_IRQ_MSIX); 268607acf909SJian Shen else 2687580a05f9SYonglong Liu vectors = pci_alloc_irq_vectors(pdev, HNAE3_MIN_VECTOR_NUM, 2688580a05f9SYonglong Liu hdev->num_msi, 2689e2cb1decSSalil Mehta PCI_IRQ_MSI | PCI_IRQ_MSIX); 269007acf909SJian Shen 2691e2cb1decSSalil Mehta if (vectors < 0) { 2692e2cb1decSSalil Mehta dev_err(&pdev->dev, 2693e2cb1decSSalil Mehta "failed(%d) to allocate MSI/MSI-X vectors\n", 2694e2cb1decSSalil Mehta vectors); 2695e2cb1decSSalil Mehta return vectors; 2696e2cb1decSSalil Mehta } 2697e2cb1decSSalil Mehta if (vectors < hdev->num_msi) 2698e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 2699adcf738bSGuojia Liao "requested %u MSI/MSI-X, but allocated %d MSI/MSI-X\n", 2700e2cb1decSSalil Mehta hdev->num_msi, vectors); 2701e2cb1decSSalil Mehta 2702e2cb1decSSalil Mehta hdev->num_msi = vectors; 2703e2cb1decSSalil Mehta hdev->num_msi_left = vectors; 2704580a05f9SYonglong Liu 2705e2cb1decSSalil Mehta hdev->base_msi_vector = pdev->irq; 270607acf909SJian Shen hdev->roce_base_vector = pdev->irq + hdev->roce_base_msix_offset; 2707e2cb1decSSalil Mehta 2708e2cb1decSSalil Mehta hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, 2709e2cb1decSSalil Mehta sizeof(u16), GFP_KERNEL); 2710e2cb1decSSalil Mehta if (!hdev->vector_status) { 2711e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 2712e2cb1decSSalil Mehta return -ENOMEM; 2713e2cb1decSSalil Mehta } 2714e2cb1decSSalil Mehta 2715e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 2716e2cb1decSSalil Mehta hdev->vector_status[i] = HCLGEVF_INVALID_VPORT; 2717e2cb1decSSalil Mehta 2718e2cb1decSSalil Mehta hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi, 2719e2cb1decSSalil Mehta sizeof(int), GFP_KERNEL); 2720e2cb1decSSalil Mehta if (!hdev->vector_irq) { 2721862d969aSHuazhong Tan devm_kfree(&pdev->dev, hdev->vector_status); 2722e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 2723e2cb1decSSalil Mehta return -ENOMEM; 2724e2cb1decSSalil Mehta } 2725e2cb1decSSalil Mehta 2726e2cb1decSSalil Mehta return 0; 2727e2cb1decSSalil Mehta } 2728e2cb1decSSalil Mehta 2729e2cb1decSSalil Mehta static void hclgevf_uninit_msi(struct hclgevf_dev *hdev) 2730e2cb1decSSalil Mehta { 2731e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 2732e2cb1decSSalil Mehta 2733862d969aSHuazhong Tan devm_kfree(&pdev->dev, hdev->vector_status); 2734862d969aSHuazhong Tan devm_kfree(&pdev->dev, hdev->vector_irq); 2735e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 2736e2cb1decSSalil Mehta } 2737e2cb1decSSalil Mehta 2738e2cb1decSSalil Mehta static int hclgevf_misc_irq_init(struct hclgevf_dev *hdev) 2739e2cb1decSSalil Mehta { 2740cdd332acSGuojia Liao int ret; 2741e2cb1decSSalil Mehta 2742e2cb1decSSalil Mehta hclgevf_get_misc_vector(hdev); 2743e2cb1decSSalil Mehta 2744f97c4d82SYonglong Liu snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", 2745f97c4d82SYonglong Liu HCLGEVF_NAME, pci_name(hdev->pdev)); 2746e2cb1decSSalil Mehta ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, 2747f97c4d82SYonglong Liu 0, hdev->misc_vector.name, hdev); 2748e2cb1decSSalil Mehta if (ret) { 2749e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF failed to request misc irq(%d)\n", 2750e2cb1decSSalil Mehta hdev->misc_vector.vector_irq); 2751e2cb1decSSalil Mehta return ret; 2752e2cb1decSSalil Mehta } 2753e2cb1decSSalil Mehta 27541819e409SXi Wang hclgevf_clear_event_cause(hdev, 0); 27551819e409SXi Wang 2756e2cb1decSSalil Mehta /* enable misc. vector(vector 0) */ 2757e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 2758e2cb1decSSalil Mehta 2759e2cb1decSSalil Mehta return ret; 2760e2cb1decSSalil Mehta } 2761e2cb1decSSalil Mehta 2762e2cb1decSSalil Mehta static void hclgevf_misc_irq_uninit(struct hclgevf_dev *hdev) 2763e2cb1decSSalil Mehta { 2764e2cb1decSSalil Mehta /* disable misc vector(vector 0) */ 2765e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 27661819e409SXi Wang synchronize_irq(hdev->misc_vector.vector_irq); 2767e2cb1decSSalil Mehta free_irq(hdev->misc_vector.vector_irq, hdev); 2768e2cb1decSSalil Mehta hclgevf_free_vector(hdev, 0); 2769e2cb1decSSalil Mehta } 2770e2cb1decSSalil Mehta 2771bb87be87SYonglong Liu static void hclgevf_info_show(struct hclgevf_dev *hdev) 2772bb87be87SYonglong Liu { 2773bb87be87SYonglong Liu struct device *dev = &hdev->pdev->dev; 2774bb87be87SYonglong Liu 2775bb87be87SYonglong Liu dev_info(dev, "VF info begin:\n"); 2776bb87be87SYonglong Liu 2777adcf738bSGuojia Liao dev_info(dev, "Task queue pairs numbers: %u\n", hdev->num_tqps); 2778adcf738bSGuojia Liao dev_info(dev, "Desc num per TX queue: %u\n", hdev->num_tx_desc); 2779adcf738bSGuojia Liao dev_info(dev, "Desc num per RX queue: %u\n", hdev->num_rx_desc); 2780adcf738bSGuojia Liao dev_info(dev, "Numbers of vports: %u\n", hdev->num_alloc_vport); 2781adcf738bSGuojia Liao dev_info(dev, "HW tc map: 0x%x\n", hdev->hw_tc_map); 2782adcf738bSGuojia Liao dev_info(dev, "PF media type of this VF: %u\n", 2783bb87be87SYonglong Liu hdev->hw.mac.media_type); 2784bb87be87SYonglong Liu 2785bb87be87SYonglong Liu dev_info(dev, "VF info end.\n"); 2786bb87be87SYonglong Liu } 2787bb87be87SYonglong Liu 27881db58f86SHuazhong Tan static int hclgevf_init_nic_client_instance(struct hnae3_ae_dev *ae_dev, 27891db58f86SHuazhong Tan struct hnae3_client *client) 27901db58f86SHuazhong Tan { 27911db58f86SHuazhong Tan struct hclgevf_dev *hdev = ae_dev->priv; 27924cd5beaaSGuangbin Huang int rst_cnt = hdev->rst_stats.rst_cnt; 27931db58f86SHuazhong Tan int ret; 27941db58f86SHuazhong Tan 27951db58f86SHuazhong Tan ret = client->ops->init_instance(&hdev->nic); 27961db58f86SHuazhong Tan if (ret) 27971db58f86SHuazhong Tan return ret; 27981db58f86SHuazhong Tan 27991db58f86SHuazhong Tan set_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state); 28004cd5beaaSGuangbin Huang if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state) || 28014cd5beaaSGuangbin Huang rst_cnt != hdev->rst_stats.rst_cnt) { 28024cd5beaaSGuangbin Huang clear_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state); 28034cd5beaaSGuangbin Huang 28044cd5beaaSGuangbin Huang client->ops->uninit_instance(&hdev->nic, 0); 28054cd5beaaSGuangbin Huang return -EBUSY; 28064cd5beaaSGuangbin Huang } 28074cd5beaaSGuangbin Huang 28081db58f86SHuazhong Tan hnae3_set_client_init_flag(client, ae_dev, 1); 28091db58f86SHuazhong Tan 28101db58f86SHuazhong Tan if (netif_msg_drv(&hdev->nic)) 28111db58f86SHuazhong Tan hclgevf_info_show(hdev); 28121db58f86SHuazhong Tan 28131db58f86SHuazhong Tan return 0; 28141db58f86SHuazhong Tan } 28151db58f86SHuazhong Tan 28161db58f86SHuazhong Tan static int hclgevf_init_roce_client_instance(struct hnae3_ae_dev *ae_dev, 28171db58f86SHuazhong Tan struct hnae3_client *client) 28181db58f86SHuazhong Tan { 28191db58f86SHuazhong Tan struct hclgevf_dev *hdev = ae_dev->priv; 28201db58f86SHuazhong Tan int ret; 28211db58f86SHuazhong Tan 28221db58f86SHuazhong Tan if (!hnae3_dev_roce_supported(hdev) || !hdev->roce_client || 28231db58f86SHuazhong Tan !hdev->nic_client) 28241db58f86SHuazhong Tan return 0; 28251db58f86SHuazhong Tan 28261db58f86SHuazhong Tan ret = hclgevf_init_roce_base_info(hdev); 28271db58f86SHuazhong Tan if (ret) 28281db58f86SHuazhong Tan return ret; 28291db58f86SHuazhong Tan 28301db58f86SHuazhong Tan ret = client->ops->init_instance(&hdev->roce); 28311db58f86SHuazhong Tan if (ret) 28321db58f86SHuazhong Tan return ret; 28331db58f86SHuazhong Tan 2834fe735c84SHuazhong Tan set_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); 28351db58f86SHuazhong Tan hnae3_set_client_init_flag(client, ae_dev, 1); 28361db58f86SHuazhong Tan 28371db58f86SHuazhong Tan return 0; 28381db58f86SHuazhong Tan } 28391db58f86SHuazhong Tan 2840e718a93fSPeng Li static int hclgevf_init_client_instance(struct hnae3_client *client, 2841e718a93fSPeng Li struct hnae3_ae_dev *ae_dev) 2842e2cb1decSSalil Mehta { 2843e718a93fSPeng Li struct hclgevf_dev *hdev = ae_dev->priv; 2844e2cb1decSSalil Mehta int ret; 2845e2cb1decSSalil Mehta 2846e2cb1decSSalil Mehta switch (client->type) { 2847e2cb1decSSalil Mehta case HNAE3_CLIENT_KNIC: 2848e2cb1decSSalil Mehta hdev->nic_client = client; 2849e2cb1decSSalil Mehta hdev->nic.client = client; 2850e2cb1decSSalil Mehta 28511db58f86SHuazhong Tan ret = hclgevf_init_nic_client_instance(ae_dev, client); 2852e2cb1decSSalil Mehta if (ret) 285349dd8054SJian Shen goto clear_nic; 2854e2cb1decSSalil Mehta 28551db58f86SHuazhong Tan ret = hclgevf_init_roce_client_instance(ae_dev, 28561db58f86SHuazhong Tan hdev->roce_client); 2857e2cb1decSSalil Mehta if (ret) 285849dd8054SJian Shen goto clear_roce; 2859d9f28fc2SJian Shen 2860e2cb1decSSalil Mehta break; 2861e2cb1decSSalil Mehta case HNAE3_CLIENT_ROCE: 2862544a7bcdSLijun Ou if (hnae3_dev_roce_supported(hdev)) { 2863e2cb1decSSalil Mehta hdev->roce_client = client; 2864e2cb1decSSalil Mehta hdev->roce.client = client; 2865544a7bcdSLijun Ou } 2866e2cb1decSSalil Mehta 28671db58f86SHuazhong Tan ret = hclgevf_init_roce_client_instance(ae_dev, client); 2868e2cb1decSSalil Mehta if (ret) 286949dd8054SJian Shen goto clear_roce; 2870e2cb1decSSalil Mehta 2871fa7a4bd5SJian Shen break; 2872fa7a4bd5SJian Shen default: 2873fa7a4bd5SJian Shen return -EINVAL; 2874e2cb1decSSalil Mehta } 2875e2cb1decSSalil Mehta 2876e2cb1decSSalil Mehta return 0; 287749dd8054SJian Shen 287849dd8054SJian Shen clear_nic: 287949dd8054SJian Shen hdev->nic_client = NULL; 288049dd8054SJian Shen hdev->nic.client = NULL; 288149dd8054SJian Shen return ret; 288249dd8054SJian Shen clear_roce: 288349dd8054SJian Shen hdev->roce_client = NULL; 288449dd8054SJian Shen hdev->roce.client = NULL; 288549dd8054SJian Shen return ret; 2886e2cb1decSSalil Mehta } 2887e2cb1decSSalil Mehta 2888e718a93fSPeng Li static void hclgevf_uninit_client_instance(struct hnae3_client *client, 2889e718a93fSPeng Li struct hnae3_ae_dev *ae_dev) 2890e2cb1decSSalil Mehta { 2891e718a93fSPeng Li struct hclgevf_dev *hdev = ae_dev->priv; 2892e718a93fSPeng Li 2893e2cb1decSSalil Mehta /* un-init roce, if it exists */ 289449dd8054SJian Shen if (hdev->roce_client) { 2895fe735c84SHuazhong Tan clear_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); 2896e2cb1decSSalil Mehta hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); 289749dd8054SJian Shen hdev->roce_client = NULL; 289849dd8054SJian Shen hdev->roce.client = NULL; 289949dd8054SJian Shen } 2900e2cb1decSSalil Mehta 2901e2cb1decSSalil Mehta /* un-init nic/unic, if this was not called by roce client */ 290249dd8054SJian Shen if (client->ops->uninit_instance && hdev->nic_client && 290349dd8054SJian Shen client->type != HNAE3_CLIENT_ROCE) { 290425d1817cSHuazhong Tan clear_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state); 290525d1817cSHuazhong Tan 2906e2cb1decSSalil Mehta client->ops->uninit_instance(&hdev->nic, 0); 290749dd8054SJian Shen hdev->nic_client = NULL; 290849dd8054SJian Shen hdev->nic.client = NULL; 290949dd8054SJian Shen } 2910e2cb1decSSalil Mehta } 2911e2cb1decSSalil Mehta 291230ae7f8aSHuazhong Tan static int hclgevf_dev_mem_map(struct hclgevf_dev *hdev) 291330ae7f8aSHuazhong Tan { 291430ae7f8aSHuazhong Tan #define HCLGEVF_MEM_BAR 4 291530ae7f8aSHuazhong Tan 291630ae7f8aSHuazhong Tan struct pci_dev *pdev = hdev->pdev; 291730ae7f8aSHuazhong Tan struct hclgevf_hw *hw = &hdev->hw; 291830ae7f8aSHuazhong Tan 291930ae7f8aSHuazhong Tan /* for device does not have device memory, return directly */ 292030ae7f8aSHuazhong Tan if (!(pci_select_bars(pdev, IORESOURCE_MEM) & BIT(HCLGEVF_MEM_BAR))) 292130ae7f8aSHuazhong Tan return 0; 292230ae7f8aSHuazhong Tan 292330ae7f8aSHuazhong Tan hw->mem_base = devm_ioremap_wc(&pdev->dev, 292430ae7f8aSHuazhong Tan pci_resource_start(pdev, 292530ae7f8aSHuazhong Tan HCLGEVF_MEM_BAR), 292630ae7f8aSHuazhong Tan pci_resource_len(pdev, HCLGEVF_MEM_BAR)); 292730ae7f8aSHuazhong Tan if (!hw->mem_base) { 2928be419fcaSColin Ian King dev_err(&pdev->dev, "failed to map device memory\n"); 292930ae7f8aSHuazhong Tan return -EFAULT; 293030ae7f8aSHuazhong Tan } 293130ae7f8aSHuazhong Tan 293230ae7f8aSHuazhong Tan return 0; 293330ae7f8aSHuazhong Tan } 293430ae7f8aSHuazhong Tan 2935e2cb1decSSalil Mehta static int hclgevf_pci_init(struct hclgevf_dev *hdev) 2936e2cb1decSSalil Mehta { 2937e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 2938e2cb1decSSalil Mehta struct hclgevf_hw *hw; 2939e2cb1decSSalil Mehta int ret; 2940e2cb1decSSalil Mehta 2941e2cb1decSSalil Mehta ret = pci_enable_device(pdev); 2942e2cb1decSSalil Mehta if (ret) { 2943e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed to enable PCI device\n"); 29443e249d3bSFuyun Liang return ret; 2945e2cb1decSSalil Mehta } 2946e2cb1decSSalil Mehta 2947e2cb1decSSalil Mehta ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 2948e2cb1decSSalil Mehta if (ret) { 2949e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't set consistent PCI DMA, exiting"); 2950e2cb1decSSalil Mehta goto err_disable_device; 2951e2cb1decSSalil Mehta } 2952e2cb1decSSalil Mehta 2953e2cb1decSSalil Mehta ret = pci_request_regions(pdev, HCLGEVF_DRIVER_NAME); 2954e2cb1decSSalil Mehta if (ret) { 2955e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI request regions failed %d\n", ret); 2956e2cb1decSSalil Mehta goto err_disable_device; 2957e2cb1decSSalil Mehta } 2958e2cb1decSSalil Mehta 2959e2cb1decSSalil Mehta pci_set_master(pdev); 2960e2cb1decSSalil Mehta hw = &hdev->hw; 2961e2cb1decSSalil Mehta hw->hdev = hdev; 29622e1ea493SPeng Li hw->io_base = pci_iomap(pdev, 2, 0); 2963e2cb1decSSalil Mehta if (!hw->io_base) { 2964e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't map configuration register space\n"); 2965e2cb1decSSalil Mehta ret = -ENOMEM; 2966e2cb1decSSalil Mehta goto err_clr_master; 2967e2cb1decSSalil Mehta } 2968e2cb1decSSalil Mehta 296930ae7f8aSHuazhong Tan ret = hclgevf_dev_mem_map(hdev); 297030ae7f8aSHuazhong Tan if (ret) 297130ae7f8aSHuazhong Tan goto err_unmap_io_base; 297230ae7f8aSHuazhong Tan 2973e2cb1decSSalil Mehta return 0; 2974e2cb1decSSalil Mehta 297530ae7f8aSHuazhong Tan err_unmap_io_base: 297630ae7f8aSHuazhong Tan pci_iounmap(pdev, hdev->hw.io_base); 2977e2cb1decSSalil Mehta err_clr_master: 2978e2cb1decSSalil Mehta pci_clear_master(pdev); 2979e2cb1decSSalil Mehta pci_release_regions(pdev); 2980e2cb1decSSalil Mehta err_disable_device: 2981e2cb1decSSalil Mehta pci_disable_device(pdev); 29823e249d3bSFuyun Liang 2983e2cb1decSSalil Mehta return ret; 2984e2cb1decSSalil Mehta } 2985e2cb1decSSalil Mehta 2986e2cb1decSSalil Mehta static void hclgevf_pci_uninit(struct hclgevf_dev *hdev) 2987e2cb1decSSalil Mehta { 2988e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 2989e2cb1decSSalil Mehta 299030ae7f8aSHuazhong Tan if (hdev->hw.mem_base) 299130ae7f8aSHuazhong Tan devm_iounmap(&pdev->dev, hdev->hw.mem_base); 299230ae7f8aSHuazhong Tan 2993e2cb1decSSalil Mehta pci_iounmap(pdev, hdev->hw.io_base); 2994e2cb1decSSalil Mehta pci_clear_master(pdev); 2995e2cb1decSSalil Mehta pci_release_regions(pdev); 2996e2cb1decSSalil Mehta pci_disable_device(pdev); 2997e2cb1decSSalil Mehta } 2998e2cb1decSSalil Mehta 299907acf909SJian Shen static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) 300007acf909SJian Shen { 300107acf909SJian Shen struct hclgevf_query_res_cmd *req; 300207acf909SJian Shen struct hclgevf_desc desc; 300307acf909SJian Shen int ret; 300407acf909SJian Shen 300507acf909SJian Shen hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_QUERY_VF_RSRC, true); 300607acf909SJian Shen ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); 300707acf909SJian Shen if (ret) { 300807acf909SJian Shen dev_err(&hdev->pdev->dev, 300907acf909SJian Shen "query vf resource failed, ret = %d.\n", ret); 301007acf909SJian Shen return ret; 301107acf909SJian Shen } 301207acf909SJian Shen 301307acf909SJian Shen req = (struct hclgevf_query_res_cmd *)desc.data; 301407acf909SJian Shen 3015580a05f9SYonglong Liu if (hnae3_dev_roce_supported(hdev)) { 301607acf909SJian Shen hdev->roce_base_msix_offset = 301760df7e91SHuazhong Tan hnae3_get_field(le16_to_cpu(req->msixcap_localid_ba_rocee), 301807acf909SJian Shen HCLGEVF_MSIX_OFT_ROCEE_M, 301907acf909SJian Shen HCLGEVF_MSIX_OFT_ROCEE_S); 302007acf909SJian Shen hdev->num_roce_msix = 302160df7e91SHuazhong Tan hnae3_get_field(le16_to_cpu(req->vf_intr_vector_number), 302207acf909SJian Shen HCLGEVF_VEC_NUM_M, HCLGEVF_VEC_NUM_S); 302307acf909SJian Shen 3024580a05f9SYonglong Liu /* nic's msix numbers is always equals to the roce's. */ 3025580a05f9SYonglong Liu hdev->num_nic_msix = hdev->num_roce_msix; 3026580a05f9SYonglong Liu 302707acf909SJian Shen /* VF should have NIC vectors and Roce vectors, NIC vectors 302807acf909SJian Shen * are queued before Roce vectors. The offset is fixed to 64. 302907acf909SJian Shen */ 303007acf909SJian Shen hdev->num_msi = hdev->num_roce_msix + 303107acf909SJian Shen hdev->roce_base_msix_offset; 303207acf909SJian Shen } else { 303307acf909SJian Shen hdev->num_msi = 303460df7e91SHuazhong Tan hnae3_get_field(le16_to_cpu(req->vf_intr_vector_number), 303507acf909SJian Shen HCLGEVF_VEC_NUM_M, HCLGEVF_VEC_NUM_S); 3036580a05f9SYonglong Liu 3037580a05f9SYonglong Liu hdev->num_nic_msix = hdev->num_msi; 3038580a05f9SYonglong Liu } 3039580a05f9SYonglong Liu 3040580a05f9SYonglong Liu if (hdev->num_nic_msix < HNAE3_MIN_VECTOR_NUM) { 3041580a05f9SYonglong Liu dev_err(&hdev->pdev->dev, 3042580a05f9SYonglong Liu "Just %u msi resources, not enough for vf(min:2).\n", 3043580a05f9SYonglong Liu hdev->num_nic_msix); 3044580a05f9SYonglong Liu return -EINVAL; 304507acf909SJian Shen } 304607acf909SJian Shen 304707acf909SJian Shen return 0; 304807acf909SJian Shen } 304907acf909SJian Shen 3050af2aedc5SGuangbin Huang static void hclgevf_set_default_dev_specs(struct hclgevf_dev *hdev) 3051af2aedc5SGuangbin Huang { 3052af2aedc5SGuangbin Huang #define HCLGEVF_MAX_NON_TSO_BD_NUM 8U 3053af2aedc5SGuangbin Huang 3054af2aedc5SGuangbin Huang struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); 3055af2aedc5SGuangbin Huang 3056af2aedc5SGuangbin Huang ae_dev->dev_specs.max_non_tso_bd_num = 3057af2aedc5SGuangbin Huang HCLGEVF_MAX_NON_TSO_BD_NUM; 3058af2aedc5SGuangbin Huang ae_dev->dev_specs.rss_ind_tbl_size = HCLGEVF_RSS_IND_TBL_SIZE; 3059af2aedc5SGuangbin Huang ae_dev->dev_specs.rss_key_size = HCLGEVF_RSS_KEY_SIZE; 3060ab16b49cSHuazhong Tan ae_dev->dev_specs.max_int_gl = HCLGEVF_DEF_MAX_INT_GL; 3061*e070c8b9SYufeng Mo ae_dev->dev_specs.max_frm_size = HCLGEVF_MAC_MAX_FRAME; 3062af2aedc5SGuangbin Huang } 3063af2aedc5SGuangbin Huang 3064af2aedc5SGuangbin Huang static void hclgevf_parse_dev_specs(struct hclgevf_dev *hdev, 3065af2aedc5SGuangbin Huang struct hclgevf_desc *desc) 3066af2aedc5SGuangbin Huang { 3067af2aedc5SGuangbin Huang struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); 3068af2aedc5SGuangbin Huang struct hclgevf_dev_specs_0_cmd *req0; 3069ab16b49cSHuazhong Tan struct hclgevf_dev_specs_1_cmd *req1; 3070af2aedc5SGuangbin Huang 3071af2aedc5SGuangbin Huang req0 = (struct hclgevf_dev_specs_0_cmd *)desc[0].data; 3072ab16b49cSHuazhong Tan req1 = (struct hclgevf_dev_specs_1_cmd *)desc[1].data; 3073af2aedc5SGuangbin Huang 3074af2aedc5SGuangbin Huang ae_dev->dev_specs.max_non_tso_bd_num = req0->max_non_tso_bd_num; 3075af2aedc5SGuangbin Huang ae_dev->dev_specs.rss_ind_tbl_size = 3076af2aedc5SGuangbin Huang le16_to_cpu(req0->rss_ind_tbl_size); 307791bfae25SHuazhong Tan ae_dev->dev_specs.int_ql_max = le16_to_cpu(req0->int_ql_max); 3078af2aedc5SGuangbin Huang ae_dev->dev_specs.rss_key_size = le16_to_cpu(req0->rss_key_size); 3079ab16b49cSHuazhong Tan ae_dev->dev_specs.max_int_gl = le16_to_cpu(req1->max_int_gl); 3080*e070c8b9SYufeng Mo ae_dev->dev_specs.max_frm_size = le16_to_cpu(req1->max_frm_size); 3081af2aedc5SGuangbin Huang } 3082af2aedc5SGuangbin Huang 308313297028SGuangbin Huang static void hclgevf_check_dev_specs(struct hclgevf_dev *hdev) 308413297028SGuangbin Huang { 308513297028SGuangbin Huang struct hnae3_dev_specs *dev_specs = &hdev->ae_dev->dev_specs; 308613297028SGuangbin Huang 308713297028SGuangbin Huang if (!dev_specs->max_non_tso_bd_num) 308813297028SGuangbin Huang dev_specs->max_non_tso_bd_num = HCLGEVF_MAX_NON_TSO_BD_NUM; 308913297028SGuangbin Huang if (!dev_specs->rss_ind_tbl_size) 309013297028SGuangbin Huang dev_specs->rss_ind_tbl_size = HCLGEVF_RSS_IND_TBL_SIZE; 309113297028SGuangbin Huang if (!dev_specs->rss_key_size) 309213297028SGuangbin Huang dev_specs->rss_key_size = HCLGEVF_RSS_KEY_SIZE; 3093ab16b49cSHuazhong Tan if (!dev_specs->max_int_gl) 3094ab16b49cSHuazhong Tan dev_specs->max_int_gl = HCLGEVF_DEF_MAX_INT_GL; 3095*e070c8b9SYufeng Mo if (!dev_specs->max_frm_size) 3096*e070c8b9SYufeng Mo dev_specs->max_frm_size = HCLGEVF_MAC_MAX_FRAME; 309713297028SGuangbin Huang } 309813297028SGuangbin Huang 3099af2aedc5SGuangbin Huang static int hclgevf_query_dev_specs(struct hclgevf_dev *hdev) 3100af2aedc5SGuangbin Huang { 3101af2aedc5SGuangbin Huang struct hclgevf_desc desc[HCLGEVF_QUERY_DEV_SPECS_BD_NUM]; 3102af2aedc5SGuangbin Huang int ret; 3103af2aedc5SGuangbin Huang int i; 3104af2aedc5SGuangbin Huang 3105af2aedc5SGuangbin Huang /* set default specifications as devices lower than version V3 do not 3106af2aedc5SGuangbin Huang * support querying specifications from firmware. 3107af2aedc5SGuangbin Huang */ 3108af2aedc5SGuangbin Huang if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) { 3109af2aedc5SGuangbin Huang hclgevf_set_default_dev_specs(hdev); 3110af2aedc5SGuangbin Huang return 0; 3111af2aedc5SGuangbin Huang } 3112af2aedc5SGuangbin Huang 3113af2aedc5SGuangbin Huang for (i = 0; i < HCLGEVF_QUERY_DEV_SPECS_BD_NUM - 1; i++) { 3114af2aedc5SGuangbin Huang hclgevf_cmd_setup_basic_desc(&desc[i], 3115af2aedc5SGuangbin Huang HCLGEVF_OPC_QUERY_DEV_SPECS, true); 3116af2aedc5SGuangbin Huang desc[i].flag |= cpu_to_le16(HCLGEVF_CMD_FLAG_NEXT); 3117af2aedc5SGuangbin Huang } 3118af2aedc5SGuangbin Huang hclgevf_cmd_setup_basic_desc(&desc[i], HCLGEVF_OPC_QUERY_DEV_SPECS, 3119af2aedc5SGuangbin Huang true); 3120af2aedc5SGuangbin Huang 3121af2aedc5SGuangbin Huang ret = hclgevf_cmd_send(&hdev->hw, desc, HCLGEVF_QUERY_DEV_SPECS_BD_NUM); 3122af2aedc5SGuangbin Huang if (ret) 3123af2aedc5SGuangbin Huang return ret; 3124af2aedc5SGuangbin Huang 3125af2aedc5SGuangbin Huang hclgevf_parse_dev_specs(hdev, desc); 312613297028SGuangbin Huang hclgevf_check_dev_specs(hdev); 3127af2aedc5SGuangbin Huang 3128af2aedc5SGuangbin Huang return 0; 3129af2aedc5SGuangbin Huang } 3130af2aedc5SGuangbin Huang 3131862d969aSHuazhong Tan static int hclgevf_pci_reset(struct hclgevf_dev *hdev) 3132862d969aSHuazhong Tan { 3133862d969aSHuazhong Tan struct pci_dev *pdev = hdev->pdev; 3134862d969aSHuazhong Tan int ret = 0; 3135862d969aSHuazhong Tan 3136862d969aSHuazhong Tan if (hdev->reset_type == HNAE3_VF_FULL_RESET && 3137862d969aSHuazhong Tan test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { 3138862d969aSHuazhong Tan hclgevf_misc_irq_uninit(hdev); 3139862d969aSHuazhong Tan hclgevf_uninit_msi(hdev); 3140862d969aSHuazhong Tan clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state); 3141862d969aSHuazhong Tan } 3142862d969aSHuazhong Tan 3143862d969aSHuazhong Tan if (!test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { 3144862d969aSHuazhong Tan pci_set_master(pdev); 3145862d969aSHuazhong Tan ret = hclgevf_init_msi(hdev); 3146862d969aSHuazhong Tan if (ret) { 3147862d969aSHuazhong Tan dev_err(&pdev->dev, 3148862d969aSHuazhong Tan "failed(%d) to init MSI/MSI-X\n", ret); 3149862d969aSHuazhong Tan return ret; 3150862d969aSHuazhong Tan } 3151862d969aSHuazhong Tan 3152862d969aSHuazhong Tan ret = hclgevf_misc_irq_init(hdev); 3153862d969aSHuazhong Tan if (ret) { 3154862d969aSHuazhong Tan hclgevf_uninit_msi(hdev); 3155862d969aSHuazhong Tan dev_err(&pdev->dev, "failed(%d) to init Misc IRQ(vector0)\n", 3156862d969aSHuazhong Tan ret); 3157862d969aSHuazhong Tan return ret; 3158862d969aSHuazhong Tan } 3159862d969aSHuazhong Tan 3160862d969aSHuazhong Tan set_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state); 3161862d969aSHuazhong Tan } 3162862d969aSHuazhong Tan 3163862d969aSHuazhong Tan return ret; 3164862d969aSHuazhong Tan } 3165862d969aSHuazhong Tan 3166039ba863SJian Shen static int hclgevf_clear_vport_list(struct hclgevf_dev *hdev) 3167039ba863SJian Shen { 3168039ba863SJian Shen struct hclge_vf_to_pf_msg send_msg; 3169039ba863SJian Shen 3170039ba863SJian Shen hclgevf_build_send_msg(&send_msg, HCLGE_MBX_HANDLE_VF_TBL, 3171039ba863SJian Shen HCLGE_MBX_VPORT_LIST_CLEAR); 3172039ba863SJian Shen return hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 3173039ba863SJian Shen } 3174039ba863SJian Shen 31759c6f7085SHuazhong Tan static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) 3176e2cb1decSSalil Mehta { 31777a01c897SSalil Mehta struct pci_dev *pdev = hdev->pdev; 3178e2cb1decSSalil Mehta int ret; 3179e2cb1decSSalil Mehta 3180862d969aSHuazhong Tan ret = hclgevf_pci_reset(hdev); 3181862d969aSHuazhong Tan if (ret) { 3182862d969aSHuazhong Tan dev_err(&pdev->dev, "pci reset failed %d\n", ret); 3183862d969aSHuazhong Tan return ret; 3184862d969aSHuazhong Tan } 3185862d969aSHuazhong Tan 31869c6f7085SHuazhong Tan ret = hclgevf_cmd_init(hdev); 31879c6f7085SHuazhong Tan if (ret) { 31889c6f7085SHuazhong Tan dev_err(&pdev->dev, "cmd failed %d\n", ret); 31899c6f7085SHuazhong Tan return ret; 31907a01c897SSalil Mehta } 3191e2cb1decSSalil Mehta 31929c6f7085SHuazhong Tan ret = hclgevf_rss_init_hw(hdev); 31939c6f7085SHuazhong Tan if (ret) { 31949c6f7085SHuazhong Tan dev_err(&hdev->pdev->dev, 31959c6f7085SHuazhong Tan "failed(%d) to initialize RSS\n", ret); 31969c6f7085SHuazhong Tan return ret; 31979c6f7085SHuazhong Tan } 31989c6f7085SHuazhong Tan 3199b26a6feaSPeng Li ret = hclgevf_config_gro(hdev, true); 3200b26a6feaSPeng Li if (ret) 3201b26a6feaSPeng Li return ret; 3202b26a6feaSPeng Li 32039c6f7085SHuazhong Tan ret = hclgevf_init_vlan_config(hdev); 32049c6f7085SHuazhong Tan if (ret) { 32059c6f7085SHuazhong Tan dev_err(&hdev->pdev->dev, 32069c6f7085SHuazhong Tan "failed(%d) to initialize VLAN config\n", ret); 32079c6f7085SHuazhong Tan return ret; 32089c6f7085SHuazhong Tan } 32099c6f7085SHuazhong Tan 3210c631c696SJian Shen set_bit(HCLGEVF_STATE_PROMISC_CHANGED, &hdev->state); 3211c631c696SJian Shen 32129c6f7085SHuazhong Tan dev_info(&hdev->pdev->dev, "Reset done\n"); 32139c6f7085SHuazhong Tan 32149c6f7085SHuazhong Tan return 0; 32159c6f7085SHuazhong Tan } 32169c6f7085SHuazhong Tan 32179c6f7085SHuazhong Tan static int hclgevf_init_hdev(struct hclgevf_dev *hdev) 32189c6f7085SHuazhong Tan { 32199c6f7085SHuazhong Tan struct pci_dev *pdev = hdev->pdev; 32209c6f7085SHuazhong Tan int ret; 32219c6f7085SHuazhong Tan 3222e2cb1decSSalil Mehta ret = hclgevf_pci_init(hdev); 322360df7e91SHuazhong Tan if (ret) 3224e2cb1decSSalil Mehta return ret; 3225e2cb1decSSalil Mehta 32268b0195a3SHuazhong Tan ret = hclgevf_cmd_queue_init(hdev); 322760df7e91SHuazhong Tan if (ret) 32288b0195a3SHuazhong Tan goto err_cmd_queue_init; 32298b0195a3SHuazhong Tan 3230eddf0462SYunsheng Lin ret = hclgevf_cmd_init(hdev); 3231eddf0462SYunsheng Lin if (ret) 3232eddf0462SYunsheng Lin goto err_cmd_init; 3233eddf0462SYunsheng Lin 323407acf909SJian Shen /* Get vf resource */ 323507acf909SJian Shen ret = hclgevf_query_vf_resource(hdev); 323660df7e91SHuazhong Tan if (ret) 32378b0195a3SHuazhong Tan goto err_cmd_init; 323807acf909SJian Shen 3239af2aedc5SGuangbin Huang ret = hclgevf_query_dev_specs(hdev); 3240af2aedc5SGuangbin Huang if (ret) { 3241af2aedc5SGuangbin Huang dev_err(&pdev->dev, 3242af2aedc5SGuangbin Huang "failed to query dev specifications, ret = %d\n", ret); 3243af2aedc5SGuangbin Huang goto err_cmd_init; 3244af2aedc5SGuangbin Huang } 3245af2aedc5SGuangbin Huang 324607acf909SJian Shen ret = hclgevf_init_msi(hdev); 324707acf909SJian Shen if (ret) { 324807acf909SJian Shen dev_err(&pdev->dev, "failed(%d) to init MSI/MSI-X\n", ret); 32498b0195a3SHuazhong Tan goto err_cmd_init; 325007acf909SJian Shen } 325107acf909SJian Shen 325207acf909SJian Shen hclgevf_state_init(hdev); 3253dea846e8SHuazhong Tan hdev->reset_level = HNAE3_VF_FUNC_RESET; 3254afb6afdbSHuazhong Tan hdev->reset_type = HNAE3_NONE_RESET; 325507acf909SJian Shen 3256e2cb1decSSalil Mehta ret = hclgevf_misc_irq_init(hdev); 325760df7e91SHuazhong Tan if (ret) 3258e2cb1decSSalil Mehta goto err_misc_irq_init; 3259e2cb1decSSalil Mehta 3260862d969aSHuazhong Tan set_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state); 3261862d969aSHuazhong Tan 3262e2cb1decSSalil Mehta ret = hclgevf_configure(hdev); 3263e2cb1decSSalil Mehta if (ret) { 3264e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", ret); 3265e2cb1decSSalil Mehta goto err_config; 3266e2cb1decSSalil Mehta } 3267e2cb1decSSalil Mehta 3268e2cb1decSSalil Mehta ret = hclgevf_alloc_tqps(hdev); 3269e2cb1decSSalil Mehta if (ret) { 3270e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to allocate TQPs\n", ret); 3271e2cb1decSSalil Mehta goto err_config; 3272e2cb1decSSalil Mehta } 3273e2cb1decSSalil Mehta 3274e2cb1decSSalil Mehta ret = hclgevf_set_handle_info(hdev); 327560df7e91SHuazhong Tan if (ret) 3276e2cb1decSSalil Mehta goto err_config; 3277e2cb1decSSalil Mehta 3278b26a6feaSPeng Li ret = hclgevf_config_gro(hdev, true); 3279b26a6feaSPeng Li if (ret) 3280b26a6feaSPeng Li goto err_config; 3281b26a6feaSPeng Li 3282e2cb1decSSalil Mehta /* Initialize RSS for this VF */ 328387ce161eSGuangbin Huang ret = hclgevf_rss_init_cfg(hdev); 328487ce161eSGuangbin Huang if (ret) { 328587ce161eSGuangbin Huang dev_err(&pdev->dev, "failed to init rss cfg, ret = %d\n", ret); 328687ce161eSGuangbin Huang goto err_config; 328787ce161eSGuangbin Huang } 328887ce161eSGuangbin Huang 3289e2cb1decSSalil Mehta ret = hclgevf_rss_init_hw(hdev); 3290e2cb1decSSalil Mehta if (ret) { 3291e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 3292e2cb1decSSalil Mehta "failed(%d) to initialize RSS\n", ret); 3293e2cb1decSSalil Mehta goto err_config; 3294e2cb1decSSalil Mehta } 3295e2cb1decSSalil Mehta 3296039ba863SJian Shen /* ensure vf tbl list as empty before init*/ 3297039ba863SJian Shen ret = hclgevf_clear_vport_list(hdev); 3298039ba863SJian Shen if (ret) { 3299039ba863SJian Shen dev_err(&pdev->dev, 3300039ba863SJian Shen "failed to clear tbl list configuration, ret = %d.\n", 3301039ba863SJian Shen ret); 3302039ba863SJian Shen goto err_config; 3303039ba863SJian Shen } 3304039ba863SJian Shen 3305e2cb1decSSalil Mehta ret = hclgevf_init_vlan_config(hdev); 3306e2cb1decSSalil Mehta if (ret) { 3307e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 3308e2cb1decSSalil Mehta "failed(%d) to initialize VLAN config\n", ret); 3309e2cb1decSSalil Mehta goto err_config; 3310e2cb1decSSalil Mehta } 3311e2cb1decSSalil Mehta 33120742ed7cSHuazhong Tan hdev->last_reset_time = jiffies; 331308d80a4cSHuazhong Tan dev_info(&hdev->pdev->dev, "finished initializing %s driver\n", 331408d80a4cSHuazhong Tan HCLGEVF_DRIVER_NAME); 3315e2cb1decSSalil Mehta 3316ff200099SYunsheng Lin hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); 3317ff200099SYunsheng Lin 3318e2cb1decSSalil Mehta return 0; 3319e2cb1decSSalil Mehta 3320e2cb1decSSalil Mehta err_config: 3321e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 3322e2cb1decSSalil Mehta err_misc_irq_init: 3323e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 3324e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 332507acf909SJian Shen err_cmd_init: 33268b0195a3SHuazhong Tan hclgevf_cmd_uninit(hdev); 33278b0195a3SHuazhong Tan err_cmd_queue_init: 3328e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 3329862d969aSHuazhong Tan clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state); 3330e2cb1decSSalil Mehta return ret; 3331e2cb1decSSalil Mehta } 3332e2cb1decSSalil Mehta 33337a01c897SSalil Mehta static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev) 3334e2cb1decSSalil Mehta { 3335d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 3336d3410018SYufeng Mo 3337e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 3338862d969aSHuazhong Tan 3339d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_VF_UNINIT, 0); 3340d3410018SYufeng Mo hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 334123b4201dSJian Shen 3342862d969aSHuazhong Tan if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { 3343eddf0462SYunsheng Lin hclgevf_misc_irq_uninit(hdev); 3344e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 33457a01c897SSalil Mehta } 33467a01c897SSalil Mehta 3347862d969aSHuazhong Tan hclgevf_cmd_uninit(hdev); 3348e3364c5fSZenghui Yu hclgevf_pci_uninit(hdev); 3349ee4bcd3bSJian Shen hclgevf_uninit_mac_list(hdev); 3350862d969aSHuazhong Tan } 3351862d969aSHuazhong Tan 33527a01c897SSalil Mehta static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) 33537a01c897SSalil Mehta { 33547a01c897SSalil Mehta struct pci_dev *pdev = ae_dev->pdev; 33557a01c897SSalil Mehta int ret; 33567a01c897SSalil Mehta 33577a01c897SSalil Mehta ret = hclgevf_alloc_hdev(ae_dev); 33587a01c897SSalil Mehta if (ret) { 33597a01c897SSalil Mehta dev_err(&pdev->dev, "hclge device allocation failed\n"); 33607a01c897SSalil Mehta return ret; 33617a01c897SSalil Mehta } 33627a01c897SSalil Mehta 33637a01c897SSalil Mehta ret = hclgevf_init_hdev(ae_dev->priv); 3364a6d818e3SYunsheng Lin if (ret) { 33657a01c897SSalil Mehta dev_err(&pdev->dev, "hclge device initialization failed\n"); 33667a01c897SSalil Mehta return ret; 33677a01c897SSalil Mehta } 33687a01c897SSalil Mehta 3369a6d818e3SYunsheng Lin return 0; 3370a6d818e3SYunsheng Lin } 3371a6d818e3SYunsheng Lin 33727a01c897SSalil Mehta static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) 33737a01c897SSalil Mehta { 33747a01c897SSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 33757a01c897SSalil Mehta 33767a01c897SSalil Mehta hclgevf_uninit_hdev(hdev); 3377e2cb1decSSalil Mehta ae_dev->priv = NULL; 3378e2cb1decSSalil Mehta } 3379e2cb1decSSalil Mehta 3380849e4607SPeng Li static u32 hclgevf_get_max_channels(struct hclgevf_dev *hdev) 3381849e4607SPeng Li { 3382849e4607SPeng Li struct hnae3_handle *nic = &hdev->nic; 3383849e4607SPeng Li struct hnae3_knic_private_info *kinfo = &nic->kinfo; 3384849e4607SPeng Li 33858be73621SHuazhong Tan return min_t(u32, hdev->rss_size_max, 338635244430SJian Shen hdev->num_tqps / kinfo->tc_info.num_tc); 3387849e4607SPeng Li } 3388849e4607SPeng Li 3389849e4607SPeng Li /** 3390849e4607SPeng Li * hclgevf_get_channels - Get the current channels enabled and max supported. 3391849e4607SPeng Li * @handle: hardware information for network interface 3392849e4607SPeng Li * @ch: ethtool channels structure 3393849e4607SPeng Li * 3394849e4607SPeng Li * We don't support separate tx and rx queues as channels. The other count 3395849e4607SPeng Li * represents how many queues are being used for control. max_combined counts 3396849e4607SPeng Li * how many queue pairs we can support. They may not be mapped 1 to 1 with 3397849e4607SPeng Li * q_vectors since we support a lot more queue pairs than q_vectors. 3398849e4607SPeng Li **/ 3399849e4607SPeng Li static void hclgevf_get_channels(struct hnae3_handle *handle, 3400849e4607SPeng Li struct ethtool_channels *ch) 3401849e4607SPeng Li { 3402849e4607SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 3403849e4607SPeng Li 3404849e4607SPeng Li ch->max_combined = hclgevf_get_max_channels(hdev); 3405849e4607SPeng Li ch->other_count = 0; 3406849e4607SPeng Li ch->max_other = 0; 34078be73621SHuazhong Tan ch->combined_count = handle->kinfo.rss_size; 3408849e4607SPeng Li } 3409849e4607SPeng Li 3410cc719218SPeng Li static void hclgevf_get_tqps_and_rss_info(struct hnae3_handle *handle, 34110d43bf45SHuazhong Tan u16 *alloc_tqps, u16 *max_rss_size) 3412cc719218SPeng Li { 3413cc719218SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 3414cc719218SPeng Li 34150d43bf45SHuazhong Tan *alloc_tqps = hdev->num_tqps; 3416cc719218SPeng Li *max_rss_size = hdev->rss_size_max; 3417cc719218SPeng Li } 3418cc719218SPeng Li 34194093d1a2SGuangbin Huang static void hclgevf_update_rss_size(struct hnae3_handle *handle, 34204093d1a2SGuangbin Huang u32 new_tqps_num) 34214093d1a2SGuangbin Huang { 34224093d1a2SGuangbin Huang struct hnae3_knic_private_info *kinfo = &handle->kinfo; 34234093d1a2SGuangbin Huang struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 34244093d1a2SGuangbin Huang u16 max_rss_size; 34254093d1a2SGuangbin Huang 34264093d1a2SGuangbin Huang kinfo->req_rss_size = new_tqps_num; 34274093d1a2SGuangbin Huang 34284093d1a2SGuangbin Huang max_rss_size = min_t(u16, hdev->rss_size_max, 342935244430SJian Shen hdev->num_tqps / kinfo->tc_info.num_tc); 34304093d1a2SGuangbin Huang 34314093d1a2SGuangbin Huang /* Use the user's configuration when it is not larger than 34324093d1a2SGuangbin Huang * max_rss_size, otherwise, use the maximum specification value. 34334093d1a2SGuangbin Huang */ 34344093d1a2SGuangbin Huang if (kinfo->req_rss_size != kinfo->rss_size && kinfo->req_rss_size && 34354093d1a2SGuangbin Huang kinfo->req_rss_size <= max_rss_size) 34364093d1a2SGuangbin Huang kinfo->rss_size = kinfo->req_rss_size; 34374093d1a2SGuangbin Huang else if (kinfo->rss_size > max_rss_size || 34384093d1a2SGuangbin Huang (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) 34394093d1a2SGuangbin Huang kinfo->rss_size = max_rss_size; 34404093d1a2SGuangbin Huang 344135244430SJian Shen kinfo->num_tqps = kinfo->tc_info.num_tc * kinfo->rss_size; 34424093d1a2SGuangbin Huang } 34434093d1a2SGuangbin Huang 34444093d1a2SGuangbin Huang static int hclgevf_set_channels(struct hnae3_handle *handle, u32 new_tqps_num, 34454093d1a2SGuangbin Huang bool rxfh_configured) 34464093d1a2SGuangbin Huang { 34474093d1a2SGuangbin Huang struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 34484093d1a2SGuangbin Huang struct hnae3_knic_private_info *kinfo = &handle->kinfo; 34494093d1a2SGuangbin Huang u16 cur_rss_size = kinfo->rss_size; 34504093d1a2SGuangbin Huang u16 cur_tqps = kinfo->num_tqps; 34514093d1a2SGuangbin Huang u32 *rss_indir; 34524093d1a2SGuangbin Huang unsigned int i; 34534093d1a2SGuangbin Huang int ret; 34544093d1a2SGuangbin Huang 34554093d1a2SGuangbin Huang hclgevf_update_rss_size(handle, new_tqps_num); 34564093d1a2SGuangbin Huang 34574093d1a2SGuangbin Huang ret = hclgevf_set_rss_tc_mode(hdev, kinfo->rss_size); 34584093d1a2SGuangbin Huang if (ret) 34594093d1a2SGuangbin Huang return ret; 34604093d1a2SGuangbin Huang 34614093d1a2SGuangbin Huang /* RSS indirection table has been configuared by user */ 34624093d1a2SGuangbin Huang if (rxfh_configured) 34634093d1a2SGuangbin Huang goto out; 34644093d1a2SGuangbin Huang 34654093d1a2SGuangbin Huang /* Reinitializes the rss indirect table according to the new RSS size */ 346687ce161eSGuangbin Huang rss_indir = kcalloc(hdev->ae_dev->dev_specs.rss_ind_tbl_size, 346787ce161eSGuangbin Huang sizeof(u32), GFP_KERNEL); 34684093d1a2SGuangbin Huang if (!rss_indir) 34694093d1a2SGuangbin Huang return -ENOMEM; 34704093d1a2SGuangbin Huang 347187ce161eSGuangbin Huang for (i = 0; i < hdev->ae_dev->dev_specs.rss_ind_tbl_size; i++) 34724093d1a2SGuangbin Huang rss_indir[i] = i % kinfo->rss_size; 34734093d1a2SGuangbin Huang 3474944de484SGuojia Liao hdev->rss_cfg.rss_size = kinfo->rss_size; 3475944de484SGuojia Liao 34764093d1a2SGuangbin Huang ret = hclgevf_set_rss(handle, rss_indir, NULL, 0); 34774093d1a2SGuangbin Huang if (ret) 34784093d1a2SGuangbin Huang dev_err(&hdev->pdev->dev, "set rss indir table fail, ret=%d\n", 34794093d1a2SGuangbin Huang ret); 34804093d1a2SGuangbin Huang 34814093d1a2SGuangbin Huang kfree(rss_indir); 34824093d1a2SGuangbin Huang 34834093d1a2SGuangbin Huang out: 34844093d1a2SGuangbin Huang if (!ret) 34854093d1a2SGuangbin Huang dev_info(&hdev->pdev->dev, 34864093d1a2SGuangbin Huang "Channels changed, rss_size from %u to %u, tqps from %u to %u", 34874093d1a2SGuangbin Huang cur_rss_size, kinfo->rss_size, 348835244430SJian Shen cur_tqps, kinfo->rss_size * kinfo->tc_info.num_tc); 34894093d1a2SGuangbin Huang 34904093d1a2SGuangbin Huang return ret; 34914093d1a2SGuangbin Huang } 34924093d1a2SGuangbin Huang 3493175ec96bSFuyun Liang static int hclgevf_get_status(struct hnae3_handle *handle) 3494175ec96bSFuyun Liang { 3495175ec96bSFuyun Liang struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 3496175ec96bSFuyun Liang 3497175ec96bSFuyun Liang return hdev->hw.mac.link; 3498175ec96bSFuyun Liang } 3499175ec96bSFuyun Liang 35004a152de9SFuyun Liang static void hclgevf_get_ksettings_an_result(struct hnae3_handle *handle, 35014a152de9SFuyun Liang u8 *auto_neg, u32 *speed, 35024a152de9SFuyun Liang u8 *duplex) 35034a152de9SFuyun Liang { 35044a152de9SFuyun Liang struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35054a152de9SFuyun Liang 35064a152de9SFuyun Liang if (speed) 35074a152de9SFuyun Liang *speed = hdev->hw.mac.speed; 35084a152de9SFuyun Liang if (duplex) 35094a152de9SFuyun Liang *duplex = hdev->hw.mac.duplex; 35104a152de9SFuyun Liang if (auto_neg) 35114a152de9SFuyun Liang *auto_neg = AUTONEG_DISABLE; 35124a152de9SFuyun Liang } 35134a152de9SFuyun Liang 35144a152de9SFuyun Liang void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed, 35154a152de9SFuyun Liang u8 duplex) 35164a152de9SFuyun Liang { 35174a152de9SFuyun Liang hdev->hw.mac.speed = speed; 35184a152de9SFuyun Liang hdev->hw.mac.duplex = duplex; 35194a152de9SFuyun Liang } 35204a152de9SFuyun Liang 35211731be4cSYonglong Liu static int hclgevf_gro_en(struct hnae3_handle *handle, bool enable) 35225c9f6b39SPeng Li { 35235c9f6b39SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35245c9f6b39SPeng Li 35255c9f6b39SPeng Li return hclgevf_config_gro(hdev, enable); 35265c9f6b39SPeng Li } 35275c9f6b39SPeng Li 352888d10bd6SJian Shen static void hclgevf_get_media_type(struct hnae3_handle *handle, u8 *media_type, 352988d10bd6SJian Shen u8 *module_type) 3530c136b884SPeng Li { 3531c136b884SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 353288d10bd6SJian Shen 3533c136b884SPeng Li if (media_type) 3534c136b884SPeng Li *media_type = hdev->hw.mac.media_type; 353588d10bd6SJian Shen 353688d10bd6SJian Shen if (module_type) 353788d10bd6SJian Shen *module_type = hdev->hw.mac.module_type; 3538c136b884SPeng Li } 3539c136b884SPeng Li 35404d60291bSHuazhong Tan static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle) 35414d60291bSHuazhong Tan { 35424d60291bSHuazhong Tan struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35434d60291bSHuazhong Tan 3544aa5c4f17SHuazhong Tan return !!hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); 35454d60291bSHuazhong Tan } 35464d60291bSHuazhong Tan 3547fe735c84SHuazhong Tan static bool hclgevf_get_cmdq_stat(struct hnae3_handle *handle) 3548fe735c84SHuazhong Tan { 3549fe735c84SHuazhong Tan struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 3550fe735c84SHuazhong Tan 3551fe735c84SHuazhong Tan return test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); 3552fe735c84SHuazhong Tan } 3553fe735c84SHuazhong Tan 35544d60291bSHuazhong Tan static bool hclgevf_ae_dev_resetting(struct hnae3_handle *handle) 35554d60291bSHuazhong Tan { 35564d60291bSHuazhong Tan struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35574d60291bSHuazhong Tan 35584d60291bSHuazhong Tan return test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 35594d60291bSHuazhong Tan } 35604d60291bSHuazhong Tan 35614d60291bSHuazhong Tan static unsigned long hclgevf_ae_dev_reset_cnt(struct hnae3_handle *handle) 35624d60291bSHuazhong Tan { 35634d60291bSHuazhong Tan struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35644d60291bSHuazhong Tan 3565c88a6e7dSHuazhong Tan return hdev->rst_stats.hw_rst_done_cnt; 35664d60291bSHuazhong Tan } 35674d60291bSHuazhong Tan 35689194d18bSliuzhongzhu static void hclgevf_get_link_mode(struct hnae3_handle *handle, 35699194d18bSliuzhongzhu unsigned long *supported, 35709194d18bSliuzhongzhu unsigned long *advertising) 35719194d18bSliuzhongzhu { 35729194d18bSliuzhongzhu struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35739194d18bSliuzhongzhu 35749194d18bSliuzhongzhu *supported = hdev->hw.mac.supported; 35759194d18bSliuzhongzhu *advertising = hdev->hw.mac.advertising; 35769194d18bSliuzhongzhu } 35779194d18bSliuzhongzhu 35781600c3e5SJian Shen #define MAX_SEPARATE_NUM 4 35791600c3e5SJian Shen #define SEPARATOR_VALUE 0xFFFFFFFF 35801600c3e5SJian Shen #define REG_NUM_PER_LINE 4 35811600c3e5SJian Shen #define REG_LEN_PER_LINE (REG_NUM_PER_LINE * sizeof(u32)) 35821600c3e5SJian Shen 35831600c3e5SJian Shen static int hclgevf_get_regs_len(struct hnae3_handle *handle) 35841600c3e5SJian Shen { 35851600c3e5SJian Shen int cmdq_lines, common_lines, ring_lines, tqp_intr_lines; 35861600c3e5SJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 35871600c3e5SJian Shen 35881600c3e5SJian Shen cmdq_lines = sizeof(cmdq_reg_addr_list) / REG_LEN_PER_LINE + 1; 35891600c3e5SJian Shen common_lines = sizeof(common_reg_addr_list) / REG_LEN_PER_LINE + 1; 35901600c3e5SJian Shen ring_lines = sizeof(ring_reg_addr_list) / REG_LEN_PER_LINE + 1; 35911600c3e5SJian Shen tqp_intr_lines = sizeof(tqp_intr_reg_addr_list) / REG_LEN_PER_LINE + 1; 35921600c3e5SJian Shen 35931600c3e5SJian Shen return (cmdq_lines + common_lines + ring_lines * hdev->num_tqps + 35941600c3e5SJian Shen tqp_intr_lines * (hdev->num_msi_used - 1)) * REG_LEN_PER_LINE; 35951600c3e5SJian Shen } 35961600c3e5SJian Shen 35971600c3e5SJian Shen static void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, 35981600c3e5SJian Shen void *data) 35991600c3e5SJian Shen { 36001600c3e5SJian Shen struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 36011600c3e5SJian Shen int i, j, reg_um, separator_num; 36021600c3e5SJian Shen u32 *reg = data; 36031600c3e5SJian Shen 36041600c3e5SJian Shen *version = hdev->fw_version; 36051600c3e5SJian Shen 36061600c3e5SJian Shen /* fetching per-VF registers values from VF PCIe register space */ 36071600c3e5SJian Shen reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32); 36081600c3e5SJian Shen separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; 36091600c3e5SJian Shen for (i = 0; i < reg_um; i++) 36101600c3e5SJian Shen *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); 36111600c3e5SJian Shen for (i = 0; i < separator_num; i++) 36121600c3e5SJian Shen *reg++ = SEPARATOR_VALUE; 36131600c3e5SJian Shen 36141600c3e5SJian Shen reg_um = sizeof(common_reg_addr_list) / sizeof(u32); 36151600c3e5SJian Shen separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; 36161600c3e5SJian Shen for (i = 0; i < reg_um; i++) 36171600c3e5SJian Shen *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); 36181600c3e5SJian Shen for (i = 0; i < separator_num; i++) 36191600c3e5SJian Shen *reg++ = SEPARATOR_VALUE; 36201600c3e5SJian Shen 36211600c3e5SJian Shen reg_um = sizeof(ring_reg_addr_list) / sizeof(u32); 36221600c3e5SJian Shen separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; 36231600c3e5SJian Shen for (j = 0; j < hdev->num_tqps; j++) { 36241600c3e5SJian Shen for (i = 0; i < reg_um; i++) 36251600c3e5SJian Shen *reg++ = hclgevf_read_dev(&hdev->hw, 36261600c3e5SJian Shen ring_reg_addr_list[i] + 36271600c3e5SJian Shen 0x200 * j); 36281600c3e5SJian Shen for (i = 0; i < separator_num; i++) 36291600c3e5SJian Shen *reg++ = SEPARATOR_VALUE; 36301600c3e5SJian Shen } 36311600c3e5SJian Shen 36321600c3e5SJian Shen reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); 36331600c3e5SJian Shen separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; 36341600c3e5SJian Shen for (j = 0; j < hdev->num_msi_used - 1; j++) { 36351600c3e5SJian Shen for (i = 0; i < reg_um; i++) 36361600c3e5SJian Shen *reg++ = hclgevf_read_dev(&hdev->hw, 36371600c3e5SJian Shen tqp_intr_reg_addr_list[i] + 36381600c3e5SJian Shen 4 * j); 36391600c3e5SJian Shen for (i = 0; i < separator_num; i++) 36401600c3e5SJian Shen *reg++ = SEPARATOR_VALUE; 36411600c3e5SJian Shen } 36421600c3e5SJian Shen } 36431600c3e5SJian Shen 364492f11ea1SJian Shen void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state, 364592f11ea1SJian Shen u8 *port_base_vlan_info, u8 data_size) 364692f11ea1SJian Shen { 364792f11ea1SJian Shen struct hnae3_handle *nic = &hdev->nic; 3648d3410018SYufeng Mo struct hclge_vf_to_pf_msg send_msg; 3649a6f7bfdcSJian Shen int ret; 365092f11ea1SJian Shen 365192f11ea1SJian Shen rtnl_lock(); 3652a6f7bfdcSJian Shen 3653b7b5d25bSGuojia Liao if (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state) || 3654b7b5d25bSGuojia Liao test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) { 3655a6f7bfdcSJian Shen dev_warn(&hdev->pdev->dev, 3656a6f7bfdcSJian Shen "is resetting when updating port based vlan info\n"); 365792f11ea1SJian Shen rtnl_unlock(); 3658a6f7bfdcSJian Shen return; 3659a6f7bfdcSJian Shen } 3660a6f7bfdcSJian Shen 3661a6f7bfdcSJian Shen ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); 3662a6f7bfdcSJian Shen if (ret) { 3663a6f7bfdcSJian Shen rtnl_unlock(); 3664a6f7bfdcSJian Shen return; 3665a6f7bfdcSJian Shen } 366692f11ea1SJian Shen 366792f11ea1SJian Shen /* send msg to PF and wait update port based vlan info */ 3668d3410018SYufeng Mo hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, 3669d3410018SYufeng Mo HCLGE_MBX_PORT_BASE_VLAN_CFG); 3670d3410018SYufeng Mo memcpy(send_msg.data, port_base_vlan_info, data_size); 3671a6f7bfdcSJian Shen ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0); 3672a6f7bfdcSJian Shen if (!ret) { 367392f11ea1SJian Shen if (state == HNAE3_PORT_BASE_VLAN_DISABLE) 3674a6f7bfdcSJian Shen nic->port_base_vlan_state = state; 367592f11ea1SJian Shen else 367692f11ea1SJian Shen nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE; 3677a6f7bfdcSJian Shen } 367892f11ea1SJian Shen 367992f11ea1SJian Shen hclgevf_notify_client(hdev, HNAE3_UP_CLIENT); 368092f11ea1SJian Shen rtnl_unlock(); 368192f11ea1SJian Shen } 368292f11ea1SJian Shen 3683e2cb1decSSalil Mehta static const struct hnae3_ae_ops hclgevf_ops = { 3684e2cb1decSSalil Mehta .init_ae_dev = hclgevf_init_ae_dev, 3685e2cb1decSSalil Mehta .uninit_ae_dev = hclgevf_uninit_ae_dev, 36866ff3cf07SHuazhong Tan .flr_prepare = hclgevf_flr_prepare, 36876ff3cf07SHuazhong Tan .flr_done = hclgevf_flr_done, 3688e718a93fSPeng Li .init_client_instance = hclgevf_init_client_instance, 3689e718a93fSPeng Li .uninit_client_instance = hclgevf_uninit_client_instance, 3690e2cb1decSSalil Mehta .start = hclgevf_ae_start, 3691e2cb1decSSalil Mehta .stop = hclgevf_ae_stop, 3692a6d818e3SYunsheng Lin .client_start = hclgevf_client_start, 3693a6d818e3SYunsheng Lin .client_stop = hclgevf_client_stop, 3694e2cb1decSSalil Mehta .map_ring_to_vector = hclgevf_map_ring_to_vector, 3695e2cb1decSSalil Mehta .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector, 3696e2cb1decSSalil Mehta .get_vector = hclgevf_get_vector, 36970d3e6631SYunsheng Lin .put_vector = hclgevf_put_vector, 3698e2cb1decSSalil Mehta .reset_queue = hclgevf_reset_tqp, 3699e2cb1decSSalil Mehta .get_mac_addr = hclgevf_get_mac_addr, 3700e2cb1decSSalil Mehta .set_mac_addr = hclgevf_set_mac_addr, 3701e2cb1decSSalil Mehta .add_uc_addr = hclgevf_add_uc_addr, 3702e2cb1decSSalil Mehta .rm_uc_addr = hclgevf_rm_uc_addr, 3703e2cb1decSSalil Mehta .add_mc_addr = hclgevf_add_mc_addr, 3704e2cb1decSSalil Mehta .rm_mc_addr = hclgevf_rm_mc_addr, 3705e2cb1decSSalil Mehta .get_stats = hclgevf_get_stats, 3706e2cb1decSSalil Mehta .update_stats = hclgevf_update_stats, 3707e2cb1decSSalil Mehta .get_strings = hclgevf_get_strings, 3708e2cb1decSSalil Mehta .get_sset_count = hclgevf_get_sset_count, 3709e2cb1decSSalil Mehta .get_rss_key_size = hclgevf_get_rss_key_size, 3710e2cb1decSSalil Mehta .get_rss = hclgevf_get_rss, 3711e2cb1decSSalil Mehta .set_rss = hclgevf_set_rss, 3712d97b3072SJian Shen .get_rss_tuple = hclgevf_get_rss_tuple, 3713d97b3072SJian Shen .set_rss_tuple = hclgevf_set_rss_tuple, 3714e2cb1decSSalil Mehta .get_tc_size = hclgevf_get_tc_size, 3715e2cb1decSSalil Mehta .get_fw_version = hclgevf_get_fw_version, 3716e2cb1decSSalil Mehta .set_vlan_filter = hclgevf_set_vlan_filter, 3717b2641e2aSYunsheng Lin .enable_hw_strip_rxvtag = hclgevf_en_hw_strip_rxvtag, 37186d4c3981SSalil Mehta .reset_event = hclgevf_reset_event, 3719720bd583SHuazhong Tan .set_default_reset_request = hclgevf_set_def_reset_request, 37204093d1a2SGuangbin Huang .set_channels = hclgevf_set_channels, 3721849e4607SPeng Li .get_channels = hclgevf_get_channels, 3722cc719218SPeng Li .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info, 37231600c3e5SJian Shen .get_regs_len = hclgevf_get_regs_len, 37241600c3e5SJian Shen .get_regs = hclgevf_get_regs, 3725175ec96bSFuyun Liang .get_status = hclgevf_get_status, 37264a152de9SFuyun Liang .get_ksettings_an_result = hclgevf_get_ksettings_an_result, 3727c136b884SPeng Li .get_media_type = hclgevf_get_media_type, 37284d60291bSHuazhong Tan .get_hw_reset_stat = hclgevf_get_hw_reset_stat, 37294d60291bSHuazhong Tan .ae_dev_resetting = hclgevf_ae_dev_resetting, 37304d60291bSHuazhong Tan .ae_dev_reset_cnt = hclgevf_ae_dev_reset_cnt, 37315c9f6b39SPeng Li .set_gro_en = hclgevf_gro_en, 3732818f1675SYunsheng Lin .set_mtu = hclgevf_set_mtu, 37330c29d191Sliuzhongzhu .get_global_queue_id = hclgevf_get_qid_global, 37348cdb992fSJian Shen .set_timer_task = hclgevf_set_timer_task, 37359194d18bSliuzhongzhu .get_link_mode = hclgevf_get_link_mode, 3736e196ec75SJian Shen .set_promisc_mode = hclgevf_set_promisc_mode, 3737c631c696SJian Shen .request_update_promisc_mode = hclgevf_request_update_promisc_mode, 3738fe735c84SHuazhong Tan .get_cmdq_stat = hclgevf_get_cmdq_stat, 3739e2cb1decSSalil Mehta }; 3740e2cb1decSSalil Mehta 3741e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf = { 3742e2cb1decSSalil Mehta .ops = &hclgevf_ops, 3743e2cb1decSSalil Mehta .pdev_id_table = ae_algovf_pci_tbl, 3744e2cb1decSSalil Mehta }; 3745e2cb1decSSalil Mehta 3746e2cb1decSSalil Mehta static int hclgevf_init(void) 3747e2cb1decSSalil Mehta { 3748e2cb1decSSalil Mehta pr_info("%s is initializing\n", HCLGEVF_NAME); 3749e2cb1decSSalil Mehta 375016deaef2SYunsheng Lin hclgevf_wq = alloc_workqueue("%s", 0, 0, HCLGEVF_NAME); 37510ea68902SYunsheng Lin if (!hclgevf_wq) { 37520ea68902SYunsheng Lin pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME); 37530ea68902SYunsheng Lin return -ENOMEM; 37540ea68902SYunsheng Lin } 37550ea68902SYunsheng Lin 3756854cf33aSFuyun Liang hnae3_register_ae_algo(&ae_algovf); 3757854cf33aSFuyun Liang 3758854cf33aSFuyun Liang return 0; 3759e2cb1decSSalil Mehta } 3760e2cb1decSSalil Mehta 3761e2cb1decSSalil Mehta static void hclgevf_exit(void) 3762e2cb1decSSalil Mehta { 3763e2cb1decSSalil Mehta hnae3_unregister_ae_algo(&ae_algovf); 37640ea68902SYunsheng Lin destroy_workqueue(hclgevf_wq); 3765e2cb1decSSalil Mehta } 3766e2cb1decSSalil Mehta module_init(hclgevf_init); 3767e2cb1decSSalil Mehta module_exit(hclgevf_exit); 3768e2cb1decSSalil Mehta 3769e2cb1decSSalil Mehta MODULE_LICENSE("GPL"); 3770e2cb1decSSalil Mehta MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 3771e2cb1decSSalil Mehta MODULE_DESCRIPTION("HCLGEVF Driver"); 3772e2cb1decSSalil Mehta MODULE_VERSION(HCLGEVF_MOD_VERSION); 3773