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 += 52cf72fa63SJian Shen le32_to_cpu(desc.data[1]); 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 += 66cf72fa63SJian Shen le32_to_cpu(desc.data[1]); 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); 108a6c51c26SJian Shen snprintf(buff, ETH_GSTRING_LEN, "txq#%d_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); 116a6c51c26SJian Shen snprintf(buff, ETH_GSTRING_LEN, "rxq#%d_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_alloc_tqps(struct hclgevf_dev *hdev) 205e2cb1decSSalil Mehta { 206e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 207e2cb1decSSalil Mehta int i; 208e2cb1decSSalil Mehta 209e2cb1decSSalil Mehta hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, 210e2cb1decSSalil Mehta sizeof(struct hclgevf_tqp), GFP_KERNEL); 211e2cb1decSSalil Mehta if (!hdev->htqp) 212e2cb1decSSalil Mehta return -ENOMEM; 213e2cb1decSSalil Mehta 214e2cb1decSSalil Mehta tqp = hdev->htqp; 215e2cb1decSSalil Mehta 216e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 217e2cb1decSSalil Mehta tqp->dev = &hdev->pdev->dev; 218e2cb1decSSalil Mehta tqp->index = i; 219e2cb1decSSalil Mehta 220e2cb1decSSalil Mehta tqp->q.ae_algo = &ae_algovf; 221e2cb1decSSalil Mehta tqp->q.buf_size = hdev->rx_buf_len; 222e2cb1decSSalil Mehta tqp->q.desc_num = hdev->num_desc; 223e2cb1decSSalil Mehta tqp->q.io_base = hdev->hw.io_base + HCLGEVF_TQP_REG_OFFSET + 224e2cb1decSSalil Mehta i * HCLGEVF_TQP_REG_SIZE; 225e2cb1decSSalil Mehta 226e2cb1decSSalil Mehta tqp++; 227e2cb1decSSalil Mehta } 228e2cb1decSSalil Mehta 229e2cb1decSSalil Mehta return 0; 230e2cb1decSSalil Mehta } 231e2cb1decSSalil Mehta 232e2cb1decSSalil Mehta static int hclgevf_knic_setup(struct hclgevf_dev *hdev) 233e2cb1decSSalil Mehta { 234e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 235e2cb1decSSalil Mehta struct hnae3_knic_private_info *kinfo; 236e2cb1decSSalil Mehta u16 new_tqps = hdev->num_tqps; 237e2cb1decSSalil Mehta int i; 238e2cb1decSSalil Mehta 239e2cb1decSSalil Mehta kinfo = &nic->kinfo; 240e2cb1decSSalil Mehta kinfo->num_tc = 0; 241e2cb1decSSalil Mehta kinfo->num_desc = hdev->num_desc; 242e2cb1decSSalil Mehta kinfo->rx_buf_len = hdev->rx_buf_len; 243e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) 244e2cb1decSSalil Mehta if (hdev->hw_tc_map & BIT(i)) 245e2cb1decSSalil Mehta kinfo->num_tc++; 246e2cb1decSSalil Mehta 247e2cb1decSSalil Mehta kinfo->rss_size 248e2cb1decSSalil Mehta = min_t(u16, hdev->rss_size_max, new_tqps / kinfo->num_tc); 249e2cb1decSSalil Mehta new_tqps = kinfo->rss_size * kinfo->num_tc; 250e2cb1decSSalil Mehta kinfo->num_tqps = min(new_tqps, hdev->num_tqps); 251e2cb1decSSalil Mehta 252e2cb1decSSalil Mehta kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, 253e2cb1decSSalil Mehta sizeof(struct hnae3_queue *), GFP_KERNEL); 254e2cb1decSSalil Mehta if (!kinfo->tqp) 255e2cb1decSSalil Mehta return -ENOMEM; 256e2cb1decSSalil Mehta 257e2cb1decSSalil Mehta for (i = 0; i < kinfo->num_tqps; i++) { 258e2cb1decSSalil Mehta hdev->htqp[i].q.handle = &hdev->nic; 259e2cb1decSSalil Mehta hdev->htqp[i].q.tqp_index = i; 260e2cb1decSSalil Mehta kinfo->tqp[i] = &hdev->htqp[i].q; 261e2cb1decSSalil Mehta } 262e2cb1decSSalil Mehta 263e2cb1decSSalil Mehta return 0; 264e2cb1decSSalil Mehta } 265e2cb1decSSalil Mehta 266e2cb1decSSalil Mehta static void hclgevf_request_link_info(struct hclgevf_dev *hdev) 267e2cb1decSSalil Mehta { 268e2cb1decSSalil Mehta int status; 269e2cb1decSSalil Mehta u8 resp_msg; 270e2cb1decSSalil Mehta 271e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_STATUS, 0, NULL, 272e2cb1decSSalil Mehta 0, false, &resp_msg, sizeof(u8)); 273e2cb1decSSalil Mehta if (status) 274e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 275e2cb1decSSalil Mehta "VF failed to fetch link status(%d) from PF", status); 276e2cb1decSSalil Mehta } 277e2cb1decSSalil Mehta 278e2cb1decSSalil Mehta void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state) 279e2cb1decSSalil Mehta { 280e2cb1decSSalil Mehta struct hnae3_handle *handle = &hdev->nic; 281e2cb1decSSalil Mehta struct hnae3_client *client; 282e2cb1decSSalil Mehta 283e2cb1decSSalil Mehta client = handle->client; 284e2cb1decSSalil Mehta 285e2cb1decSSalil Mehta if (link_state != hdev->hw.mac.link) { 286e2cb1decSSalil Mehta client->ops->link_status_change(handle, !!link_state); 287e2cb1decSSalil Mehta hdev->hw.mac.link = link_state; 288e2cb1decSSalil Mehta } 289e2cb1decSSalil Mehta } 290e2cb1decSSalil Mehta 291e2cb1decSSalil Mehta static int hclgevf_set_handle_info(struct hclgevf_dev *hdev) 292e2cb1decSSalil Mehta { 293e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 294e2cb1decSSalil Mehta int ret; 295e2cb1decSSalil Mehta 296e2cb1decSSalil Mehta nic->ae_algo = &ae_algovf; 297e2cb1decSSalil Mehta nic->pdev = hdev->pdev; 298e2cb1decSSalil Mehta nic->numa_node_mask = hdev->numa_node_mask; 299424eb834SSalil Mehta nic->flags |= HNAE3_SUPPORT_VF; 300e2cb1decSSalil Mehta 301e2cb1decSSalil Mehta if (hdev->ae_dev->dev_type != HNAE3_DEV_KNIC) { 302e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "unsupported device type %d\n", 303e2cb1decSSalil Mehta hdev->ae_dev->dev_type); 304e2cb1decSSalil Mehta return -EINVAL; 305e2cb1decSSalil Mehta } 306e2cb1decSSalil Mehta 307e2cb1decSSalil Mehta ret = hclgevf_knic_setup(hdev); 308e2cb1decSSalil Mehta if (ret) 309e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF knic setup failed %d\n", 310e2cb1decSSalil Mehta ret); 311e2cb1decSSalil Mehta return ret; 312e2cb1decSSalil Mehta } 313e2cb1decSSalil Mehta 314e2cb1decSSalil Mehta static void hclgevf_free_vector(struct hclgevf_dev *hdev, int vector_id) 315e2cb1decSSalil Mehta { 316e2cb1decSSalil Mehta hdev->vector_status[vector_id] = HCLGEVF_INVALID_VPORT; 317e2cb1decSSalil Mehta hdev->num_msi_left += 1; 318e2cb1decSSalil Mehta hdev->num_msi_used -= 1; 319e2cb1decSSalil Mehta } 320e2cb1decSSalil Mehta 321e2cb1decSSalil Mehta static int hclgevf_get_vector(struct hnae3_handle *handle, u16 vector_num, 322e2cb1decSSalil Mehta struct hnae3_vector_info *vector_info) 323e2cb1decSSalil Mehta { 324e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 325e2cb1decSSalil Mehta struct hnae3_vector_info *vector = vector_info; 326e2cb1decSSalil Mehta int alloc = 0; 327e2cb1decSSalil Mehta int i, j; 328e2cb1decSSalil Mehta 329e2cb1decSSalil Mehta vector_num = min(hdev->num_msi_left, vector_num); 330e2cb1decSSalil Mehta 331e2cb1decSSalil Mehta for (j = 0; j < vector_num; j++) { 332e2cb1decSSalil Mehta for (i = HCLGEVF_MISC_VECTOR_NUM + 1; i < hdev->num_msi; i++) { 333e2cb1decSSalil Mehta if (hdev->vector_status[i] == HCLGEVF_INVALID_VPORT) { 334e2cb1decSSalil Mehta vector->vector = pci_irq_vector(hdev->pdev, i); 335e2cb1decSSalil Mehta vector->io_addr = hdev->hw.io_base + 336e2cb1decSSalil Mehta HCLGEVF_VECTOR_REG_BASE + 337e2cb1decSSalil Mehta (i - 1) * HCLGEVF_VECTOR_REG_OFFSET; 338e2cb1decSSalil Mehta hdev->vector_status[i] = 0; 339e2cb1decSSalil Mehta hdev->vector_irq[i] = vector->vector; 340e2cb1decSSalil Mehta 341e2cb1decSSalil Mehta vector++; 342e2cb1decSSalil Mehta alloc++; 343e2cb1decSSalil Mehta 344e2cb1decSSalil Mehta break; 345e2cb1decSSalil Mehta } 346e2cb1decSSalil Mehta } 347e2cb1decSSalil Mehta } 348e2cb1decSSalil Mehta hdev->num_msi_left -= alloc; 349e2cb1decSSalil Mehta hdev->num_msi_used += alloc; 350e2cb1decSSalil Mehta 351e2cb1decSSalil Mehta return alloc; 352e2cb1decSSalil Mehta } 353e2cb1decSSalil Mehta 354e2cb1decSSalil Mehta static int hclgevf_get_vector_index(struct hclgevf_dev *hdev, int vector) 355e2cb1decSSalil Mehta { 356e2cb1decSSalil Mehta int i; 357e2cb1decSSalil Mehta 358e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 359e2cb1decSSalil Mehta if (vector == hdev->vector_irq[i]) 360e2cb1decSSalil Mehta return i; 361e2cb1decSSalil Mehta 362e2cb1decSSalil Mehta return -EINVAL; 363e2cb1decSSalil Mehta } 364e2cb1decSSalil Mehta 365e2cb1decSSalil Mehta static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle) 366e2cb1decSSalil Mehta { 367e2cb1decSSalil Mehta return HCLGEVF_RSS_KEY_SIZE; 368e2cb1decSSalil Mehta } 369e2cb1decSSalil Mehta 370e2cb1decSSalil Mehta static u32 hclgevf_get_rss_indir_size(struct hnae3_handle *handle) 371e2cb1decSSalil Mehta { 372e2cb1decSSalil Mehta return HCLGEVF_RSS_IND_TBL_SIZE; 373e2cb1decSSalil Mehta } 374e2cb1decSSalil Mehta 375e2cb1decSSalil Mehta static int hclgevf_set_rss_indir_table(struct hclgevf_dev *hdev) 376e2cb1decSSalil Mehta { 377e2cb1decSSalil Mehta const u8 *indir = hdev->rss_cfg.rss_indirection_tbl; 378e2cb1decSSalil Mehta struct hclgevf_rss_indirection_table_cmd *req; 379e2cb1decSSalil Mehta struct hclgevf_desc desc; 380e2cb1decSSalil Mehta int status; 381e2cb1decSSalil Mehta int i, j; 382e2cb1decSSalil Mehta 383e2cb1decSSalil Mehta req = (struct hclgevf_rss_indirection_table_cmd *)desc.data; 384e2cb1decSSalil Mehta 385e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_CFG_TBL_NUM; i++) { 386e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_INDIR_TABLE, 387e2cb1decSSalil Mehta false); 388e2cb1decSSalil Mehta req->start_table_index = i * HCLGEVF_RSS_CFG_TBL_SIZE; 389e2cb1decSSalil Mehta req->rss_set_bitmap = HCLGEVF_RSS_SET_BITMAP_MSK; 390e2cb1decSSalil Mehta for (j = 0; j < HCLGEVF_RSS_CFG_TBL_SIZE; j++) 391e2cb1decSSalil Mehta req->rss_result[j] = 392e2cb1decSSalil Mehta indir[i * HCLGEVF_RSS_CFG_TBL_SIZE + j]; 393e2cb1decSSalil Mehta 394e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 395e2cb1decSSalil Mehta if (status) { 396e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 397e2cb1decSSalil Mehta "VF failed(=%d) to set RSS indirection table\n", 398e2cb1decSSalil Mehta status); 399e2cb1decSSalil Mehta return status; 400e2cb1decSSalil Mehta } 401e2cb1decSSalil Mehta } 402e2cb1decSSalil Mehta 403e2cb1decSSalil Mehta return 0; 404e2cb1decSSalil Mehta } 405e2cb1decSSalil Mehta 406e2cb1decSSalil Mehta static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size) 407e2cb1decSSalil Mehta { 408e2cb1decSSalil Mehta struct hclgevf_rss_tc_mode_cmd *req; 409e2cb1decSSalil Mehta u16 tc_offset[HCLGEVF_MAX_TC_NUM]; 410e2cb1decSSalil Mehta u16 tc_valid[HCLGEVF_MAX_TC_NUM]; 411e2cb1decSSalil Mehta u16 tc_size[HCLGEVF_MAX_TC_NUM]; 412e2cb1decSSalil Mehta struct hclgevf_desc desc; 413e2cb1decSSalil Mehta u16 roundup_size; 414e2cb1decSSalil Mehta int status; 415e2cb1decSSalil Mehta int i; 416e2cb1decSSalil Mehta 417e2cb1decSSalil Mehta req = (struct hclgevf_rss_tc_mode_cmd *)desc.data; 418e2cb1decSSalil Mehta 419e2cb1decSSalil Mehta roundup_size = roundup_pow_of_two(rss_size); 420e2cb1decSSalil Mehta roundup_size = ilog2(roundup_size); 421e2cb1decSSalil Mehta 422e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 423e2cb1decSSalil Mehta tc_valid[i] = !!(hdev->hw_tc_map & BIT(i)); 424e2cb1decSSalil Mehta tc_size[i] = roundup_size; 425e2cb1decSSalil Mehta tc_offset[i] = rss_size * i; 426e2cb1decSSalil Mehta } 427e2cb1decSSalil Mehta 428e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false); 429e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 430e2cb1decSSalil Mehta hnae_set_bit(req->rss_tc_mode[i], HCLGEVF_RSS_TC_VALID_B, 431e2cb1decSSalil Mehta (tc_valid[i] & 0x1)); 432e2cb1decSSalil Mehta hnae_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_SIZE_M, 433e2cb1decSSalil Mehta HCLGEVF_RSS_TC_SIZE_S, tc_size[i]); 434e2cb1decSSalil Mehta hnae_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_OFFSET_M, 435e2cb1decSSalil Mehta HCLGEVF_RSS_TC_OFFSET_S, tc_offset[i]); 436e2cb1decSSalil Mehta } 437e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 438e2cb1decSSalil Mehta if (status) 439e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 440e2cb1decSSalil Mehta "VF failed(=%d) to set rss tc mode\n", status); 441e2cb1decSSalil Mehta 442e2cb1decSSalil Mehta return status; 443e2cb1decSSalil Mehta } 444e2cb1decSSalil Mehta 445e2cb1decSSalil Mehta static int hclgevf_get_rss_hw_cfg(struct hnae3_handle *handle, u8 *hash, 446e2cb1decSSalil Mehta u8 *key) 447e2cb1decSSalil Mehta { 448e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 449e2cb1decSSalil Mehta struct hclgevf_rss_config_cmd *req; 450e2cb1decSSalil Mehta int lkup_times = key ? 3 : 1; 451e2cb1decSSalil Mehta struct hclgevf_desc desc; 452e2cb1decSSalil Mehta int key_offset; 453e2cb1decSSalil Mehta int key_size; 454e2cb1decSSalil Mehta int status; 455e2cb1decSSalil Mehta 456e2cb1decSSalil Mehta req = (struct hclgevf_rss_config_cmd *)desc.data; 457e2cb1decSSalil Mehta lkup_times = (lkup_times == 3) ? 3 : ((hash) ? 1 : 0); 458e2cb1decSSalil Mehta 459e2cb1decSSalil Mehta for (key_offset = 0; key_offset < lkup_times; key_offset++) { 460e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 461e2cb1decSSalil Mehta HCLGEVF_OPC_RSS_GENERIC_CONFIG, 462e2cb1decSSalil Mehta true); 463e2cb1decSSalil Mehta req->hash_config |= (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET); 464e2cb1decSSalil Mehta 465e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 466e2cb1decSSalil Mehta if (status) { 467e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 468e2cb1decSSalil Mehta "failed to get hardware RSS cfg, status = %d\n", 469e2cb1decSSalil Mehta status); 470e2cb1decSSalil Mehta return status; 471e2cb1decSSalil Mehta } 472e2cb1decSSalil Mehta 473e2cb1decSSalil Mehta if (key_offset == 2) 474e2cb1decSSalil Mehta key_size = 475e2cb1decSSalil Mehta HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2; 476e2cb1decSSalil Mehta else 477e2cb1decSSalil Mehta key_size = HCLGEVF_RSS_HASH_KEY_NUM; 478e2cb1decSSalil Mehta 479e2cb1decSSalil Mehta if (key) 480e2cb1decSSalil Mehta memcpy(key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, 481e2cb1decSSalil Mehta req->hash_key, 482e2cb1decSSalil Mehta key_size); 483e2cb1decSSalil Mehta } 484e2cb1decSSalil Mehta 485e2cb1decSSalil Mehta if (hash) { 486e2cb1decSSalil Mehta if ((req->hash_config & 0xf) == HCLGEVF_RSS_HASH_ALGO_TOEPLITZ) 487e2cb1decSSalil Mehta *hash = ETH_RSS_HASH_TOP; 488e2cb1decSSalil Mehta else 489e2cb1decSSalil Mehta *hash = ETH_RSS_HASH_UNKNOWN; 490e2cb1decSSalil Mehta } 491e2cb1decSSalil Mehta 492e2cb1decSSalil Mehta return 0; 493e2cb1decSSalil Mehta } 494e2cb1decSSalil Mehta 495e2cb1decSSalil Mehta static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key, 496e2cb1decSSalil Mehta u8 *hfunc) 497e2cb1decSSalil Mehta { 498e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 499e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 500e2cb1decSSalil Mehta int i; 501e2cb1decSSalil Mehta 502e2cb1decSSalil Mehta if (indir) 503e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 504e2cb1decSSalil Mehta indir[i] = rss_cfg->rss_indirection_tbl[i]; 505e2cb1decSSalil Mehta 506e2cb1decSSalil Mehta return hclgevf_get_rss_hw_cfg(handle, hfunc, key); 507e2cb1decSSalil Mehta } 508e2cb1decSSalil Mehta 509e2cb1decSSalil Mehta static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, 510e2cb1decSSalil Mehta const u8 *key, const u8 hfunc) 511e2cb1decSSalil Mehta { 512e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 513e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 514e2cb1decSSalil Mehta int i; 515e2cb1decSSalil Mehta 516e2cb1decSSalil Mehta /* update the shadow RSS table with user specified qids */ 517e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 518e2cb1decSSalil Mehta rss_cfg->rss_indirection_tbl[i] = indir[i]; 519e2cb1decSSalil Mehta 520e2cb1decSSalil Mehta /* update the hardware */ 521e2cb1decSSalil Mehta return hclgevf_set_rss_indir_table(hdev); 522e2cb1decSSalil Mehta } 523e2cb1decSSalil Mehta 524e2cb1decSSalil Mehta static int hclgevf_get_tc_size(struct hnae3_handle *handle) 525e2cb1decSSalil Mehta { 526e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 527e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 528e2cb1decSSalil Mehta 529e2cb1decSSalil Mehta return rss_cfg->rss_size; 530e2cb1decSSalil Mehta } 531e2cb1decSSalil Mehta 532e2cb1decSSalil Mehta static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, 533e2cb1decSSalil Mehta int vector, 534e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 535e2cb1decSSalil Mehta { 536e2cb1decSSalil Mehta #define HCLGEVF_RING_NODE_VARIABLE_NUM 3 537e2cb1decSSalil Mehta #define HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM 3 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; 542e2cb1decSSalil Mehta int i, 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 hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 555e2cb1decSSalil Mehta type = en ? 556e2cb1decSSalil Mehta HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR; 557e2cb1decSSalil Mehta req->msg[0] = type; 558e2cb1decSSalil Mehta req->msg[1] = vector_id; /* vector_id should be id in VF */ 559e2cb1decSSalil Mehta 560e2cb1decSSalil Mehta i = 0; 561e2cb1decSSalil Mehta for (node = ring_chain; node; node = node->next) { 562e2cb1decSSalil Mehta i++; 563e2cb1decSSalil Mehta /* msg[2] is cause num */ 564e2cb1decSSalil Mehta req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i] = 565e2cb1decSSalil Mehta hnae_get_bit(node->flag, HNAE3_RING_TYPE_B); 566e2cb1decSSalil Mehta req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 1] = 567e2cb1decSSalil Mehta node->tqp_index; 56879eee410SFuyun Liang req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 2] = 56979eee410SFuyun Liang hnae_get_field(node->int_gl_idx, 57079eee410SFuyun Liang HNAE3_RING_GL_IDX_M, 57179eee410SFuyun Liang HNAE3_RING_GL_IDX_S); 57279eee410SFuyun Liang 573e2cb1decSSalil Mehta if (i == (HCLGE_MBX_VF_MSG_DATA_NUM - 574e2cb1decSSalil Mehta HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM) / 575e2cb1decSSalil Mehta HCLGEVF_RING_NODE_VARIABLE_NUM) { 576e2cb1decSSalil Mehta req->msg[2] = i; 577e2cb1decSSalil Mehta 578e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 579e2cb1decSSalil Mehta if (status) { 580e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 581e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", 582e2cb1decSSalil Mehta status); 583e2cb1decSSalil Mehta return status; 584e2cb1decSSalil Mehta } 585e2cb1decSSalil Mehta i = 0; 586e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 587e2cb1decSSalil Mehta HCLGEVF_OPC_MBX_VF_TO_PF, 588e2cb1decSSalil Mehta false); 589e2cb1decSSalil Mehta req->msg[0] = type; 590e2cb1decSSalil Mehta req->msg[1] = vector_id; 591e2cb1decSSalil Mehta } 592e2cb1decSSalil Mehta } 593e2cb1decSSalil Mehta 594e2cb1decSSalil Mehta if (i > 0) { 595e2cb1decSSalil Mehta req->msg[2] = i; 596e2cb1decSSalil Mehta 597e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 598e2cb1decSSalil Mehta if (status) { 599e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 600e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", status); 601e2cb1decSSalil Mehta return status; 602e2cb1decSSalil Mehta } 603e2cb1decSSalil Mehta } 604e2cb1decSSalil Mehta 605e2cb1decSSalil Mehta return 0; 606e2cb1decSSalil Mehta } 607e2cb1decSSalil Mehta 608e2cb1decSSalil Mehta static int hclgevf_map_ring_to_vector(struct hnae3_handle *handle, int vector, 609e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 610e2cb1decSSalil Mehta { 611e2cb1decSSalil Mehta return hclgevf_bind_ring_to_vector(handle, true, vector, ring_chain); 612e2cb1decSSalil Mehta } 613e2cb1decSSalil Mehta 614e2cb1decSSalil Mehta static int hclgevf_unmap_ring_from_vector( 615e2cb1decSSalil Mehta struct hnae3_handle *handle, 616e2cb1decSSalil Mehta int vector, 617e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 618e2cb1decSSalil Mehta { 619e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 620e2cb1decSSalil Mehta int ret, vector_id; 621e2cb1decSSalil Mehta 622e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 623e2cb1decSSalil Mehta if (vector_id < 0) { 624e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 625e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 626e2cb1decSSalil Mehta return vector_id; 627e2cb1decSSalil Mehta } 628e2cb1decSSalil Mehta 629e2cb1decSSalil Mehta ret = hclgevf_bind_ring_to_vector(handle, false, vector, ring_chain); 6300d3e6631SYunsheng Lin if (ret) 631e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 632e2cb1decSSalil Mehta "Unmap ring from vector fail. vector=%d, ret =%d\n", 633e2cb1decSSalil Mehta vector_id, 634e2cb1decSSalil Mehta ret); 6350d3e6631SYunsheng Lin 636e2cb1decSSalil Mehta return ret; 637e2cb1decSSalil Mehta } 638e2cb1decSSalil Mehta 6390d3e6631SYunsheng Lin static int hclgevf_put_vector(struct hnae3_handle *handle, int vector) 6400d3e6631SYunsheng Lin { 6410d3e6631SYunsheng Lin struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 6420d3e6631SYunsheng Lin 643e2cb1decSSalil Mehta hclgevf_free_vector(hdev, vector); 644e2cb1decSSalil Mehta 645e2cb1decSSalil Mehta return 0; 646e2cb1decSSalil Mehta } 647e2cb1decSSalil Mehta 648e2cb1decSSalil Mehta static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) 649e2cb1decSSalil Mehta { 650e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 651e2cb1decSSalil Mehta struct hclgevf_desc desc; 652e2cb1decSSalil Mehta int status; 653e2cb1decSSalil Mehta 654e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 655e2cb1decSSalil Mehta 656e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 657e2cb1decSSalil Mehta req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; 658e2cb1decSSalil Mehta req->msg[1] = en; 659e2cb1decSSalil Mehta 660e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 661e2cb1decSSalil Mehta if (status) 662e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 663e2cb1decSSalil Mehta "Set promisc mode fail, status is %d.\n", status); 664e2cb1decSSalil Mehta 665e2cb1decSSalil Mehta return status; 666e2cb1decSSalil Mehta } 667e2cb1decSSalil Mehta 668e2cb1decSSalil Mehta static void hclgevf_set_promisc_mode(struct hnae3_handle *handle, u32 en) 669e2cb1decSSalil Mehta { 670e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 671e2cb1decSSalil Mehta 672e2cb1decSSalil Mehta hclgevf_cmd_set_promisc_mode(hdev, en); 673e2cb1decSSalil Mehta } 674e2cb1decSSalil Mehta 675e2cb1decSSalil Mehta static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, 676e2cb1decSSalil Mehta int stream_id, bool enable) 677e2cb1decSSalil Mehta { 678e2cb1decSSalil Mehta struct hclgevf_cfg_com_tqp_queue_cmd *req; 679e2cb1decSSalil Mehta struct hclgevf_desc desc; 680e2cb1decSSalil Mehta int status; 681e2cb1decSSalil Mehta 682e2cb1decSSalil Mehta req = (struct hclgevf_cfg_com_tqp_queue_cmd *)desc.data; 683e2cb1decSSalil Mehta 684e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_CFG_COM_TQP_QUEUE, 685e2cb1decSSalil Mehta false); 686e2cb1decSSalil Mehta req->tqp_id = cpu_to_le16(tqp_id & HCLGEVF_RING_ID_MASK); 687e2cb1decSSalil Mehta req->stream_id = cpu_to_le16(stream_id); 688e2cb1decSSalil Mehta req->enable |= enable << HCLGEVF_TQP_ENABLE_B; 689e2cb1decSSalil Mehta 690e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 691e2cb1decSSalil Mehta if (status) 692e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 693e2cb1decSSalil Mehta "TQP enable fail, status =%d.\n", status); 694e2cb1decSSalil Mehta 695e2cb1decSSalil Mehta return status; 696e2cb1decSSalil Mehta } 697e2cb1decSSalil Mehta 698e2cb1decSSalil Mehta static int hclgevf_get_queue_id(struct hnae3_queue *queue) 699e2cb1decSSalil Mehta { 700e2cb1decSSalil Mehta struct hclgevf_tqp *tqp = container_of(queue, struct hclgevf_tqp, q); 701e2cb1decSSalil Mehta 702e2cb1decSSalil Mehta return tqp->index; 703e2cb1decSSalil Mehta } 704e2cb1decSSalil Mehta 705e2cb1decSSalil Mehta static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) 706e2cb1decSSalil Mehta { 707e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 708e2cb1decSSalil Mehta struct hnae3_queue *queue; 709e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 710e2cb1decSSalil Mehta int i; 711e2cb1decSSalil Mehta 712e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 713e2cb1decSSalil Mehta queue = handle->kinfo.tqp[i]; 714e2cb1decSSalil Mehta tqp = container_of(queue, struct hclgevf_tqp, q); 715e2cb1decSSalil Mehta memset(&tqp->tqp_stats, 0, sizeof(tqp->tqp_stats)); 716e2cb1decSSalil Mehta } 717e2cb1decSSalil Mehta } 718e2cb1decSSalil Mehta 719e2cb1decSSalil Mehta static int hclgevf_cfg_func_mta_filter(struct hnae3_handle *handle, bool en) 720e2cb1decSSalil Mehta { 721e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 722e2cb1decSSalil Mehta u8 msg[2] = {0}; 723e2cb1decSSalil Mehta 724e2cb1decSSalil Mehta msg[0] = en; 725e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 726e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, 727e2cb1decSSalil Mehta msg, 1, false, NULL, 0); 728e2cb1decSSalil Mehta } 729e2cb1decSSalil Mehta 730e2cb1decSSalil Mehta static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) 731e2cb1decSSalil Mehta { 732e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 733e2cb1decSSalil Mehta 734e2cb1decSSalil Mehta ether_addr_copy(p, hdev->hw.mac.mac_addr); 735e2cb1decSSalil Mehta } 736e2cb1decSSalil Mehta 73759098055SFuyun Liang static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p, 73859098055SFuyun Liang bool is_first) 739e2cb1decSSalil Mehta { 740e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 741e2cb1decSSalil Mehta u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; 742e2cb1decSSalil Mehta u8 *new_mac_addr = (u8 *)p; 743e2cb1decSSalil Mehta u8 msg_data[ETH_ALEN * 2]; 74459098055SFuyun Liang u16 subcode; 745e2cb1decSSalil Mehta int status; 746e2cb1decSSalil Mehta 747e2cb1decSSalil Mehta ether_addr_copy(msg_data, new_mac_addr); 748e2cb1decSSalil Mehta ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); 749e2cb1decSSalil Mehta 75059098055SFuyun Liang subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD : 75159098055SFuyun Liang HCLGE_MBX_MAC_VLAN_UC_MODIFY; 75259098055SFuyun Liang 753e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 75459098055SFuyun Liang subcode, msg_data, ETH_ALEN * 2, 755e2cb1decSSalil Mehta false, NULL, 0); 756e2cb1decSSalil Mehta if (!status) 757e2cb1decSSalil Mehta ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); 758e2cb1decSSalil Mehta 759e2cb1decSSalil Mehta return status; 760e2cb1decSSalil Mehta } 761e2cb1decSSalil Mehta 762e2cb1decSSalil Mehta static int hclgevf_add_uc_addr(struct hnae3_handle *handle, 763e2cb1decSSalil Mehta const unsigned char *addr) 764e2cb1decSSalil Mehta { 765e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 766e2cb1decSSalil Mehta 767e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 768e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_ADD, 769e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 770e2cb1decSSalil Mehta } 771e2cb1decSSalil Mehta 772e2cb1decSSalil Mehta static int hclgevf_rm_uc_addr(struct hnae3_handle *handle, 773e2cb1decSSalil Mehta const unsigned char *addr) 774e2cb1decSSalil Mehta { 775e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 776e2cb1decSSalil Mehta 777e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 778e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_REMOVE, 779e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 780e2cb1decSSalil Mehta } 781e2cb1decSSalil Mehta 782e2cb1decSSalil Mehta static int hclgevf_add_mc_addr(struct hnae3_handle *handle, 783e2cb1decSSalil Mehta const unsigned char *addr) 784e2cb1decSSalil Mehta { 785e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 786e2cb1decSSalil Mehta 787e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 788e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_ADD, 789e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 790e2cb1decSSalil Mehta } 791e2cb1decSSalil Mehta 792e2cb1decSSalil Mehta static int hclgevf_rm_mc_addr(struct hnae3_handle *handle, 793e2cb1decSSalil Mehta const unsigned char *addr) 794e2cb1decSSalil Mehta { 795e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 796e2cb1decSSalil Mehta 797e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 798e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_REMOVE, 799e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 800e2cb1decSSalil Mehta } 801e2cb1decSSalil Mehta 802e2cb1decSSalil Mehta static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, 803e2cb1decSSalil Mehta __be16 proto, u16 vlan_id, 804e2cb1decSSalil Mehta bool is_kill) 805e2cb1decSSalil Mehta { 806e2cb1decSSalil Mehta #define HCLGEVF_VLAN_MBX_MSG_LEN 5 807e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 808e2cb1decSSalil Mehta u8 msg_data[HCLGEVF_VLAN_MBX_MSG_LEN]; 809e2cb1decSSalil Mehta 810e2cb1decSSalil Mehta if (vlan_id > 4095) 811e2cb1decSSalil Mehta return -EINVAL; 812e2cb1decSSalil Mehta 813e2cb1decSSalil Mehta if (proto != htons(ETH_P_8021Q)) 814e2cb1decSSalil Mehta return -EPROTONOSUPPORT; 815e2cb1decSSalil Mehta 816e2cb1decSSalil Mehta msg_data[0] = is_kill; 817e2cb1decSSalil Mehta memcpy(&msg_data[1], &vlan_id, sizeof(vlan_id)); 818e2cb1decSSalil Mehta memcpy(&msg_data[3], &proto, sizeof(proto)); 819e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, 820e2cb1decSSalil Mehta HCLGE_MBX_VLAN_FILTER, msg_data, 821e2cb1decSSalil Mehta HCLGEVF_VLAN_MBX_MSG_LEN, false, NULL, 0); 822e2cb1decSSalil Mehta } 823e2cb1decSSalil Mehta 824e2cb1decSSalil Mehta static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 825e2cb1decSSalil Mehta { 826e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 827e2cb1decSSalil Mehta u8 msg_data[2]; 828e2cb1decSSalil Mehta 829e2cb1decSSalil Mehta memcpy(&msg_data[0], &queue_id, sizeof(queue_id)); 830e2cb1decSSalil Mehta 831e2cb1decSSalil Mehta hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data, 2, false, 832e2cb1decSSalil Mehta 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); 1069e2cb1decSSalil Mehta } 1070e2cb1decSSalil Mehta 1071e2cb1decSSalil Mehta static void hclgevf_state_init(struct hclgevf_dev *hdev) 1072e2cb1decSSalil Mehta { 1073e2cb1decSSalil Mehta /* setup tasks for the MBX */ 1074e2cb1decSSalil Mehta INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task); 1075e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 1076e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 1077e2cb1decSSalil Mehta 1078e2cb1decSSalil Mehta /* setup tasks for service timer */ 1079e2cb1decSSalil Mehta timer_setup(&hdev->service_timer, hclgevf_service_timer, 0); 1080e2cb1decSSalil Mehta 1081e2cb1decSSalil Mehta INIT_WORK(&hdev->service_task, hclgevf_service_task); 1082e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 1083e2cb1decSSalil Mehta 1084e2cb1decSSalil Mehta mutex_init(&hdev->mbx_resp.mbx_mutex); 1085e2cb1decSSalil Mehta 1086e2cb1decSSalil Mehta /* bring the device down */ 1087e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1088e2cb1decSSalil Mehta } 1089e2cb1decSSalil Mehta 1090e2cb1decSSalil Mehta static void hclgevf_state_uninit(struct hclgevf_dev *hdev) 1091e2cb1decSSalil Mehta { 1092e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1093e2cb1decSSalil Mehta 1094e2cb1decSSalil Mehta if (hdev->service_timer.function) 1095e2cb1decSSalil Mehta del_timer_sync(&hdev->service_timer); 1096e2cb1decSSalil Mehta if (hdev->service_task.func) 1097e2cb1decSSalil Mehta cancel_work_sync(&hdev->service_task); 1098e2cb1decSSalil Mehta if (hdev->mbx_service_task.func) 1099e2cb1decSSalil Mehta cancel_work_sync(&hdev->mbx_service_task); 1100e2cb1decSSalil Mehta 1101e2cb1decSSalil Mehta mutex_destroy(&hdev->mbx_resp.mbx_mutex); 1102e2cb1decSSalil Mehta } 1103e2cb1decSSalil Mehta 1104e2cb1decSSalil Mehta static int hclgevf_init_msi(struct hclgevf_dev *hdev) 1105e2cb1decSSalil Mehta { 1106e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1107e2cb1decSSalil Mehta int vectors; 1108e2cb1decSSalil Mehta int i; 1109e2cb1decSSalil Mehta 1110e2cb1decSSalil Mehta hdev->num_msi = HCLGEVF_MAX_VF_VECTOR_NUM; 1111e2cb1decSSalil Mehta 1112e2cb1decSSalil Mehta vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, 1113e2cb1decSSalil Mehta PCI_IRQ_MSI | PCI_IRQ_MSIX); 1114e2cb1decSSalil Mehta if (vectors < 0) { 1115e2cb1decSSalil Mehta dev_err(&pdev->dev, 1116e2cb1decSSalil Mehta "failed(%d) to allocate MSI/MSI-X vectors\n", 1117e2cb1decSSalil Mehta vectors); 1118e2cb1decSSalil Mehta return vectors; 1119e2cb1decSSalil Mehta } 1120e2cb1decSSalil Mehta if (vectors < hdev->num_msi) 1121e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1122e2cb1decSSalil Mehta "requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n", 1123e2cb1decSSalil Mehta hdev->num_msi, vectors); 1124e2cb1decSSalil Mehta 1125e2cb1decSSalil Mehta hdev->num_msi = vectors; 1126e2cb1decSSalil Mehta hdev->num_msi_left = vectors; 1127e2cb1decSSalil Mehta hdev->base_msi_vector = pdev->irq; 1128e2cb1decSSalil Mehta 1129e2cb1decSSalil Mehta hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, 1130e2cb1decSSalil Mehta sizeof(u16), GFP_KERNEL); 1131e2cb1decSSalil Mehta if (!hdev->vector_status) { 1132e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1133e2cb1decSSalil Mehta return -ENOMEM; 1134e2cb1decSSalil Mehta } 1135e2cb1decSSalil Mehta 1136e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 1137e2cb1decSSalil Mehta hdev->vector_status[i] = HCLGEVF_INVALID_VPORT; 1138e2cb1decSSalil Mehta 1139e2cb1decSSalil Mehta hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi, 1140e2cb1decSSalil Mehta sizeof(int), GFP_KERNEL); 1141e2cb1decSSalil Mehta if (!hdev->vector_irq) { 1142e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1143e2cb1decSSalil Mehta return -ENOMEM; 1144e2cb1decSSalil Mehta } 1145e2cb1decSSalil Mehta 1146e2cb1decSSalil Mehta return 0; 1147e2cb1decSSalil Mehta } 1148e2cb1decSSalil Mehta 1149e2cb1decSSalil Mehta static void hclgevf_uninit_msi(struct hclgevf_dev *hdev) 1150e2cb1decSSalil Mehta { 1151e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1152e2cb1decSSalil Mehta 1153e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1154e2cb1decSSalil Mehta } 1155e2cb1decSSalil Mehta 1156e2cb1decSSalil Mehta static int hclgevf_misc_irq_init(struct hclgevf_dev *hdev) 1157e2cb1decSSalil Mehta { 1158e2cb1decSSalil Mehta int ret = 0; 1159e2cb1decSSalil Mehta 1160e2cb1decSSalil Mehta hclgevf_get_misc_vector(hdev); 1161e2cb1decSSalil Mehta 1162e2cb1decSSalil Mehta ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, 1163e2cb1decSSalil Mehta 0, "hclgevf_cmd", hdev); 1164e2cb1decSSalil Mehta if (ret) { 1165e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF failed to request misc irq(%d)\n", 1166e2cb1decSSalil Mehta hdev->misc_vector.vector_irq); 1167e2cb1decSSalil Mehta return ret; 1168e2cb1decSSalil Mehta } 1169e2cb1decSSalil Mehta 1170e2cb1decSSalil Mehta /* enable misc. vector(vector 0) */ 1171e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 1172e2cb1decSSalil Mehta 1173e2cb1decSSalil Mehta return ret; 1174e2cb1decSSalil Mehta } 1175e2cb1decSSalil Mehta 1176e2cb1decSSalil Mehta static void hclgevf_misc_irq_uninit(struct hclgevf_dev *hdev) 1177e2cb1decSSalil Mehta { 1178e2cb1decSSalil Mehta /* disable misc vector(vector 0) */ 1179e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 1180e2cb1decSSalil Mehta free_irq(hdev->misc_vector.vector_irq, hdev); 1181e2cb1decSSalil Mehta hclgevf_free_vector(hdev, 0); 1182e2cb1decSSalil Mehta } 1183e2cb1decSSalil Mehta 1184e2cb1decSSalil Mehta static int hclgevf_init_instance(struct hclgevf_dev *hdev, 1185e2cb1decSSalil Mehta struct hnae3_client *client) 1186e2cb1decSSalil Mehta { 1187e2cb1decSSalil Mehta int ret; 1188e2cb1decSSalil Mehta 1189e2cb1decSSalil Mehta switch (client->type) { 1190e2cb1decSSalil Mehta case HNAE3_CLIENT_KNIC: 1191e2cb1decSSalil Mehta hdev->nic_client = client; 1192e2cb1decSSalil Mehta hdev->nic.client = client; 1193e2cb1decSSalil Mehta 1194e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->nic); 1195e2cb1decSSalil Mehta if (ret) 1196e2cb1decSSalil Mehta return ret; 1197e2cb1decSSalil Mehta 1198e2cb1decSSalil Mehta if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { 1199e2cb1decSSalil Mehta struct hnae3_client *rc = hdev->roce_client; 1200e2cb1decSSalil Mehta 1201e2cb1decSSalil Mehta ret = hclgevf_init_roce_base_info(hdev); 1202e2cb1decSSalil Mehta if (ret) 1203e2cb1decSSalil Mehta return ret; 1204e2cb1decSSalil Mehta ret = rc->ops->init_instance(&hdev->roce); 1205e2cb1decSSalil Mehta if (ret) 1206e2cb1decSSalil Mehta return ret; 1207e2cb1decSSalil Mehta } 1208e2cb1decSSalil Mehta break; 1209e2cb1decSSalil Mehta case HNAE3_CLIENT_UNIC: 1210e2cb1decSSalil Mehta hdev->nic_client = client; 1211e2cb1decSSalil Mehta hdev->nic.client = client; 1212e2cb1decSSalil Mehta 1213e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->nic); 1214e2cb1decSSalil Mehta if (ret) 1215e2cb1decSSalil Mehta return ret; 1216e2cb1decSSalil Mehta break; 1217e2cb1decSSalil Mehta case HNAE3_CLIENT_ROCE: 1218e2cb1decSSalil Mehta hdev->roce_client = client; 1219e2cb1decSSalil Mehta hdev->roce.client = client; 1220e2cb1decSSalil Mehta 1221e2cb1decSSalil Mehta if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { 1222e2cb1decSSalil Mehta ret = hclgevf_init_roce_base_info(hdev); 1223e2cb1decSSalil Mehta if (ret) 1224e2cb1decSSalil Mehta return ret; 1225e2cb1decSSalil Mehta 1226e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->roce); 1227e2cb1decSSalil Mehta if (ret) 1228e2cb1decSSalil Mehta return ret; 1229e2cb1decSSalil Mehta } 1230e2cb1decSSalil Mehta } 1231e2cb1decSSalil Mehta 1232e2cb1decSSalil Mehta return 0; 1233e2cb1decSSalil Mehta } 1234e2cb1decSSalil Mehta 1235e2cb1decSSalil Mehta static void hclgevf_uninit_instance(struct hclgevf_dev *hdev, 1236e2cb1decSSalil Mehta struct hnae3_client *client) 1237e2cb1decSSalil Mehta { 1238e2cb1decSSalil Mehta /* un-init roce, if it exists */ 1239e2cb1decSSalil Mehta if (hdev->roce_client) 1240e2cb1decSSalil Mehta hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); 1241e2cb1decSSalil Mehta 1242e2cb1decSSalil Mehta /* un-init nic/unic, if this was not called by roce client */ 1243e2cb1decSSalil Mehta if ((client->ops->uninit_instance) && 1244e2cb1decSSalil Mehta (client->type != HNAE3_CLIENT_ROCE)) 1245e2cb1decSSalil Mehta client->ops->uninit_instance(&hdev->nic, 0); 1246e2cb1decSSalil Mehta } 1247e2cb1decSSalil Mehta 1248e2cb1decSSalil Mehta static int hclgevf_register_client(struct hnae3_client *client, 1249e2cb1decSSalil Mehta struct hnae3_ae_dev *ae_dev) 1250e2cb1decSSalil Mehta { 1251e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1252e2cb1decSSalil Mehta 1253e2cb1decSSalil Mehta return hclgevf_init_instance(hdev, client); 1254e2cb1decSSalil Mehta } 1255e2cb1decSSalil Mehta 1256e2cb1decSSalil Mehta static void hclgevf_unregister_client(struct hnae3_client *client, 1257e2cb1decSSalil Mehta struct hnae3_ae_dev *ae_dev) 1258e2cb1decSSalil Mehta { 1259e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1260e2cb1decSSalil Mehta 1261e2cb1decSSalil Mehta hclgevf_uninit_instance(hdev, client); 1262e2cb1decSSalil Mehta } 1263e2cb1decSSalil Mehta 1264e2cb1decSSalil Mehta static int hclgevf_pci_init(struct hclgevf_dev *hdev) 1265e2cb1decSSalil Mehta { 1266e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1267e2cb1decSSalil Mehta struct hclgevf_hw *hw; 1268e2cb1decSSalil Mehta int ret; 1269e2cb1decSSalil Mehta 1270e2cb1decSSalil Mehta ret = pci_enable_device(pdev); 1271e2cb1decSSalil Mehta if (ret) { 1272e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed to enable PCI device\n"); 1273e2cb1decSSalil Mehta goto err_no_drvdata; 1274e2cb1decSSalil Mehta } 1275e2cb1decSSalil Mehta 1276e2cb1decSSalil Mehta ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 1277e2cb1decSSalil Mehta if (ret) { 1278e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't set consistent PCI DMA, exiting"); 1279e2cb1decSSalil Mehta goto err_disable_device; 1280e2cb1decSSalil Mehta } 1281e2cb1decSSalil Mehta 1282e2cb1decSSalil Mehta ret = pci_request_regions(pdev, HCLGEVF_DRIVER_NAME); 1283e2cb1decSSalil Mehta if (ret) { 1284e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI request regions failed %d\n", ret); 1285e2cb1decSSalil Mehta goto err_disable_device; 1286e2cb1decSSalil Mehta } 1287e2cb1decSSalil Mehta 1288e2cb1decSSalil Mehta pci_set_master(pdev); 1289e2cb1decSSalil Mehta hw = &hdev->hw; 1290e2cb1decSSalil Mehta hw->hdev = hdev; 12912e1ea493SPeng Li hw->io_base = pci_iomap(pdev, 2, 0); 1292e2cb1decSSalil Mehta if (!hw->io_base) { 1293e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't map configuration register space\n"); 1294e2cb1decSSalil Mehta ret = -ENOMEM; 1295e2cb1decSSalil Mehta goto err_clr_master; 1296e2cb1decSSalil Mehta } 1297e2cb1decSSalil Mehta 1298e2cb1decSSalil Mehta return 0; 1299e2cb1decSSalil Mehta 1300e2cb1decSSalil Mehta err_clr_master: 1301e2cb1decSSalil Mehta pci_clear_master(pdev); 1302e2cb1decSSalil Mehta pci_release_regions(pdev); 1303e2cb1decSSalil Mehta err_disable_device: 1304e2cb1decSSalil Mehta pci_disable_device(pdev); 1305e2cb1decSSalil Mehta err_no_drvdata: 1306e2cb1decSSalil Mehta pci_set_drvdata(pdev, NULL); 1307e2cb1decSSalil Mehta return ret; 1308e2cb1decSSalil Mehta } 1309e2cb1decSSalil Mehta 1310e2cb1decSSalil Mehta static void hclgevf_pci_uninit(struct hclgevf_dev *hdev) 1311e2cb1decSSalil Mehta { 1312e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1313e2cb1decSSalil Mehta 1314e2cb1decSSalil Mehta pci_iounmap(pdev, hdev->hw.io_base); 1315e2cb1decSSalil Mehta pci_clear_master(pdev); 1316e2cb1decSSalil Mehta pci_release_regions(pdev); 1317e2cb1decSSalil Mehta pci_disable_device(pdev); 1318e2cb1decSSalil Mehta pci_set_drvdata(pdev, NULL); 1319e2cb1decSSalil Mehta } 1320e2cb1decSSalil Mehta 1321e2cb1decSSalil Mehta static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) 1322e2cb1decSSalil Mehta { 1323e2cb1decSSalil Mehta struct pci_dev *pdev = ae_dev->pdev; 1324e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 1325e2cb1decSSalil Mehta int ret; 1326e2cb1decSSalil Mehta 1327e2cb1decSSalil Mehta hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); 1328e2cb1decSSalil Mehta if (!hdev) 1329e2cb1decSSalil Mehta return -ENOMEM; 1330e2cb1decSSalil Mehta 1331e2cb1decSSalil Mehta hdev->pdev = pdev; 1332e2cb1decSSalil Mehta hdev->ae_dev = ae_dev; 1333e2cb1decSSalil Mehta ae_dev->priv = hdev; 1334e2cb1decSSalil Mehta 1335e2cb1decSSalil Mehta ret = hclgevf_pci_init(hdev); 1336e2cb1decSSalil Mehta if (ret) { 1337e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI initialization failed\n"); 1338e2cb1decSSalil Mehta return ret; 1339e2cb1decSSalil Mehta } 1340e2cb1decSSalil Mehta 1341e2cb1decSSalil Mehta ret = hclgevf_init_msi(hdev); 1342e2cb1decSSalil Mehta if (ret) { 1343e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to init MSI/MSI-X\n", ret); 1344e2cb1decSSalil Mehta goto err_irq_init; 1345e2cb1decSSalil Mehta } 1346e2cb1decSSalil Mehta 1347e2cb1decSSalil Mehta hclgevf_state_init(hdev); 1348e2cb1decSSalil Mehta 1349e2cb1decSSalil Mehta ret = hclgevf_misc_irq_init(hdev); 1350e2cb1decSSalil Mehta if (ret) { 1351e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to init Misc IRQ(vector0)\n", 1352e2cb1decSSalil Mehta ret); 1353e2cb1decSSalil Mehta goto err_misc_irq_init; 1354e2cb1decSSalil Mehta } 1355e2cb1decSSalil Mehta 1356e2cb1decSSalil Mehta ret = hclgevf_cmd_init(hdev); 1357e2cb1decSSalil Mehta if (ret) 1358e2cb1decSSalil Mehta goto err_cmd_init; 1359e2cb1decSSalil Mehta 1360e2cb1decSSalil Mehta ret = hclgevf_configure(hdev); 1361e2cb1decSSalil Mehta if (ret) { 1362e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", ret); 1363e2cb1decSSalil Mehta goto err_config; 1364e2cb1decSSalil Mehta } 1365e2cb1decSSalil Mehta 1366e2cb1decSSalil Mehta ret = hclgevf_alloc_tqps(hdev); 1367e2cb1decSSalil Mehta if (ret) { 1368e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to allocate TQPs\n", ret); 1369e2cb1decSSalil Mehta goto err_config; 1370e2cb1decSSalil Mehta } 1371e2cb1decSSalil Mehta 1372e2cb1decSSalil Mehta ret = hclgevf_set_handle_info(hdev); 1373e2cb1decSSalil Mehta if (ret) { 1374e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to set handle info\n", ret); 1375e2cb1decSSalil Mehta goto err_config; 1376e2cb1decSSalil Mehta } 1377e2cb1decSSalil Mehta 1378e2cb1decSSalil Mehta /* Initialize VF's MTA */ 1379e2cb1decSSalil Mehta hdev->accept_mta_mc = true; 1380e2cb1decSSalil Mehta ret = hclgevf_cfg_func_mta_filter(&hdev->nic, hdev->accept_mta_mc); 1381e2cb1decSSalil Mehta if (ret) { 1382e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1383e2cb1decSSalil Mehta "failed(%d) to set mta filter mode\n", ret); 1384e2cb1decSSalil Mehta goto err_config; 1385e2cb1decSSalil Mehta } 1386e2cb1decSSalil Mehta 1387e2cb1decSSalil Mehta /* Initialize RSS for this VF */ 1388e2cb1decSSalil Mehta ret = hclgevf_rss_init_hw(hdev); 1389e2cb1decSSalil Mehta if (ret) { 1390e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1391e2cb1decSSalil Mehta "failed(%d) to initialize RSS\n", ret); 1392e2cb1decSSalil Mehta goto err_config; 1393e2cb1decSSalil Mehta } 1394e2cb1decSSalil Mehta 1395e2cb1decSSalil Mehta ret = hclgevf_init_vlan_config(hdev); 1396e2cb1decSSalil Mehta if (ret) { 1397e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1398e2cb1decSSalil Mehta "failed(%d) to initialize VLAN config\n", ret); 1399e2cb1decSSalil Mehta goto err_config; 1400e2cb1decSSalil Mehta } 1401e2cb1decSSalil Mehta 1402e2cb1decSSalil Mehta pr_info("finished initializing %s driver\n", HCLGEVF_DRIVER_NAME); 1403e2cb1decSSalil Mehta 1404e2cb1decSSalil Mehta return 0; 1405e2cb1decSSalil Mehta 1406e2cb1decSSalil Mehta err_config: 1407e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1408e2cb1decSSalil Mehta err_cmd_init: 1409e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1410e2cb1decSSalil Mehta err_misc_irq_init: 1411e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1412e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1413e2cb1decSSalil Mehta err_irq_init: 1414e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1415e2cb1decSSalil Mehta return ret; 1416e2cb1decSSalil Mehta } 1417e2cb1decSSalil Mehta 1418e2cb1decSSalil Mehta static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) 1419e2cb1decSSalil Mehta { 1420e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1421e2cb1decSSalil Mehta 1422e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1423e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1424e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1425e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1426e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1427e2cb1decSSalil Mehta ae_dev->priv = NULL; 1428e2cb1decSSalil Mehta } 1429e2cb1decSSalil Mehta 1430849e4607SPeng Li static u32 hclgevf_get_max_channels(struct hclgevf_dev *hdev) 1431849e4607SPeng Li { 1432849e4607SPeng Li struct hnae3_handle *nic = &hdev->nic; 1433849e4607SPeng Li struct hnae3_knic_private_info *kinfo = &nic->kinfo; 1434849e4607SPeng Li 1435849e4607SPeng Li return min_t(u32, hdev->rss_size_max * kinfo->num_tc, hdev->num_tqps); 1436849e4607SPeng Li } 1437849e4607SPeng Li 1438849e4607SPeng Li /** 1439849e4607SPeng Li * hclgevf_get_channels - Get the current channels enabled and max supported. 1440849e4607SPeng Li * @handle: hardware information for network interface 1441849e4607SPeng Li * @ch: ethtool channels structure 1442849e4607SPeng Li * 1443849e4607SPeng Li * We don't support separate tx and rx queues as channels. The other count 1444849e4607SPeng Li * represents how many queues are being used for control. max_combined counts 1445849e4607SPeng Li * how many queue pairs we can support. They may not be mapped 1 to 1 with 1446849e4607SPeng Li * q_vectors since we support a lot more queue pairs than q_vectors. 1447849e4607SPeng Li **/ 1448849e4607SPeng Li static void hclgevf_get_channels(struct hnae3_handle *handle, 1449849e4607SPeng Li struct ethtool_channels *ch) 1450849e4607SPeng Li { 1451849e4607SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1452849e4607SPeng Li 1453849e4607SPeng Li ch->max_combined = hclgevf_get_max_channels(hdev); 1454849e4607SPeng Li ch->other_count = 0; 1455849e4607SPeng Li ch->max_other = 0; 1456849e4607SPeng Li ch->combined_count = hdev->num_tqps; 1457849e4607SPeng Li } 1458849e4607SPeng Li 1459cc719218SPeng Li static void hclgevf_get_tqps_and_rss_info(struct hnae3_handle *handle, 1460cc719218SPeng Li u16 *free_tqps, u16 *max_rss_size) 1461cc719218SPeng Li { 1462cc719218SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1463cc719218SPeng Li 1464cc719218SPeng Li *free_tqps = 0; 1465cc719218SPeng Li *max_rss_size = hdev->rss_size_max; 1466cc719218SPeng Li } 1467cc719218SPeng Li 1468e2cb1decSSalil Mehta static const struct hnae3_ae_ops hclgevf_ops = { 1469e2cb1decSSalil Mehta .init_ae_dev = hclgevf_init_ae_dev, 1470e2cb1decSSalil Mehta .uninit_ae_dev = hclgevf_uninit_ae_dev, 1471e2cb1decSSalil Mehta .init_client_instance = hclgevf_register_client, 1472e2cb1decSSalil Mehta .uninit_client_instance = hclgevf_unregister_client, 1473e2cb1decSSalil Mehta .start = hclgevf_ae_start, 1474e2cb1decSSalil Mehta .stop = hclgevf_ae_stop, 1475e2cb1decSSalil Mehta .map_ring_to_vector = hclgevf_map_ring_to_vector, 1476e2cb1decSSalil Mehta .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector, 1477e2cb1decSSalil Mehta .get_vector = hclgevf_get_vector, 14780d3e6631SYunsheng Lin .put_vector = hclgevf_put_vector, 1479e2cb1decSSalil Mehta .reset_queue = hclgevf_reset_tqp, 1480e2cb1decSSalil Mehta .set_promisc_mode = hclgevf_set_promisc_mode, 1481e2cb1decSSalil Mehta .get_mac_addr = hclgevf_get_mac_addr, 1482e2cb1decSSalil Mehta .set_mac_addr = hclgevf_set_mac_addr, 1483e2cb1decSSalil Mehta .add_uc_addr = hclgevf_add_uc_addr, 1484e2cb1decSSalil Mehta .rm_uc_addr = hclgevf_rm_uc_addr, 1485e2cb1decSSalil Mehta .add_mc_addr = hclgevf_add_mc_addr, 1486e2cb1decSSalil Mehta .rm_mc_addr = hclgevf_rm_mc_addr, 1487e2cb1decSSalil Mehta .get_stats = hclgevf_get_stats, 1488e2cb1decSSalil Mehta .update_stats = hclgevf_update_stats, 1489e2cb1decSSalil Mehta .get_strings = hclgevf_get_strings, 1490e2cb1decSSalil Mehta .get_sset_count = hclgevf_get_sset_count, 1491e2cb1decSSalil Mehta .get_rss_key_size = hclgevf_get_rss_key_size, 1492e2cb1decSSalil Mehta .get_rss_indir_size = hclgevf_get_rss_indir_size, 1493e2cb1decSSalil Mehta .get_rss = hclgevf_get_rss, 1494e2cb1decSSalil Mehta .set_rss = hclgevf_set_rss, 1495e2cb1decSSalil Mehta .get_tc_size = hclgevf_get_tc_size, 1496e2cb1decSSalil Mehta .get_fw_version = hclgevf_get_fw_version, 1497e2cb1decSSalil Mehta .set_vlan_filter = hclgevf_set_vlan_filter, 1498849e4607SPeng Li .get_channels = hclgevf_get_channels, 1499cc719218SPeng Li .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info, 1500e2cb1decSSalil Mehta }; 1501e2cb1decSSalil Mehta 1502e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf = { 1503e2cb1decSSalil Mehta .ops = &hclgevf_ops, 1504e2cb1decSSalil Mehta .name = HCLGEVF_NAME, 1505e2cb1decSSalil Mehta .pdev_id_table = ae_algovf_pci_tbl, 1506e2cb1decSSalil Mehta }; 1507e2cb1decSSalil Mehta 1508e2cb1decSSalil Mehta static int hclgevf_init(void) 1509e2cb1decSSalil Mehta { 1510e2cb1decSSalil Mehta pr_info("%s is initializing\n", HCLGEVF_NAME); 1511e2cb1decSSalil Mehta 1512e2cb1decSSalil Mehta return hnae3_register_ae_algo(&ae_algovf); 1513e2cb1decSSalil Mehta } 1514e2cb1decSSalil Mehta 1515e2cb1decSSalil Mehta static void hclgevf_exit(void) 1516e2cb1decSSalil Mehta { 1517e2cb1decSSalil Mehta hnae3_unregister_ae_algo(&ae_algovf); 1518e2cb1decSSalil Mehta } 1519e2cb1decSSalil Mehta module_init(hclgevf_init); 1520e2cb1decSSalil Mehta module_exit(hclgevf_exit); 1521e2cb1decSSalil Mehta 1522e2cb1decSSalil Mehta MODULE_LICENSE("GPL"); 1523e2cb1decSSalil Mehta MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 1524e2cb1decSSalil Mehta MODULE_DESCRIPTION("HCLGEVF Driver"); 1525e2cb1decSSalil Mehta MODULE_VERSION(HCLGEVF_MOD_VERSION); 1526