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_enable_tso(struct hclgevf_dev *hdev, int enable) 205e2cb1decSSalil Mehta { 206e2cb1decSSalil Mehta struct hclgevf_cfg_tso_status_cmd *req; 207e2cb1decSSalil Mehta struct hclgevf_desc desc; 208e2cb1decSSalil Mehta 209e2cb1decSSalil Mehta req = (struct hclgevf_cfg_tso_status_cmd *)desc.data; 210e2cb1decSSalil Mehta 211e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_TSO_GENERIC_CONFIG, 212e2cb1decSSalil Mehta false); 213e2cb1decSSalil Mehta hnae_set_bit(req->tso_enable, HCLGEVF_TSO_ENABLE_B, enable); 214e2cb1decSSalil Mehta 215e2cb1decSSalil Mehta return hclgevf_cmd_send(&hdev->hw, &desc, 1); 216e2cb1decSSalil Mehta } 217e2cb1decSSalil Mehta 218e2cb1decSSalil Mehta static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev) 219e2cb1decSSalil Mehta { 220e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 221e2cb1decSSalil Mehta int i; 222e2cb1decSSalil Mehta 223e2cb1decSSalil Mehta hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, 224e2cb1decSSalil Mehta sizeof(struct hclgevf_tqp), GFP_KERNEL); 225e2cb1decSSalil Mehta if (!hdev->htqp) 226e2cb1decSSalil Mehta return -ENOMEM; 227e2cb1decSSalil Mehta 228e2cb1decSSalil Mehta tqp = hdev->htqp; 229e2cb1decSSalil Mehta 230e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 231e2cb1decSSalil Mehta tqp->dev = &hdev->pdev->dev; 232e2cb1decSSalil Mehta tqp->index = i; 233e2cb1decSSalil Mehta 234e2cb1decSSalil Mehta tqp->q.ae_algo = &ae_algovf; 235e2cb1decSSalil Mehta tqp->q.buf_size = hdev->rx_buf_len; 236e2cb1decSSalil Mehta tqp->q.desc_num = hdev->num_desc; 237e2cb1decSSalil Mehta tqp->q.io_base = hdev->hw.io_base + HCLGEVF_TQP_REG_OFFSET + 238e2cb1decSSalil Mehta i * HCLGEVF_TQP_REG_SIZE; 239e2cb1decSSalil Mehta 240e2cb1decSSalil Mehta tqp++; 241e2cb1decSSalil Mehta } 242e2cb1decSSalil Mehta 243e2cb1decSSalil Mehta return 0; 244e2cb1decSSalil Mehta } 245e2cb1decSSalil Mehta 246e2cb1decSSalil Mehta static int hclgevf_knic_setup(struct hclgevf_dev *hdev) 247e2cb1decSSalil Mehta { 248e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 249e2cb1decSSalil Mehta struct hnae3_knic_private_info *kinfo; 250e2cb1decSSalil Mehta u16 new_tqps = hdev->num_tqps; 251e2cb1decSSalil Mehta int i; 252e2cb1decSSalil Mehta 253e2cb1decSSalil Mehta kinfo = &nic->kinfo; 254e2cb1decSSalil Mehta kinfo->num_tc = 0; 255e2cb1decSSalil Mehta kinfo->num_desc = hdev->num_desc; 256e2cb1decSSalil Mehta kinfo->rx_buf_len = hdev->rx_buf_len; 257e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) 258e2cb1decSSalil Mehta if (hdev->hw_tc_map & BIT(i)) 259e2cb1decSSalil Mehta kinfo->num_tc++; 260e2cb1decSSalil Mehta 261e2cb1decSSalil Mehta kinfo->rss_size 262e2cb1decSSalil Mehta = min_t(u16, hdev->rss_size_max, new_tqps / kinfo->num_tc); 263e2cb1decSSalil Mehta new_tqps = kinfo->rss_size * kinfo->num_tc; 264e2cb1decSSalil Mehta kinfo->num_tqps = min(new_tqps, hdev->num_tqps); 265e2cb1decSSalil Mehta 266e2cb1decSSalil Mehta kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, 267e2cb1decSSalil Mehta sizeof(struct hnae3_queue *), GFP_KERNEL); 268e2cb1decSSalil Mehta if (!kinfo->tqp) 269e2cb1decSSalil Mehta return -ENOMEM; 270e2cb1decSSalil Mehta 271e2cb1decSSalil Mehta for (i = 0; i < kinfo->num_tqps; i++) { 272e2cb1decSSalil Mehta hdev->htqp[i].q.handle = &hdev->nic; 273e2cb1decSSalil Mehta hdev->htqp[i].q.tqp_index = i; 274e2cb1decSSalil Mehta kinfo->tqp[i] = &hdev->htqp[i].q; 275e2cb1decSSalil Mehta } 276e2cb1decSSalil Mehta 277e2cb1decSSalil Mehta return 0; 278e2cb1decSSalil Mehta } 279e2cb1decSSalil Mehta 280e2cb1decSSalil Mehta static void hclgevf_request_link_info(struct hclgevf_dev *hdev) 281e2cb1decSSalil Mehta { 282e2cb1decSSalil Mehta int status; 283e2cb1decSSalil Mehta u8 resp_msg; 284e2cb1decSSalil Mehta 285e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_STATUS, 0, NULL, 286e2cb1decSSalil Mehta 0, false, &resp_msg, sizeof(u8)); 287e2cb1decSSalil Mehta if (status) 288e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 289e2cb1decSSalil Mehta "VF failed to fetch link status(%d) from PF", status); 290e2cb1decSSalil Mehta } 291e2cb1decSSalil Mehta 292e2cb1decSSalil Mehta void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state) 293e2cb1decSSalil Mehta { 294e2cb1decSSalil Mehta struct hnae3_handle *handle = &hdev->nic; 295e2cb1decSSalil Mehta struct hnae3_client *client; 296e2cb1decSSalil Mehta 297e2cb1decSSalil Mehta client = handle->client; 298e2cb1decSSalil Mehta 299e2cb1decSSalil Mehta if (link_state != hdev->hw.mac.link) { 300e2cb1decSSalil Mehta client->ops->link_status_change(handle, !!link_state); 301e2cb1decSSalil Mehta hdev->hw.mac.link = link_state; 302e2cb1decSSalil Mehta } 303e2cb1decSSalil Mehta } 304e2cb1decSSalil Mehta 305e2cb1decSSalil Mehta static int hclgevf_set_handle_info(struct hclgevf_dev *hdev) 306e2cb1decSSalil Mehta { 307e2cb1decSSalil Mehta struct hnae3_handle *nic = &hdev->nic; 308e2cb1decSSalil Mehta int ret; 309e2cb1decSSalil Mehta 310e2cb1decSSalil Mehta nic->ae_algo = &ae_algovf; 311e2cb1decSSalil Mehta nic->pdev = hdev->pdev; 312e2cb1decSSalil Mehta nic->numa_node_mask = hdev->numa_node_mask; 313424eb834SSalil Mehta nic->flags |= HNAE3_SUPPORT_VF; 314e2cb1decSSalil Mehta 315e2cb1decSSalil Mehta if (hdev->ae_dev->dev_type != HNAE3_DEV_KNIC) { 316e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "unsupported device type %d\n", 317e2cb1decSSalil Mehta hdev->ae_dev->dev_type); 318e2cb1decSSalil Mehta return -EINVAL; 319e2cb1decSSalil Mehta } 320e2cb1decSSalil Mehta 321e2cb1decSSalil Mehta ret = hclgevf_knic_setup(hdev); 322e2cb1decSSalil Mehta if (ret) 323e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, "VF knic setup failed %d\n", 324e2cb1decSSalil Mehta ret); 325e2cb1decSSalil Mehta return ret; 326e2cb1decSSalil Mehta } 327e2cb1decSSalil Mehta 328e2cb1decSSalil Mehta static void hclgevf_free_vector(struct hclgevf_dev *hdev, int vector_id) 329e2cb1decSSalil Mehta { 330e2cb1decSSalil Mehta hdev->vector_status[vector_id] = HCLGEVF_INVALID_VPORT; 331e2cb1decSSalil Mehta hdev->num_msi_left += 1; 332e2cb1decSSalil Mehta hdev->num_msi_used -= 1; 333e2cb1decSSalil Mehta } 334e2cb1decSSalil Mehta 335e2cb1decSSalil Mehta static int hclgevf_get_vector(struct hnae3_handle *handle, u16 vector_num, 336e2cb1decSSalil Mehta struct hnae3_vector_info *vector_info) 337e2cb1decSSalil Mehta { 338e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 339e2cb1decSSalil Mehta struct hnae3_vector_info *vector = vector_info; 340e2cb1decSSalil Mehta int alloc = 0; 341e2cb1decSSalil Mehta int i, j; 342e2cb1decSSalil Mehta 343e2cb1decSSalil Mehta vector_num = min(hdev->num_msi_left, vector_num); 344e2cb1decSSalil Mehta 345e2cb1decSSalil Mehta for (j = 0; j < vector_num; j++) { 346e2cb1decSSalil Mehta for (i = HCLGEVF_MISC_VECTOR_NUM + 1; i < hdev->num_msi; i++) { 347e2cb1decSSalil Mehta if (hdev->vector_status[i] == HCLGEVF_INVALID_VPORT) { 348e2cb1decSSalil Mehta vector->vector = pci_irq_vector(hdev->pdev, i); 349e2cb1decSSalil Mehta vector->io_addr = hdev->hw.io_base + 350e2cb1decSSalil Mehta HCLGEVF_VECTOR_REG_BASE + 351e2cb1decSSalil Mehta (i - 1) * HCLGEVF_VECTOR_REG_OFFSET; 352e2cb1decSSalil Mehta hdev->vector_status[i] = 0; 353e2cb1decSSalil Mehta hdev->vector_irq[i] = vector->vector; 354e2cb1decSSalil Mehta 355e2cb1decSSalil Mehta vector++; 356e2cb1decSSalil Mehta alloc++; 357e2cb1decSSalil Mehta 358e2cb1decSSalil Mehta break; 359e2cb1decSSalil Mehta } 360e2cb1decSSalil Mehta } 361e2cb1decSSalil Mehta } 362e2cb1decSSalil Mehta hdev->num_msi_left -= alloc; 363e2cb1decSSalil Mehta hdev->num_msi_used += alloc; 364e2cb1decSSalil Mehta 365e2cb1decSSalil Mehta return alloc; 366e2cb1decSSalil Mehta } 367e2cb1decSSalil Mehta 368e2cb1decSSalil Mehta static int hclgevf_get_vector_index(struct hclgevf_dev *hdev, int vector) 369e2cb1decSSalil Mehta { 370e2cb1decSSalil Mehta int i; 371e2cb1decSSalil Mehta 372e2cb1decSSalil Mehta for (i = 0; i < hdev->num_msi; i++) 373e2cb1decSSalil Mehta if (vector == hdev->vector_irq[i]) 374e2cb1decSSalil Mehta return i; 375e2cb1decSSalil Mehta 376e2cb1decSSalil Mehta return -EINVAL; 377e2cb1decSSalil Mehta } 378e2cb1decSSalil Mehta 379e2cb1decSSalil Mehta static u32 hclgevf_get_rss_key_size(struct hnae3_handle *handle) 380e2cb1decSSalil Mehta { 381e2cb1decSSalil Mehta return HCLGEVF_RSS_KEY_SIZE; 382e2cb1decSSalil Mehta } 383e2cb1decSSalil Mehta 384e2cb1decSSalil Mehta static u32 hclgevf_get_rss_indir_size(struct hnae3_handle *handle) 385e2cb1decSSalil Mehta { 386e2cb1decSSalil Mehta return HCLGEVF_RSS_IND_TBL_SIZE; 387e2cb1decSSalil Mehta } 388e2cb1decSSalil Mehta 389e2cb1decSSalil Mehta static int hclgevf_set_rss_indir_table(struct hclgevf_dev *hdev) 390e2cb1decSSalil Mehta { 391e2cb1decSSalil Mehta const u8 *indir = hdev->rss_cfg.rss_indirection_tbl; 392e2cb1decSSalil Mehta struct hclgevf_rss_indirection_table_cmd *req; 393e2cb1decSSalil Mehta struct hclgevf_desc desc; 394e2cb1decSSalil Mehta int status; 395e2cb1decSSalil Mehta int i, j; 396e2cb1decSSalil Mehta 397e2cb1decSSalil Mehta req = (struct hclgevf_rss_indirection_table_cmd *)desc.data; 398e2cb1decSSalil Mehta 399e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_CFG_TBL_NUM; i++) { 400e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_INDIR_TABLE, 401e2cb1decSSalil Mehta false); 402e2cb1decSSalil Mehta req->start_table_index = i * HCLGEVF_RSS_CFG_TBL_SIZE; 403e2cb1decSSalil Mehta req->rss_set_bitmap = HCLGEVF_RSS_SET_BITMAP_MSK; 404e2cb1decSSalil Mehta for (j = 0; j < HCLGEVF_RSS_CFG_TBL_SIZE; j++) 405e2cb1decSSalil Mehta req->rss_result[j] = 406e2cb1decSSalil Mehta indir[i * HCLGEVF_RSS_CFG_TBL_SIZE + j]; 407e2cb1decSSalil Mehta 408e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 409e2cb1decSSalil Mehta if (status) { 410e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 411e2cb1decSSalil Mehta "VF failed(=%d) to set RSS indirection table\n", 412e2cb1decSSalil Mehta status); 413e2cb1decSSalil Mehta return status; 414e2cb1decSSalil Mehta } 415e2cb1decSSalil Mehta } 416e2cb1decSSalil Mehta 417e2cb1decSSalil Mehta return 0; 418e2cb1decSSalil Mehta } 419e2cb1decSSalil Mehta 420e2cb1decSSalil Mehta static int hclgevf_set_rss_tc_mode(struct hclgevf_dev *hdev, u16 rss_size) 421e2cb1decSSalil Mehta { 422e2cb1decSSalil Mehta struct hclgevf_rss_tc_mode_cmd *req; 423e2cb1decSSalil Mehta u16 tc_offset[HCLGEVF_MAX_TC_NUM]; 424e2cb1decSSalil Mehta u16 tc_valid[HCLGEVF_MAX_TC_NUM]; 425e2cb1decSSalil Mehta u16 tc_size[HCLGEVF_MAX_TC_NUM]; 426e2cb1decSSalil Mehta struct hclgevf_desc desc; 427e2cb1decSSalil Mehta u16 roundup_size; 428e2cb1decSSalil Mehta int status; 429e2cb1decSSalil Mehta int i; 430e2cb1decSSalil Mehta 431e2cb1decSSalil Mehta req = (struct hclgevf_rss_tc_mode_cmd *)desc.data; 432e2cb1decSSalil Mehta 433e2cb1decSSalil Mehta roundup_size = roundup_pow_of_two(rss_size); 434e2cb1decSSalil Mehta roundup_size = ilog2(roundup_size); 435e2cb1decSSalil Mehta 436e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 437e2cb1decSSalil Mehta tc_valid[i] = !!(hdev->hw_tc_map & BIT(i)); 438e2cb1decSSalil Mehta tc_size[i] = roundup_size; 439e2cb1decSSalil Mehta tc_offset[i] = rss_size * i; 440e2cb1decSSalil Mehta } 441e2cb1decSSalil Mehta 442e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false); 443e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { 444e2cb1decSSalil Mehta hnae_set_bit(req->rss_tc_mode[i], HCLGEVF_RSS_TC_VALID_B, 445e2cb1decSSalil Mehta (tc_valid[i] & 0x1)); 446e2cb1decSSalil Mehta hnae_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_SIZE_M, 447e2cb1decSSalil Mehta HCLGEVF_RSS_TC_SIZE_S, tc_size[i]); 448e2cb1decSSalil Mehta hnae_set_field(req->rss_tc_mode[i], HCLGEVF_RSS_TC_OFFSET_M, 449e2cb1decSSalil Mehta HCLGEVF_RSS_TC_OFFSET_S, tc_offset[i]); 450e2cb1decSSalil Mehta } 451e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 452e2cb1decSSalil Mehta if (status) 453e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 454e2cb1decSSalil Mehta "VF failed(=%d) to set rss tc mode\n", status); 455e2cb1decSSalil Mehta 456e2cb1decSSalil Mehta return status; 457e2cb1decSSalil Mehta } 458e2cb1decSSalil Mehta 459e2cb1decSSalil Mehta static int hclgevf_get_rss_hw_cfg(struct hnae3_handle *handle, u8 *hash, 460e2cb1decSSalil Mehta u8 *key) 461e2cb1decSSalil Mehta { 462e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 463e2cb1decSSalil Mehta struct hclgevf_rss_config_cmd *req; 464e2cb1decSSalil Mehta int lkup_times = key ? 3 : 1; 465e2cb1decSSalil Mehta struct hclgevf_desc desc; 466e2cb1decSSalil Mehta int key_offset; 467e2cb1decSSalil Mehta int key_size; 468e2cb1decSSalil Mehta int status; 469e2cb1decSSalil Mehta 470e2cb1decSSalil Mehta req = (struct hclgevf_rss_config_cmd *)desc.data; 471e2cb1decSSalil Mehta lkup_times = (lkup_times == 3) ? 3 : ((hash) ? 1 : 0); 472e2cb1decSSalil Mehta 473e2cb1decSSalil Mehta for (key_offset = 0; key_offset < lkup_times; key_offset++) { 474e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 475e2cb1decSSalil Mehta HCLGEVF_OPC_RSS_GENERIC_CONFIG, 476e2cb1decSSalil Mehta true); 477e2cb1decSSalil Mehta req->hash_config |= (key_offset << HCLGEVF_RSS_HASH_KEY_OFFSET); 478e2cb1decSSalil Mehta 479e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 480e2cb1decSSalil Mehta if (status) { 481e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 482e2cb1decSSalil Mehta "failed to get hardware RSS cfg, status = %d\n", 483e2cb1decSSalil Mehta status); 484e2cb1decSSalil Mehta return status; 485e2cb1decSSalil Mehta } 486e2cb1decSSalil Mehta 487e2cb1decSSalil Mehta if (key_offset == 2) 488e2cb1decSSalil Mehta key_size = 489e2cb1decSSalil Mehta HCLGEVF_RSS_KEY_SIZE - HCLGEVF_RSS_HASH_KEY_NUM * 2; 490e2cb1decSSalil Mehta else 491e2cb1decSSalil Mehta key_size = HCLGEVF_RSS_HASH_KEY_NUM; 492e2cb1decSSalil Mehta 493e2cb1decSSalil Mehta if (key) 494e2cb1decSSalil Mehta memcpy(key + key_offset * HCLGEVF_RSS_HASH_KEY_NUM, 495e2cb1decSSalil Mehta req->hash_key, 496e2cb1decSSalil Mehta key_size); 497e2cb1decSSalil Mehta } 498e2cb1decSSalil Mehta 499e2cb1decSSalil Mehta if (hash) { 500e2cb1decSSalil Mehta if ((req->hash_config & 0xf) == HCLGEVF_RSS_HASH_ALGO_TOEPLITZ) 501e2cb1decSSalil Mehta *hash = ETH_RSS_HASH_TOP; 502e2cb1decSSalil Mehta else 503e2cb1decSSalil Mehta *hash = ETH_RSS_HASH_UNKNOWN; 504e2cb1decSSalil Mehta } 505e2cb1decSSalil Mehta 506e2cb1decSSalil Mehta return 0; 507e2cb1decSSalil Mehta } 508e2cb1decSSalil Mehta 509e2cb1decSSalil Mehta static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key, 510e2cb1decSSalil Mehta 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 if (indir) 517e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 518e2cb1decSSalil Mehta indir[i] = rss_cfg->rss_indirection_tbl[i]; 519e2cb1decSSalil Mehta 520e2cb1decSSalil Mehta return hclgevf_get_rss_hw_cfg(handle, hfunc, key); 521e2cb1decSSalil Mehta } 522e2cb1decSSalil Mehta 523e2cb1decSSalil Mehta static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, 524e2cb1decSSalil Mehta const u8 *key, const u8 hfunc) 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 int i; 529e2cb1decSSalil Mehta 530e2cb1decSSalil Mehta /* update the shadow RSS table with user specified qids */ 531e2cb1decSSalil Mehta for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) 532e2cb1decSSalil Mehta rss_cfg->rss_indirection_tbl[i] = indir[i]; 533e2cb1decSSalil Mehta 534e2cb1decSSalil Mehta /* update the hardware */ 535e2cb1decSSalil Mehta return hclgevf_set_rss_indir_table(hdev); 536e2cb1decSSalil Mehta } 537e2cb1decSSalil Mehta 538e2cb1decSSalil Mehta static int hclgevf_get_tc_size(struct hnae3_handle *handle) 539e2cb1decSSalil Mehta { 540e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 541e2cb1decSSalil Mehta struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; 542e2cb1decSSalil Mehta 543e2cb1decSSalil Mehta return rss_cfg->rss_size; 544e2cb1decSSalil Mehta } 545e2cb1decSSalil Mehta 546e2cb1decSSalil Mehta static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en, 547e2cb1decSSalil Mehta int vector, 548e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 549e2cb1decSSalil Mehta { 550e2cb1decSSalil Mehta #define HCLGEVF_RING_NODE_VARIABLE_NUM 3 551e2cb1decSSalil Mehta #define HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM 3 552e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 553e2cb1decSSalil Mehta struct hnae3_ring_chain_node *node; 554e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 555e2cb1decSSalil Mehta struct hclgevf_desc desc; 556e2cb1decSSalil Mehta int i, vector_id; 557e2cb1decSSalil Mehta int status; 558e2cb1decSSalil Mehta u8 type; 559e2cb1decSSalil Mehta 560e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 561e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 562e2cb1decSSalil Mehta if (vector_id < 0) { 563e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 564e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 565e2cb1decSSalil Mehta return vector_id; 566e2cb1decSSalil Mehta } 567e2cb1decSSalil Mehta 568e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 569e2cb1decSSalil Mehta type = en ? 570e2cb1decSSalil Mehta HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR; 571e2cb1decSSalil Mehta req->msg[0] = type; 572e2cb1decSSalil Mehta req->msg[1] = vector_id; /* vector_id should be id in VF */ 573e2cb1decSSalil Mehta 574e2cb1decSSalil Mehta i = 0; 575e2cb1decSSalil Mehta for (node = ring_chain; node; node = node->next) { 576e2cb1decSSalil Mehta i++; 577e2cb1decSSalil Mehta /* msg[2] is cause num */ 578e2cb1decSSalil Mehta req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i] = 579e2cb1decSSalil Mehta hnae_get_bit(node->flag, HNAE3_RING_TYPE_B); 580e2cb1decSSalil Mehta req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 1] = 581e2cb1decSSalil Mehta node->tqp_index; 582e2cb1decSSalil Mehta if (i == (HCLGE_MBX_VF_MSG_DATA_NUM - 583e2cb1decSSalil Mehta HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM) / 584e2cb1decSSalil Mehta HCLGEVF_RING_NODE_VARIABLE_NUM) { 585e2cb1decSSalil Mehta req->msg[2] = i; 586e2cb1decSSalil Mehta 587e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 588e2cb1decSSalil Mehta if (status) { 589e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 590e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", 591e2cb1decSSalil Mehta status); 592e2cb1decSSalil Mehta return status; 593e2cb1decSSalil Mehta } 594e2cb1decSSalil Mehta i = 0; 595e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, 596e2cb1decSSalil Mehta HCLGEVF_OPC_MBX_VF_TO_PF, 597e2cb1decSSalil Mehta false); 598e2cb1decSSalil Mehta req->msg[0] = type; 599e2cb1decSSalil Mehta req->msg[1] = vector_id; 600e2cb1decSSalil Mehta } 601e2cb1decSSalil Mehta } 602e2cb1decSSalil Mehta 603e2cb1decSSalil Mehta if (i > 0) { 604e2cb1decSSalil Mehta req->msg[2] = i; 605e2cb1decSSalil Mehta 606e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 607e2cb1decSSalil Mehta if (status) { 608e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 609e2cb1decSSalil Mehta "Map TQP fail, status is %d.\n", status); 610e2cb1decSSalil Mehta return status; 611e2cb1decSSalil Mehta } 612e2cb1decSSalil Mehta } 613e2cb1decSSalil Mehta 614e2cb1decSSalil Mehta return 0; 615e2cb1decSSalil Mehta } 616e2cb1decSSalil Mehta 617e2cb1decSSalil Mehta static int hclgevf_map_ring_to_vector(struct hnae3_handle *handle, int vector, 618e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 619e2cb1decSSalil Mehta { 620e2cb1decSSalil Mehta return hclgevf_bind_ring_to_vector(handle, true, vector, ring_chain); 621e2cb1decSSalil Mehta } 622e2cb1decSSalil Mehta 623e2cb1decSSalil Mehta static int hclgevf_unmap_ring_from_vector( 624e2cb1decSSalil Mehta struct hnae3_handle *handle, 625e2cb1decSSalil Mehta int vector, 626e2cb1decSSalil Mehta struct hnae3_ring_chain_node *ring_chain) 627e2cb1decSSalil Mehta { 628e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 629e2cb1decSSalil Mehta int ret, vector_id; 630e2cb1decSSalil Mehta 631e2cb1decSSalil Mehta vector_id = hclgevf_get_vector_index(hdev, vector); 632e2cb1decSSalil Mehta if (vector_id < 0) { 633e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 634e2cb1decSSalil Mehta "Get vector index fail. ret =%d\n", vector_id); 635e2cb1decSSalil Mehta return vector_id; 636e2cb1decSSalil Mehta } 637e2cb1decSSalil Mehta 638e2cb1decSSalil Mehta ret = hclgevf_bind_ring_to_vector(handle, false, vector, ring_chain); 639e2cb1decSSalil Mehta if (ret) { 640e2cb1decSSalil Mehta dev_err(&handle->pdev->dev, 641e2cb1decSSalil Mehta "Unmap ring from vector fail. vector=%d, ret =%d\n", 642e2cb1decSSalil Mehta vector_id, 643e2cb1decSSalil Mehta ret); 644e2cb1decSSalil Mehta return ret; 645e2cb1decSSalil Mehta } 646e2cb1decSSalil Mehta 647e2cb1decSSalil Mehta hclgevf_free_vector(hdev, vector); 648e2cb1decSSalil Mehta 649e2cb1decSSalil Mehta return 0; 650e2cb1decSSalil Mehta } 651e2cb1decSSalil Mehta 652e2cb1decSSalil Mehta static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) 653e2cb1decSSalil Mehta { 654e2cb1decSSalil Mehta struct hclge_mbx_vf_to_pf_cmd *req; 655e2cb1decSSalil Mehta struct hclgevf_desc desc; 656e2cb1decSSalil Mehta int status; 657e2cb1decSSalil Mehta 658e2cb1decSSalil Mehta req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; 659e2cb1decSSalil Mehta 660e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); 661e2cb1decSSalil Mehta req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; 662e2cb1decSSalil Mehta req->msg[1] = en; 663e2cb1decSSalil Mehta 664e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 665e2cb1decSSalil Mehta if (status) 666e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 667e2cb1decSSalil Mehta "Set promisc mode fail, status is %d.\n", status); 668e2cb1decSSalil Mehta 669e2cb1decSSalil Mehta return status; 670e2cb1decSSalil Mehta } 671e2cb1decSSalil Mehta 672e2cb1decSSalil Mehta static void hclgevf_set_promisc_mode(struct hnae3_handle *handle, u32 en) 673e2cb1decSSalil Mehta { 674e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 675e2cb1decSSalil Mehta 676e2cb1decSSalil Mehta hclgevf_cmd_set_promisc_mode(hdev, en); 677e2cb1decSSalil Mehta } 678e2cb1decSSalil Mehta 679e2cb1decSSalil Mehta static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, 680e2cb1decSSalil Mehta int stream_id, bool enable) 681e2cb1decSSalil Mehta { 682e2cb1decSSalil Mehta struct hclgevf_cfg_com_tqp_queue_cmd *req; 683e2cb1decSSalil Mehta struct hclgevf_desc desc; 684e2cb1decSSalil Mehta int status; 685e2cb1decSSalil Mehta 686e2cb1decSSalil Mehta req = (struct hclgevf_cfg_com_tqp_queue_cmd *)desc.data; 687e2cb1decSSalil Mehta 688e2cb1decSSalil Mehta hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_CFG_COM_TQP_QUEUE, 689e2cb1decSSalil Mehta false); 690e2cb1decSSalil Mehta req->tqp_id = cpu_to_le16(tqp_id & HCLGEVF_RING_ID_MASK); 691e2cb1decSSalil Mehta req->stream_id = cpu_to_le16(stream_id); 692e2cb1decSSalil Mehta req->enable |= enable << HCLGEVF_TQP_ENABLE_B; 693e2cb1decSSalil Mehta 694e2cb1decSSalil Mehta status = hclgevf_cmd_send(&hdev->hw, &desc, 1); 695e2cb1decSSalil Mehta if (status) 696e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 697e2cb1decSSalil Mehta "TQP enable fail, status =%d.\n", status); 698e2cb1decSSalil Mehta 699e2cb1decSSalil Mehta return status; 700e2cb1decSSalil Mehta } 701e2cb1decSSalil Mehta 702e2cb1decSSalil Mehta static int hclgevf_get_queue_id(struct hnae3_queue *queue) 703e2cb1decSSalil Mehta { 704e2cb1decSSalil Mehta struct hclgevf_tqp *tqp = container_of(queue, struct hclgevf_tqp, q); 705e2cb1decSSalil Mehta 706e2cb1decSSalil Mehta return tqp->index; 707e2cb1decSSalil Mehta } 708e2cb1decSSalil Mehta 709e2cb1decSSalil Mehta static void hclgevf_reset_tqp_stats(struct hnae3_handle *handle) 710e2cb1decSSalil Mehta { 711e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 712e2cb1decSSalil Mehta struct hnae3_queue *queue; 713e2cb1decSSalil Mehta struct hclgevf_tqp *tqp; 714e2cb1decSSalil Mehta int i; 715e2cb1decSSalil Mehta 716e2cb1decSSalil Mehta for (i = 0; i < hdev->num_tqps; i++) { 717e2cb1decSSalil Mehta queue = handle->kinfo.tqp[i]; 718e2cb1decSSalil Mehta tqp = container_of(queue, struct hclgevf_tqp, q); 719e2cb1decSSalil Mehta memset(&tqp->tqp_stats, 0, sizeof(tqp->tqp_stats)); 720e2cb1decSSalil Mehta } 721e2cb1decSSalil Mehta } 722e2cb1decSSalil Mehta 723e2cb1decSSalil Mehta static int hclgevf_cfg_func_mta_filter(struct hnae3_handle *handle, bool en) 724e2cb1decSSalil Mehta { 725e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 726e2cb1decSSalil Mehta u8 msg[2] = {0}; 727e2cb1decSSalil Mehta 728e2cb1decSSalil Mehta msg[0] = en; 729e2cb1decSSalil Mehta return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, 730e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, 731e2cb1decSSalil Mehta msg, 1, false, NULL, 0); 732e2cb1decSSalil Mehta } 733e2cb1decSSalil Mehta 734e2cb1decSSalil Mehta static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) 735e2cb1decSSalil Mehta { 736e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 737e2cb1decSSalil Mehta 738e2cb1decSSalil Mehta ether_addr_copy(p, hdev->hw.mac.mac_addr); 739e2cb1decSSalil Mehta } 740e2cb1decSSalil Mehta 741e2cb1decSSalil Mehta static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p) 742e2cb1decSSalil Mehta { 743e2cb1decSSalil Mehta struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 744e2cb1decSSalil Mehta u8 *old_mac_addr = (u8 *)hdev->hw.mac.mac_addr; 745e2cb1decSSalil Mehta u8 *new_mac_addr = (u8 *)p; 746e2cb1decSSalil Mehta u8 msg_data[ETH_ALEN * 2]; 747e2cb1decSSalil Mehta int status; 748e2cb1decSSalil Mehta 749e2cb1decSSalil Mehta ether_addr_copy(msg_data, new_mac_addr); 750e2cb1decSSalil Mehta ether_addr_copy(&msg_data[ETH_ALEN], old_mac_addr); 751e2cb1decSSalil Mehta 752e2cb1decSSalil Mehta status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_UNICAST, 753e2cb1decSSalil Mehta HCLGE_MBX_MAC_VLAN_UC_MODIFY, 754e2cb1decSSalil Mehta 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 ret = hclgevf_enable_tso(hdev, true); 1379e2cb1decSSalil Mehta if (ret) { 1380e2cb1decSSalil Mehta dev_err(&pdev->dev, "failed(%d) to enable tso\n", ret); 1381e2cb1decSSalil Mehta goto err_config; 1382e2cb1decSSalil Mehta } 1383e2cb1decSSalil Mehta 1384e2cb1decSSalil Mehta /* Initialize VF's MTA */ 1385e2cb1decSSalil Mehta hdev->accept_mta_mc = true; 1386e2cb1decSSalil Mehta ret = hclgevf_cfg_func_mta_filter(&hdev->nic, hdev->accept_mta_mc); 1387e2cb1decSSalil Mehta if (ret) { 1388e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1389e2cb1decSSalil Mehta "failed(%d) to set mta filter mode\n", ret); 1390e2cb1decSSalil Mehta goto err_config; 1391e2cb1decSSalil Mehta } 1392e2cb1decSSalil Mehta 1393e2cb1decSSalil Mehta /* Initialize RSS for this VF */ 1394e2cb1decSSalil Mehta ret = hclgevf_rss_init_hw(hdev); 1395e2cb1decSSalil Mehta if (ret) { 1396e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1397e2cb1decSSalil Mehta "failed(%d) to initialize RSS\n", ret); 1398e2cb1decSSalil Mehta goto err_config; 1399e2cb1decSSalil Mehta } 1400e2cb1decSSalil Mehta 1401e2cb1decSSalil Mehta ret = hclgevf_init_vlan_config(hdev); 1402e2cb1decSSalil Mehta if (ret) { 1403e2cb1decSSalil Mehta dev_err(&hdev->pdev->dev, 1404e2cb1decSSalil Mehta "failed(%d) to initialize VLAN config\n", ret); 1405e2cb1decSSalil Mehta goto err_config; 1406e2cb1decSSalil Mehta } 1407e2cb1decSSalil Mehta 1408e2cb1decSSalil Mehta pr_info("finished initializing %s driver\n", HCLGEVF_DRIVER_NAME); 1409e2cb1decSSalil Mehta 1410e2cb1decSSalil Mehta return 0; 1411e2cb1decSSalil Mehta 1412e2cb1decSSalil Mehta err_config: 1413e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1414e2cb1decSSalil Mehta err_cmd_init: 1415e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1416e2cb1decSSalil Mehta err_misc_irq_init: 1417e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1418e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1419e2cb1decSSalil Mehta err_irq_init: 1420e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1421e2cb1decSSalil Mehta return ret; 1422e2cb1decSSalil Mehta } 1423e2cb1decSSalil Mehta 1424e2cb1decSSalil Mehta static void hclgevf_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) 1425e2cb1decSSalil Mehta { 1426e2cb1decSSalil Mehta struct hclgevf_dev *hdev = ae_dev->priv; 1427e2cb1decSSalil Mehta 1428e2cb1decSSalil Mehta hclgevf_cmd_uninit(hdev); 1429e2cb1decSSalil Mehta hclgevf_misc_irq_uninit(hdev); 1430e2cb1decSSalil Mehta hclgevf_state_uninit(hdev); 1431e2cb1decSSalil Mehta hclgevf_uninit_msi(hdev); 1432e2cb1decSSalil Mehta hclgevf_pci_uninit(hdev); 1433e2cb1decSSalil Mehta ae_dev->priv = NULL; 1434e2cb1decSSalil Mehta } 1435e2cb1decSSalil Mehta 1436849e4607SPeng Li static u32 hclgevf_get_max_channels(struct hclgevf_dev *hdev) 1437849e4607SPeng Li { 1438849e4607SPeng Li struct hnae3_handle *nic = &hdev->nic; 1439849e4607SPeng Li struct hnae3_knic_private_info *kinfo = &nic->kinfo; 1440849e4607SPeng Li 1441849e4607SPeng Li return min_t(u32, hdev->rss_size_max * kinfo->num_tc, hdev->num_tqps); 1442849e4607SPeng Li } 1443849e4607SPeng Li 1444849e4607SPeng Li /** 1445849e4607SPeng Li * hclgevf_get_channels - Get the current channels enabled and max supported. 1446849e4607SPeng Li * @handle: hardware information for network interface 1447849e4607SPeng Li * @ch: ethtool channels structure 1448849e4607SPeng Li * 1449849e4607SPeng Li * We don't support separate tx and rx queues as channels. The other count 1450849e4607SPeng Li * represents how many queues are being used for control. max_combined counts 1451849e4607SPeng Li * how many queue pairs we can support. They may not be mapped 1 to 1 with 1452849e4607SPeng Li * q_vectors since we support a lot more queue pairs than q_vectors. 1453849e4607SPeng Li **/ 1454849e4607SPeng Li static void hclgevf_get_channels(struct hnae3_handle *handle, 1455849e4607SPeng Li struct ethtool_channels *ch) 1456849e4607SPeng Li { 1457849e4607SPeng Li struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); 1458849e4607SPeng Li 1459849e4607SPeng Li ch->max_combined = hclgevf_get_max_channels(hdev); 1460849e4607SPeng Li ch->other_count = 0; 1461849e4607SPeng Li ch->max_other = 0; 1462849e4607SPeng Li ch->combined_count = hdev->num_tqps; 1463849e4607SPeng Li } 1464849e4607SPeng Li 1465e2cb1decSSalil Mehta static const struct hnae3_ae_ops hclgevf_ops = { 1466e2cb1decSSalil Mehta .init_ae_dev = hclgevf_init_ae_dev, 1467e2cb1decSSalil Mehta .uninit_ae_dev = hclgevf_uninit_ae_dev, 1468e2cb1decSSalil Mehta .init_client_instance = hclgevf_register_client, 1469e2cb1decSSalil Mehta .uninit_client_instance = hclgevf_unregister_client, 1470e2cb1decSSalil Mehta .start = hclgevf_ae_start, 1471e2cb1decSSalil Mehta .stop = hclgevf_ae_stop, 1472e2cb1decSSalil Mehta .map_ring_to_vector = hclgevf_map_ring_to_vector, 1473e2cb1decSSalil Mehta .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector, 1474e2cb1decSSalil Mehta .get_vector = hclgevf_get_vector, 1475e2cb1decSSalil Mehta .reset_queue = hclgevf_reset_tqp, 1476e2cb1decSSalil Mehta .set_promisc_mode = hclgevf_set_promisc_mode, 1477e2cb1decSSalil Mehta .get_mac_addr = hclgevf_get_mac_addr, 1478e2cb1decSSalil Mehta .set_mac_addr = hclgevf_set_mac_addr, 1479e2cb1decSSalil Mehta .add_uc_addr = hclgevf_add_uc_addr, 1480e2cb1decSSalil Mehta .rm_uc_addr = hclgevf_rm_uc_addr, 1481e2cb1decSSalil Mehta .add_mc_addr = hclgevf_add_mc_addr, 1482e2cb1decSSalil Mehta .rm_mc_addr = hclgevf_rm_mc_addr, 1483e2cb1decSSalil Mehta .get_stats = hclgevf_get_stats, 1484e2cb1decSSalil Mehta .update_stats = hclgevf_update_stats, 1485e2cb1decSSalil Mehta .get_strings = hclgevf_get_strings, 1486e2cb1decSSalil Mehta .get_sset_count = hclgevf_get_sset_count, 1487e2cb1decSSalil Mehta .get_rss_key_size = hclgevf_get_rss_key_size, 1488e2cb1decSSalil Mehta .get_rss_indir_size = hclgevf_get_rss_indir_size, 1489e2cb1decSSalil Mehta .get_rss = hclgevf_get_rss, 1490e2cb1decSSalil Mehta .set_rss = hclgevf_set_rss, 1491e2cb1decSSalil Mehta .get_tc_size = hclgevf_get_tc_size, 1492e2cb1decSSalil Mehta .get_fw_version = hclgevf_get_fw_version, 1493e2cb1decSSalil Mehta .set_vlan_filter = hclgevf_set_vlan_filter, 1494849e4607SPeng Li .get_channels = hclgevf_get_channels, 1495e2cb1decSSalil Mehta }; 1496e2cb1decSSalil Mehta 1497e2cb1decSSalil Mehta static struct hnae3_ae_algo ae_algovf = { 1498e2cb1decSSalil Mehta .ops = &hclgevf_ops, 1499e2cb1decSSalil Mehta .name = HCLGEVF_NAME, 1500e2cb1decSSalil Mehta .pdev_id_table = ae_algovf_pci_tbl, 1501e2cb1decSSalil Mehta }; 1502e2cb1decSSalil Mehta 1503e2cb1decSSalil Mehta static int hclgevf_init(void) 1504e2cb1decSSalil Mehta { 1505e2cb1decSSalil Mehta pr_info("%s is initializing\n", HCLGEVF_NAME); 1506e2cb1decSSalil Mehta 1507e2cb1decSSalil Mehta return hnae3_register_ae_algo(&ae_algovf); 1508e2cb1decSSalil Mehta } 1509e2cb1decSSalil Mehta 1510e2cb1decSSalil Mehta static void hclgevf_exit(void) 1511e2cb1decSSalil Mehta { 1512e2cb1decSSalil Mehta hnae3_unregister_ae_algo(&ae_algovf); 1513e2cb1decSSalil Mehta } 1514e2cb1decSSalil Mehta module_init(hclgevf_init); 1515e2cb1decSSalil Mehta module_exit(hclgevf_exit); 1516e2cb1decSSalil Mehta 1517e2cb1decSSalil Mehta MODULE_LICENSE("GPL"); 1518e2cb1decSSalil Mehta MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 1519e2cb1decSSalil Mehta MODULE_DESCRIPTION("HCLGEVF Driver"); 1520e2cb1decSSalil Mehta MODULE_VERSION(HCLGEVF_MOD_VERSION); 1521