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