1e2cb1decSSalil Mehta // SPDX-License-Identifier: GPL-2.0+ 2e2cb1decSSalil Mehta // Copyright (c) 2016-2017 Hisilicon Limited. 3e2cb1decSSalil Mehta 4e2cb1decSSalil Mehta #include <linux/etherdevice.h> 5e2cb1decSSalil Mehta #include "hclgevf_cmd.h" 6e2cb1decSSalil Mehta #include "hclgevf_main.h" 7e2cb1decSSalil Mehta #include "hclge_mbx.h" 8e2cb1decSSalil Mehta #include "hnae3.h" 9e2cb1decSSalil Mehta 10e2cb1decSSalil Mehta #define HCLGEVF_NAME "hclgevf" 11e2cb1decSSalil Mehta 12e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf; 13e2cb1decSSalil Mehta 14e2cb1decSSalil Mehta static const struct pci_device_id ae_algovf_pci_tbl[] = { 15e2cb1decSSalil Mehta {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_VF), 0}, 16e2cb1decSSalil Mehta {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF), 0}, 17e2cb1decSSalil Mehta /* required last entry */ 18e2cb1decSSalil Mehta {0, } 19e2cb1decSSalil Mehta }; 20e2cb1decSSalil Mehta 21e2cb1decSSalil Mehta static inline struct hclgevf_dev *hclgevf_ae_get_hdev( 22e2cb1decSSalil Mehta struct hnae3_handle *handle) 23e2cb1decSSalil Mehta { 24e2cb1decSSalil Mehta return container_of(handle, struct hclgevf_dev, nic); 25e2cb1decSSalil Mehta } 26e2cb1decSSalil Mehta 27e2cb1decSSalil Mehta static int hclgevf_tqps_update_stats(struct hnae3_handle *handle) 28e2cb1decSSalil Mehta { 29e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 30e2cb1decSSalil Mehta struct hnae3_queue *queue; 31e2cb1decSSalil Mehta struct hclgevf_desc desc; 32e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 33e2cb1decSSalil Mehta int status; 34e2cb1decSSalil Mehta int i; 35e2cb1decSSalil Mehta 36e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 37e2cb1decSSalil Mehta queue = handle->kinfo.tqp[i]; 38e2cb1decSSalil Mehta tqp = container_of(queue, struct hclgevf_tqp, q); 39e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 40e2cb1decSSalil Mehta HCLGEVF_OPC_QUERY_RX_STATUS, 41e2cb1decSSalil Mehta true); 42e2cb1decSSalil Mehta 43e2cb1decSSalil Mehta desc.data[0] = cpu_to_le32(tqp->index & 0x1ff); 44e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 45e2cb1decSSalil Mehta if (status) { 46e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 47e2cb1decSSalil Mehta "Query tqp stat fail, status = %d,queue = %d\n", 48e2cb1decSSalil Mehta status, i); 49e2cb1decSSalil Mehta return status; 50e2cb1decSSalil Mehta } 51e2cb1decSSalil Mehta tqp->tqp_stats.rcb_rx_ring_pktnum_rcd += 52e2cb1decSSalil Mehta le32_to_cpu(desc.data[4]); 53e2cb1decSSalil Mehta 54e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_QUERY_TX_STATUS, 55e2cb1decSSalil Mehta true); 56e2cb1decSSalil Mehta 57e2cb1decSSalil Mehta desc.data[0] = cpu_to_le32(tqp->index & 0x1ff); 58e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 59e2cb1decSSalil Mehta if (status) { 60e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 61e2cb1decSSalil Mehta "Query tqp stat fail, status = %d,queue = %d\n", 62e2cb1decSSalil Mehta status, i); 63e2cb1decSSalil Mehta return status; 64e2cb1decSSalil Mehta } 65e2cb1decSSalil Mehta tqp->tqp_stats.rcb_tx_ring_pktnum_rcd += 66e2cb1decSSalil Mehta le32_to_cpu(desc.data[4]); 67e2cb1decSSalil Mehta } 68e2cb1decSSalil Mehta 69e2cb1decSSalil Mehta return 0; 70e2cb1decSSalil Mehta } 71e2cb1decSSalil Mehta 72e2cb1decSSalil Mehta static u64 *hclgevf_tqps_get_stats(struct hnae3_handle *handle, u64 *data) 73e2cb1decSSalil Mehta { 74e2cb1decSSalil Mehta struct hnae3_knic_private_info *kinfo = &handle->kinfo; 75e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 76e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 77e2cb1decSSalil Mehta u64 *buff = data; 78e2cb1decSSalil Mehta int i; 79e2cb1decSSalil Mehta 80e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 81e2cb1decSSalil Mehta tqp = container_of(handle->kinfo.tqp[i], struct hclgevf_tqp, q); 82e2cb1decSSalil Mehta *buff++ = tqp->tqp_stats.rcb_tx_ring_pktnum_rcd; 83e2cb1decSSalil Mehta } 84e2cb1decSSalil Mehta for (i = 0; i < kinfo->num_tqps; i++) { 85e2cb1decSSalil Mehta tqp = container_of(handle->kinfo.tqp[i], struct hclgevf_tqp, q); 86e2cb1decSSalil Mehta *buff++ = tqp->tqp_stats.rcb_rx_ring_pktnum_rcd; 87e2cb1decSSalil Mehta } 88e2cb1decSSalil Mehta 89e2cb1decSSalil Mehta return buff; 90e2cb1decSSalil Mehta } 91e2cb1decSSalil Mehta 92e2cb1decSSalil Mehta static int hclgevf_tqps_get_sset_count(struct hnae3_handle *handle, int strset) 93e2cb1decSSalil Mehta { 94e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 95e2cb1decSSalil Mehta 96e2cb1decSSalil Mehta return hdev->num_tqps * 2; 97e2cb1decSSalil Mehta } 98e2cb1decSSalil Mehta 99e2cb1decSSalil Mehta static u8 *hclgevf_tqps_get_strings(struct hnae3_handle *handle, u8 *data) 100e2cb1decSSalil Mehta { 101e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 102e2cb1decSSalil Mehta u8 *buff = data; 103e2cb1decSSalil Mehta int i = 0; 104e2cb1decSSalil Mehta 105e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 106e2cb1decSSalil Mehta struct hclgevf_tqp *tqp = container_of(handle->kinfo.tqp[i], 107e2cb1decSSalil Mehta struct hclgevf_tqp, q); 108e2cb1decSSalil Mehta snprintf(buff, ETH_GSTRING_LEN, "rcb_q%d_tx_pktnum_rcd", 109e2cb1decSSalil Mehta tqp->index); 110e2cb1decSSalil Mehta buff += ETH_GSTRING_LEN; 111e2cb1decSSalil Mehta } 112e2cb1decSSalil Mehta 113e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 114e2cb1decSSalil Mehta struct hclgevf_tqp *tqp = container_of(handle->kinfo.tqp[i], 115e2cb1decSSalil Mehta struct hclgevf_tqp, q); 116e2cb1decSSalil Mehta snprintf(buff, ETH_GSTRING_LEN, "rcb_q%d_rx_pktnum_rcd", 117e2cb1decSSalil Mehta tqp->index); 118e2cb1decSSalil Mehta buff += ETH_GSTRING_LEN; 119e2cb1decSSalil Mehta } 120e2cb1decSSalil Mehta 121e2cb1decSSalil Mehta return buff; 122e2cb1decSSalil Mehta } 123e2cb1decSSalil Mehta 124e2cb1decSSalil Mehta static void hclgevf_update_stats(struct hnae3_handle *handle, 125e2cb1decSSalil Mehta struct net_device_stats *net_stats) 126e2cb1decSSalil Mehta { 127e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 128e2cb1decSSalil Mehta int status; 129e2cb1decSSalil Mehta 130e2cb1decSSalil Mehta status = hclgevf_tqps_update_stats(handle); 131e2cb1decSSalil Mehta if (status) 132e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 133e2cb1decSSalil Mehta "VF update of TQPS stats fail, status = %d.\n", 134e2cb1decSSalil Mehta status); 135e2cb1decSSalil Mehta } 136e2cb1decSSalil Mehta 137e2cb1decSSalil Mehta static int hclgevf_get_sset_count(struct hnae3_handle *handle, int strset) 138e2cb1decSSalil Mehta { 139e2cb1decSSalil Mehta if (strset == ETH_SS_TEST) 140e2cb1decSSalil Mehta return -EOPNOTSUPP; 141e2cb1decSSalil Mehta else if (strset == ETH_SS_STATS) 142e2cb1decSSalil Mehta return hclgevf_tqps_get_sset_count(handle, strset); 143e2cb1decSSalil Mehta 144e2cb1decSSalil Mehta return 0; 145e2cb1decSSalil Mehta } 146e2cb1decSSalil Mehta 147e2cb1decSSalil Mehta static void hclgevf_get_strings(struct hnae3_handle *handle, u32 strset, 148e2cb1decSSalil Mehta u8 *data) 149e2cb1decSSalil Mehta { 150e2cb1decSSalil Mehta u8 *p = (char *)data; 151e2cb1decSSalil Mehta 152e2cb1decSSalil Mehta if (strset == ETH_SS_STATS) 153e2cb1decSSalil Mehta p = hclgevf_tqps_get_strings(handle, p); 154e2cb1decSSalil Mehta } 155e2cb1decSSalil Mehta 156e2cb1decSSalil Mehta static void hclgevf_get_stats(struct hnae3_handle *handle, u64 *data) 157e2cb1decSSalil Mehta { 158e2cb1decSSalil Mehta hclgevf_tqps_get_stats(handle, data); 159e2cb1decSSalil Mehta } 160e2cb1decSSalil Mehta 161e2cb1decSSalil Mehta static int hclgevf_get_tc_info(struct hclgevf_dev *hdev) 162e2cb1decSSalil Mehta { 163e2cb1decSSalil Mehta u8 resp_msg; 164e2cb1decSSalil Mehta int status; 165e2cb1decSSalil Mehta 166e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_TCINFO, 0, NULL, 0, 167e2cb1decSSalil Mehta true, &resp_msg, sizeof(u8)); 168e2cb1decSSalil Mehta if (status) { 169e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 170e2cb1decSSalil Mehta "VF request to get TC info from PF failed %d", 171e2cb1decSSalil Mehta status); 172e2cb1decSSalil Mehta return status; 173e2cb1decSSalil Mehta } 174e2cb1decSSalil Mehta 175e2cb1decSSalil Mehta hdev->hw_tc_map = resp_msg; 176e2cb1decSSalil Mehta 177e2cb1decSSalil Mehta return 0; 178e2cb1decSSalil Mehta } 179e2cb1decSSalil Mehta 180e2cb1decSSalil Mehta static int hclge_get_queue_info(struct hclgevf_dev *hdev) 181e2cb1decSSalil Mehta { 182e2cb1decSSalil Mehta #define HCLGEVF_TQPS_RSS_INFO_LEN 8 183e2cb1decSSalil Mehta u8 resp_msg[HCLGEVF_TQPS_RSS_INFO_LEN]; 184e2cb1decSSalil Mehta int status; 185e2cb1decSSalil Mehta 186e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_QINFO, 0, NULL, 0, 187e2cb1decSSalil Mehta true, resp_msg, 188e2cb1decSSalil Mehta HCLGEVF_TQPS_RSS_INFO_LEN); 189e2cb1decSSalil Mehta if (status) { 190e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 191e2cb1decSSalil Mehta "VF request to get tqp info from PF failed %d", 192e2cb1decSSalil Mehta status); 193e2cb1decSSalil Mehta return status; 194e2cb1decSSalil Mehta } 195e2cb1decSSalil Mehta 196e2cb1decSSalil Mehta memcpy(&hdev->num_tqps, &resp_msg[0], sizeof(u16)); 197e2cb1decSSalil Mehta memcpy(&hdev->rss_size_max, &resp_msg[2], sizeof(u16)); 198e2cb1decSSalil Mehta memcpy(&hdev->num_desc, &resp_msg[4], sizeof(u16)); 199e2cb1decSSalil Mehta memcpy(&hdev->rx_buf_len, &resp_msg[6], sizeof(u16)); 200e2cb1decSSalil Mehta 201e2cb1decSSalil Mehta return 0; 202e2cb1decSSalil Mehta } 203e2cb1decSSalil Mehta 204e2cb1decSSalil Mehta static int hclgevf_enable_tso(struct hclgevf_dev *hdev, int enable) 205e2cb1decSSalil Mehta { 206e2cb1decSSalil Mehta struct hclgevf_cfg_tso_status_cmd *req; 207e2cb1decSSalil Mehta struct hclgevf_desc desc; 208e2cb1decSSalil Mehta 209e2cb1decSSalil Mehta req = (struct hclgevf_cfg_tso_status_cmd *)desc.data; 210e2cb1decSSalil Mehta 211e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_TSO_GENERIC_CONFIG, 212e2cb1decSSalil Mehta false); 213e2cb1decSSalil Mehta hnae_set_bit(req->tso_enable, HCLGEVF_TSO_ENABLE_B, enable); 214e2cb1decSSalil Mehta 215e2cb1decSSalil Mehta return hclgevf_cmd_send(&hdev->hw, &desc, 1); 216e2cb1decSSalil Mehta } 217e2cb1decSSalil Mehta 218e2cb1decSSalil Mehta static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev) 219e2cb1decSSalil Mehta { 220e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 221e2cb1decSSalil Mehta int i; 222e2cb1decSSalil Mehta 223e2cb1decSSalil Mehta hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, 224e2cb1decSSalil Mehta sizeof(struct hclgevf_tqp), GFP_KERNEL); 225e2cb1decSSalil Mehta if (!hdev->htqp) 226e2cb1decSSalil Mehta return -ENOMEM; 227e2cb1decSSalil Mehta 228e2cb1decSSalil Mehta tqp = hdev->htqp; 229e2cb1decSSalil Mehta 230e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 231e2cb1decSSalil Mehta tqp->dev = &hdev->pdev->dev; 232e2cb1decSSalil Mehta tqp->index = i; 233e2cb1decSSalil Mehta 234e2cb1decSSalil Mehta tqp->q.ae_algo = &ae_algovf; 235e2cb1decSSalil Mehta tqp->q.buf_size = hdev->rx_buf_len; 236e2cb1decSSalil Mehta tqp->q.desc_num = hdev->num_desc; 237e2cb1decSSalil Mehta tqp->q.io_base = hdev->hw.io_base + HCLGEVF_TQP_REG_OFFSET + 238e2cb1decSSalil Mehta i * HCLGEVF_TQP_REG_SIZE; 239e2cb1decSSalil Mehta 240e2cb1decSSalil Mehta tqp++; 241e2cb1decSSalil Mehta } 242e2cb1decSSalil Mehta 243e2cb1decSSalil Mehta return 0; 244e2cb1decSSalil Mehta } 245e2cb1decSSalil Mehta 246e2cb1decSSalil Mehta static int hclgevf_knic_setup(struct hclgevf_dev *hdev) 247e2cb1decSSalil Mehta { 248e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 249e2cb1decSSalil Mehta struct hnae3_knic_private_info *kinfo; 250e2cb1decSSalil Mehta u16 new_tqps = hdev->num_tqps; 251e2cb1decSSalil Mehta int i; 252e2cb1decSSalil Mehta 253e2cb1decSSalil Mehta kinfo = &nic->kinfo; 254e2cb1decSSalil Mehta kinfo->num_tc = 0; 255e2cb1decSSalil Mehta kinfo->num_desc = hdev->num_desc; 256e2cb1decSSalil Mehta kinfo->rx_buf_len = hdev->rx_buf_len; 257e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) 258e2cb1decSSalil Mehta if (hdev->hw_tc_map & BIT(i)) 259e2cb1decSSalil Mehta kinfo->num_tc++; 260e2cb1decSSalil Mehta 261e2cb1decSSalil Mehta kinfo->rss_size 262e2cb1decSSalil Mehta = min_t(u16, hdev->rss_size_max, new_tqps / kinfo->num_tc); 263e2cb1decSSalil Mehta new_tqps = kinfo->rss_size * kinfo->num_tc; 264e2cb1decSSalil Mehta kinfo->num_tqps = min(new_tqps, hdev->num_tqps); 265e2cb1decSSalil Mehta 266e2cb1decSSalil Mehta kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, 267e2cb1decSSalil Mehta sizeof(struct hnae3_queue *), GFP_KERNEL); 268e2cb1decSSalil Mehta if (!kinfo->tqp) 269e2cb1decSSalil Mehta return -ENOMEM; 270e2cb1decSSalil Mehta 271e2cb1decSSalil Mehta for (i = 0; i < kinfo->num_tqps; i++) { 272e2cb1decSSalil Mehta hdev->htqp[i].q.handle = &hdev->nic; 273e2cb1decSSalil Mehta hdev->htqp[i].q.tqp_index = i; 274e2cb1decSSalil Mehta kinfo->tqp[i] = &hdev->htqp[i].q; 275e2cb1decSSalil Mehta } 276e2cb1decSSalil Mehta 277e2cb1decSSalil Mehta return 0; 278e2cb1decSSalil Mehta } 279e2cb1decSSalil Mehta 280e2cb1decSSalil Mehta static void hclgevf_request_link_info(struct hclgevf_dev *hdev) 281e2cb1decSSalil Mehta { 282e2cb1decSSalil Mehta int status; 283e2cb1decSSalil Mehta u8 resp_msg; 284e2cb1decSSalil Mehta 285e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_STATUS, 0, NULL, 286e2cb1decSSalil Mehta 0, false, &resp_msg, sizeof(u8)); 287e2cb1decSSalil Mehta if (status) 288e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 289e2cb1decSSalil Mehta "VF failed to fetch link status(%d) from PF", status); 290e2cb1decSSalil Mehta } 291e2cb1decSSalil Mehta 292e2cb1decSSalil Mehta void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state) 293e2cb1decSSalil Mehta { 294e2cb1decSSalil Mehta struct hnae3_handle *handle = &hdev->nic; 295e2cb1decSSalil Mehta struct hnae3_client *client; 296e2cb1decSSalil Mehta 297e2cb1decSSalil Mehta client = handle->client; 298e2cb1decSSalil Mehta 299e2cb1decSSalil Mehta if (link_state != hdev->hw.mac.link) { 300e2cb1decSSalil Mehta client->ops->link_status_change(handle, !!link_state); 301e2cb1decSSalil Mehta hdev->hw.mac.link = link_state; 302e2cb1decSSalil Mehta } 303e2cb1decSSalil Mehta } 304e2cb1decSSalil Mehta 305e2cb1decSSalil Mehta static int hclgevf_set_handle_info(struct hclgevf_dev *hdev) 306e2cb1decSSalil Mehta { 307e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 308e2cb1decSSalil Mehta int ret; 309e2cb1decSSalil Mehta 310e2cb1decSSalil Mehta nic->ae_algo = &ae_algovf; 311e2cb1decSSalil Mehta nic->pdev = hdev->pdev; 312e2cb1decSSalil Mehta nic->numa_node_mask = hdev->numa_node_mask; 313e2cb1decSSalil Mehta 314e2cb1decSSalil Mehta if (hdev->ae_dev->dev_type != HNAE3_DEV_KNIC) { 315e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "unsupported device type %d\n", 316e2cb1decSSalil Mehta hdev->ae_dev->dev_type); 317e2cb1decSSalil Mehta return -EINVAL; 318e2cb1decSSalil Mehta } 319e2cb1decSSalil Mehta 320e2cb1decSSalil Mehta ret = hclgevf_knic_setup(hdev); 321e2cb1decSSalil Mehta if (ret) 322e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF knic setup failed %d\n", 323e2cb1decSSalil Mehta ret); 324e2cb1decSSalil Mehta return ret; 325e2cb1decSSalil Mehta } 326e2cb1decSSalil Mehta 327e2cb1decSSalil Mehta static void hclgevf_free_vector(struct hclgevf_dev *hdev, int vector_id) 328e2cb1decSSalil Mehta { 329e2cb1decSSalil Mehta hdev->vector_status[vector_id] = HCLGEVF_INVALID_VPORT; 330e2cb1decSSalil Mehta hdev->num_msi_left += 1; 331e2cb1decSSalil Mehta hdev->num_msi_used -= 1; 332e2cb1decSSalil Mehta } 333e2cb1decSSalil Mehta 334e2cb1decSSalil Mehta static int hclgevf_get_vector(struct hnae3_handle *handle, u16 vector_num, 335e2cb1decSSalil Mehta struct hnae3_vector_info *vector_info) 336e2cb1decSSalil Mehta { 337e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 338e2cb1decSSalil Mehta struct hnae3_vector_info *vector = vector_info; 339e2cb1decSSalil Mehta int alloc = 0; 340e2cb1decSSalil Mehta int i, j; 341e2cb1decSSalil Mehta 342e2cb1decSSalil Mehta vector_num = min(hdev->num_msi_left, vector_num); 343e2cb1decSSalil Mehta 344e2cb1decSSalil Mehta for (j = 0; j < vector_num; j++) { 345e2cb1decSSalil Mehta for (i = HCLGEVF_MISC_VECTOR_NUM + 1; i < hdev->num_msi; i++) { 346e2cb1decSSalil Mehta if (hdev->vector_status[i] == HCLGEVF_INVALID_VPORT) { 347e2cb1decSSalil Mehta vector->vector = pci_irq_vector(hdev->pdev, i); 348e2cb1decSSalil Mehta vector->io_addr = hdev->hw.io_base + 349e2cb1decSSalil Mehta HCLGEVF_VECTOR_REG_BASE + 350e2cb1decSSalil Mehta (i - 1) * HCLGEVF_VECTOR_REG_OFFSET; 351e2cb1decSSalil Mehta hdev->vector_status[i] = 0; 352e2cb1decSSalil Mehta hdev->vector_irq[i] = vector->vector; 353e2cb1decSSalil Mehta 354e2cb1decSSalil Mehta vector++; 355e2cb1decSSalil Mehta alloc++; 356e2cb1decSSalil Mehta 357e2cb1decSSalil Mehta break; 358e2cb1decSSalil Mehta } 359e2cb1decSSalil Mehta } 360e2cb1decSSalil Mehta } 361e2cb1decSSalil Mehta hdev->num_msi_left -= alloc; 362e2cb1decSSalil Mehta hdev->num_msi_used += alloc; 363e2cb1decSSalil Mehta 364e2cb1decSSalil Mehta return alloc; 365e2cb1decSSalil Mehta } 366e2cb1decSSalil Mehta 367e2cb1decSSalil Mehta static int hclgevf_get_vector_index(struct hclgevf_dev *hdev, int vector) 368e2cb1decSSalil Mehta { 369e2cb1decSSalil Mehta int i; 370e2cb1decSSalil Mehta 371e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 372e2cb1decSSalil Mehta if (vector == hdev->vector_irq[i]) 373e2cb1decSSalil Mehta return i; 374e2cb1decSSalil Mehta 375e2cb1decSSalil Mehta return -EINVAL; 376e2cb1decSSalil Mehta } 377e2cb1decSSalil Mehta 378e2cb1decSSalil Mehta static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle) 379e2cb1decSSalil Mehta { 380e2cb1decSSalil Mehta return HCLGEVF_RSS_KEY_SIZE; 381e2cb1decSSalil Mehta } 382e2cb1decSSalil Mehta 383e2cb1decSSalil Mehta static u32 hclgevf_get_rss_indir_size(struct hnae3_handle *handle) 384e2cb1decSSalil Mehta { 385e2cb1decSSalil Mehta return HCLGEVF_RSS_IND_TBL_SIZE; 386e2cb1decSSalil Mehta } 387e2cb1decSSalil Mehta 388e2cb1decSSalil Mehta static int hclgevf_set_rss_indir_table(struct hclgevf_dev *hdev) 389e2cb1decSSalil Mehta { 390e2cb1decSSalil Mehta const u8 *indir = hdev->rss_cfg.rss_indirection_tbl; 391e2cb1decSSalil Mehta struct hclgevf_rss_indirection_table_cmd *req; 392e2cb1decSSalil Mehta struct hclgevf_desc desc; 393e2cb1decSSalil Mehta int status; 394e2cb1decSSalil Mehta int i, j; 395e2cb1decSSalil Mehta 396e2cb1decSSalil Mehta req = (struct hclgevf_rss_indirection_table_cmd *)desc.data; 397e2cb1decSSalil Mehta 398e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_CFG_TBL_NUM; i++) { 399e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_INDIR_TABLE, 400e2cb1decSSalil Mehta false); 401e2cb1decSSalil Mehta req->start_table_index = i * HCLGEVF_RSS_CFG_TBL_SIZE; 402e2cb1decSSalil Mehta req->rss_set_bitmap = HCLGEVF_RSS_SET_BITMAP_MSK; 403e2cb1decSSalil Mehta for (j = 0; j < HCLGEVF_RSS_CFG_TBL_SIZE; j++) 404e2cb1decSSalil Mehta req->rss_result[j] = 405e2cb1decSSalil Mehta indir[i * HCLGEVF_RSS_CFG_TBL_SIZE + j]; 406e2cb1decSSalil Mehta 407e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 408e2cb1decSSalil Mehta if (status) { 409e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 410e2cb1decSSalil Mehta "VF failed(=%d) to set RSS indirection table\n", 411e2cb1decSSalil Mehta status); 412e2cb1decSSalil Mehta return status; 413e2cb1decSSalil Mehta } 414e2cb1decSSalil Mehta } 415e2cb1decSSalil Mehta 416e2cb1decSSalil Mehta return 0; 417e2cb1decSSalil Mehta } 418e2cb1decSSalil Mehta 419e2cb1decSSalil Mehta static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size) 420e2cb1decSSalil Mehta { 421e2cb1decSSalil Mehta struct hclgevf_rss_tc_mode_cmd *req; 422e2cb1decSSalil Mehta u16 tc_offset[HCLGEVF_MAX_TC_NUM]; 423e2cb1decSSalil Mehta u16 tc_valid[HCLGEVF_MAX_TC_NUM]; 424e2cb1decSSalil Mehta u16 tc_size[HCLGEVF_MAX_TC_NUM]; 425e2cb1decSSalil Mehta struct hclgevf_desc desc; 426e2cb1decSSalil Mehta u16 roundup_size; 427e2cb1decSSalil Mehta int status; 428e2cb1decSSalil Mehta int i; 429e2cb1decSSalil Mehta 430e2cb1decSSalil Mehta req = (struct hclgevf_rss_tc_mode_cmd *)desc.data; 431e2cb1decSSalil Mehta 432e2cb1decSSalil Mehta roundup_size = roundup_pow_of_two(rss_size); 433e2cb1decSSalil Mehta roundup_size = ilog2(roundup_size); 434e2cb1decSSalil Mehta 435e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 436e2cb1decSSalil Mehta tc_valid[i] = !!(hdev->hw_tc_map & BIT(i)); 437e2cb1decSSalil Mehta tc_size[i] = roundup_size; 438e2cb1decSSalil Mehta tc_offset[i] = rss_size * i; 439e2cb1decSSalil Mehta } 440e2cb1decSSalil Mehta 441e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false); 442e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 443e2cb1decSSalil Mehta hnae_set_bit(req->rss_tc_mode[i], HCLGEVF_RSS_TC_VALID_B, 444e2cb1decSSalil Mehta (tc_valid[i] & 0x1)); 445e2cb1decSSalil Mehta hnae_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_SIZE_M, 446e2cb1decSSalil Mehta HCLGEVF_RSS_TC_SIZE_S, tc_size[i]); 447e2cb1decSSalil Mehta hnae_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_OFFSET_M, 448e2cb1decSSalil Mehta HCLGEVF_RSS_TC_OFFSET_S, tc_offset[i]); 449e2cb1decSSalil Mehta } 450e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 451e2cb1decSSalil Mehta if (status) 452e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 453e2cb1decSSalil Mehta "VF failed(=%d) to set rss tc mode\n", status); 454e2cb1decSSalil Mehta 455e2cb1decSSalil Mehta return status; 456e2cb1decSSalil Mehta } 457e2cb1decSSalil Mehta 458e2cb1decSSalil Mehta static int hclgevf_get_rss_hw_cfg(struct hnae3_handle *handle, u8 *hash, 459e2cb1decSSalil Mehta u8 *key) 460e2cb1decSSalil Mehta { 461e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 462e2cb1decSSalil Mehta struct hclgevf_rss_config_cmd *req; 463e2cb1decSSalil Mehta int lkup_times = key ? 3 : 1; 464e2cb1decSSalil Mehta struct hclgevf_desc desc; 465e2cb1decSSalil Mehta int key_offset; 466e2cb1decSSalil Mehta int key_size; 467e2cb1decSSalil Mehta int status; 468e2cb1decSSalil Mehta 469e2cb1decSSalil Mehta req = (struct hclgevf_rss_config_cmd *)desc.data; 470e2cb1decSSalil Mehta lkup_times = (lkup_times == 3) ? 3 : ((hash) ? 1 : 0); 471e2cb1decSSalil Mehta 472e2cb1decSSalil Mehta for (key_offset = 0; key_offset < lkup_times; key_offset++) { 473e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 474e2cb1decSSalil Mehta HCLGEVF_OPC_RSS_GENERIC_CONFIG, 475e2cb1decSSalil Mehta true); 476e2cb1decSSalil Mehta req->hash_config |= (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET); 477e2cb1decSSalil Mehta 478e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 479e2cb1decSSalil Mehta if (status) { 480e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 481e2cb1decSSalil Mehta "failed to get hardware RSS cfg, status = %d\n", 482e2cb1decSSalil Mehta status); 483e2cb1decSSalil Mehta return status; 484e2cb1decSSalil Mehta } 485e2cb1decSSalil Mehta 486e2cb1decSSalil Mehta if (key_offset == 2) 487e2cb1decSSalil Mehta key_size = 488e2cb1decSSalil Mehta HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2; 489e2cb1decSSalil Mehta else 490e2cb1decSSalil Mehta key_size = HCLGEVF_RSS_HASH_KEY_NUM; 491e2cb1decSSalil Mehta 492e2cb1decSSalil Mehta if (key) 493e2cb1decSSalil Mehta memcpy(key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, 494e2cb1decSSalil Mehta req->hash_key, 495e2cb1decSSalil Mehta key_size); 496e2cb1decSSalil Mehta } 497e2cb1decSSalil Mehta 498e2cb1decSSalil Mehta if (hash) { 499e2cb1decSSalil Mehta if ((req->hash_config & 0xf) == HCLGEVF_RSS_HASH_ALGO_TOEPLITZ) 500e2cb1decSSalil Mehta *hash = ETH_RSS_HASH_TOP; 501e2cb1decSSalil Mehta else 502e2cb1decSSalil Mehta *hash = ETH_RSS_HASH_UNKNOWN; 503e2cb1decSSalil Mehta } 504e2cb1decSSalil Mehta 505e2cb1decSSalil Mehta return 0; 506e2cb1decSSalil Mehta } 507e2cb1decSSalil Mehta 508e2cb1decSSalil Mehta static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key, 509e2cb1decSSalil Mehta u8 *hfunc) 510e2cb1decSSalil Mehta { 511e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 512e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 513e2cb1decSSalil Mehta int i; 514e2cb1decSSalil Mehta 515e2cb1decSSalil Mehta if (indir) 516e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 517e2cb1decSSalil Mehta indir[i] = rss_cfg->rss_indirection_tbl[i]; 518e2cb1decSSalil Mehta 519e2cb1decSSalil Mehta return hclgevf_get_rss_hw_cfg(handle, hfunc, key); 520e2cb1decSSalil Mehta } 521e2cb1decSSalil Mehta 522e2cb1decSSalil Mehta static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, 523e2cb1decSSalil Mehta const u8 *key, const u8 hfunc) 524e2cb1decSSalil Mehta { 525e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 526e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 527e2cb1decSSalil Mehta int i; 528e2cb1decSSalil Mehta 529e2cb1decSSalil Mehta /* update the shadow RSS table with user specified qids */ 530e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 531e2cb1decSSalil Mehta rss_cfg->rss_indirection_tbl[i] = indir[i]; 532e2cb1decSSalil Mehta 533e2cb1decSSalil Mehta /* update the hardware */ 534e2cb1decSSalil Mehta return hclgevf_set_rss_indir_table(hdev); 535e2cb1decSSalil Mehta } 536e2cb1decSSalil Mehta 537e2cb1decSSalil Mehta static int hclgevf_get_tc_size(struct hnae3_handle *handle) 538e2cb1decSSalil Mehta { 539e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 540e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 541e2cb1decSSalil Mehta 542e2cb1decSSalil Mehta return rss_cfg->rss_size; 543e2cb1decSSalil Mehta } 544e2cb1decSSalil Mehta 545e2cb1decSSalil Mehta static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, 546e2cb1decSSalil Mehta int vector, 547e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 548e2cb1decSSalil Mehta { 549e2cb1decSSalil Mehta #define HCLGEVF_RING_NODE_VARIABLE_NUM 3 550e2cb1decSSalil Mehta #define HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM 3 551e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 552e2cb1decSSalil Mehta struct hnae3_ring_chain_node *node; 553e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 554e2cb1decSSalil Mehta struct hclgevf_desc desc; 555e2cb1decSSalil Mehta int i, vector_id; 556e2cb1decSSalil Mehta int status; 557e2cb1decSSalil Mehta u8 type; 558e2cb1decSSalil Mehta 559e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 560e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 561e2cb1decSSalil Mehta if (vector_id < 0) { 562e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 563e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 564e2cb1decSSalil Mehta return vector_id; 565e2cb1decSSalil Mehta } 566e2cb1decSSalil Mehta 567e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 568e2cb1decSSalil Mehta type = en ? 569e2cb1decSSalil Mehta HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR; 570e2cb1decSSalil Mehta req->msg[0] = type; 571e2cb1decSSalil Mehta req->msg[1] = vector_id; /* vector_id should be id in VF */ 572e2cb1decSSalil Mehta 573e2cb1decSSalil Mehta i = 0; 574e2cb1decSSalil Mehta for (node = ring_chain; node; node = node->next) { 575e2cb1decSSalil Mehta i++; 576e2cb1decSSalil Mehta /* msg[2] is cause num */ 577e2cb1decSSalil Mehta req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i] = 578e2cb1decSSalil Mehta hnae_get_bit(node->flag, HNAE3_RING_TYPE_B); 579e2cb1decSSalil Mehta req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 1] = 580e2cb1decSSalil Mehta node->tqp_index; 581e2cb1decSSalil Mehta if (i == (HCLGE_MBX_VF_MSG_DATA_NUM - 582e2cb1decSSalil Mehta HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM) / 583e2cb1decSSalil Mehta HCLGEVF_RING_NODE_VARIABLE_NUM) { 584e2cb1decSSalil Mehta req->msg[2] = i; 585e2cb1decSSalil Mehta 586e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 587e2cb1decSSalil Mehta if (status) { 588e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 589e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", 590e2cb1decSSalil Mehta status); 591e2cb1decSSalil Mehta return status; 592e2cb1decSSalil Mehta } 593e2cb1decSSalil Mehta i = 0; 594e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 595e2cb1decSSalil Mehta HCLGEVF_OPC_MBX_VF_TO_PF, 596e2cb1decSSalil Mehta false); 597e2cb1decSSalil Mehta req->msg[0] = type; 598e2cb1decSSalil Mehta req->msg[1] = vector_id; 599e2cb1decSSalil Mehta } 600e2cb1decSSalil Mehta } 601e2cb1decSSalil Mehta 602e2cb1decSSalil Mehta if (i > 0) { 603e2cb1decSSalil Mehta req->msg[2] = i; 604e2cb1decSSalil Mehta 605e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 606e2cb1decSSalil Mehta if (status) { 607e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 608e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", status); 609e2cb1decSSalil Mehta return status; 610e2cb1decSSalil Mehta } 611e2cb1decSSalil Mehta } 612e2cb1decSSalil Mehta 613e2cb1decSSalil Mehta return 0; 614e2cb1decSSalil Mehta } 615e2cb1decSSalil Mehta 616e2cb1decSSalil Mehta static int hclgevf_map_ring_to_vector(struct hnae3_handle *handle, int vector, 617e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 618e2cb1decSSalil Mehta { 619e2cb1decSSalil Mehta return hclgevf_bind_ring_to_vector(handle, true, vector, ring_chain); 620e2cb1decSSalil Mehta } 621e2cb1decSSalil Mehta 622e2cb1decSSalil Mehta static int hclgevf_unmap_ring_from_vector( 623e2cb1decSSalil Mehta struct hnae3_handle *handle, 624e2cb1decSSalil Mehta int vector, 625e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 626e2cb1decSSalil Mehta { 627e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 628e2cb1decSSalil Mehta int ret, vector_id; 629e2cb1decSSalil Mehta 630e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 631e2cb1decSSalil Mehta if (vector_id < 0) { 632e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 633e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 634e2cb1decSSalil Mehta return vector_id; 635e2cb1decSSalil Mehta } 636e2cb1decSSalil Mehta 637e2cb1decSSalil Mehta ret = hclgevf_bind_ring_to_vector(handle, false, vector, ring_chain); 638e2cb1decSSalil Mehta if (ret) { 639e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 640e2cb1decSSalil Mehta "Unmap ring from vector fail. vector=%d, ret =%d\n", 641e2cb1decSSalil Mehta vector_id, 642e2cb1decSSalil Mehta ret); 643e2cb1decSSalil Mehta return ret; 644e2cb1decSSalil Mehta } 645e2cb1decSSalil Mehta 646e2cb1decSSalil Mehta hclgevf_free_vector(hdev, vector); 647e2cb1decSSalil Mehta 648e2cb1decSSalil Mehta return 0; 649e2cb1decSSalil Mehta } 650e2cb1decSSalil Mehta 651e2cb1decSSalil Mehta static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) 652e2cb1decSSalil Mehta { 653e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 654e2cb1decSSalil Mehta struct hclgevf_desc desc; 655e2cb1decSSalil Mehta int status; 656e2cb1decSSalil Mehta 657e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 658e2cb1decSSalil Mehta 659e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 660e2cb1decSSalil Mehta req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; 661e2cb1decSSalil Mehta req->msg[1] = en; 662e2cb1decSSalil Mehta 663e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 664e2cb1decSSalil Mehta if (status) 665e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 666e2cb1decSSalil Mehta "Set promisc mode fail, status is %d.\n", status); 667e2cb1decSSalil Mehta 668e2cb1decSSalil Mehta return status; 669e2cb1decSSalil Mehta } 670e2cb1decSSalil Mehta 671e2cb1decSSalil Mehta static void hclgevf_set_promisc_mode(struct hnae3_handle *handle, u32 en) 672e2cb1decSSalil Mehta { 673e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 674e2cb1decSSalil Mehta 675e2cb1decSSalil Mehta hclgevf_cmd_set_promisc_mode(hdev, en); 676e2cb1decSSalil Mehta } 677e2cb1decSSalil Mehta 678e2cb1decSSalil Mehta static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, 679e2cb1decSSalil Mehta int stream_id, bool enable) 680e2cb1decSSalil Mehta { 681e2cb1decSSalil Mehta struct hclgevf_cfg_com_tqp_queue_cmd *req; 682e2cb1decSSalil Mehta struct hclgevf_desc desc; 683e2cb1decSSalil Mehta int status; 684e2cb1decSSalil Mehta 685e2cb1decSSalil Mehta req = (struct hclgevf_cfg_com_tqp_queue_cmd *)desc.data; 686e2cb1decSSalil Mehta 687e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_CFG_COM_TQP_QUEUE, 688e2cb1decSSalil Mehta false); 689e2cb1decSSalil Mehta req->tqp_id = cpu_to_le16(tqp_id & HCLGEVF_RING_ID_MASK); 690e2cb1decSSalil Mehta req->stream_id = cpu_to_le16(stream_id); 691e2cb1decSSalil Mehta req->enable |= enable << HCLGEVF_TQP_ENABLE_B; 692e2cb1decSSalil Mehta 693e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 694e2cb1decSSalil Mehta if (status) 695e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 696e2cb1decSSalil Mehta "TQP enable fail, status =%d.\n", status); 697e2cb1decSSalil Mehta 698e2cb1decSSalil Mehta return status; 699e2cb1decSSalil Mehta } 700e2cb1decSSalil Mehta 701e2cb1decSSalil Mehta static int hclgevf_get_queue_id(struct hnae3_queue *queue) 702e2cb1decSSalil Mehta { 703e2cb1decSSalil Mehta struct hclgevf_tqp *tqp = container_of(queue, struct hclgevf_tqp, q); 704e2cb1decSSalil Mehta 705e2cb1decSSalil Mehta return tqp->index; 706e2cb1decSSalil Mehta } 707e2cb1decSSalil Mehta 708e2cb1decSSalil Mehta static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) 709e2cb1decSSalil Mehta { 710e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 711e2cb1decSSalil Mehta struct hnae3_queue *queue; 712e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 713e2cb1decSSalil Mehta int i; 714e2cb1decSSalil Mehta 715e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 716e2cb1decSSalil Mehta queue = handle->kinfo.tqp[i]; 717e2cb1decSSalil Mehta tqp = container_of(queue, struct hclgevf_tqp, q); 718e2cb1decSSalil Mehta memset(&tqp->tqp_stats, 0, sizeof(tqp->tqp_stats)); 719e2cb1decSSalil Mehta } 720e2cb1decSSalil Mehta } 721e2cb1decSSalil Mehta 722e2cb1decSSalil Mehta static int hclgevf_cfg_func_mta_filter(struct hnae3_handle *handle, bool en) 723e2cb1decSSalil Mehta { 724e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 725e2cb1decSSalil Mehta u8 msg[2] = {0}; 726e2cb1decSSalil Mehta 727e2cb1decSSalil Mehta msg[0] = en; 728e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 729e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, 730e2cb1decSSalil Mehta msg, 1, false, NULL, 0); 731e2cb1decSSalil Mehta } 732e2cb1decSSalil Mehta 733e2cb1decSSalil Mehta static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) 734e2cb1decSSalil Mehta { 735e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 736e2cb1decSSalil Mehta 737e2cb1decSSalil Mehta ether_addr_copy(p, hdev->hw.mac.mac_addr); 738e2cb1decSSalil Mehta } 739e2cb1decSSalil Mehta 740e2cb1decSSalil Mehta static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p) 741e2cb1decSSalil Mehta { 742e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 743e2cb1decSSalil Mehta u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; 744e2cb1decSSalil Mehta u8 *new_mac_addr = (u8 *)p; 745e2cb1decSSalil Mehta u8 msg_data[ETH_ALEN * 2]; 746e2cb1decSSalil Mehta int status; 747e2cb1decSSalil Mehta 748e2cb1decSSalil Mehta ether_addr_copy(msg_data, new_mac_addr); 749e2cb1decSSalil Mehta ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); 750e2cb1decSSalil Mehta 751e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 752e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_MODIFY, 753e2cb1decSSalil Mehta msg_data, ETH_ALEN * 2, 754e2cb1decSSalil Mehta false, NULL, 0); 755e2cb1decSSalil Mehta if (!status) 756e2cb1decSSalil Mehta ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); 757e2cb1decSSalil Mehta 758e2cb1decSSalil Mehta return status; 759e2cb1decSSalil Mehta } 760e2cb1decSSalil Mehta 761e2cb1decSSalil Mehta static int hclgevf_add_uc_addr(struct hnae3_handle *handle, 762e2cb1decSSalil Mehta const unsigned char *addr) 763e2cb1decSSalil Mehta { 764e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 765e2cb1decSSalil Mehta 766e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 767e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_ADD, 768e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 769e2cb1decSSalil Mehta } 770e2cb1decSSalil Mehta 771e2cb1decSSalil Mehta static int hclgevf_rm_uc_addr(struct hnae3_handle *handle, 772e2cb1decSSalil Mehta const unsigned char *addr) 773e2cb1decSSalil Mehta { 774e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 775e2cb1decSSalil Mehta 776e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 777e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_REMOVE, 778e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 779e2cb1decSSalil Mehta } 780e2cb1decSSalil Mehta 781e2cb1decSSalil Mehta static int hclgevf_add_mc_addr(struct hnae3_handle *handle, 782e2cb1decSSalil Mehta const unsigned char *addr) 783e2cb1decSSalil Mehta { 784e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 785e2cb1decSSalil Mehta 786e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 787e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_ADD, 788e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 789e2cb1decSSalil Mehta } 790e2cb1decSSalil Mehta 791e2cb1decSSalil Mehta static int hclgevf_rm_mc_addr(struct hnae3_handle *handle, 792e2cb1decSSalil Mehta const unsigned char *addr) 793e2cb1decSSalil Mehta { 794e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 795e2cb1decSSalil Mehta 796e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 797e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_REMOVE, 798e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 799e2cb1decSSalil Mehta } 800e2cb1decSSalil Mehta 801e2cb1decSSalil Mehta static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, 802e2cb1decSSalil Mehta __be16 proto, u16 vlan_id, 803e2cb1decSSalil Mehta bool is_kill) 804e2cb1decSSalil Mehta { 805e2cb1decSSalil Mehta #define HCLGEVF_VLAN_MBX_MSG_LEN 5 806e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 807e2cb1decSSalil Mehta u8 msg_data[HCLGEVF_VLAN_MBX_MSG_LEN]; 808e2cb1decSSalil Mehta 809e2cb1decSSalil Mehta if (vlan_id > 4095) 810e2cb1decSSalil Mehta return -EINVAL; 811e2cb1decSSalil Mehta 812e2cb1decSSalil Mehta if (proto != htons(ETH_P_8021Q)) 813e2cb1decSSalil Mehta return -EPROTONOSUPPORT; 814e2cb1decSSalil Mehta 815e2cb1decSSalil Mehta msg_data[0] = is_kill; 816e2cb1decSSalil Mehta memcpy(&msg_data[1], &vlan_id, sizeof(vlan_id)); 817e2cb1decSSalil Mehta memcpy(&msg_data[3], &proto, sizeof(proto)); 818e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, 819e2cb1decSSalil Mehta HCLGE_MBX_VLAN_FILTER, msg_data, 820e2cb1decSSalil Mehta HCLGEVF_VLAN_MBX_MSG_LEN, false, NULL, 0); 821e2cb1decSSalil Mehta } 822e2cb1decSSalil Mehta 823e2cb1decSSalil Mehta static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 824e2cb1decSSalil Mehta { 825e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 826e2cb1decSSalil Mehta u8 msg_data[2]; 827e2cb1decSSalil Mehta 828e2cb1decSSalil Mehta memcpy(&msg_data[0], &queue_id, sizeof(queue_id)); 829e2cb1decSSalil Mehta 830e2cb1decSSalil Mehta hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data, 2, false, 831e2cb1decSSalil Mehta NULL, 0); 832e2cb1decSSalil Mehta } 833e2cb1decSSalil Mehta 834e2cb1decSSalil Mehta static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) 835e2cb1decSSalil Mehta { 836e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 837e2cb1decSSalil Mehta 838e2cb1decSSalil Mehta return hdev->fw_version; 839e2cb1decSSalil Mehta } 840e2cb1decSSalil Mehta 841e2cb1decSSalil Mehta static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev) 842e2cb1decSSalil Mehta { 843e2cb1decSSalil Mehta struct hclgevf_misc_vector *vector = &hdev->misc_vector; 844e2cb1decSSalil Mehta 845e2cb1decSSalil Mehta vector->vector_irq = pci_irq_vector(hdev->pdev, 846e2cb1decSSalil Mehta HCLGEVF_MISC_VECTOR_NUM); 847e2cb1decSSalil Mehta vector->addr = hdev->hw.io_base + HCLGEVF_MISC_VECTOR_REG_BASE; 848e2cb1decSSalil Mehta /* vector status always valid for Vector 0 */ 849e2cb1decSSalil Mehta hdev->vector_status[HCLGEVF_MISC_VECTOR_NUM] = 0; 850e2cb1decSSalil Mehta hdev->vector_irq[HCLGEVF_MISC_VECTOR_NUM] = vector->vector_irq; 851e2cb1decSSalil Mehta 852e2cb1decSSalil Mehta hdev->num_msi_left -= 1; 853e2cb1decSSalil Mehta hdev->num_msi_used += 1; 854e2cb1decSSalil Mehta } 855e2cb1decSSalil Mehta 856e2cb1decSSalil Mehta static void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) 857e2cb1decSSalil Mehta { 858e2cb1decSSalil Mehta if (!test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) 859e2cb1decSSalil Mehta schedule_work(&hdev->mbx_service_task); 860e2cb1decSSalil Mehta } 861e2cb1decSSalil Mehta 862e2cb1decSSalil Mehta static void hclgevf_task_schedule(struct hclgevf_dev *hdev) 863e2cb1decSSalil Mehta { 864e2cb1decSSalil Mehta if (!test_bit(HCLGEVF_STATE_DOWN, &hdev->state) && 865e2cb1decSSalil Mehta !test_and_set_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state)) 866e2cb1decSSalil Mehta schedule_work(&hdev->service_task); 867e2cb1decSSalil Mehta } 868e2cb1decSSalil Mehta 869e2cb1decSSalil Mehta static void hclgevf_service_timer(struct timer_list *t) 870e2cb1decSSalil Mehta { 871e2cb1decSSalil Mehta struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer); 872e2cb1decSSalil Mehta 873e2cb1decSSalil Mehta mod_timer(&hdev->service_timer, jiffies + 5 * HZ); 874e2cb1decSSalil Mehta 875e2cb1decSSalil Mehta hclgevf_task_schedule(hdev); 876e2cb1decSSalil Mehta } 877e2cb1decSSalil Mehta 878e2cb1decSSalil Mehta static void hclgevf_mailbox_service_task(struct work_struct *work) 879e2cb1decSSalil Mehta { 880e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 881e2cb1decSSalil Mehta 882e2cb1decSSalil Mehta hdev = container_of(work, struct hclgevf_dev, mbx_service_task); 883e2cb1decSSalil Mehta 884e2cb1decSSalil Mehta if (test_and_set_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) 885e2cb1decSSalil Mehta return; 886e2cb1decSSalil Mehta 887e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 888e2cb1decSSalil Mehta 889e2cb1decSSalil Mehta hclgevf_mbx_handler(hdev); 890e2cb1decSSalil Mehta 891e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 892e2cb1decSSalil Mehta } 893e2cb1decSSalil Mehta 894e2cb1decSSalil Mehta static void hclgevf_service_task(struct work_struct *work) 895e2cb1decSSalil Mehta { 896e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 897e2cb1decSSalil Mehta 898e2cb1decSSalil Mehta hdev = container_of(work, struct hclgevf_dev, service_task); 899e2cb1decSSalil Mehta 900e2cb1decSSalil Mehta /* request the link status from the PF. PF would be able to tell VF 901e2cb1decSSalil Mehta * about such updates in future so we might remove this later 902e2cb1decSSalil Mehta */ 903e2cb1decSSalil Mehta hclgevf_request_link_info(hdev); 904e2cb1decSSalil Mehta 905e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 906e2cb1decSSalil Mehta } 907e2cb1decSSalil Mehta 908e2cb1decSSalil Mehta static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr) 909e2cb1decSSalil Mehta { 910e2cb1decSSalil Mehta hclgevf_write_dev(&hdev->hw, HCLGEVF_VECTOR0_CMDQ_SRC_REG, regclr); 911e2cb1decSSalil Mehta } 912e2cb1decSSalil Mehta 913e2cb1decSSalil Mehta static bool hclgevf_check_event_cause(struct hclgevf_dev *hdev, u32 *clearval) 914e2cb1decSSalil Mehta { 915e2cb1decSSalil Mehta u32 cmdq_src_reg; 916e2cb1decSSalil Mehta 917e2cb1decSSalil Mehta /* fetch the events from their corresponding regs */ 918e2cb1decSSalil Mehta cmdq_src_reg = hclgevf_read_dev(&hdev->hw, 919e2cb1decSSalil Mehta HCLGEVF_VECTOR0_CMDQ_SRC_REG); 920e2cb1decSSalil Mehta 921e2cb1decSSalil Mehta /* check for vector0 mailbox(=CMDQ RX) event source */ 922e2cb1decSSalil Mehta if (BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) { 923e2cb1decSSalil Mehta cmdq_src_reg &= ~BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B); 924e2cb1decSSalil Mehta *clearval = cmdq_src_reg; 925e2cb1decSSalil Mehta return true; 926e2cb1decSSalil Mehta } 927e2cb1decSSalil Mehta 928e2cb1decSSalil Mehta dev_dbg(&hdev->pdev->dev, "vector 0 interrupt from unknown source\n"); 929e2cb1decSSalil Mehta 930e2cb1decSSalil Mehta return false; 931e2cb1decSSalil Mehta } 932e2cb1decSSalil Mehta 933e2cb1decSSalil Mehta static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en) 934e2cb1decSSalil Mehta { 935e2cb1decSSalil Mehta writel(en ? 1 : 0, vector->addr); 936e2cb1decSSalil Mehta } 937e2cb1decSSalil Mehta 938e2cb1decSSalil Mehta static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) 939e2cb1decSSalil Mehta { 940e2cb1decSSalil Mehta struct hclgevf_dev *hdev = data; 941e2cb1decSSalil Mehta u32 clearval; 942e2cb1decSSalil Mehta 943e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 944e2cb1decSSalil Mehta if (!hclgevf_check_event_cause(hdev, &clearval)) 945e2cb1decSSalil Mehta goto skip_sched; 946e2cb1decSSalil Mehta 947e2cb1decSSalil Mehta /* schedule the VF mailbox service task, if not already scheduled */ 948e2cb1decSSalil Mehta hclgevf_mbx_task_schedule(hdev); 949e2cb1decSSalil Mehta 950e2cb1decSSalil Mehta hclgevf_clear_event_cause(hdev, clearval); 951e2cb1decSSalil Mehta 952e2cb1decSSalil Mehta skip_sched: 953e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 954e2cb1decSSalil Mehta 955e2cb1decSSalil Mehta return IRQ_HANDLED; 956e2cb1decSSalil Mehta } 957e2cb1decSSalil Mehta 958e2cb1decSSalil Mehta static int hclgevf_configure(struct hclgevf_dev *hdev) 959e2cb1decSSalil Mehta { 960e2cb1decSSalil Mehta int ret; 961e2cb1decSSalil Mehta 962e2cb1decSSalil Mehta /* get queue configuration from PF */ 963e2cb1decSSalil Mehta ret = hclge_get_queue_info(hdev); 964e2cb1decSSalil Mehta if (ret) 965e2cb1decSSalil Mehta return ret; 966e2cb1decSSalil Mehta /* get tc configuration from PF */ 967e2cb1decSSalil Mehta return hclgevf_get_tc_info(hdev); 968e2cb1decSSalil Mehta } 969e2cb1decSSalil Mehta 970e2cb1decSSalil Mehta static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) 971e2cb1decSSalil Mehta { 972e2cb1decSSalil Mehta struct hnae3_handle *roce = &hdev->roce; 973e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 974e2cb1decSSalil Mehta 975e2cb1decSSalil Mehta roce->rinfo.num_vectors = HCLGEVF_ROCEE_VECTOR_NUM; 976e2cb1decSSalil Mehta 977e2cb1decSSalil Mehta if (hdev->num_msi_left < roce->rinfo.num_vectors || 978e2cb1decSSalil Mehta hdev->num_msi_left == 0) 979e2cb1decSSalil Mehta return -EINVAL; 980e2cb1decSSalil Mehta 981e2cb1decSSalil Mehta roce->rinfo.base_vector = 982e2cb1decSSalil Mehta hdev->vector_status[hdev->num_msi_used]; 983e2cb1decSSalil Mehta 984e2cb1decSSalil Mehta roce->rinfo.netdev = nic->kinfo.netdev; 985e2cb1decSSalil Mehta roce->rinfo.roce_io_base = hdev->hw.io_base; 986e2cb1decSSalil Mehta 987e2cb1decSSalil Mehta roce->pdev = nic->pdev; 988e2cb1decSSalil Mehta roce->ae_algo = nic->ae_algo; 989e2cb1decSSalil Mehta roce->numa_node_mask = nic->numa_node_mask; 990e2cb1decSSalil Mehta 991e2cb1decSSalil Mehta return 0; 992e2cb1decSSalil Mehta } 993e2cb1decSSalil Mehta 994e2cb1decSSalil Mehta static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) 995e2cb1decSSalil Mehta { 996e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 997e2cb1decSSalil Mehta int i, ret; 998e2cb1decSSalil Mehta 999e2cb1decSSalil Mehta rss_cfg->rss_size = hdev->rss_size_max; 1000e2cb1decSSalil Mehta 1001e2cb1decSSalil Mehta /* Initialize RSS indirect table for each vport */ 1002e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 1003e2cb1decSSalil Mehta rss_cfg->rss_indirection_tbl[i] = i % hdev->rss_size_max; 1004e2cb1decSSalil Mehta 1005e2cb1decSSalil Mehta ret = hclgevf_set_rss_indir_table(hdev); 1006e2cb1decSSalil Mehta if (ret) 1007e2cb1decSSalil Mehta return ret; 1008e2cb1decSSalil Mehta 1009e2cb1decSSalil Mehta return hclgevf_set_rss_tc_mode(hdev, hdev->rss_size_max); 1010e2cb1decSSalil Mehta } 1011e2cb1decSSalil Mehta 1012e2cb1decSSalil Mehta static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) 1013e2cb1decSSalil Mehta { 1014e2cb1decSSalil Mehta /* other vlan config(like, VLAN TX/RX offload) would also be added 1015e2cb1decSSalil Mehta * here later 1016e2cb1decSSalil Mehta */ 1017e2cb1decSSalil Mehta return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, 1018e2cb1decSSalil Mehta false); 1019e2cb1decSSalil Mehta } 1020e2cb1decSSalil Mehta 1021e2cb1decSSalil Mehta static int hclgevf_ae_start(struct hnae3_handle *handle) 1022e2cb1decSSalil Mehta { 1023e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1024e2cb1decSSalil Mehta int i, queue_id; 1025e2cb1decSSalil Mehta 1026e2cb1decSSalil Mehta for (i = 0; i < handle->kinfo.num_tqps; i++) { 1027e2cb1decSSalil Mehta /* ring enable */ 1028e2cb1decSSalil Mehta queue_id = hclgevf_get_queue_id(handle->kinfo.tqp[i]); 1029e2cb1decSSalil Mehta if (queue_id < 0) { 1030e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1031e2cb1decSSalil Mehta "Get invalid queue id, ignore it\n"); 1032e2cb1decSSalil Mehta continue; 1033e2cb1decSSalil Mehta } 1034e2cb1decSSalil Mehta 1035e2cb1decSSalil Mehta hclgevf_tqp_enable(hdev, queue_id, 0, true); 1036e2cb1decSSalil Mehta } 1037e2cb1decSSalil Mehta 1038e2cb1decSSalil Mehta /* reset tqp stats */ 1039e2cb1decSSalil Mehta hclgevf_reset_tqp_stats(handle); 1040e2cb1decSSalil Mehta 1041e2cb1decSSalil Mehta hclgevf_request_link_info(hdev); 1042e2cb1decSSalil Mehta 1043e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1044e2cb1decSSalil Mehta mod_timer(&hdev->service_timer, jiffies + HZ); 1045e2cb1decSSalil Mehta 1046e2cb1decSSalil Mehta return 0; 1047e2cb1decSSalil Mehta } 1048e2cb1decSSalil Mehta 1049e2cb1decSSalil Mehta static void hclgevf_ae_stop(struct hnae3_handle *handle) 1050e2cb1decSSalil Mehta { 1051e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1052e2cb1decSSalil Mehta int i, queue_id; 1053e2cb1decSSalil Mehta 1054e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 1055e2cb1decSSalil Mehta /* Ring disable */ 1056e2cb1decSSalil Mehta queue_id = hclgevf_get_queue_id(handle->kinfo.tqp[i]); 1057e2cb1decSSalil Mehta if (queue_id < 0) { 1058e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1059e2cb1decSSalil Mehta "Get invalid queue id, ignore it\n"); 1060e2cb1decSSalil Mehta continue; 1061e2cb1decSSalil Mehta } 1062e2cb1decSSalil Mehta 1063e2cb1decSSalil Mehta hclgevf_tqp_enable(hdev, queue_id, 0, false); 1064e2cb1decSSalil Mehta } 1065e2cb1decSSalil Mehta 1066e2cb1decSSalil Mehta /* reset tqp stats */ 1067e2cb1decSSalil Mehta hclgevf_reset_tqp_stats(handle); 1068e2cb1decSSalil Mehta } 1069e2cb1decSSalil Mehta 1070e2cb1decSSalil Mehta static void hclgevf_state_init(struct hclgevf_dev *hdev) 1071e2cb1decSSalil Mehta { 1072e2cb1decSSalil Mehta /* setup tasks for the MBX */ 1073e2cb1decSSalil Mehta INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task); 1074e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 1075e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 1076e2cb1decSSalil Mehta 1077e2cb1decSSalil Mehta /* setup tasks for service timer */ 1078e2cb1decSSalil Mehta timer_setup(&hdev->service_timer, hclgevf_service_timer, 0); 1079e2cb1decSSalil Mehta 1080e2cb1decSSalil Mehta INIT_WORK(&hdev->service_task, hclgevf_service_task); 1081e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 1082e2cb1decSSalil Mehta 1083e2cb1decSSalil Mehta mutex_init(&hdev->mbx_resp.mbx_mutex); 1084e2cb1decSSalil Mehta 1085e2cb1decSSalil Mehta /* bring the device down */ 1086e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1087e2cb1decSSalil Mehta } 1088e2cb1decSSalil Mehta 1089e2cb1decSSalil Mehta static void hclgevf_state_uninit(struct hclgevf_dev *hdev) 1090e2cb1decSSalil Mehta { 1091e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1092e2cb1decSSalil Mehta 1093e2cb1decSSalil Mehta if (hdev->service_timer.function) 1094e2cb1decSSalil Mehta del_timer_sync(&hdev->service_timer); 1095e2cb1decSSalil Mehta if (hdev->service_task.func) 1096e2cb1decSSalil Mehta cancel_work_sync(&hdev->service_task); 1097e2cb1decSSalil Mehta if (hdev->mbx_service_task.func) 1098e2cb1decSSalil Mehta cancel_work_sync(&hdev->mbx_service_task); 1099e2cb1decSSalil Mehta 1100e2cb1decSSalil Mehta mutex_destroy(&hdev->mbx_resp.mbx_mutex); 1101e2cb1decSSalil Mehta } 1102e2cb1decSSalil Mehta 1103e2cb1decSSalil Mehta static int hclgevf_init_msi(struct hclgevf_dev *hdev) 1104e2cb1decSSalil Mehta { 1105e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1106e2cb1decSSalil Mehta int vectors; 1107e2cb1decSSalil Mehta int i; 1108e2cb1decSSalil Mehta 1109e2cb1decSSalil Mehta hdev->num_msi = HCLGEVF_MAX_VF_VECTOR_NUM; 1110e2cb1decSSalil Mehta 1111e2cb1decSSalil Mehta vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, 1112e2cb1decSSalil Mehta PCI_IRQ_MSI | PCI_IRQ_MSIX); 1113e2cb1decSSalil Mehta if (vectors < 0) { 1114e2cb1decSSalil Mehta dev_err(&pdev->dev, 1115e2cb1decSSalil Mehta "failed(%d) to allocate MSI/MSI-X vectors\n", 1116e2cb1decSSalil Mehta vectors); 1117e2cb1decSSalil Mehta return vectors; 1118e2cb1decSSalil Mehta } 1119e2cb1decSSalil Mehta if (vectors < hdev->num_msi) 1120e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1121e2cb1decSSalil Mehta "requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n", 1122e2cb1decSSalil Mehta hdev->num_msi, vectors); 1123e2cb1decSSalil Mehta 1124e2cb1decSSalil Mehta hdev->num_msi = vectors; 1125e2cb1decSSalil Mehta hdev->num_msi_left = vectors; 1126e2cb1decSSalil Mehta hdev->base_msi_vector = pdev->irq; 1127e2cb1decSSalil Mehta 1128e2cb1decSSalil Mehta hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, 1129e2cb1decSSalil Mehta sizeof(u16), GFP_KERNEL); 1130e2cb1decSSalil Mehta if (!hdev->vector_status) { 1131e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1132e2cb1decSSalil Mehta return -ENOMEM; 1133e2cb1decSSalil Mehta } 1134e2cb1decSSalil Mehta 1135e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 1136e2cb1decSSalil Mehta hdev->vector_status[i] = HCLGEVF_INVALID_VPORT; 1137e2cb1decSSalil Mehta 1138e2cb1decSSalil Mehta hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi, 1139e2cb1decSSalil Mehta sizeof(int), GFP_KERNEL); 1140e2cb1decSSalil Mehta if (!hdev->vector_irq) { 1141e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1142e2cb1decSSalil Mehta return -ENOMEM; 1143e2cb1decSSalil Mehta } 1144e2cb1decSSalil Mehta 1145e2cb1decSSalil Mehta return 0; 1146e2cb1decSSalil Mehta } 1147e2cb1decSSalil Mehta 1148e2cb1decSSalil Mehta static void hclgevf_uninit_msi(struct hclgevf_dev *hdev) 1149e2cb1decSSalil Mehta { 1150e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1151e2cb1decSSalil Mehta 1152e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1153e2cb1decSSalil Mehta } 1154e2cb1decSSalil Mehta 1155e2cb1decSSalil Mehta static int hclgevf_misc_irq_init(struct hclgevf_dev *hdev) 1156e2cb1decSSalil Mehta { 1157e2cb1decSSalil Mehta int ret = 0; 1158e2cb1decSSalil Mehta 1159e2cb1decSSalil Mehta hclgevf_get_misc_vector(hdev); 1160e2cb1decSSalil Mehta 1161e2cb1decSSalil Mehta ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, 1162e2cb1decSSalil Mehta 0, "hclgevf_cmd", hdev); 1163e2cb1decSSalil Mehta if (ret) { 1164e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF failed to request misc irq(%d)\n", 1165e2cb1decSSalil Mehta hdev->misc_vector.vector_irq); 1166e2cb1decSSalil Mehta return ret; 1167e2cb1decSSalil Mehta } 1168e2cb1decSSalil Mehta 1169e2cb1decSSalil Mehta /* enable misc. vector(vector 0) */ 1170e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 1171e2cb1decSSalil Mehta 1172e2cb1decSSalil Mehta return ret; 1173e2cb1decSSalil Mehta } 1174e2cb1decSSalil Mehta 1175e2cb1decSSalil Mehta static void hclgevf_misc_irq_uninit(struct hclgevf_dev *hdev) 1176e2cb1decSSalil Mehta { 1177e2cb1decSSalil Mehta /* disable misc vector(vector 0) */ 1178e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 1179e2cb1decSSalil Mehta free_irq(hdev->misc_vector.vector_irq, hdev); 1180e2cb1decSSalil Mehta hclgevf_free_vector(hdev, 0); 1181e2cb1decSSalil Mehta } 1182e2cb1decSSalil Mehta 1183e2cb1decSSalil Mehta static int hclgevf_init_instance(struct hclgevf_dev *hdev, 1184e2cb1decSSalil Mehta struct hnae3_client *client) 1185e2cb1decSSalil Mehta { 1186e2cb1decSSalil Mehta int ret; 1187e2cb1decSSalil Mehta 1188e2cb1decSSalil Mehta switch (client->type) { 1189e2cb1decSSalil Mehta case HNAE3_CLIENT_KNIC: 1190e2cb1decSSalil Mehta hdev->nic_client = client; 1191e2cb1decSSalil Mehta hdev->nic.client = client; 1192e2cb1decSSalil Mehta 1193e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->nic); 1194e2cb1decSSalil Mehta if (ret) 1195e2cb1decSSalil Mehta return ret; 1196e2cb1decSSalil Mehta 1197e2cb1decSSalil Mehta if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { 1198e2cb1decSSalil Mehta struct hnae3_client *rc = hdev->roce_client; 1199e2cb1decSSalil Mehta 1200e2cb1decSSalil Mehta ret = hclgevf_init_roce_base_info(hdev); 1201e2cb1decSSalil Mehta if (ret) 1202e2cb1decSSalil Mehta return ret; 1203e2cb1decSSalil Mehta ret = rc->ops->init_instance(&hdev->roce); 1204e2cb1decSSalil Mehta if (ret) 1205e2cb1decSSalil Mehta return ret; 1206e2cb1decSSalil Mehta } 1207e2cb1decSSalil Mehta break; 1208e2cb1decSSalil Mehta case HNAE3_CLIENT_UNIC: 1209e2cb1decSSalil Mehta hdev->nic_client = client; 1210e2cb1decSSalil Mehta hdev->nic.client = client; 1211e2cb1decSSalil Mehta 1212e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->nic); 1213e2cb1decSSalil Mehta if (ret) 1214e2cb1decSSalil Mehta return ret; 1215e2cb1decSSalil Mehta break; 1216e2cb1decSSalil Mehta case HNAE3_CLIENT_ROCE: 1217e2cb1decSSalil Mehta hdev->roce_client = client; 1218e2cb1decSSalil Mehta hdev->roce.client = client; 1219e2cb1decSSalil Mehta 1220e2cb1decSSalil Mehta if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { 1221e2cb1decSSalil Mehta ret = hclgevf_init_roce_base_info(hdev); 1222e2cb1decSSalil Mehta if (ret) 1223e2cb1decSSalil Mehta return ret; 1224e2cb1decSSalil Mehta 1225e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->roce); 1226e2cb1decSSalil Mehta if (ret) 1227e2cb1decSSalil Mehta return ret; 1228e2cb1decSSalil Mehta } 1229e2cb1decSSalil Mehta } 1230e2cb1decSSalil Mehta 1231e2cb1decSSalil Mehta return 0; 1232e2cb1decSSalil Mehta } 1233e2cb1decSSalil Mehta 1234e2cb1decSSalil Mehta static void hclgevf_uninit_instance(struct hclgevf_dev *hdev, 1235e2cb1decSSalil Mehta struct hnae3_client *client) 1236e2cb1decSSalil Mehta { 1237e2cb1decSSalil Mehta /* un-init roce, if it exists */ 1238e2cb1decSSalil Mehta if (hdev->roce_client) 1239e2cb1decSSalil Mehta hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); 1240e2cb1decSSalil Mehta 1241e2cb1decSSalil Mehta /* un-init nic/unic, if this was not called by roce client */ 1242e2cb1decSSalil Mehta if ((client->ops->uninit_instance) && 1243e2cb1decSSalil Mehta (client->type != HNAE3_CLIENT_ROCE)) 1244e2cb1decSSalil Mehta client->ops->uninit_instance(&hdev->nic, 0); 1245e2cb1decSSalil Mehta } 1246e2cb1decSSalil Mehta 1247e2cb1decSSalil Mehta static int hclgevf_register_client(struct hnae3_client *client, 1248e2cb1decSSalil Mehta struct hnae3_ae_dev *ae_dev) 1249e2cb1decSSalil Mehta { 1250e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1251e2cb1decSSalil Mehta 1252e2cb1decSSalil Mehta return hclgevf_init_instance(hdev, client); 1253e2cb1decSSalil Mehta } 1254e2cb1decSSalil Mehta 1255e2cb1decSSalil Mehta static void hclgevf_unregister_client(struct hnae3_client *client, 1256e2cb1decSSalil Mehta struct hnae3_ae_dev *ae_dev) 1257e2cb1decSSalil Mehta { 1258e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1259e2cb1decSSalil Mehta 1260e2cb1decSSalil Mehta hclgevf_uninit_instance(hdev, client); 1261e2cb1decSSalil Mehta } 1262e2cb1decSSalil Mehta 1263e2cb1decSSalil Mehta static int hclgevf_pci_init(struct hclgevf_dev *hdev) 1264e2cb1decSSalil Mehta { 1265e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1266e2cb1decSSalil Mehta struct hclgevf_hw *hw; 1267e2cb1decSSalil Mehta int ret; 1268e2cb1decSSalil Mehta 1269e2cb1decSSalil Mehta ret = pci_enable_device(pdev); 1270e2cb1decSSalil Mehta if (ret) { 1271e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed to enable PCI device\n"); 1272e2cb1decSSalil Mehta goto err_no_drvdata; 1273e2cb1decSSalil Mehta } 1274e2cb1decSSalil Mehta 1275e2cb1decSSalil Mehta ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 1276e2cb1decSSalil Mehta if (ret) { 1277e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't set consistent PCI DMA, exiting"); 1278e2cb1decSSalil Mehta goto err_disable_device; 1279e2cb1decSSalil Mehta } 1280e2cb1decSSalil Mehta 1281e2cb1decSSalil Mehta ret = pci_request_regions(pdev, HCLGEVF_DRIVER_NAME); 1282e2cb1decSSalil Mehta if (ret) { 1283e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI request regions failed %d\n", ret); 1284e2cb1decSSalil Mehta goto err_disable_device; 1285e2cb1decSSalil Mehta } 1286e2cb1decSSalil Mehta 1287e2cb1decSSalil Mehta pci_set_master(pdev); 1288e2cb1decSSalil Mehta hw = &hdev->hw; 1289e2cb1decSSalil Mehta hw->hdev = hdev; 1290e2cb1decSSalil Mehta hw->io_base = pci_iomap(pdev, 2, 0);; 1291e2cb1decSSalil Mehta if (!hw->io_base) { 1292e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't map configuration register space\n"); 1293e2cb1decSSalil Mehta ret = -ENOMEM; 1294e2cb1decSSalil Mehta goto err_clr_master; 1295e2cb1decSSalil Mehta } 1296e2cb1decSSalil Mehta 1297e2cb1decSSalil Mehta return 0; 1298e2cb1decSSalil Mehta 1299e2cb1decSSalil Mehta err_clr_master: 1300e2cb1decSSalil Mehta pci_clear_master(pdev); 1301e2cb1decSSalil Mehta pci_release_regions(pdev); 1302e2cb1decSSalil Mehta err_disable_device: 1303e2cb1decSSalil Mehta pci_disable_device(pdev); 1304e2cb1decSSalil Mehta err_no_drvdata: 1305e2cb1decSSalil Mehta pci_set_drvdata(pdev, NULL); 1306e2cb1decSSalil Mehta return ret; 1307e2cb1decSSalil Mehta } 1308e2cb1decSSalil Mehta 1309e2cb1decSSalil Mehta static void hclgevf_pci_uninit(struct hclgevf_dev *hdev) 1310e2cb1decSSalil Mehta { 1311e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1312e2cb1decSSalil Mehta 1313e2cb1decSSalil Mehta pci_iounmap(pdev, hdev->hw.io_base); 1314e2cb1decSSalil Mehta pci_clear_master(pdev); 1315e2cb1decSSalil Mehta pci_release_regions(pdev); 1316e2cb1decSSalil Mehta pci_disable_device(pdev); 1317e2cb1decSSalil Mehta pci_set_drvdata(pdev, NULL); 1318e2cb1decSSalil Mehta } 1319e2cb1decSSalil Mehta 1320e2cb1decSSalil Mehta static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) 1321e2cb1decSSalil Mehta { 1322e2cb1decSSalil Mehta struct pci_dev *pdev = ae_dev->pdev; 1323e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 1324e2cb1decSSalil Mehta int ret; 1325e2cb1decSSalil Mehta 1326e2cb1decSSalil Mehta hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); 1327e2cb1decSSalil Mehta if (!hdev) 1328e2cb1decSSalil Mehta return -ENOMEM; 1329e2cb1decSSalil Mehta 1330e2cb1decSSalil Mehta hdev->pdev = pdev; 1331e2cb1decSSalil Mehta hdev->ae_dev = ae_dev; 1332e2cb1decSSalil Mehta ae_dev->priv = hdev; 1333e2cb1decSSalil Mehta 1334e2cb1decSSalil Mehta ret = hclgevf_pci_init(hdev); 1335e2cb1decSSalil Mehta if (ret) { 1336e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI initialization failed\n"); 1337e2cb1decSSalil Mehta return ret; 1338e2cb1decSSalil Mehta } 1339e2cb1decSSalil Mehta 1340e2cb1decSSalil Mehta ret = hclgevf_init_msi(hdev); 1341e2cb1decSSalil Mehta if (ret) { 1342e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to init MSI/MSI-X\n", ret); 1343e2cb1decSSalil Mehta goto err_irq_init; 1344e2cb1decSSalil Mehta } 1345e2cb1decSSalil Mehta 1346e2cb1decSSalil Mehta hclgevf_state_init(hdev); 1347e2cb1decSSalil Mehta 1348e2cb1decSSalil Mehta ret = hclgevf_misc_irq_init(hdev); 1349e2cb1decSSalil Mehta if (ret) { 1350e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to init Misc IRQ(vector0)\n", 1351e2cb1decSSalil Mehta ret); 1352e2cb1decSSalil Mehta goto err_misc_irq_init; 1353e2cb1decSSalil Mehta } 1354e2cb1decSSalil Mehta 1355e2cb1decSSalil Mehta ret = hclgevf_cmd_init(hdev); 1356e2cb1decSSalil Mehta if (ret) 1357e2cb1decSSalil Mehta goto err_cmd_init; 1358e2cb1decSSalil Mehta 1359e2cb1decSSalil Mehta ret = hclgevf_configure(hdev); 1360e2cb1decSSalil Mehta if (ret) { 1361e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", ret); 1362e2cb1decSSalil Mehta goto err_config; 1363e2cb1decSSalil Mehta } 1364e2cb1decSSalil Mehta 1365e2cb1decSSalil Mehta ret = hclgevf_alloc_tqps(hdev); 1366e2cb1decSSalil Mehta if (ret) { 1367e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to allocate TQPs\n", ret); 1368e2cb1decSSalil Mehta goto err_config; 1369e2cb1decSSalil Mehta } 1370e2cb1decSSalil Mehta 1371e2cb1decSSalil Mehta ret = hclgevf_set_handle_info(hdev); 1372e2cb1decSSalil Mehta if (ret) { 1373e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to set handle info\n", ret); 1374e2cb1decSSalil Mehta goto err_config; 1375e2cb1decSSalil Mehta } 1376e2cb1decSSalil Mehta 1377e2cb1decSSalil Mehta ret = hclgevf_enable_tso(hdev, true); 1378e2cb1decSSalil Mehta if (ret) { 1379e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to enable tso\n", ret); 1380e2cb1decSSalil Mehta goto err_config; 1381e2cb1decSSalil Mehta } 1382e2cb1decSSalil Mehta 1383e2cb1decSSalil Mehta /* Initialize VF's MTA */ 1384e2cb1decSSalil Mehta hdev->accept_mta_mc = true; 1385e2cb1decSSalil Mehta ret = hclgevf_cfg_func_mta_filter(&hdev->nic, hdev->accept_mta_mc); 1386e2cb1decSSalil Mehta if (ret) { 1387e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1388e2cb1decSSalil Mehta "failed(%d) to set mta filter mode\n", ret); 1389e2cb1decSSalil Mehta goto err_config; 1390e2cb1decSSalil Mehta } 1391e2cb1decSSalil Mehta 1392e2cb1decSSalil Mehta /* Initialize RSS for this VF */ 1393e2cb1decSSalil Mehta ret = hclgevf_rss_init_hw(hdev); 1394e2cb1decSSalil Mehta if (ret) { 1395e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1396e2cb1decSSalil Mehta "failed(%d) to initialize RSS\n", ret); 1397e2cb1decSSalil Mehta goto err_config; 1398e2cb1decSSalil Mehta } 1399e2cb1decSSalil Mehta 1400e2cb1decSSalil Mehta ret = hclgevf_init_vlan_config(hdev); 1401e2cb1decSSalil Mehta if (ret) { 1402e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1403e2cb1decSSalil Mehta "failed(%d) to initialize VLAN config\n", ret); 1404e2cb1decSSalil Mehta goto err_config; 1405e2cb1decSSalil Mehta } 1406e2cb1decSSalil Mehta 1407e2cb1decSSalil Mehta pr_info("finished initializing %s driver\n", HCLGEVF_DRIVER_NAME); 1408e2cb1decSSalil Mehta 1409e2cb1decSSalil Mehta return 0; 1410e2cb1decSSalil Mehta 1411e2cb1decSSalil Mehta err_config: 1412e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1413e2cb1decSSalil Mehta err_cmd_init: 1414e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1415e2cb1decSSalil Mehta err_misc_irq_init: 1416e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1417e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1418e2cb1decSSalil Mehta err_irq_init: 1419e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1420e2cb1decSSalil Mehta return ret; 1421e2cb1decSSalil Mehta } 1422e2cb1decSSalil Mehta 1423e2cb1decSSalil Mehta static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) 1424e2cb1decSSalil Mehta { 1425e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1426e2cb1decSSalil Mehta 1427e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1428e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1429e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1430e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1431e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1432e2cb1decSSalil Mehta ae_dev->priv = NULL; 1433e2cb1decSSalil Mehta } 1434e2cb1decSSalil Mehta 1435e2cb1decSSalil Mehta static const struct hnae3_ae_ops hclgevf_ops = { 1436e2cb1decSSalil Mehta .init_ae_dev = hclgevf_init_ae_dev, 1437e2cb1decSSalil Mehta .uninit_ae_dev = hclgevf_uninit_ae_dev, 1438e2cb1decSSalil Mehta .init_client_instance = hclgevf_register_client, 1439e2cb1decSSalil Mehta .uninit_client_instance = hclgevf_unregister_client, 1440e2cb1decSSalil Mehta .start = hclgevf_ae_start, 1441e2cb1decSSalil Mehta .stop = hclgevf_ae_stop, 1442e2cb1decSSalil Mehta .map_ring_to_vector = hclgevf_map_ring_to_vector, 1443e2cb1decSSalil Mehta .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector, 1444e2cb1decSSalil Mehta .get_vector = hclgevf_get_vector, 1445e2cb1decSSalil Mehta .reset_queue = hclgevf_reset_tqp, 1446e2cb1decSSalil Mehta .set_promisc_mode = hclgevf_set_promisc_mode, 1447e2cb1decSSalil Mehta .get_mac_addr = hclgevf_get_mac_addr, 1448e2cb1decSSalil Mehta .set_mac_addr = hclgevf_set_mac_addr, 1449e2cb1decSSalil Mehta .add_uc_addr = hclgevf_add_uc_addr, 1450e2cb1decSSalil Mehta .rm_uc_addr = hclgevf_rm_uc_addr, 1451e2cb1decSSalil Mehta .add_mc_addr = hclgevf_add_mc_addr, 1452e2cb1decSSalil Mehta .rm_mc_addr = hclgevf_rm_mc_addr, 1453e2cb1decSSalil Mehta .get_stats = hclgevf_get_stats, 1454e2cb1decSSalil Mehta .update_stats = hclgevf_update_stats, 1455e2cb1decSSalil Mehta .get_strings = hclgevf_get_strings, 1456e2cb1decSSalil Mehta .get_sset_count = hclgevf_get_sset_count, 1457e2cb1decSSalil Mehta .get_rss_key_size = hclgevf_get_rss_key_size, 1458e2cb1decSSalil Mehta .get_rss_indir_size = hclgevf_get_rss_indir_size, 1459e2cb1decSSalil Mehta .get_rss = hclgevf_get_rss, 1460e2cb1decSSalil Mehta .set_rss = hclgevf_set_rss, 1461e2cb1decSSalil Mehta .get_tc_size = hclgevf_get_tc_size, 1462e2cb1decSSalil Mehta .get_fw_version = hclgevf_get_fw_version, 1463e2cb1decSSalil Mehta .set_vlan_filter = hclgevf_set_vlan_filter, 1464e2cb1decSSalil Mehta }; 1465e2cb1decSSalil Mehta 1466e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf = { 1467e2cb1decSSalil Mehta .ops = &hclgevf_ops, 1468e2cb1decSSalil Mehta .name = HCLGEVF_NAME, 1469e2cb1decSSalil Mehta .pdev_id_table = ae_algovf_pci_tbl, 1470e2cb1decSSalil Mehta }; 1471e2cb1decSSalil Mehta 1472e2cb1decSSalil Mehta static int hclgevf_init(void) 1473e2cb1decSSalil Mehta { 1474e2cb1decSSalil Mehta pr_info("%s is initializing\n", HCLGEVF_NAME); 1475e2cb1decSSalil Mehta 1476e2cb1decSSalil Mehta return hnae3_register_ae_algo(&ae_algovf); 1477e2cb1decSSalil Mehta } 1478e2cb1decSSalil Mehta 1479e2cb1decSSalil Mehta static void hclgevf_exit(void) 1480e2cb1decSSalil Mehta { 1481e2cb1decSSalil Mehta hnae3_unregister_ae_algo(&ae_algovf); 1482e2cb1decSSalil Mehta } 1483e2cb1decSSalil Mehta module_init(hclgevf_init); 1484e2cb1decSSalil Mehta module_exit(hclgevf_exit); 1485e2cb1decSSalil Mehta 1486e2cb1decSSalil Mehta MODULE_LICENSE("GPL"); 1487e2cb1decSSalil Mehta MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 1488e2cb1decSSalil Mehta MODULE_DESCRIPTION("HCLGEVF Driver"); 1489e2cb1decSSalil Mehta MODULE_VERSION(HCLGEVF_MOD_VERSION); 1490