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 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 537e2cb1decSSalil Mehta struct hnae3_ring_chain_node *node; 538e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 539e2cb1decSSalil Mehta struct hclgevf_desc desc; 5405d02a58dSYunsheng Lin int i = 0, vector_id; 541e2cb1decSSalil Mehta int status; 542e2cb1decSSalil Mehta u8 type; 543e2cb1decSSalil Mehta 544e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 545e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 546e2cb1decSSalil Mehta if (vector_id < 0) { 547e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 548e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 549e2cb1decSSalil Mehta return vector_id; 550e2cb1decSSalil Mehta } 551e2cb1decSSalil Mehta 552e2cb1decSSalil Mehta for (node = ring_chain; node; node = node->next) { 5535d02a58dSYunsheng Lin int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 5545d02a58dSYunsheng Lin HCLGE_MBX_RING_NODE_VARIABLE_NUM * i; 5555d02a58dSYunsheng Lin 5565d02a58dSYunsheng Lin if (i == 0) { 5575d02a58dSYunsheng Lin hclgevf_cmd_setup_basic_desc(&desc, 5585d02a58dSYunsheng Lin HCLGEVF_OPC_MBX_VF_TO_PF, 5595d02a58dSYunsheng Lin false); 5605d02a58dSYunsheng Lin type = en ? 5615d02a58dSYunsheng Lin HCLGE_MBX_MAP_RING_TO_VECTOR : 5625d02a58dSYunsheng Lin HCLGE_MBX_UNMAP_RING_TO_VECTOR; 5635d02a58dSYunsheng Lin req->msg[0] = type; 5645d02a58dSYunsheng Lin req->msg[1] = vector_id; 5655d02a58dSYunsheng Lin } 5665d02a58dSYunsheng Lin 5675d02a58dSYunsheng Lin req->msg[idx_offset] = 568e2cb1decSSalil Mehta hnae_get_bit(node->flag, HNAE3_RING_TYPE_B); 5695d02a58dSYunsheng Lin req->msg[idx_offset + 1] = node->tqp_index; 5705d02a58dSYunsheng Lin req->msg[idx_offset + 2] = hnae_get_field(node->int_gl_idx, 57179eee410SFuyun Liang HNAE3_RING_GL_IDX_M, 57279eee410SFuyun Liang HNAE3_RING_GL_IDX_S); 57379eee410SFuyun Liang 5745d02a58dSYunsheng Lin i++; 5755d02a58dSYunsheng Lin if ((i == (HCLGE_MBX_VF_MSG_DATA_NUM - 5765d02a58dSYunsheng Lin HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) / 5775d02a58dSYunsheng Lin HCLGE_MBX_RING_NODE_VARIABLE_NUM) || 5785d02a58dSYunsheng Lin !node->next) { 579e2cb1decSSalil Mehta req->msg[2] = i; 580e2cb1decSSalil Mehta 581e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 582e2cb1decSSalil Mehta if (status) { 583e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 584e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", 585e2cb1decSSalil Mehta status); 586e2cb1decSSalil Mehta return status; 587e2cb1decSSalil Mehta } 588e2cb1decSSalil Mehta i = 0; 589e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 590e2cb1decSSalil Mehta HCLGEVF_OPC_MBX_VF_TO_PF, 591e2cb1decSSalil Mehta false); 592e2cb1decSSalil Mehta req->msg[0] = type; 593e2cb1decSSalil Mehta req->msg[1] = vector_id; 594e2cb1decSSalil Mehta } 595e2cb1decSSalil Mehta } 596e2cb1decSSalil Mehta 597e2cb1decSSalil Mehta return 0; 598e2cb1decSSalil Mehta } 599e2cb1decSSalil Mehta 600e2cb1decSSalil Mehta static int hclgevf_map_ring_to_vector(struct hnae3_handle *handle, int vector, 601e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 602e2cb1decSSalil Mehta { 603e2cb1decSSalil Mehta return hclgevf_bind_ring_to_vector(handle, true, vector, ring_chain); 604e2cb1decSSalil Mehta } 605e2cb1decSSalil Mehta 606e2cb1decSSalil Mehta static int hclgevf_unmap_ring_from_vector( 607e2cb1decSSalil Mehta struct hnae3_handle *handle, 608e2cb1decSSalil Mehta int vector, 609e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 610e2cb1decSSalil Mehta { 611e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 612e2cb1decSSalil Mehta int ret, vector_id; 613e2cb1decSSalil Mehta 614e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 615e2cb1decSSalil Mehta if (vector_id < 0) { 616e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 617e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 618e2cb1decSSalil Mehta return vector_id; 619e2cb1decSSalil Mehta } 620e2cb1decSSalil Mehta 621e2cb1decSSalil Mehta ret = hclgevf_bind_ring_to_vector(handle, false, vector, ring_chain); 6220d3e6631SYunsheng Lin if (ret) 623e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 624e2cb1decSSalil Mehta "Unmap ring from vector fail. vector=%d, ret =%d\n", 625e2cb1decSSalil Mehta vector_id, 626e2cb1decSSalil Mehta ret); 6270d3e6631SYunsheng Lin 628e2cb1decSSalil Mehta return ret; 629e2cb1decSSalil Mehta } 630e2cb1decSSalil Mehta 6310d3e6631SYunsheng Lin static int hclgevf_put_vector(struct hnae3_handle *handle, int vector) 6320d3e6631SYunsheng Lin { 6330d3e6631SYunsheng Lin struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 6340d3e6631SYunsheng Lin 635e2cb1decSSalil Mehta hclgevf_free_vector(hdev, vector); 636e2cb1decSSalil Mehta 637e2cb1decSSalil Mehta return 0; 638e2cb1decSSalil Mehta } 639e2cb1decSSalil Mehta 640e2cb1decSSalil Mehta static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) 641e2cb1decSSalil Mehta { 642e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 643e2cb1decSSalil Mehta struct hclgevf_desc desc; 644e2cb1decSSalil Mehta int status; 645e2cb1decSSalil Mehta 646e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 647e2cb1decSSalil Mehta 648e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 649e2cb1decSSalil Mehta req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; 650e2cb1decSSalil Mehta req->msg[1] = en; 651e2cb1decSSalil Mehta 652e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 653e2cb1decSSalil Mehta if (status) 654e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 655e2cb1decSSalil Mehta "Set promisc mode fail, status is %d.\n", status); 656e2cb1decSSalil Mehta 657e2cb1decSSalil Mehta return status; 658e2cb1decSSalil Mehta } 659e2cb1decSSalil Mehta 660e2cb1decSSalil Mehta static void hclgevf_set_promisc_mode(struct hnae3_handle *handle, u32 en) 661e2cb1decSSalil Mehta { 662e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 663e2cb1decSSalil Mehta 664e2cb1decSSalil Mehta hclgevf_cmd_set_promisc_mode(hdev, en); 665e2cb1decSSalil Mehta } 666e2cb1decSSalil Mehta 667e2cb1decSSalil Mehta static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, 668e2cb1decSSalil Mehta int stream_id, bool enable) 669e2cb1decSSalil Mehta { 670e2cb1decSSalil Mehta struct hclgevf_cfg_com_tqp_queue_cmd *req; 671e2cb1decSSalil Mehta struct hclgevf_desc desc; 672e2cb1decSSalil Mehta int status; 673e2cb1decSSalil Mehta 674e2cb1decSSalil Mehta req = (struct hclgevf_cfg_com_tqp_queue_cmd *)desc.data; 675e2cb1decSSalil Mehta 676e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_CFG_COM_TQP_QUEUE, 677e2cb1decSSalil Mehta false); 678e2cb1decSSalil Mehta req->tqp_id = cpu_to_le16(tqp_id & HCLGEVF_RING_ID_MASK); 679e2cb1decSSalil Mehta req->stream_id = cpu_to_le16(stream_id); 680e2cb1decSSalil Mehta req->enable |= enable << HCLGEVF_TQP_ENABLE_B; 681e2cb1decSSalil Mehta 682e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 683e2cb1decSSalil Mehta if (status) 684e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 685e2cb1decSSalil Mehta "TQP enable fail, status =%d.\n", status); 686e2cb1decSSalil Mehta 687e2cb1decSSalil Mehta return status; 688e2cb1decSSalil Mehta } 689e2cb1decSSalil Mehta 690e2cb1decSSalil Mehta static int hclgevf_get_queue_id(struct hnae3_queue *queue) 691e2cb1decSSalil Mehta { 692e2cb1decSSalil Mehta struct hclgevf_tqp *tqp = container_of(queue, struct hclgevf_tqp, q); 693e2cb1decSSalil Mehta 694e2cb1decSSalil Mehta return tqp->index; 695e2cb1decSSalil Mehta } 696e2cb1decSSalil Mehta 697e2cb1decSSalil Mehta static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) 698e2cb1decSSalil Mehta { 699e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 700e2cb1decSSalil Mehta struct hnae3_queue *queue; 701e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 702e2cb1decSSalil Mehta int i; 703e2cb1decSSalil Mehta 704e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 705e2cb1decSSalil Mehta queue = handle->kinfo.tqp[i]; 706e2cb1decSSalil Mehta tqp = container_of(queue, struct hclgevf_tqp, q); 707e2cb1decSSalil Mehta memset(&tqp->tqp_stats, 0, sizeof(tqp->tqp_stats)); 708e2cb1decSSalil Mehta } 709e2cb1decSSalil Mehta } 710e2cb1decSSalil Mehta 711e2cb1decSSalil Mehta static int hclgevf_cfg_func_mta_filter(struct hnae3_handle *handle, bool en) 712e2cb1decSSalil Mehta { 713e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 714e2cb1decSSalil Mehta u8 msg[2] = {0}; 715e2cb1decSSalil Mehta 716e2cb1decSSalil Mehta msg[0] = en; 717e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 718e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, 719e2cb1decSSalil Mehta msg, 1, false, NULL, 0); 720e2cb1decSSalil Mehta } 721e2cb1decSSalil Mehta 722e2cb1decSSalil Mehta static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) 723e2cb1decSSalil Mehta { 724e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 725e2cb1decSSalil Mehta 726e2cb1decSSalil Mehta ether_addr_copy(p, hdev->hw.mac.mac_addr); 727e2cb1decSSalil Mehta } 728e2cb1decSSalil Mehta 72959098055SFuyun Liang static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p, 73059098055SFuyun Liang bool is_first) 731e2cb1decSSalil Mehta { 732e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 733e2cb1decSSalil Mehta u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; 734e2cb1decSSalil Mehta u8 *new_mac_addr = (u8 *)p; 735e2cb1decSSalil Mehta u8 msg_data[ETH_ALEN * 2]; 73659098055SFuyun Liang u16 subcode; 737e2cb1decSSalil Mehta int status; 738e2cb1decSSalil Mehta 739e2cb1decSSalil Mehta ether_addr_copy(msg_data, new_mac_addr); 740e2cb1decSSalil Mehta ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); 741e2cb1decSSalil Mehta 74259098055SFuyun Liang subcode = is_first ? HCLGE_MBX_MAC_VLAN_UC_ADD : 74359098055SFuyun Liang HCLGE_MBX_MAC_VLAN_UC_MODIFY; 74459098055SFuyun Liang 745e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 74659098055SFuyun Liang subcode, msg_data, ETH_ALEN * 2, 7472097fdefSJian Shen true, NULL, 0); 748e2cb1decSSalil Mehta if (!status) 749e2cb1decSSalil Mehta ether_addr_copy(hdev->hw.mac.mac_addr, new_mac_addr); 750e2cb1decSSalil Mehta 751e2cb1decSSalil Mehta return status; 752e2cb1decSSalil Mehta } 753e2cb1decSSalil Mehta 754e2cb1decSSalil Mehta static int hclgevf_add_uc_addr(struct hnae3_handle *handle, 755e2cb1decSSalil Mehta const unsigned char *addr) 756e2cb1decSSalil Mehta { 757e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 758e2cb1decSSalil Mehta 759e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 760e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_ADD, 761e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 762e2cb1decSSalil Mehta } 763e2cb1decSSalil Mehta 764e2cb1decSSalil Mehta static int hclgevf_rm_uc_addr(struct hnae3_handle *handle, 765e2cb1decSSalil Mehta const unsigned char *addr) 766e2cb1decSSalil Mehta { 767e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 768e2cb1decSSalil Mehta 769e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 770e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_REMOVE, 771e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 772e2cb1decSSalil Mehta } 773e2cb1decSSalil Mehta 774e2cb1decSSalil Mehta static int hclgevf_add_mc_addr(struct hnae3_handle *handle, 775e2cb1decSSalil Mehta const unsigned char *addr) 776e2cb1decSSalil Mehta { 777e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 778e2cb1decSSalil Mehta 779e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 780e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_ADD, 781e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 782e2cb1decSSalil Mehta } 783e2cb1decSSalil Mehta 784e2cb1decSSalil Mehta static int hclgevf_rm_mc_addr(struct hnae3_handle *handle, 785e2cb1decSSalil Mehta const unsigned char *addr) 786e2cb1decSSalil Mehta { 787e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 788e2cb1decSSalil Mehta 789e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 790e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_REMOVE, 791e2cb1decSSalil Mehta addr, ETH_ALEN, false, NULL, 0); 792e2cb1decSSalil Mehta } 793e2cb1decSSalil Mehta 794e2cb1decSSalil Mehta static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, 795e2cb1decSSalil Mehta __be16 proto, u16 vlan_id, 796e2cb1decSSalil Mehta bool is_kill) 797e2cb1decSSalil Mehta { 798e2cb1decSSalil Mehta #define HCLGEVF_VLAN_MBX_MSG_LEN 5 799e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 800e2cb1decSSalil Mehta u8 msg_data[HCLGEVF_VLAN_MBX_MSG_LEN]; 801e2cb1decSSalil Mehta 802e2cb1decSSalil Mehta if (vlan_id > 4095) 803e2cb1decSSalil Mehta return -EINVAL; 804e2cb1decSSalil Mehta 805e2cb1decSSalil Mehta if (proto != htons(ETH_P_8021Q)) 806e2cb1decSSalil Mehta return -EPROTONOSUPPORT; 807e2cb1decSSalil Mehta 808e2cb1decSSalil Mehta msg_data[0] = is_kill; 809e2cb1decSSalil Mehta memcpy(&msg_data[1], &vlan_id, sizeof(vlan_id)); 810e2cb1decSSalil Mehta memcpy(&msg_data[3], &proto, sizeof(proto)); 811e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, 812e2cb1decSSalil Mehta HCLGE_MBX_VLAN_FILTER, msg_data, 813e2cb1decSSalil Mehta HCLGEVF_VLAN_MBX_MSG_LEN, false, NULL, 0); 814e2cb1decSSalil Mehta } 815e2cb1decSSalil Mehta 816e2cb1decSSalil Mehta static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 817e2cb1decSSalil Mehta { 818e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 819e2cb1decSSalil Mehta u8 msg_data[2]; 8201a426f8bSPeng Li int ret; 821e2cb1decSSalil Mehta 822e2cb1decSSalil Mehta memcpy(&msg_data[0], &queue_id, sizeof(queue_id)); 823e2cb1decSSalil Mehta 8241a426f8bSPeng Li /* disable vf queue before send queue reset msg to PF */ 8251a426f8bSPeng Li ret = hclgevf_tqp_enable(hdev, queue_id, 0, false); 8261a426f8bSPeng Li if (ret) 8271a426f8bSPeng Li return; 8281a426f8bSPeng Li 8291a426f8bSPeng Li hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data, 8301a426f8bSPeng Li 2, true, NULL, 0); 831e2cb1decSSalil Mehta } 832e2cb1decSSalil Mehta 833e2cb1decSSalil Mehta static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) 834e2cb1decSSalil Mehta { 835e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 836e2cb1decSSalil Mehta 837e2cb1decSSalil Mehta return hdev->fw_version; 838e2cb1decSSalil Mehta } 839e2cb1decSSalil Mehta 840e2cb1decSSalil Mehta static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev) 841e2cb1decSSalil Mehta { 842e2cb1decSSalil Mehta struct hclgevf_misc_vector *vector = &hdev->misc_vector; 843e2cb1decSSalil Mehta 844e2cb1decSSalil Mehta vector->vector_irq = pci_irq_vector(hdev->pdev, 845e2cb1decSSalil Mehta HCLGEVF_MISC_VECTOR_NUM); 846e2cb1decSSalil Mehta vector->addr = hdev->hw.io_base + HCLGEVF_MISC_VECTOR_REG_BASE; 847e2cb1decSSalil Mehta /* vector status always valid for Vector 0 */ 848e2cb1decSSalil Mehta hdev->vector_status[HCLGEVF_MISC_VECTOR_NUM] = 0; 849e2cb1decSSalil Mehta hdev->vector_irq[HCLGEVF_MISC_VECTOR_NUM] = vector->vector_irq; 850e2cb1decSSalil Mehta 851e2cb1decSSalil Mehta hdev->num_msi_left -= 1; 852e2cb1decSSalil Mehta hdev->num_msi_used += 1; 853e2cb1decSSalil Mehta } 854e2cb1decSSalil Mehta 855e2cb1decSSalil Mehta static void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) 856e2cb1decSSalil Mehta { 857e2cb1decSSalil Mehta if (!test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) 858e2cb1decSSalil Mehta schedule_work(&hdev->mbx_service_task); 859e2cb1decSSalil Mehta } 860e2cb1decSSalil Mehta 861e2cb1decSSalil Mehta static void hclgevf_task_schedule(struct hclgevf_dev *hdev) 862e2cb1decSSalil Mehta { 863e2cb1decSSalil Mehta if (!test_bit(HCLGEVF_STATE_DOWN, &hdev->state) && 864e2cb1decSSalil Mehta !test_and_set_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state)) 865e2cb1decSSalil Mehta schedule_work(&hdev->service_task); 866e2cb1decSSalil Mehta } 867e2cb1decSSalil Mehta 868e2cb1decSSalil Mehta static void hclgevf_service_timer(struct timer_list *t) 869e2cb1decSSalil Mehta { 870e2cb1decSSalil Mehta struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer); 871e2cb1decSSalil Mehta 872e2cb1decSSalil Mehta mod_timer(&hdev->service_timer, jiffies + 5 * HZ); 873e2cb1decSSalil Mehta 874e2cb1decSSalil Mehta hclgevf_task_schedule(hdev); 875e2cb1decSSalil Mehta } 876e2cb1decSSalil Mehta 877e2cb1decSSalil Mehta static void hclgevf_mailbox_service_task(struct work_struct *work) 878e2cb1decSSalil Mehta { 879e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 880e2cb1decSSalil Mehta 881e2cb1decSSalil Mehta hdev = container_of(work, struct hclgevf_dev, mbx_service_task); 882e2cb1decSSalil Mehta 883e2cb1decSSalil Mehta if (test_and_set_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) 884e2cb1decSSalil Mehta return; 885e2cb1decSSalil Mehta 886e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 887e2cb1decSSalil Mehta 888e2cb1decSSalil Mehta hclgevf_mbx_handler(hdev); 889e2cb1decSSalil Mehta 890e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 891e2cb1decSSalil Mehta } 892e2cb1decSSalil Mehta 893e2cb1decSSalil Mehta static void hclgevf_service_task(struct work_struct *work) 894e2cb1decSSalil Mehta { 895e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 896e2cb1decSSalil Mehta 897e2cb1decSSalil Mehta hdev = container_of(work, struct hclgevf_dev, service_task); 898e2cb1decSSalil Mehta 899e2cb1decSSalil Mehta /* request the link status from the PF. PF would be able to tell VF 900e2cb1decSSalil Mehta * about such updates in future so we might remove this later 901e2cb1decSSalil Mehta */ 902e2cb1decSSalil Mehta hclgevf_request_link_info(hdev); 903e2cb1decSSalil Mehta 904e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 905e2cb1decSSalil Mehta } 906e2cb1decSSalil Mehta 907e2cb1decSSalil Mehta static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr) 908e2cb1decSSalil Mehta { 909e2cb1decSSalil Mehta hclgevf_write_dev(&hdev->hw, HCLGEVF_VECTOR0_CMDQ_SRC_REG, regclr); 910e2cb1decSSalil Mehta } 911e2cb1decSSalil Mehta 912e2cb1decSSalil Mehta static bool hclgevf_check_event_cause(struct hclgevf_dev *hdev, u32 *clearval) 913e2cb1decSSalil Mehta { 914e2cb1decSSalil Mehta u32 cmdq_src_reg; 915e2cb1decSSalil Mehta 916e2cb1decSSalil Mehta /* fetch the events from their corresponding regs */ 917e2cb1decSSalil Mehta cmdq_src_reg = hclgevf_read_dev(&hdev->hw, 918e2cb1decSSalil Mehta HCLGEVF_VECTOR0_CMDQ_SRC_REG); 919e2cb1decSSalil Mehta 920e2cb1decSSalil Mehta /* check for vector0 mailbox(=CMDQ RX) event source */ 921e2cb1decSSalil Mehta if (BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) { 922e2cb1decSSalil Mehta cmdq_src_reg &= ~BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B); 923e2cb1decSSalil Mehta *clearval = cmdq_src_reg; 924e2cb1decSSalil Mehta return true; 925e2cb1decSSalil Mehta } 926e2cb1decSSalil Mehta 927e2cb1decSSalil Mehta dev_dbg(&hdev->pdev->dev, "vector 0 interrupt from unknown source\n"); 928e2cb1decSSalil Mehta 929e2cb1decSSalil Mehta return false; 930e2cb1decSSalil Mehta } 931e2cb1decSSalil Mehta 932e2cb1decSSalil Mehta static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en) 933e2cb1decSSalil Mehta { 934e2cb1decSSalil Mehta writel(en ? 1 : 0, vector->addr); 935e2cb1decSSalil Mehta } 936e2cb1decSSalil Mehta 937e2cb1decSSalil Mehta static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) 938e2cb1decSSalil Mehta { 939e2cb1decSSalil Mehta struct hclgevf_dev *hdev = data; 940e2cb1decSSalil Mehta u32 clearval; 941e2cb1decSSalil Mehta 942e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 943e2cb1decSSalil Mehta if (!hclgevf_check_event_cause(hdev, &clearval)) 944e2cb1decSSalil Mehta goto skip_sched; 945e2cb1decSSalil Mehta 946e2cb1decSSalil Mehta /* schedule the VF mailbox service task, if not already scheduled */ 947e2cb1decSSalil Mehta hclgevf_mbx_task_schedule(hdev); 948e2cb1decSSalil Mehta 949e2cb1decSSalil Mehta hclgevf_clear_event_cause(hdev, clearval); 950e2cb1decSSalil Mehta 951e2cb1decSSalil Mehta skip_sched: 952e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 953e2cb1decSSalil Mehta 954e2cb1decSSalil Mehta return IRQ_HANDLED; 955e2cb1decSSalil Mehta } 956e2cb1decSSalil Mehta 957e2cb1decSSalil Mehta static int hclgevf_configure(struct hclgevf_dev *hdev) 958e2cb1decSSalil Mehta { 959e2cb1decSSalil Mehta int ret; 960e2cb1decSSalil Mehta 961e2cb1decSSalil Mehta /* get queue configuration from PF */ 962e2cb1decSSalil Mehta ret = hclge_get_queue_info(hdev); 963e2cb1decSSalil Mehta if (ret) 964e2cb1decSSalil Mehta return ret; 965e2cb1decSSalil Mehta /* get tc configuration from PF */ 966e2cb1decSSalil Mehta return hclgevf_get_tc_info(hdev); 967e2cb1decSSalil Mehta } 968e2cb1decSSalil Mehta 969e2cb1decSSalil Mehta static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) 970e2cb1decSSalil Mehta { 971e2cb1decSSalil Mehta struct hnae3_handle *roce = &hdev->roce; 972e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 973e2cb1decSSalil Mehta 974e2cb1decSSalil Mehta roce->rinfo.num_vectors = HCLGEVF_ROCEE_VECTOR_NUM; 975e2cb1decSSalil Mehta 976e2cb1decSSalil Mehta if (hdev->num_msi_left < roce->rinfo.num_vectors || 977e2cb1decSSalil Mehta hdev->num_msi_left == 0) 978e2cb1decSSalil Mehta return -EINVAL; 979e2cb1decSSalil Mehta 980e2cb1decSSalil Mehta roce->rinfo.base_vector = 981e2cb1decSSalil Mehta hdev->vector_status[hdev->num_msi_used]; 982e2cb1decSSalil Mehta 983e2cb1decSSalil Mehta roce->rinfo.netdev = nic->kinfo.netdev; 984e2cb1decSSalil Mehta roce->rinfo.roce_io_base = hdev->hw.io_base; 985e2cb1decSSalil Mehta 986e2cb1decSSalil Mehta roce->pdev = nic->pdev; 987e2cb1decSSalil Mehta roce->ae_algo = nic->ae_algo; 988e2cb1decSSalil Mehta roce->numa_node_mask = nic->numa_node_mask; 989e2cb1decSSalil Mehta 990e2cb1decSSalil Mehta return 0; 991e2cb1decSSalil Mehta } 992e2cb1decSSalil Mehta 993e2cb1decSSalil Mehta static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) 994e2cb1decSSalil Mehta { 995e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 996e2cb1decSSalil Mehta int i, ret; 997e2cb1decSSalil Mehta 998e2cb1decSSalil Mehta rss_cfg->rss_size = hdev->rss_size_max; 999e2cb1decSSalil Mehta 1000e2cb1decSSalil Mehta /* Initialize RSS indirect table for each vport */ 1001e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 1002e2cb1decSSalil Mehta rss_cfg->rss_indirection_tbl[i] = i % hdev->rss_size_max; 1003e2cb1decSSalil Mehta 1004e2cb1decSSalil Mehta ret = hclgevf_set_rss_indir_table(hdev); 1005e2cb1decSSalil Mehta if (ret) 1006e2cb1decSSalil Mehta return ret; 1007e2cb1decSSalil Mehta 1008e2cb1decSSalil Mehta return hclgevf_set_rss_tc_mode(hdev, hdev->rss_size_max); 1009e2cb1decSSalil Mehta } 1010e2cb1decSSalil Mehta 1011e2cb1decSSalil Mehta static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) 1012e2cb1decSSalil Mehta { 1013e2cb1decSSalil Mehta /* other vlan config(like, VLAN TX/RX offload) would also be added 1014e2cb1decSSalil Mehta * here later 1015e2cb1decSSalil Mehta */ 1016e2cb1decSSalil Mehta return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, 1017e2cb1decSSalil Mehta false); 1018e2cb1decSSalil Mehta } 1019e2cb1decSSalil Mehta 1020e2cb1decSSalil Mehta static int hclgevf_ae_start(struct hnae3_handle *handle) 1021e2cb1decSSalil Mehta { 1022e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1023e2cb1decSSalil Mehta int i, queue_id; 1024e2cb1decSSalil Mehta 1025e2cb1decSSalil Mehta for (i = 0; i < handle->kinfo.num_tqps; i++) { 1026e2cb1decSSalil Mehta /* ring enable */ 1027e2cb1decSSalil Mehta queue_id = hclgevf_get_queue_id(handle->kinfo.tqp[i]); 1028e2cb1decSSalil Mehta if (queue_id < 0) { 1029e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1030e2cb1decSSalil Mehta "Get invalid queue id, ignore it\n"); 1031e2cb1decSSalil Mehta continue; 1032e2cb1decSSalil Mehta } 1033e2cb1decSSalil Mehta 1034e2cb1decSSalil Mehta hclgevf_tqp_enable(hdev, queue_id, 0, true); 1035e2cb1decSSalil Mehta } 1036e2cb1decSSalil Mehta 1037e2cb1decSSalil Mehta /* reset tqp stats */ 1038e2cb1decSSalil Mehta hclgevf_reset_tqp_stats(handle); 1039e2cb1decSSalil Mehta 1040e2cb1decSSalil Mehta hclgevf_request_link_info(hdev); 1041e2cb1decSSalil Mehta 1042e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1043e2cb1decSSalil Mehta mod_timer(&hdev->service_timer, jiffies + HZ); 1044e2cb1decSSalil Mehta 1045e2cb1decSSalil Mehta return 0; 1046e2cb1decSSalil Mehta } 1047e2cb1decSSalil Mehta 1048e2cb1decSSalil Mehta static void hclgevf_ae_stop(struct hnae3_handle *handle) 1049e2cb1decSSalil Mehta { 1050e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1051e2cb1decSSalil Mehta int i, queue_id; 1052e2cb1decSSalil Mehta 1053e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 1054e2cb1decSSalil Mehta /* Ring disable */ 1055e2cb1decSSalil Mehta queue_id = hclgevf_get_queue_id(handle->kinfo.tqp[i]); 1056e2cb1decSSalil Mehta if (queue_id < 0) { 1057e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1058e2cb1decSSalil Mehta "Get invalid queue id, ignore it\n"); 1059e2cb1decSSalil Mehta continue; 1060e2cb1decSSalil Mehta } 1061e2cb1decSSalil Mehta 1062e2cb1decSSalil Mehta hclgevf_tqp_enable(hdev, queue_id, 0, false); 1063e2cb1decSSalil Mehta } 1064e2cb1decSSalil Mehta 1065e2cb1decSSalil Mehta /* reset tqp stats */ 1066e2cb1decSSalil Mehta hclgevf_reset_tqp_stats(handle); 10678cc6c1f7SFuyun Liang del_timer_sync(&hdev->service_timer); 10688cc6c1f7SFuyun Liang cancel_work_sync(&hdev->service_task); 10698cc6c1f7SFuyun Liang hclgevf_update_link_status(hdev, 0); 1070e2cb1decSSalil Mehta } 1071e2cb1decSSalil Mehta 1072e2cb1decSSalil Mehta static void hclgevf_state_init(struct hclgevf_dev *hdev) 1073e2cb1decSSalil Mehta { 1074e2cb1decSSalil Mehta /* setup tasks for the MBX */ 1075e2cb1decSSalil Mehta INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task); 1076e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); 1077e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); 1078e2cb1decSSalil Mehta 1079e2cb1decSSalil Mehta /* setup tasks for service timer */ 1080e2cb1decSSalil Mehta timer_setup(&hdev->service_timer, hclgevf_service_timer, 0); 1081e2cb1decSSalil Mehta 1082e2cb1decSSalil Mehta INIT_WORK(&hdev->service_task, hclgevf_service_task); 1083e2cb1decSSalil Mehta clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 1084e2cb1decSSalil Mehta 1085e2cb1decSSalil Mehta mutex_init(&hdev->mbx_resp.mbx_mutex); 1086e2cb1decSSalil Mehta 1087e2cb1decSSalil Mehta /* bring the device down */ 1088e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1089e2cb1decSSalil Mehta } 1090e2cb1decSSalil Mehta 1091e2cb1decSSalil Mehta static void hclgevf_state_uninit(struct hclgevf_dev *hdev) 1092e2cb1decSSalil Mehta { 1093e2cb1decSSalil Mehta set_bit(HCLGEVF_STATE_DOWN, &hdev->state); 1094e2cb1decSSalil Mehta 1095e2cb1decSSalil Mehta if (hdev->service_timer.function) 1096e2cb1decSSalil Mehta del_timer_sync(&hdev->service_timer); 1097e2cb1decSSalil Mehta if (hdev->service_task.func) 1098e2cb1decSSalil Mehta cancel_work_sync(&hdev->service_task); 1099e2cb1decSSalil Mehta if (hdev->mbx_service_task.func) 1100e2cb1decSSalil Mehta cancel_work_sync(&hdev->mbx_service_task); 1101e2cb1decSSalil Mehta 1102e2cb1decSSalil Mehta mutex_destroy(&hdev->mbx_resp.mbx_mutex); 1103e2cb1decSSalil Mehta } 1104e2cb1decSSalil Mehta 1105e2cb1decSSalil Mehta static int hclgevf_init_msi(struct hclgevf_dev *hdev) 1106e2cb1decSSalil Mehta { 1107e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1108e2cb1decSSalil Mehta int vectors; 1109e2cb1decSSalil Mehta int i; 1110e2cb1decSSalil Mehta 1111e2cb1decSSalil Mehta hdev->num_msi = HCLGEVF_MAX_VF_VECTOR_NUM; 1112e2cb1decSSalil Mehta 1113e2cb1decSSalil Mehta vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, 1114e2cb1decSSalil Mehta PCI_IRQ_MSI | PCI_IRQ_MSIX); 1115e2cb1decSSalil Mehta if (vectors < 0) { 1116e2cb1decSSalil Mehta dev_err(&pdev->dev, 1117e2cb1decSSalil Mehta "failed(%d) to allocate MSI/MSI-X vectors\n", 1118e2cb1decSSalil Mehta vectors); 1119e2cb1decSSalil Mehta return vectors; 1120e2cb1decSSalil Mehta } 1121e2cb1decSSalil Mehta if (vectors < hdev->num_msi) 1122e2cb1decSSalil Mehta dev_warn(&hdev->pdev->dev, 1123e2cb1decSSalil Mehta "requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n", 1124e2cb1decSSalil Mehta hdev->num_msi, vectors); 1125e2cb1decSSalil Mehta 1126e2cb1decSSalil Mehta hdev->num_msi = vectors; 1127e2cb1decSSalil Mehta hdev->num_msi_left = vectors; 1128e2cb1decSSalil Mehta hdev->base_msi_vector = pdev->irq; 1129e2cb1decSSalil Mehta 1130e2cb1decSSalil Mehta hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, 1131e2cb1decSSalil Mehta sizeof(u16), GFP_KERNEL); 1132e2cb1decSSalil Mehta if (!hdev->vector_status) { 1133e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1134e2cb1decSSalil Mehta return -ENOMEM; 1135e2cb1decSSalil Mehta } 1136e2cb1decSSalil Mehta 1137e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 1138e2cb1decSSalil Mehta hdev->vector_status[i] = HCLGEVF_INVALID_VPORT; 1139e2cb1decSSalil Mehta 1140e2cb1decSSalil Mehta hdev->vector_irq = devm_kcalloc(&pdev->dev, hdev->num_msi, 1141e2cb1decSSalil Mehta sizeof(int), GFP_KERNEL); 1142e2cb1decSSalil Mehta if (!hdev->vector_irq) { 1143e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1144e2cb1decSSalil Mehta return -ENOMEM; 1145e2cb1decSSalil Mehta } 1146e2cb1decSSalil Mehta 1147e2cb1decSSalil Mehta return 0; 1148e2cb1decSSalil Mehta } 1149e2cb1decSSalil Mehta 1150e2cb1decSSalil Mehta static void hclgevf_uninit_msi(struct hclgevf_dev *hdev) 1151e2cb1decSSalil Mehta { 1152e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1153e2cb1decSSalil Mehta 1154e2cb1decSSalil Mehta pci_free_irq_vectors(pdev); 1155e2cb1decSSalil Mehta } 1156e2cb1decSSalil Mehta 1157e2cb1decSSalil Mehta static int hclgevf_misc_irq_init(struct hclgevf_dev *hdev) 1158e2cb1decSSalil Mehta { 1159e2cb1decSSalil Mehta int ret = 0; 1160e2cb1decSSalil Mehta 1161e2cb1decSSalil Mehta hclgevf_get_misc_vector(hdev); 1162e2cb1decSSalil Mehta 1163e2cb1decSSalil Mehta ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, 1164e2cb1decSSalil Mehta 0, "hclgevf_cmd", hdev); 1165e2cb1decSSalil Mehta if (ret) { 1166e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF failed to request misc irq(%d)\n", 1167e2cb1decSSalil Mehta hdev->misc_vector.vector_irq); 1168e2cb1decSSalil Mehta return ret; 1169e2cb1decSSalil Mehta } 1170e2cb1decSSalil Mehta 1171e2cb1decSSalil Mehta /* enable misc. vector(vector 0) */ 1172e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, true); 1173e2cb1decSSalil Mehta 1174e2cb1decSSalil Mehta return ret; 1175e2cb1decSSalil Mehta } 1176e2cb1decSSalil Mehta 1177e2cb1decSSalil Mehta static void hclgevf_misc_irq_uninit(struct hclgevf_dev *hdev) 1178e2cb1decSSalil Mehta { 1179e2cb1decSSalil Mehta /* disable misc vector(vector 0) */ 1180e2cb1decSSalil Mehta hclgevf_enable_vector(&hdev->misc_vector, false); 1181e2cb1decSSalil Mehta free_irq(hdev->misc_vector.vector_irq, hdev); 1182e2cb1decSSalil Mehta hclgevf_free_vector(hdev, 0); 1183e2cb1decSSalil Mehta } 1184e2cb1decSSalil Mehta 1185e2cb1decSSalil Mehta static int hclgevf_init_instance(struct hclgevf_dev *hdev, 1186e2cb1decSSalil Mehta struct hnae3_client *client) 1187e2cb1decSSalil Mehta { 1188e2cb1decSSalil Mehta int ret; 1189e2cb1decSSalil Mehta 1190e2cb1decSSalil Mehta switch (client->type) { 1191e2cb1decSSalil Mehta case HNAE3_CLIENT_KNIC: 1192e2cb1decSSalil Mehta hdev->nic_client = client; 1193e2cb1decSSalil Mehta hdev->nic.client = client; 1194e2cb1decSSalil Mehta 1195e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->nic); 1196e2cb1decSSalil Mehta if (ret) 1197e2cb1decSSalil Mehta return ret; 1198e2cb1decSSalil Mehta 1199e2cb1decSSalil Mehta if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { 1200e2cb1decSSalil Mehta struct hnae3_client *rc = hdev->roce_client; 1201e2cb1decSSalil Mehta 1202e2cb1decSSalil Mehta ret = hclgevf_init_roce_base_info(hdev); 1203e2cb1decSSalil Mehta if (ret) 1204e2cb1decSSalil Mehta return ret; 1205e2cb1decSSalil Mehta ret = rc->ops->init_instance(&hdev->roce); 1206e2cb1decSSalil Mehta if (ret) 1207e2cb1decSSalil Mehta return ret; 1208e2cb1decSSalil Mehta } 1209e2cb1decSSalil Mehta break; 1210e2cb1decSSalil Mehta case HNAE3_CLIENT_UNIC: 1211e2cb1decSSalil Mehta hdev->nic_client = client; 1212e2cb1decSSalil Mehta hdev->nic.client = client; 1213e2cb1decSSalil Mehta 1214e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->nic); 1215e2cb1decSSalil Mehta if (ret) 1216e2cb1decSSalil Mehta return ret; 1217e2cb1decSSalil Mehta break; 1218e2cb1decSSalil Mehta case HNAE3_CLIENT_ROCE: 1219e2cb1decSSalil Mehta hdev->roce_client = client; 1220e2cb1decSSalil Mehta hdev->roce.client = client; 1221e2cb1decSSalil Mehta 1222e2cb1decSSalil Mehta if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { 1223e2cb1decSSalil Mehta ret = hclgevf_init_roce_base_info(hdev); 1224e2cb1decSSalil Mehta if (ret) 1225e2cb1decSSalil Mehta return ret; 1226e2cb1decSSalil Mehta 1227e2cb1decSSalil Mehta ret = client->ops->init_instance(&hdev->roce); 1228e2cb1decSSalil Mehta if (ret) 1229e2cb1decSSalil Mehta return ret; 1230e2cb1decSSalil Mehta } 1231e2cb1decSSalil Mehta } 1232e2cb1decSSalil Mehta 1233e2cb1decSSalil Mehta return 0; 1234e2cb1decSSalil Mehta } 1235e2cb1decSSalil Mehta 1236e2cb1decSSalil Mehta static void hclgevf_uninit_instance(struct hclgevf_dev *hdev, 1237e2cb1decSSalil Mehta struct hnae3_client *client) 1238e2cb1decSSalil Mehta { 1239e2cb1decSSalil Mehta /* un-init roce, if it exists */ 1240e2cb1decSSalil Mehta if (hdev->roce_client) 1241e2cb1decSSalil Mehta hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); 1242e2cb1decSSalil Mehta 1243e2cb1decSSalil Mehta /* un-init nic/unic, if this was not called by roce client */ 1244e2cb1decSSalil Mehta if ((client->ops->uninit_instance) && 1245e2cb1decSSalil Mehta (client->type != HNAE3_CLIENT_ROCE)) 1246e2cb1decSSalil Mehta client->ops->uninit_instance(&hdev->nic, 0); 1247e2cb1decSSalil Mehta } 1248e2cb1decSSalil Mehta 1249e2cb1decSSalil Mehta static int hclgevf_register_client(struct hnae3_client *client, 1250e2cb1decSSalil Mehta struct hnae3_ae_dev *ae_dev) 1251e2cb1decSSalil Mehta { 1252e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1253e2cb1decSSalil Mehta 1254e2cb1decSSalil Mehta return hclgevf_init_instance(hdev, client); 1255e2cb1decSSalil Mehta } 1256e2cb1decSSalil Mehta 1257e2cb1decSSalil Mehta static void hclgevf_unregister_client(struct hnae3_client *client, 1258e2cb1decSSalil Mehta struct hnae3_ae_dev *ae_dev) 1259e2cb1decSSalil Mehta { 1260e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1261e2cb1decSSalil Mehta 1262e2cb1decSSalil Mehta hclgevf_uninit_instance(hdev, client); 1263e2cb1decSSalil Mehta } 1264e2cb1decSSalil Mehta 1265e2cb1decSSalil Mehta static int hclgevf_pci_init(struct hclgevf_dev *hdev) 1266e2cb1decSSalil Mehta { 1267e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1268e2cb1decSSalil Mehta struct hclgevf_hw *hw; 1269e2cb1decSSalil Mehta int ret; 1270e2cb1decSSalil Mehta 1271e2cb1decSSalil Mehta ret = pci_enable_device(pdev); 1272e2cb1decSSalil Mehta if (ret) { 1273e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed to enable PCI device\n"); 1274e2cb1decSSalil Mehta goto err_no_drvdata; 1275e2cb1decSSalil Mehta } 1276e2cb1decSSalil Mehta 1277e2cb1decSSalil Mehta ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 1278e2cb1decSSalil Mehta if (ret) { 1279e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't set consistent PCI DMA, exiting"); 1280e2cb1decSSalil Mehta goto err_disable_device; 1281e2cb1decSSalil Mehta } 1282e2cb1decSSalil Mehta 1283e2cb1decSSalil Mehta ret = pci_request_regions(pdev, HCLGEVF_DRIVER_NAME); 1284e2cb1decSSalil Mehta if (ret) { 1285e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI request regions failed %d\n", ret); 1286e2cb1decSSalil Mehta goto err_disable_device; 1287e2cb1decSSalil Mehta } 1288e2cb1decSSalil Mehta 1289e2cb1decSSalil Mehta pci_set_master(pdev); 1290e2cb1decSSalil Mehta hw = &hdev->hw; 1291e2cb1decSSalil Mehta hw->hdev = hdev; 12922e1ea493SPeng Li hw->io_base = pci_iomap(pdev, 2, 0); 1293e2cb1decSSalil Mehta if (!hw->io_base) { 1294e2cb1decSSalil Mehta dev_err(&pdev->dev, "can't map configuration register space\n"); 1295e2cb1decSSalil Mehta ret = -ENOMEM; 1296e2cb1decSSalil Mehta goto err_clr_master; 1297e2cb1decSSalil Mehta } 1298e2cb1decSSalil Mehta 1299e2cb1decSSalil Mehta return 0; 1300e2cb1decSSalil Mehta 1301e2cb1decSSalil Mehta err_clr_master: 1302e2cb1decSSalil Mehta pci_clear_master(pdev); 1303e2cb1decSSalil Mehta pci_release_regions(pdev); 1304e2cb1decSSalil Mehta err_disable_device: 1305e2cb1decSSalil Mehta pci_disable_device(pdev); 1306e2cb1decSSalil Mehta err_no_drvdata: 1307e2cb1decSSalil Mehta pci_set_drvdata(pdev, NULL); 1308e2cb1decSSalil Mehta return ret; 1309e2cb1decSSalil Mehta } 1310e2cb1decSSalil Mehta 1311e2cb1decSSalil Mehta static void hclgevf_pci_uninit(struct hclgevf_dev *hdev) 1312e2cb1decSSalil Mehta { 1313e2cb1decSSalil Mehta struct pci_dev *pdev = hdev->pdev; 1314e2cb1decSSalil Mehta 1315e2cb1decSSalil Mehta pci_iounmap(pdev, hdev->hw.io_base); 1316e2cb1decSSalil Mehta pci_clear_master(pdev); 1317e2cb1decSSalil Mehta pci_release_regions(pdev); 1318e2cb1decSSalil Mehta pci_disable_device(pdev); 1319e2cb1decSSalil Mehta pci_set_drvdata(pdev, NULL); 1320e2cb1decSSalil Mehta } 1321e2cb1decSSalil Mehta 1322e2cb1decSSalil Mehta static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) 1323e2cb1decSSalil Mehta { 1324e2cb1decSSalil Mehta struct pci_dev *pdev = ae_dev->pdev; 1325e2cb1decSSalil Mehta struct hclgevf_dev *hdev; 1326e2cb1decSSalil Mehta int ret; 1327e2cb1decSSalil Mehta 1328e2cb1decSSalil Mehta hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); 1329e2cb1decSSalil Mehta if (!hdev) 1330e2cb1decSSalil Mehta return -ENOMEM; 1331e2cb1decSSalil Mehta 1332e2cb1decSSalil Mehta hdev->pdev = pdev; 1333e2cb1decSSalil Mehta hdev->ae_dev = ae_dev; 1334e2cb1decSSalil Mehta ae_dev->priv = hdev; 1335e2cb1decSSalil Mehta 1336e2cb1decSSalil Mehta ret = hclgevf_pci_init(hdev); 1337e2cb1decSSalil Mehta if (ret) { 1338e2cb1decSSalil Mehta dev_err(&pdev->dev, "PCI initialization failed\n"); 1339e2cb1decSSalil Mehta return ret; 1340e2cb1decSSalil Mehta } 1341e2cb1decSSalil Mehta 1342e2cb1decSSalil Mehta ret = hclgevf_init_msi(hdev); 1343e2cb1decSSalil Mehta if (ret) { 1344e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to init MSI/MSI-X\n", ret); 1345e2cb1decSSalil Mehta goto err_irq_init; 1346e2cb1decSSalil Mehta } 1347e2cb1decSSalil Mehta 1348e2cb1decSSalil Mehta hclgevf_state_init(hdev); 1349e2cb1decSSalil Mehta 1350e2cb1decSSalil Mehta ret = hclgevf_misc_irq_init(hdev); 1351e2cb1decSSalil Mehta if (ret) { 1352e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to init Misc IRQ(vector0)\n", 1353e2cb1decSSalil Mehta ret); 1354e2cb1decSSalil Mehta goto err_misc_irq_init; 1355e2cb1decSSalil Mehta } 1356e2cb1decSSalil Mehta 1357e2cb1decSSalil Mehta ret = hclgevf_cmd_init(hdev); 1358e2cb1decSSalil Mehta if (ret) 1359e2cb1decSSalil Mehta goto err_cmd_init; 1360e2cb1decSSalil Mehta 1361e2cb1decSSalil Mehta ret = hclgevf_configure(hdev); 1362e2cb1decSSalil Mehta if (ret) { 1363e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to fetch configuration\n", ret); 1364e2cb1decSSalil Mehta goto err_config; 1365e2cb1decSSalil Mehta } 1366e2cb1decSSalil Mehta 1367e2cb1decSSalil Mehta ret = hclgevf_alloc_tqps(hdev); 1368e2cb1decSSalil Mehta if (ret) { 1369e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to allocate TQPs\n", ret); 1370e2cb1decSSalil Mehta goto err_config; 1371e2cb1decSSalil Mehta } 1372e2cb1decSSalil Mehta 1373e2cb1decSSalil Mehta ret = hclgevf_set_handle_info(hdev); 1374e2cb1decSSalil Mehta if (ret) { 1375e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to set handle info\n", ret); 1376e2cb1decSSalil Mehta goto err_config; 1377e2cb1decSSalil Mehta } 1378e2cb1decSSalil Mehta 1379e2cb1decSSalil Mehta /* Initialize VF's MTA */ 1380e2cb1decSSalil Mehta hdev->accept_mta_mc = true; 1381e2cb1decSSalil Mehta ret = hclgevf_cfg_func_mta_filter(&hdev->nic, hdev->accept_mta_mc); 1382e2cb1decSSalil Mehta if (ret) { 1383e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1384e2cb1decSSalil Mehta "failed(%d) to set mta filter mode\n", ret); 1385e2cb1decSSalil Mehta goto err_config; 1386e2cb1decSSalil Mehta } 1387e2cb1decSSalil Mehta 1388e2cb1decSSalil Mehta /* Initialize RSS for this VF */ 1389e2cb1decSSalil Mehta ret = hclgevf_rss_init_hw(hdev); 1390e2cb1decSSalil Mehta if (ret) { 1391e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1392e2cb1decSSalil Mehta "failed(%d) to initialize RSS\n", ret); 1393e2cb1decSSalil Mehta goto err_config; 1394e2cb1decSSalil Mehta } 1395e2cb1decSSalil Mehta 1396e2cb1decSSalil Mehta ret = hclgevf_init_vlan_config(hdev); 1397e2cb1decSSalil Mehta if (ret) { 1398e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1399e2cb1decSSalil Mehta "failed(%d) to initialize VLAN config\n", ret); 1400e2cb1decSSalil Mehta goto err_config; 1401e2cb1decSSalil Mehta } 1402e2cb1decSSalil Mehta 1403e2cb1decSSalil Mehta pr_info("finished initializing %s driver\n", HCLGEVF_DRIVER_NAME); 1404e2cb1decSSalil Mehta 1405e2cb1decSSalil Mehta return 0; 1406e2cb1decSSalil Mehta 1407e2cb1decSSalil Mehta err_config: 1408e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1409e2cb1decSSalil Mehta err_cmd_init: 1410e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1411e2cb1decSSalil Mehta err_misc_irq_init: 1412e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1413e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1414e2cb1decSSalil Mehta err_irq_init: 1415e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1416e2cb1decSSalil Mehta return ret; 1417e2cb1decSSalil Mehta } 1418e2cb1decSSalil Mehta 1419e2cb1decSSalil Mehta static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) 1420e2cb1decSSalil Mehta { 1421e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1422e2cb1decSSalil Mehta 1423e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1424e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1425e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1426e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1427e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1428e2cb1decSSalil Mehta ae_dev->priv = NULL; 1429e2cb1decSSalil Mehta } 1430e2cb1decSSalil Mehta 1431849e4607SPeng Li static u32 hclgevf_get_max_channels(struct hclgevf_dev *hdev) 1432849e4607SPeng Li { 1433849e4607SPeng Li struct hnae3_handle *nic = &hdev->nic; 1434849e4607SPeng Li struct hnae3_knic_private_info *kinfo = &nic->kinfo; 1435849e4607SPeng Li 1436849e4607SPeng Li return min_t(u32, hdev->rss_size_max * kinfo->num_tc, hdev->num_tqps); 1437849e4607SPeng Li } 1438849e4607SPeng Li 1439849e4607SPeng Li /** 1440849e4607SPeng Li * hclgevf_get_channels - Get the current channels enabled and max supported. 1441849e4607SPeng Li * @handle: hardware information for network interface 1442849e4607SPeng Li * @ch: ethtool channels structure 1443849e4607SPeng Li * 1444849e4607SPeng Li * We don't support separate tx and rx queues as channels. The other count 1445849e4607SPeng Li * represents how many queues are being used for control. max_combined counts 1446849e4607SPeng Li * how many queue pairs we can support. They may not be mapped 1 to 1 with 1447849e4607SPeng Li * q_vectors since we support a lot more queue pairs than q_vectors. 1448849e4607SPeng Li **/ 1449849e4607SPeng Li static void hclgevf_get_channels(struct hnae3_handle *handle, 1450849e4607SPeng Li struct ethtool_channels *ch) 1451849e4607SPeng Li { 1452849e4607SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1453849e4607SPeng Li 1454849e4607SPeng Li ch->max_combined = hclgevf_get_max_channels(hdev); 1455849e4607SPeng Li ch->other_count = 0; 1456849e4607SPeng Li ch->max_other = 0; 1457849e4607SPeng Li ch->combined_count = hdev->num_tqps; 1458849e4607SPeng Li } 1459849e4607SPeng Li 1460cc719218SPeng Li static void hclgevf_get_tqps_and_rss_info(struct hnae3_handle *handle, 1461cc719218SPeng Li u16 *free_tqps, u16 *max_rss_size) 1462cc719218SPeng Li { 1463cc719218SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1464cc719218SPeng Li 1465cc719218SPeng Li *free_tqps = 0; 1466cc719218SPeng Li *max_rss_size = hdev->rss_size_max; 1467cc719218SPeng Li } 1468cc719218SPeng Li 1469e2cb1decSSalil Mehta static const struct hnae3_ae_ops hclgevf_ops = { 1470e2cb1decSSalil Mehta .init_ae_dev = hclgevf_init_ae_dev, 1471e2cb1decSSalil Mehta .uninit_ae_dev = hclgevf_uninit_ae_dev, 1472e2cb1decSSalil Mehta .init_client_instance = hclgevf_register_client, 1473e2cb1decSSalil Mehta .uninit_client_instance = hclgevf_unregister_client, 1474e2cb1decSSalil Mehta .start = hclgevf_ae_start, 1475e2cb1decSSalil Mehta .stop = hclgevf_ae_stop, 1476e2cb1decSSalil Mehta .map_ring_to_vector = hclgevf_map_ring_to_vector, 1477e2cb1decSSalil Mehta .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector, 1478e2cb1decSSalil Mehta .get_vector = hclgevf_get_vector, 14790d3e6631SYunsheng Lin .put_vector = hclgevf_put_vector, 1480e2cb1decSSalil Mehta .reset_queue = hclgevf_reset_tqp, 1481e2cb1decSSalil Mehta .set_promisc_mode = hclgevf_set_promisc_mode, 1482e2cb1decSSalil Mehta .get_mac_addr = hclgevf_get_mac_addr, 1483e2cb1decSSalil Mehta .set_mac_addr = hclgevf_set_mac_addr, 1484e2cb1decSSalil Mehta .add_uc_addr = hclgevf_add_uc_addr, 1485e2cb1decSSalil Mehta .rm_uc_addr = hclgevf_rm_uc_addr, 1486e2cb1decSSalil Mehta .add_mc_addr = hclgevf_add_mc_addr, 1487e2cb1decSSalil Mehta .rm_mc_addr = hclgevf_rm_mc_addr, 1488e2cb1decSSalil Mehta .get_stats = hclgevf_get_stats, 1489e2cb1decSSalil Mehta .update_stats = hclgevf_update_stats, 1490e2cb1decSSalil Mehta .get_strings = hclgevf_get_strings, 1491e2cb1decSSalil Mehta .get_sset_count = hclgevf_get_sset_count, 1492e2cb1decSSalil Mehta .get_rss_key_size = hclgevf_get_rss_key_size, 1493e2cb1decSSalil Mehta .get_rss_indir_size = hclgevf_get_rss_indir_size, 1494e2cb1decSSalil Mehta .get_rss = hclgevf_get_rss, 1495e2cb1decSSalil Mehta .set_rss = hclgevf_set_rss, 1496e2cb1decSSalil Mehta .get_tc_size = hclgevf_get_tc_size, 1497e2cb1decSSalil Mehta .get_fw_version = hclgevf_get_fw_version, 1498e2cb1decSSalil Mehta .set_vlan_filter = hclgevf_set_vlan_filter, 1499849e4607SPeng Li .get_channels = hclgevf_get_channels, 1500cc719218SPeng Li .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info, 1501e2cb1decSSalil Mehta }; 1502e2cb1decSSalil Mehta 1503e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf = { 1504e2cb1decSSalil Mehta .ops = &hclgevf_ops, 1505e2cb1decSSalil Mehta .name = HCLGEVF_NAME, 1506e2cb1decSSalil Mehta .pdev_id_table = ae_algovf_pci_tbl, 1507e2cb1decSSalil Mehta }; 1508e2cb1decSSalil Mehta 1509e2cb1decSSalil Mehta static int hclgevf_init(void) 1510e2cb1decSSalil Mehta { 1511e2cb1decSSalil Mehta pr_info("%s is initializing\n", HCLGEVF_NAME); 1512e2cb1decSSalil Mehta 1513e2cb1decSSalil Mehta return hnae3_register_ae_algo(&ae_algovf); 1514e2cb1decSSalil Mehta } 1515e2cb1decSSalil Mehta 1516e2cb1decSSalil Mehta static void hclgevf_exit(void) 1517e2cb1decSSalil Mehta { 1518e2cb1decSSalil Mehta hnae3_unregister_ae_algo(&ae_algovf); 1519e2cb1decSSalil Mehta } 1520e2cb1decSSalil Mehta module_init(hclgevf_init); 1521e2cb1decSSalil Mehta module_exit(hclgevf_exit); 1522e2cb1decSSalil Mehta 1523e2cb1decSSalil Mehta MODULE_LICENSE("GPL"); 1524e2cb1decSSalil Mehta MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 1525e2cb1decSSalil Mehta MODULE_DESCRIPTION("HCLGEVF Driver"); 1526e2cb1decSSalil Mehta MODULE_VERSION(HCLGEVF_MOD_VERSION); 1527