1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2017 Intel Corporation 3 */ 4 5 #include <sys/queue.h> 6 #include <stdio.h> 7 #include <errno.h> 8 #include <stdint.h> 9 #include <string.h> 10 #include <unistd.h> 11 #include <stdarg.h> 12 #include <inttypes.h> 13 14 #include <rte_string_fns.h> 15 #include <rte_pci.h> 16 #include <rte_ether.h> 17 #include <rte_ethdev_driver.h> 18 #include <rte_malloc.h> 19 #include <rte_memcpy.h> 20 21 #include "i40e_logs.h" 22 #include "base/i40e_prototype.h" 23 #include "base/i40e_adminq_cmd.h" 24 #include "base/i40e_type.h" 25 #include "i40e_ethdev.h" 26 #include "i40e_rxtx.h" 27 #include "i40e_pf.h" 28 #include "rte_pmd_i40e.h" 29 30 #define I40E_CFG_CRCSTRIP_DEFAULT 1 31 32 static int 33 i40e_pf_host_switch_queues(struct i40e_pf_vf *vf, 34 struct virtchnl_queue_select *qsel, 35 bool on); 36 37 /** 38 * Bind PF queues with VSI and VF. 39 **/ 40 static int 41 i40e_pf_vf_queues_mapping(struct i40e_pf_vf *vf) 42 { 43 int i; 44 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 45 uint16_t vsi_id = vf->vsi->vsi_id; 46 uint16_t vf_id = vf->vf_idx; 47 uint16_t nb_qps = vf->vsi->nb_qps; 48 uint16_t qbase = vf->vsi->base_queue; 49 uint16_t q1, q2; 50 uint32_t val; 51 52 /* 53 * VF should use scatter range queues. So, it needn't 54 * to set QBASE in this register. 55 */ 56 i40e_write_rx_ctl(hw, I40E_VSILAN_QBASE(vsi_id), 57 I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK); 58 59 /* Set to enable VFLAN_QTABLE[] registers valid */ 60 I40E_WRITE_REG(hw, I40E_VPLAN_MAPENA(vf_id), 61 I40E_VPLAN_MAPENA_TXRX_ENA_MASK); 62 63 /* map PF queues to VF */ 64 for (i = 0; i < nb_qps; i++) { 65 val = ((qbase + i) & I40E_VPLAN_QTABLE_QINDEX_MASK); 66 I40E_WRITE_REG(hw, I40E_VPLAN_QTABLE(i, vf_id), val); 67 } 68 69 /* map PF queues to VSI */ 70 for (i = 0; i < I40E_MAX_QP_NUM_PER_VF / 2; i++) { 71 if (2 * i > nb_qps - 1) 72 q1 = I40E_VSILAN_QTABLE_QINDEX_0_MASK; 73 else 74 q1 = qbase + 2 * i; 75 76 if (2 * i + 1 > nb_qps - 1) 77 q2 = I40E_VSILAN_QTABLE_QINDEX_0_MASK; 78 else 79 q2 = qbase + 2 * i + 1; 80 81 val = (q2 << I40E_VSILAN_QTABLE_QINDEX_1_SHIFT) + q1; 82 i40e_write_rx_ctl(hw, I40E_VSILAN_QTABLE(i, vsi_id), val); 83 } 84 I40E_WRITE_FLUSH(hw); 85 86 return I40E_SUCCESS; 87 } 88 89 90 /** 91 * Proceed VF reset operation. 92 */ 93 int 94 i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset) 95 { 96 uint32_t val, i; 97 struct i40e_hw *hw; 98 struct i40e_pf *pf; 99 uint16_t vf_id, abs_vf_id, vf_msix_num; 100 int ret; 101 struct virtchnl_queue_select qsel; 102 103 if (vf == NULL) 104 return -EINVAL; 105 106 pf = vf->pf; 107 hw = I40E_PF_TO_HW(vf->pf); 108 vf_id = vf->vf_idx; 109 abs_vf_id = vf_id + hw->func_caps.vf_base_id; 110 111 /* Notify VF that we are in VFR progress */ 112 I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), VIRTCHNL_VFR_INPROGRESS); 113 114 /* 115 * If require a SW VF reset, a VFLR interrupt will be generated, 116 * this function will be called again. To avoid it, 117 * disable interrupt first. 118 */ 119 if (do_hw_reset) { 120 vf->state = I40E_VF_INRESET; 121 val = I40E_READ_REG(hw, I40E_VPGEN_VFRTRIG(vf_id)); 122 val |= I40E_VPGEN_VFRTRIG_VFSWR_MASK; 123 I40E_WRITE_REG(hw, I40E_VPGEN_VFRTRIG(vf_id), val); 124 I40E_WRITE_FLUSH(hw); 125 } 126 127 #define VFRESET_MAX_WAIT_CNT 100 128 /* Wait until VF reset is done */ 129 for (i = 0; i < VFRESET_MAX_WAIT_CNT; i++) { 130 rte_delay_us(10); 131 val = I40E_READ_REG(hw, I40E_VPGEN_VFRSTAT(vf_id)); 132 if (val & I40E_VPGEN_VFRSTAT_VFRD_MASK) 133 break; 134 } 135 136 if (i >= VFRESET_MAX_WAIT_CNT) { 137 PMD_DRV_LOG(ERR, "VF reset timeout"); 138 return -ETIMEDOUT; 139 } 140 /* This is not first time to do reset, do cleanup job first */ 141 if (vf->vsi) { 142 /* Disable queues */ 143 memset(&qsel, 0, sizeof(qsel)); 144 for (i = 0; i < vf->vsi->nb_qps; i++) 145 qsel.rx_queues |= 1 << i; 146 qsel.tx_queues = qsel.rx_queues; 147 ret = i40e_pf_host_switch_queues(vf, &qsel, false); 148 if (ret != I40E_SUCCESS) { 149 PMD_DRV_LOG(ERR, "Disable VF queues failed"); 150 return -EFAULT; 151 } 152 153 /* Disable VF interrupt setting */ 154 vf_msix_num = hw->func_caps.num_msix_vectors_vf; 155 for (i = 0; i < vf_msix_num; i++) { 156 if (!i) 157 val = I40E_VFINT_DYN_CTL0(vf_id); 158 else 159 val = I40E_VFINT_DYN_CTLN(((vf_msix_num - 1) * 160 (vf_id)) + (i - 1)); 161 I40E_WRITE_REG(hw, val, I40E_VFINT_DYN_CTLN_CLEARPBA_MASK); 162 } 163 I40E_WRITE_FLUSH(hw); 164 165 /* remove VSI */ 166 ret = i40e_vsi_release(vf->vsi); 167 if (ret != I40E_SUCCESS) { 168 PMD_DRV_LOG(ERR, "Release VSI failed"); 169 return -EFAULT; 170 } 171 } 172 173 #define I40E_VF_PCI_ADDR 0xAA 174 #define I40E_VF_PEND_MASK 0x20 175 /* Check the pending transactions of this VF */ 176 /* Use absolute VF id, refer to datasheet for details */ 177 I40E_WRITE_REG(hw, I40E_PF_PCI_CIAA, I40E_VF_PCI_ADDR | 178 (abs_vf_id << I40E_PF_PCI_CIAA_VF_NUM_SHIFT)); 179 for (i = 0; i < VFRESET_MAX_WAIT_CNT; i++) { 180 rte_delay_us(1); 181 val = I40E_READ_REG(hw, I40E_PF_PCI_CIAD); 182 if ((val & I40E_VF_PEND_MASK) == 0) 183 break; 184 } 185 186 if (i >= VFRESET_MAX_WAIT_CNT) { 187 PMD_DRV_LOG(ERR, "Wait VF PCI transaction end timeout"); 188 return -ETIMEDOUT; 189 } 190 191 /* Reset done, Set COMPLETE flag and clear reset bit */ 192 I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), VIRTCHNL_VFR_COMPLETED); 193 val = I40E_READ_REG(hw, I40E_VPGEN_VFRTRIG(vf_id)); 194 val &= ~I40E_VPGEN_VFRTRIG_VFSWR_MASK; 195 I40E_WRITE_REG(hw, I40E_VPGEN_VFRTRIG(vf_id), val); 196 vf->reset_cnt++; 197 I40E_WRITE_FLUSH(hw); 198 199 /* Allocate resource again */ 200 if (pf->floating_veb && pf->floating_veb_list[vf_id]) { 201 vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV, 202 NULL, vf->vf_idx); 203 } else { 204 vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV, 205 vf->pf->main_vsi, vf->vf_idx); 206 } 207 208 if (vf->vsi == NULL) { 209 PMD_DRV_LOG(ERR, "Add vsi failed"); 210 return -EFAULT; 211 } 212 213 ret = i40e_pf_vf_queues_mapping(vf); 214 if (ret != I40E_SUCCESS) { 215 PMD_DRV_LOG(ERR, "queue mapping error"); 216 i40e_vsi_release(vf->vsi); 217 return -EFAULT; 218 } 219 220 I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), VIRTCHNL_VFR_VFACTIVE); 221 222 return ret; 223 } 224 225 int 226 i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf, 227 uint32_t opcode, 228 uint32_t retval, 229 uint8_t *msg, 230 uint16_t msglen) 231 { 232 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 233 uint16_t abs_vf_id = hw->func_caps.vf_base_id + vf->vf_idx; 234 int ret; 235 236 ret = i40e_aq_send_msg_to_vf(hw, abs_vf_id, opcode, retval, 237 msg, msglen, NULL); 238 if (ret) { 239 PMD_INIT_LOG(ERR, "Fail to send message to VF, err %u", 240 hw->aq.asq_last_status); 241 } 242 243 return ret; 244 } 245 246 static void 247 i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf, uint8_t *msg, 248 bool b_op) 249 { 250 struct virtchnl_version_info info; 251 252 /* VF and PF drivers need to follow the Virtchnl definition, No matter 253 * it's DPDK or other kernel drivers. 254 * The original DPDK host specific feature 255 * like CFG_VLAN_PVID and CONFIG_VSI_QUEUES_EXT will not available. 256 */ 257 258 info.major = VIRTCHNL_VERSION_MAJOR; 259 vf->version = *(struct virtchnl_version_info *)msg; 260 if (VF_IS_V10(&vf->version)) 261 info.minor = VIRTCHNL_VERSION_MINOR_NO_VF_CAPS; 262 else 263 info.minor = VIRTCHNL_VERSION_MINOR; 264 265 if (b_op) 266 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_VERSION, 267 I40E_SUCCESS, 268 (uint8_t *)&info, 269 sizeof(info)); 270 else 271 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_VERSION, 272 I40E_NOT_SUPPORTED, 273 (uint8_t *)&info, 274 sizeof(info)); 275 } 276 277 static int 278 i40e_pf_host_process_cmd_reset_vf(struct i40e_pf_vf *vf) 279 { 280 i40e_pf_host_vf_reset(vf, 1); 281 282 /* No feedback will be sent to VF for VFLR */ 283 return I40E_SUCCESS; 284 } 285 286 static int 287 i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, uint8_t *msg, 288 bool b_op) 289 { 290 struct virtchnl_vf_resource *vf_res = NULL; 291 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 292 uint32_t len = 0; 293 uint64_t default_hena = I40E_RSS_HENA_ALL; 294 int ret = I40E_SUCCESS; 295 296 if (!b_op) { 297 i40e_pf_host_send_msg_to_vf(vf, 298 VIRTCHNL_OP_GET_VF_RESOURCES, 299 I40E_NOT_SUPPORTED, NULL, 0); 300 return ret; 301 } 302 303 /* only have 1 VSI by default */ 304 len = sizeof(struct virtchnl_vf_resource) + 305 I40E_DEFAULT_VF_VSI_NUM * 306 sizeof(struct virtchnl_vsi_resource); 307 308 vf_res = rte_zmalloc("i40e_vf_res", len, 0); 309 if (vf_res == NULL) { 310 PMD_DRV_LOG(ERR, "failed to allocate mem"); 311 ret = I40E_ERR_NO_MEMORY; 312 vf_res = NULL; 313 len = 0; 314 goto send_msg; 315 } 316 317 if (VF_IS_V10(&vf->version)) /* doesn't support offload negotiate */ 318 vf->request_caps = VIRTCHNL_VF_OFFLOAD_L2 | 319 VIRTCHNL_VF_OFFLOAD_VLAN; 320 else 321 vf->request_caps = *(uint32_t *)msg; 322 323 /* enable all RSS by default, 324 * doesn't support hena setting by virtchnnl yet. 325 */ 326 if (vf->request_caps & VIRTCHNL_VF_OFFLOAD_RSS_PF) { 327 I40E_WRITE_REG(hw, I40E_VFQF_HENA1(0, vf->vf_idx), 328 (uint32_t)default_hena); 329 I40E_WRITE_REG(hw, I40E_VFQF_HENA1(1, vf->vf_idx), 330 (uint32_t)(default_hena >> 32)); 331 I40E_WRITE_FLUSH(hw); 332 } 333 334 vf_res->vf_cap_flags = vf->request_caps & 335 I40E_VIRTCHNL_OFFLOAD_CAPS; 336 /* For X722, it supports write back on ITR 337 * without binding queue to interrupt vector. 338 */ 339 if (hw->mac.type == I40E_MAC_X722) 340 vf_res->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_WB_ON_ITR; 341 vf_res->max_vectors = hw->func_caps.num_msix_vectors_vf; 342 vf_res->num_queue_pairs = vf->vsi->nb_qps; 343 vf_res->num_vsis = I40E_DEFAULT_VF_VSI_NUM; 344 vf_res->rss_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 4; 345 vf_res->rss_lut_size = (I40E_VFQF_HLUT1_MAX_INDEX + 1) * 4; 346 347 /* Change below setting if PF host can support more VSIs for VF */ 348 vf_res->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV; 349 vf_res->vsi_res[0].vsi_id = vf->vsi->vsi_id; 350 vf_res->vsi_res[0].num_queue_pairs = vf->vsi->nb_qps; 351 rte_ether_addr_copy(&vf->mac_addr, 352 (struct rte_ether_addr *)vf_res->vsi_res[0].default_mac_addr); 353 354 send_msg: 355 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_VF_RESOURCES, 356 ret, (uint8_t *)vf_res, len); 357 rte_free(vf_res); 358 359 return ret; 360 } 361 362 static int 363 i40e_pf_host_hmc_config_rxq(struct i40e_hw *hw, 364 struct i40e_pf_vf *vf, 365 struct virtchnl_rxq_info *rxq, 366 uint8_t crcstrip) 367 { 368 int err = I40E_SUCCESS; 369 struct i40e_hmc_obj_rxq rx_ctx; 370 uint16_t abs_queue_id = vf->vsi->base_queue + rxq->queue_id; 371 372 /* Clear the context structure first */ 373 memset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq)); 374 rx_ctx.dbuff = rxq->databuffer_size >> I40E_RXQ_CTX_DBUFF_SHIFT; 375 rx_ctx.hbuff = rxq->hdr_size >> I40E_RXQ_CTX_HBUFF_SHIFT; 376 rx_ctx.base = rxq->dma_ring_addr / I40E_QUEUE_BASE_ADDR_UNIT; 377 rx_ctx.qlen = rxq->ring_len; 378 #ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC 379 rx_ctx.dsize = 1; 380 #endif 381 382 if (rxq->splithdr_enabled) { 383 rx_ctx.hsplit_0 = I40E_HEADER_SPLIT_ALL; 384 rx_ctx.dtype = i40e_header_split_enabled; 385 } else { 386 rx_ctx.hsplit_0 = I40E_HEADER_SPLIT_NONE; 387 rx_ctx.dtype = i40e_header_split_none; 388 } 389 rx_ctx.rxmax = rxq->max_pkt_size; 390 rx_ctx.tphrdesc_ena = 1; 391 rx_ctx.tphwdesc_ena = 1; 392 rx_ctx.tphdata_ena = 1; 393 rx_ctx.tphhead_ena = 1; 394 rx_ctx.lrxqthresh = 2; 395 rx_ctx.crcstrip = crcstrip; 396 rx_ctx.l2tsel = 1; 397 rx_ctx.prefena = 1; 398 399 err = i40e_clear_lan_rx_queue_context(hw, abs_queue_id); 400 if (err != I40E_SUCCESS) 401 return err; 402 err = i40e_set_lan_rx_queue_context(hw, abs_queue_id, &rx_ctx); 403 404 return err; 405 } 406 407 static inline uint8_t 408 i40e_vsi_get_tc_of_queue(struct i40e_vsi *vsi, 409 uint16_t queue_id) 410 { 411 struct i40e_aqc_vsi_properties_data *info = &vsi->info; 412 uint16_t bsf, qp_idx; 413 uint8_t i; 414 415 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 416 if (vsi->enabled_tc & (1 << i)) { 417 qp_idx = rte_le_to_cpu_16((info->tc_mapping[i] & 418 I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >> 419 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT); 420 bsf = rte_le_to_cpu_16((info->tc_mapping[i] & 421 I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >> 422 I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT); 423 if (queue_id >= qp_idx && queue_id < qp_idx + (1 << bsf)) 424 return i; 425 } 426 } 427 return 0; 428 } 429 430 static int 431 i40e_pf_host_hmc_config_txq(struct i40e_hw *hw, 432 struct i40e_pf_vf *vf, 433 struct virtchnl_txq_info *txq) 434 { 435 int err = I40E_SUCCESS; 436 struct i40e_hmc_obj_txq tx_ctx; 437 struct i40e_vsi *vsi = vf->vsi; 438 uint32_t qtx_ctl; 439 uint16_t abs_queue_id = vsi->base_queue + txq->queue_id; 440 uint8_t dcb_tc; 441 442 /* clear the context structure first */ 443 memset(&tx_ctx, 0, sizeof(tx_ctx)); 444 tx_ctx.base = txq->dma_ring_addr / I40E_QUEUE_BASE_ADDR_UNIT; 445 tx_ctx.qlen = txq->ring_len; 446 dcb_tc = i40e_vsi_get_tc_of_queue(vsi, txq->queue_id); 447 tx_ctx.rdylist = rte_le_to_cpu_16(vsi->info.qs_handle[dcb_tc]); 448 tx_ctx.head_wb_ena = txq->headwb_enabled; 449 tx_ctx.head_wb_addr = txq->dma_headwb_addr; 450 451 err = i40e_clear_lan_tx_queue_context(hw, abs_queue_id); 452 if (err != I40E_SUCCESS) 453 return err; 454 455 err = i40e_set_lan_tx_queue_context(hw, abs_queue_id, &tx_ctx); 456 if (err != I40E_SUCCESS) 457 return err; 458 459 /* bind queue with VF function, since TX/QX will appear in pair, 460 * so only has QTX_CTL to set. 461 */ 462 qtx_ctl = (I40E_QTX_CTL_VF_QUEUE << I40E_QTX_CTL_PFVF_Q_SHIFT) | 463 ((hw->pf_id << I40E_QTX_CTL_PF_INDX_SHIFT) & 464 I40E_QTX_CTL_PF_INDX_MASK) | 465 (((vf->vf_idx + hw->func_caps.vf_base_id) << 466 I40E_QTX_CTL_VFVM_INDX_SHIFT) & 467 I40E_QTX_CTL_VFVM_INDX_MASK); 468 I40E_WRITE_REG(hw, I40E_QTX_CTL(abs_queue_id), qtx_ctl); 469 I40E_WRITE_FLUSH(hw); 470 471 return I40E_SUCCESS; 472 } 473 474 static int 475 i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf, 476 uint8_t *msg, 477 uint16_t msglen, 478 bool b_op) 479 { 480 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 481 struct i40e_vsi *vsi = vf->vsi; 482 struct virtchnl_vsi_queue_config_info *vc_vqci = 483 (struct virtchnl_vsi_queue_config_info *)msg; 484 struct virtchnl_queue_pair_info *vc_qpi; 485 int i, ret = I40E_SUCCESS; 486 487 if (!b_op) { 488 i40e_pf_host_send_msg_to_vf(vf, 489 VIRTCHNL_OP_CONFIG_VSI_QUEUES, 490 I40E_NOT_SUPPORTED, NULL, 0); 491 return ret; 492 } 493 494 if (!msg || vc_vqci->num_queue_pairs > vsi->nb_qps || 495 vc_vqci->num_queue_pairs > I40E_MAX_VSI_QP || 496 msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqci, 497 vc_vqci->num_queue_pairs)) { 498 PMD_DRV_LOG(ERR, "vsi_queue_config_info argument wrong"); 499 ret = I40E_ERR_PARAM; 500 goto send_msg; 501 } 502 503 vc_qpi = vc_vqci->qpair; 504 for (i = 0; i < vc_vqci->num_queue_pairs; i++) { 505 if (vc_qpi[i].rxq.queue_id > vsi->nb_qps - 1 || 506 vc_qpi[i].txq.queue_id > vsi->nb_qps - 1) { 507 ret = I40E_ERR_PARAM; 508 goto send_msg; 509 } 510 511 /* 512 * Apply VF RX queue setting to HMC. 513 * If the opcode is VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT, 514 * then the extra information of 515 * 'struct virtchnl_queue_pair_extra_info' is needed, 516 * otherwise set the last parameter to NULL. 517 */ 518 if (i40e_pf_host_hmc_config_rxq(hw, vf, &vc_qpi[i].rxq, 519 I40E_CFG_CRCSTRIP_DEFAULT) != I40E_SUCCESS) { 520 PMD_DRV_LOG(ERR, "Configure RX queue HMC failed"); 521 ret = I40E_ERR_PARAM; 522 goto send_msg; 523 } 524 525 /* Apply VF TX queue setting to HMC */ 526 if (i40e_pf_host_hmc_config_txq(hw, vf, 527 &vc_qpi[i].txq) != I40E_SUCCESS) { 528 PMD_DRV_LOG(ERR, "Configure TX queue HMC failed"); 529 ret = I40E_ERR_PARAM; 530 goto send_msg; 531 } 532 } 533 534 send_msg: 535 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, 536 ret, NULL, 0); 537 538 return ret; 539 } 540 541 static void 542 i40e_pf_config_irq_link_list(struct i40e_pf_vf *vf, 543 struct virtchnl_vector_map *vvm) 544 { 545 #define BITS_PER_CHAR 8 546 uint64_t linklistmap = 0, tempmap; 547 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 548 uint16_t qid; 549 bool b_first_q = true; 550 enum i40e_queue_type qtype; 551 uint16_t vector_id; 552 uint32_t reg, reg_idx; 553 uint16_t itr_idx = 0, i; 554 555 vector_id = vvm->vector_id; 556 /* setup the head */ 557 if (!vector_id) 558 reg_idx = I40E_VPINT_LNKLST0(vf->vf_idx); 559 else 560 reg_idx = I40E_VPINT_LNKLSTN( 561 ((hw->func_caps.num_msix_vectors_vf - 1) * vf->vf_idx) 562 + (vector_id - 1)); 563 564 if (vvm->rxq_map == 0 && vvm->txq_map == 0) { 565 I40E_WRITE_REG(hw, reg_idx, 566 I40E_VPINT_LNKLST0_FIRSTQ_INDX_MASK); 567 goto cfg_irq_done; 568 } 569 570 /* sort all rx and tx queues */ 571 tempmap = vvm->rxq_map; 572 for (i = 0; i < sizeof(vvm->rxq_map) * BITS_PER_CHAR; i++) { 573 if (tempmap & 0x1) 574 linklistmap |= (1 << (2 * i)); 575 tempmap >>= 1; 576 } 577 578 tempmap = vvm->txq_map; 579 for (i = 0; i < sizeof(vvm->txq_map) * BITS_PER_CHAR; i++) { 580 if (tempmap & 0x1) 581 linklistmap |= (1 << (2 * i + 1)); 582 tempmap >>= 1; 583 } 584 585 /* Link all rx and tx queues into a chained list */ 586 tempmap = linklistmap; 587 i = 0; 588 b_first_q = true; 589 do { 590 if (tempmap & 0x1) { 591 qtype = (enum i40e_queue_type)(i % 2); 592 qid = vf->vsi->base_queue + i / 2; 593 if (b_first_q) { 594 /* This is header */ 595 b_first_q = false; 596 reg = ((qtype << 597 I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT) 598 | qid); 599 } else { 600 /* element in the link list */ 601 reg = (vector_id) | 602 (qtype << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) | 603 (qid << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) | 604 BIT(I40E_QINT_RQCTL_CAUSE_ENA_SHIFT) | 605 (itr_idx << I40E_QINT_RQCTL_ITR_INDX_SHIFT); 606 } 607 I40E_WRITE_REG(hw, reg_idx, reg); 608 /* find next register to program */ 609 switch (qtype) { 610 case I40E_QUEUE_TYPE_RX: 611 reg_idx = I40E_QINT_RQCTL(qid); 612 itr_idx = vvm->rxitr_idx; 613 break; 614 case I40E_QUEUE_TYPE_TX: 615 reg_idx = I40E_QINT_TQCTL(qid); 616 itr_idx = vvm->txitr_idx; 617 break; 618 default: 619 break; 620 } 621 } 622 i++; 623 tempmap >>= 1; 624 } while (tempmap); 625 626 /* Terminate the link list */ 627 reg = (vector_id) | 628 (0 << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) | 629 (0x7FF << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) | 630 BIT(I40E_QINT_RQCTL_CAUSE_ENA_SHIFT) | 631 (itr_idx << I40E_QINT_RQCTL_ITR_INDX_SHIFT); 632 I40E_WRITE_REG(hw, reg_idx, reg); 633 634 cfg_irq_done: 635 I40E_WRITE_FLUSH(hw); 636 } 637 638 static int 639 i40e_pf_host_process_cmd_config_irq_map(struct i40e_pf_vf *vf, 640 uint8_t *msg, uint16_t msglen, 641 bool b_op) 642 { 643 int ret = I40E_SUCCESS; 644 struct i40e_pf *pf = vf->pf; 645 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 646 struct virtchnl_irq_map_info *irqmap = 647 (struct virtchnl_irq_map_info *)msg; 648 struct virtchnl_vector_map *map; 649 int i; 650 uint16_t vector_id, itr_idx; 651 unsigned long qbit_max; 652 653 if (!b_op) { 654 i40e_pf_host_send_msg_to_vf( 655 vf, 656 VIRTCHNL_OP_CONFIG_IRQ_MAP, 657 I40E_NOT_SUPPORTED, NULL, 0); 658 return ret; 659 } 660 661 if (msg == NULL || msglen < sizeof(struct virtchnl_irq_map_info)) { 662 PMD_DRV_LOG(ERR, "buffer too short"); 663 ret = I40E_ERR_PARAM; 664 goto send_msg; 665 } 666 667 /* PF host will support both DPDK VF or Linux VF driver, identify by 668 * number of vectors requested. 669 */ 670 671 /* DPDK VF only requires single vector */ 672 if (irqmap->num_vectors == 1) { 673 /* This MSIX intr store the intr in VF range */ 674 vf->vsi->msix_intr = irqmap->vecmap[0].vector_id; 675 vf->vsi->nb_msix = irqmap->num_vectors; 676 vf->vsi->nb_used_qps = vf->vsi->nb_qps; 677 itr_idx = irqmap->vecmap[0].rxitr_idx; 678 679 /* Don't care how the TX/RX queue mapping with this vector. 680 * Link all VF RX queues together. Only did mapping work. 681 * VF can disable/enable the intr by itself. 682 */ 683 i40e_vsi_queues_bind_intr(vf->vsi, itr_idx); 684 goto send_msg; 685 } 686 687 /* Then, it's Linux VF driver */ 688 qbit_max = 1 << pf->vf_nb_qp_max; 689 for (i = 0; i < irqmap->num_vectors; i++) { 690 map = &irqmap->vecmap[i]; 691 692 vector_id = map->vector_id; 693 /* validate msg params */ 694 if (vector_id >= hw->func_caps.num_msix_vectors_vf) { 695 ret = I40E_ERR_PARAM; 696 goto send_msg; 697 } 698 699 if ((map->rxq_map < qbit_max) && (map->txq_map < qbit_max)) { 700 i40e_pf_config_irq_link_list(vf, map); 701 } else { 702 /* configured queue size excceed limit */ 703 ret = I40E_ERR_PARAM; 704 goto send_msg; 705 } 706 } 707 708 send_msg: 709 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_IRQ_MAP, 710 ret, NULL, 0); 711 712 return ret; 713 } 714 715 static int 716 i40e_pf_host_switch_queues(struct i40e_pf_vf *vf, 717 struct virtchnl_queue_select *qsel, 718 bool on) 719 { 720 int ret = I40E_SUCCESS; 721 int i; 722 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 723 uint16_t baseq = vf->vsi->base_queue; 724 725 if (qsel->rx_queues + qsel->tx_queues == 0) 726 return I40E_ERR_PARAM; 727 728 /* always enable RX first and disable last */ 729 /* Enable RX if it's enable */ 730 if (on) { 731 for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++) 732 if (qsel->rx_queues & (1 << i)) { 733 ret = i40e_switch_rx_queue(hw, baseq + i, on); 734 if (ret != I40E_SUCCESS) 735 return ret; 736 } 737 } 738 739 /* Enable/Disable TX */ 740 for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++) 741 if (qsel->tx_queues & (1 << i)) { 742 ret = i40e_switch_tx_queue(hw, baseq + i, on); 743 if (ret != I40E_SUCCESS) 744 return ret; 745 } 746 747 /* disable RX last if it's disable */ 748 if (!on) { 749 /* disable RX */ 750 for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++) 751 if (qsel->rx_queues & (1 << i)) { 752 ret = i40e_switch_rx_queue(hw, baseq + i, on); 753 if (ret != I40E_SUCCESS) 754 return ret; 755 } 756 } 757 758 return ret; 759 } 760 761 static int 762 i40e_pf_host_process_cmd_enable_queues(struct i40e_pf_vf *vf, 763 uint8_t *msg, 764 uint16_t msglen) 765 { 766 int ret = I40E_SUCCESS; 767 struct virtchnl_queue_select *q_sel = 768 (struct virtchnl_queue_select *)msg; 769 770 if (msg == NULL || msglen != sizeof(*q_sel)) { 771 ret = I40E_ERR_PARAM; 772 goto send_msg; 773 } 774 ret = i40e_pf_host_switch_queues(vf, q_sel, true); 775 776 send_msg: 777 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, 778 ret, NULL, 0); 779 780 return ret; 781 } 782 783 static int 784 i40e_pf_host_process_cmd_disable_queues(struct i40e_pf_vf *vf, 785 uint8_t *msg, 786 uint16_t msglen, 787 bool b_op) 788 { 789 int ret = I40E_SUCCESS; 790 struct virtchnl_queue_select *q_sel = 791 (struct virtchnl_queue_select *)msg; 792 793 if (!b_op) { 794 i40e_pf_host_send_msg_to_vf( 795 vf, 796 VIRTCHNL_OP_DISABLE_QUEUES, 797 I40E_NOT_SUPPORTED, NULL, 0); 798 return ret; 799 } 800 801 if (msg == NULL || msglen != sizeof(*q_sel)) { 802 ret = I40E_ERR_PARAM; 803 goto send_msg; 804 } 805 ret = i40e_pf_host_switch_queues(vf, q_sel, false); 806 807 send_msg: 808 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_QUEUES, 809 ret, NULL, 0); 810 811 return ret; 812 } 813 814 815 static int 816 i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf, 817 uint8_t *msg, 818 uint16_t msglen, 819 bool b_op) 820 { 821 int ret = I40E_SUCCESS; 822 struct virtchnl_ether_addr_list *addr_list = 823 (struct virtchnl_ether_addr_list *)msg; 824 struct i40e_mac_filter_info filter; 825 int i; 826 struct rte_ether_addr *mac; 827 828 if (!b_op) { 829 i40e_pf_host_send_msg_to_vf( 830 vf, 831 VIRTCHNL_OP_ADD_ETH_ADDR, 832 I40E_NOT_SUPPORTED, NULL, 0); 833 return ret; 834 } 835 836 memset(&filter, 0 , sizeof(struct i40e_mac_filter_info)); 837 838 if (msg == NULL || msglen <= sizeof(*addr_list)) { 839 PMD_DRV_LOG(ERR, "add_ether_address argument too short"); 840 ret = I40E_ERR_PARAM; 841 goto send_msg; 842 } 843 844 for (i = 0; i < addr_list->num_elements; i++) { 845 mac = (struct rte_ether_addr *)(addr_list->list[i].addr); 846 rte_memcpy(&filter.mac_addr, mac, RTE_ETHER_ADDR_LEN); 847 filter.filter_type = RTE_MACVLAN_PERFECT_MATCH; 848 if (rte_is_zero_ether_addr(mac) || 849 i40e_vsi_add_mac(vf->vsi, &filter)) { 850 ret = I40E_ERR_INVALID_MAC_ADDR; 851 goto send_msg; 852 } 853 } 854 855 send_msg: 856 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_ETH_ADDR, 857 ret, NULL, 0); 858 859 return ret; 860 } 861 862 static int 863 i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf, 864 uint8_t *msg, 865 uint16_t msglen, 866 bool b_op) 867 { 868 int ret = I40E_SUCCESS; 869 struct virtchnl_ether_addr_list *addr_list = 870 (struct virtchnl_ether_addr_list *)msg; 871 int i; 872 struct rte_ether_addr *mac; 873 874 if (!b_op) { 875 i40e_pf_host_send_msg_to_vf( 876 vf, 877 VIRTCHNL_OP_DEL_ETH_ADDR, 878 I40E_NOT_SUPPORTED, NULL, 0); 879 return ret; 880 } 881 882 if (msg == NULL || msglen <= sizeof(*addr_list)) { 883 PMD_DRV_LOG(ERR, "delete_ether_address argument too short"); 884 ret = I40E_ERR_PARAM; 885 goto send_msg; 886 } 887 888 for (i = 0; i < addr_list->num_elements; i++) { 889 mac = (struct rte_ether_addr *)(addr_list->list[i].addr); 890 if (rte_is_zero_ether_addr(mac) || 891 i40e_vsi_delete_mac(vf->vsi, mac)) { 892 ret = I40E_ERR_INVALID_MAC_ADDR; 893 goto send_msg; 894 } 895 } 896 897 send_msg: 898 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_ETH_ADDR, 899 ret, NULL, 0); 900 901 return ret; 902 } 903 904 static int 905 i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf, 906 uint8_t *msg, uint16_t msglen, 907 bool b_op) 908 { 909 int ret = I40E_SUCCESS; 910 struct virtchnl_vlan_filter_list *vlan_filter_list = 911 (struct virtchnl_vlan_filter_list *)msg; 912 int i; 913 uint16_t *vid; 914 915 if (!b_op) { 916 i40e_pf_host_send_msg_to_vf( 917 vf, 918 VIRTCHNL_OP_ADD_VLAN, 919 I40E_NOT_SUPPORTED, NULL, 0); 920 return ret; 921 } 922 923 if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) { 924 PMD_DRV_LOG(ERR, "add_vlan argument too short"); 925 ret = I40E_ERR_PARAM; 926 goto send_msg; 927 } 928 929 vid = vlan_filter_list->vlan_id; 930 931 for (i = 0; i < vlan_filter_list->num_elements; i++) { 932 ret = i40e_vsi_add_vlan(vf->vsi, vid[i]); 933 if(ret != I40E_SUCCESS) 934 goto send_msg; 935 } 936 937 send_msg: 938 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_VLAN, 939 ret, NULL, 0); 940 941 return ret; 942 } 943 944 static int 945 i40e_pf_host_process_cmd_del_vlan(struct i40e_pf_vf *vf, 946 uint8_t *msg, 947 uint16_t msglen, 948 bool b_op) 949 { 950 int ret = I40E_SUCCESS; 951 struct virtchnl_vlan_filter_list *vlan_filter_list = 952 (struct virtchnl_vlan_filter_list *)msg; 953 int i; 954 uint16_t *vid; 955 956 if (!b_op) { 957 i40e_pf_host_send_msg_to_vf( 958 vf, 959 VIRTCHNL_OP_DEL_VLAN, 960 I40E_NOT_SUPPORTED, NULL, 0); 961 return ret; 962 } 963 964 if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) { 965 PMD_DRV_LOG(ERR, "delete_vlan argument too short"); 966 ret = I40E_ERR_PARAM; 967 goto send_msg; 968 } 969 970 vid = vlan_filter_list->vlan_id; 971 for (i = 0; i < vlan_filter_list->num_elements; i++) { 972 ret = i40e_vsi_delete_vlan(vf->vsi, vid[i]); 973 if(ret != I40E_SUCCESS) 974 goto send_msg; 975 } 976 977 send_msg: 978 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_VLAN, 979 ret, NULL, 0); 980 981 return ret; 982 } 983 984 static int 985 i40e_pf_host_process_cmd_config_promisc_mode( 986 struct i40e_pf_vf *vf, 987 uint8_t *msg, 988 uint16_t msglen, 989 bool b_op) 990 { 991 int ret = I40E_SUCCESS; 992 struct virtchnl_promisc_info *promisc = 993 (struct virtchnl_promisc_info *)msg; 994 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 995 bool unicast = FALSE, multicast = FALSE; 996 997 if (!b_op) { 998 i40e_pf_host_send_msg_to_vf( 999 vf, 1000 VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, 1001 I40E_NOT_SUPPORTED, NULL, 0); 1002 return ret; 1003 } 1004 1005 if (msg == NULL || msglen != sizeof(*promisc)) { 1006 ret = I40E_ERR_PARAM; 1007 goto send_msg; 1008 } 1009 1010 if (promisc->flags & FLAG_VF_UNICAST_PROMISC) 1011 unicast = TRUE; 1012 ret = i40e_aq_set_vsi_unicast_promiscuous(hw, 1013 vf->vsi->seid, unicast, NULL, true); 1014 if (ret != I40E_SUCCESS) 1015 goto send_msg; 1016 1017 if (promisc->flags & FLAG_VF_MULTICAST_PROMISC) 1018 multicast = TRUE; 1019 ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid, 1020 multicast, NULL); 1021 1022 send_msg: 1023 i40e_pf_host_send_msg_to_vf(vf, 1024 VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, ret, NULL, 0); 1025 1026 return ret; 1027 } 1028 1029 static int 1030 i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf, bool b_op) 1031 { 1032 i40e_update_vsi_stats(vf->vsi); 1033 1034 if (b_op) 1035 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS, 1036 I40E_SUCCESS, 1037 (uint8_t *)&vf->vsi->eth_stats, 1038 sizeof(vf->vsi->eth_stats)); 1039 else 1040 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS, 1041 I40E_NOT_SUPPORTED, 1042 (uint8_t *)&vf->vsi->eth_stats, 1043 sizeof(vf->vsi->eth_stats)); 1044 1045 return I40E_SUCCESS; 1046 } 1047 1048 static int 1049 i40e_pf_host_process_cmd_enable_vlan_strip(struct i40e_pf_vf *vf, bool b_op) 1050 { 1051 int ret = I40E_SUCCESS; 1052 1053 if (!b_op) { 1054 i40e_pf_host_send_msg_to_vf( 1055 vf, 1056 VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, 1057 I40E_NOT_SUPPORTED, NULL, 0); 1058 return ret; 1059 } 1060 1061 ret = i40e_vsi_config_vlan_stripping(vf->vsi, TRUE); 1062 if (ret != 0) 1063 PMD_DRV_LOG(ERR, "Failed to enable vlan stripping"); 1064 1065 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, 1066 ret, NULL, 0); 1067 1068 return ret; 1069 } 1070 1071 static int 1072 i40e_pf_host_process_cmd_disable_vlan_strip(struct i40e_pf_vf *vf, bool b_op) 1073 { 1074 int ret = I40E_SUCCESS; 1075 1076 if (!b_op) { 1077 i40e_pf_host_send_msg_to_vf( 1078 vf, 1079 VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, 1080 I40E_NOT_SUPPORTED, NULL, 0); 1081 return ret; 1082 } 1083 1084 ret = i40e_vsi_config_vlan_stripping(vf->vsi, FALSE); 1085 if (ret != 0) 1086 PMD_DRV_LOG(ERR, "Failed to disable vlan stripping"); 1087 1088 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, 1089 ret, NULL, 0); 1090 1091 return ret; 1092 } 1093 1094 static int 1095 i40e_pf_host_process_cmd_set_rss_lut(struct i40e_pf_vf *vf, 1096 uint8_t *msg, 1097 uint16_t msglen, 1098 bool b_op) 1099 { 1100 struct virtchnl_rss_lut *rss_lut = (struct virtchnl_rss_lut *)msg; 1101 uint16_t valid_len; 1102 int ret = I40E_SUCCESS; 1103 1104 if (!b_op) { 1105 i40e_pf_host_send_msg_to_vf( 1106 vf, 1107 VIRTCHNL_OP_CONFIG_RSS_LUT, 1108 I40E_NOT_SUPPORTED, NULL, 0); 1109 return ret; 1110 } 1111 1112 if (!msg || msglen <= sizeof(struct virtchnl_rss_lut)) { 1113 PMD_DRV_LOG(ERR, "set_rss_lut argument too short"); 1114 ret = I40E_ERR_PARAM; 1115 goto send_msg; 1116 } 1117 valid_len = sizeof(struct virtchnl_rss_lut) + rss_lut->lut_entries - 1; 1118 if (msglen < valid_len) { 1119 PMD_DRV_LOG(ERR, "set_rss_lut length mismatch"); 1120 ret = I40E_ERR_PARAM; 1121 goto send_msg; 1122 } 1123 1124 ret = i40e_set_rss_lut(vf->vsi, rss_lut->lut, rss_lut->lut_entries); 1125 1126 send_msg: 1127 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, 1128 ret, NULL, 0); 1129 1130 return ret; 1131 } 1132 1133 static int 1134 i40e_pf_host_process_cmd_set_rss_key(struct i40e_pf_vf *vf, 1135 uint8_t *msg, 1136 uint16_t msglen, 1137 bool b_op) 1138 { 1139 struct virtchnl_rss_key *rss_key = (struct virtchnl_rss_key *)msg; 1140 uint16_t valid_len; 1141 int ret = I40E_SUCCESS; 1142 1143 if (!b_op) { 1144 i40e_pf_host_send_msg_to_vf( 1145 vf, 1146 VIRTCHNL_OP_DEL_VLAN, 1147 VIRTCHNL_OP_CONFIG_RSS_KEY, NULL, 0); 1148 return ret; 1149 } 1150 1151 if (!msg || msglen <= sizeof(struct virtchnl_rss_key)) { 1152 PMD_DRV_LOG(ERR, "set_rss_key argument too short"); 1153 ret = I40E_ERR_PARAM; 1154 goto send_msg; 1155 } 1156 valid_len = sizeof(struct virtchnl_rss_key) + rss_key->key_len - 1; 1157 if (msglen < valid_len) { 1158 PMD_DRV_LOG(ERR, "set_rss_key length mismatch"); 1159 ret = I40E_ERR_PARAM; 1160 goto send_msg; 1161 } 1162 1163 ret = i40e_set_rss_key(vf->vsi, rss_key->key, rss_key->key_len); 1164 1165 send_msg: 1166 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY, 1167 ret, NULL, 0); 1168 1169 return ret; 1170 } 1171 1172 void 1173 i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf) 1174 { 1175 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 1176 struct virtchnl_pf_event event; 1177 uint16_t vf_id = vf->vf_idx; 1178 uint32_t tval, rval; 1179 1180 event.event = VIRTCHNL_EVENT_LINK_CHANGE; 1181 event.event_data.link_event.link_status = 1182 dev->data->dev_link.link_status; 1183 1184 /* need to convert the ETH_SPEED_xxx into VIRTCHNL_LINK_SPEED_xxx */ 1185 switch (dev->data->dev_link.link_speed) { 1186 case ETH_SPEED_NUM_100M: 1187 event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_100MB; 1188 break; 1189 case ETH_SPEED_NUM_1G: 1190 event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_1GB; 1191 break; 1192 case ETH_SPEED_NUM_10G: 1193 event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_10GB; 1194 break; 1195 case ETH_SPEED_NUM_20G: 1196 event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_20GB; 1197 break; 1198 case ETH_SPEED_NUM_25G: 1199 event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_25GB; 1200 break; 1201 case ETH_SPEED_NUM_40G: 1202 event.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_40GB; 1203 break; 1204 default: 1205 event.event_data.link_event.link_speed = 1206 VIRTCHNL_LINK_SPEED_UNKNOWN; 1207 break; 1208 } 1209 1210 tval = I40E_READ_REG(hw, I40E_VF_ATQLEN(vf_id)); 1211 rval = I40E_READ_REG(hw, I40E_VF_ARQLEN(vf_id)); 1212 1213 if (tval & I40E_VF_ATQLEN_ATQLEN_MASK || 1214 tval & I40E_VF_ATQLEN_ATQENABLE_MASK || 1215 rval & I40E_VF_ARQLEN_ARQLEN_MASK || 1216 rval & I40E_VF_ARQLEN_ARQENABLE_MASK) 1217 i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_EVENT, 1218 I40E_SUCCESS, (uint8_t *)&event, sizeof(event)); 1219 } 1220 1221 /** 1222 * i40e_vc_notify_vf_reset 1223 * @vf: pointer to the VF structure 1224 * 1225 * indicate a pending reset to the given VF 1226 **/ 1227 static void 1228 i40e_vc_notify_vf_reset(struct i40e_pf_vf *vf) 1229 { 1230 struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); 1231 struct virtchnl_pf_event pfe; 1232 int abs_vf_id; 1233 uint16_t vf_id = vf->vf_idx; 1234 1235 abs_vf_id = vf_id + hw->func_caps.vf_base_id; 1236 pfe.event = VIRTCHNL_EVENT_RESET_IMPENDING; 1237 pfe.severity = PF_EVENT_SEVERITY_CERTAIN_DOOM; 1238 i40e_aq_send_msg_to_vf(hw, abs_vf_id, VIRTCHNL_OP_EVENT, 0, (u8 *)&pfe, 1239 sizeof(struct virtchnl_pf_event), NULL); 1240 } 1241 1242 static int 1243 i40e_pf_host_process_cmd_request_queues(struct i40e_pf_vf *vf, uint8_t *msg) 1244 { 1245 struct virtchnl_vf_res_request *vfres = 1246 (struct virtchnl_vf_res_request *)msg; 1247 struct i40e_pf *pf; 1248 uint32_t req_pairs = vfres->num_queue_pairs; 1249 uint32_t cur_pairs = vf->vsi->nb_used_qps; 1250 1251 pf = vf->pf; 1252 1253 if (!rte_is_power_of_2(req_pairs)) 1254 req_pairs = i40e_align_floor(req_pairs) << 1; 1255 1256 if (req_pairs == 0) { 1257 PMD_DRV_LOG(ERR, "VF %d tried to request 0 queues. Ignoring.\n", 1258 vf->vf_idx); 1259 } else if (req_pairs > I40E_MAX_QP_NUM_PER_VF) { 1260 PMD_DRV_LOG(ERR, 1261 "VF %d tried to request more than %d queues.\n", 1262 vf->vf_idx, 1263 I40E_MAX_QP_NUM_PER_VF); 1264 vfres->num_queue_pairs = I40E_MAX_QP_NUM_PER_VF; 1265 } else if (req_pairs > cur_pairs + pf->qp_pool.num_free) { 1266 PMD_DRV_LOG(ERR, "VF %d requested %d queues (rounded to %d) " 1267 "but only %d available\n", 1268 vf->vf_idx, 1269 vfres->num_queue_pairs, 1270 req_pairs, 1271 cur_pairs + pf->qp_pool.num_free); 1272 vfres->num_queue_pairs = i40e_align_floor(pf->qp_pool.num_free + 1273 cur_pairs); 1274 } else { 1275 i40e_vc_notify_vf_reset(vf); 1276 vf->vsi->nb_qps = req_pairs; 1277 pf->vf_nb_qps = req_pairs; 1278 i40e_pf_host_process_cmd_reset_vf(vf); 1279 1280 return 0; 1281 } 1282 1283 return i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0, 1284 (u8 *)vfres, sizeof(*vfres)); 1285 } 1286 1287 void 1288 i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev, 1289 uint16_t abs_vf_id, uint32_t opcode, 1290 __rte_unused uint32_t retval, 1291 uint8_t *msg, 1292 uint16_t msglen) 1293 { 1294 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1295 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 1296 struct i40e_pf_vf *vf; 1297 /* AdminQ will pass absolute VF id, transfer to internal vf id */ 1298 uint16_t vf_id = abs_vf_id - hw->func_caps.vf_base_id; 1299 struct rte_pmd_i40e_mb_event_param ret_param; 1300 uint64_t first_cycle, cur_cycle; 1301 bool b_op = TRUE; 1302 int ret; 1303 1304 if (vf_id > pf->vf_num - 1 || !pf->vfs) { 1305 PMD_DRV_LOG(ERR, "invalid argument"); 1306 return; 1307 } 1308 1309 vf = &pf->vfs[vf_id]; 1310 1311 cur_cycle = rte_get_timer_cycles(); 1312 1313 /* if the VF being blocked, ignore the message and return */ 1314 if (cur_cycle < vf->ignore_end_cycle) 1315 return; 1316 1317 if (!vf->vsi) { 1318 PMD_DRV_LOG(ERR, "NO VSI associated with VF found"); 1319 i40e_pf_host_send_msg_to_vf(vf, opcode, 1320 I40E_ERR_NO_AVAILABLE_VSI, NULL, 0); 1321 goto check; 1322 } 1323 1324 /* perform basic checks on the msg */ 1325 ret = virtchnl_vc_validate_vf_msg(&vf->version, opcode, msg, msglen); 1326 1327 /* perform additional checks specific to this driver */ 1328 if (opcode == VIRTCHNL_OP_CONFIG_RSS_KEY) { 1329 struct virtchnl_rss_key *vrk = (struct virtchnl_rss_key *)msg; 1330 1331 if (vrk->key_len != ((I40E_PFQF_HKEY_MAX_INDEX + 1) * 4)) 1332 ret = VIRTCHNL_ERR_PARAM; 1333 } else if (opcode == VIRTCHNL_OP_CONFIG_RSS_LUT) { 1334 struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg; 1335 1336 if (vrl->lut_entries != ((I40E_VFQF_HLUT1_MAX_INDEX + 1) * 4)) 1337 ret = VIRTCHNL_ERR_PARAM; 1338 } 1339 1340 if (ret) { 1341 PMD_DRV_LOG(ERR, "Invalid message from VF %u, opcode %u, len %u", 1342 vf_id, opcode, msglen); 1343 i40e_pf_host_send_msg_to_vf(vf, opcode, 1344 I40E_ERR_PARAM, NULL, 0); 1345 goto check; 1346 } 1347 1348 /** 1349 * initialise structure to send to user application 1350 * will return response from user in retval field 1351 */ 1352 ret_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED; 1353 ret_param.vfid = vf_id; 1354 ret_param.msg_type = opcode; 1355 ret_param.msg = (void *)msg; 1356 ret_param.msglen = msglen; 1357 1358 /** 1359 * Ask user application if we're allowed to perform those functions. 1360 * If we get ret_param.retval == RTE_PMD_I40E_MB_EVENT_PROCEED, 1361 * then business as usual. 1362 * If RTE_PMD_I40E_MB_EVENT_NOOP_ACK or RTE_PMD_I40E_MB_EVENT_NOOP_NACK, 1363 * do nothing and send not_supported to VF. As PF must send a response 1364 * to VF and ACK/NACK is not defined. 1365 */ 1366 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &ret_param); 1367 if (ret_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) { 1368 PMD_DRV_LOG(WARNING, "VF to PF message(%d) is not permitted!", 1369 opcode); 1370 b_op = FALSE; 1371 } 1372 1373 switch (opcode) { 1374 case VIRTCHNL_OP_VERSION: 1375 PMD_DRV_LOG(INFO, "OP_VERSION received"); 1376 i40e_pf_host_process_cmd_version(vf, msg, b_op); 1377 break; 1378 case VIRTCHNL_OP_RESET_VF: 1379 PMD_DRV_LOG(INFO, "OP_RESET_VF received"); 1380 i40e_pf_host_process_cmd_reset_vf(vf); 1381 break; 1382 case VIRTCHNL_OP_GET_VF_RESOURCES: 1383 PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received"); 1384 i40e_pf_host_process_cmd_get_vf_resource(vf, msg, b_op); 1385 break; 1386 case VIRTCHNL_OP_CONFIG_VSI_QUEUES: 1387 PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received"); 1388 i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, 1389 msglen, b_op); 1390 break; 1391 case VIRTCHNL_OP_CONFIG_IRQ_MAP: 1392 PMD_DRV_LOG(INFO, "OP_CONFIG_IRQ_MAP received"); 1393 i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen, b_op); 1394 break; 1395 case VIRTCHNL_OP_ENABLE_QUEUES: 1396 PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received"); 1397 if (b_op) { 1398 i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen); 1399 i40e_notify_vf_link_status(dev, vf); 1400 } else { 1401 i40e_pf_host_send_msg_to_vf( 1402 vf, VIRTCHNL_OP_ENABLE_QUEUES, 1403 I40E_NOT_SUPPORTED, NULL, 0); 1404 } 1405 break; 1406 case VIRTCHNL_OP_DISABLE_QUEUES: 1407 PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received"); 1408 i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen, b_op); 1409 break; 1410 case VIRTCHNL_OP_ADD_ETH_ADDR: 1411 PMD_DRV_LOG(INFO, "OP_ADD_ETHER_ADDRESS received"); 1412 i40e_pf_host_process_cmd_add_ether_address(vf, msg, 1413 msglen, b_op); 1414 break; 1415 case VIRTCHNL_OP_DEL_ETH_ADDR: 1416 PMD_DRV_LOG(INFO, "OP_DEL_ETHER_ADDRESS received"); 1417 i40e_pf_host_process_cmd_del_ether_address(vf, msg, 1418 msglen, b_op); 1419 break; 1420 case VIRTCHNL_OP_ADD_VLAN: 1421 PMD_DRV_LOG(INFO, "OP_ADD_VLAN received"); 1422 i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op); 1423 break; 1424 case VIRTCHNL_OP_DEL_VLAN: 1425 PMD_DRV_LOG(INFO, "OP_DEL_VLAN received"); 1426 i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op); 1427 break; 1428 case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: 1429 PMD_DRV_LOG(INFO, "OP_CONFIG_PROMISCUOUS_MODE received"); 1430 i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, 1431 msglen, b_op); 1432 break; 1433 case VIRTCHNL_OP_GET_STATS: 1434 PMD_DRV_LOG(INFO, "OP_GET_STATS received"); 1435 i40e_pf_host_process_cmd_get_stats(vf, b_op); 1436 break; 1437 case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: 1438 PMD_DRV_LOG(INFO, "OP_ENABLE_VLAN_STRIPPING received"); 1439 i40e_pf_host_process_cmd_enable_vlan_strip(vf, b_op); 1440 break; 1441 case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING: 1442 PMD_DRV_LOG(INFO, "OP_DISABLE_VLAN_STRIPPING received"); 1443 i40e_pf_host_process_cmd_disable_vlan_strip(vf, b_op); 1444 break; 1445 case VIRTCHNL_OP_CONFIG_RSS_LUT: 1446 PMD_DRV_LOG(INFO, "OP_CONFIG_RSS_LUT received"); 1447 i40e_pf_host_process_cmd_set_rss_lut(vf, msg, msglen, b_op); 1448 break; 1449 case VIRTCHNL_OP_CONFIG_RSS_KEY: 1450 PMD_DRV_LOG(INFO, "OP_CONFIG_RSS_KEY received"); 1451 i40e_pf_host_process_cmd_set_rss_key(vf, msg, msglen, b_op); 1452 break; 1453 case VIRTCHNL_OP_REQUEST_QUEUES: 1454 PMD_DRV_LOG(INFO, "OP_REQUEST_QUEUES received"); 1455 i40e_pf_host_process_cmd_request_queues(vf, msg); 1456 break; 1457 1458 /* Don't add command supported below, which will 1459 * return an error code. 1460 */ 1461 default: 1462 PMD_DRV_LOG(ERR, "%u received, not supported", opcode); 1463 i40e_pf_host_send_msg_to_vf(vf, opcode, I40E_ERR_PARAM, 1464 NULL, 0); 1465 break; 1466 } 1467 1468 check: 1469 /* if message validation not enabled */ 1470 if (!pf->vf_msg_cfg.max_msg) 1471 return; 1472 1473 /* store current cycle */ 1474 vf->msg_timestamps[vf->msg_index++] = cur_cycle; 1475 vf->msg_index %= pf->vf_msg_cfg.max_msg; 1476 1477 /* read the timestamp of earliest message */ 1478 first_cycle = vf->msg_timestamps[vf->msg_index]; 1479 1480 /* 1481 * If the time span from the arrival time of first message to 1482 * the arrival time of current message smaller than `period`, 1483 * that mean too much message in this statistic period. 1484 */ 1485 if (first_cycle && cur_cycle < first_cycle + 1486 (uint64_t)pf->vf_msg_cfg.period * rte_get_timer_hz()) { 1487 PMD_DRV_LOG(WARNING, "VF %u too much messages(%u in %u" 1488 " seconds),\n\tany new message from which" 1489 " will be ignored during next %u seconds!", 1490 vf_id, pf->vf_msg_cfg.max_msg, 1491 (uint32_t)((cur_cycle - first_cycle + 1492 rte_get_timer_hz() - 1) / rte_get_timer_hz()), 1493 pf->vf_msg_cfg.ignore_second); 1494 vf->ignore_end_cycle = rte_get_timer_cycles() + 1495 pf->vf_msg_cfg.ignore_second * 1496 rte_get_timer_hz(); 1497 } 1498 } 1499 1500 int 1501 i40e_pf_host_init(struct rte_eth_dev *dev) 1502 { 1503 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1504 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 1505 size_t size; 1506 int ret, i; 1507 uint32_t val; 1508 1509 PMD_INIT_FUNC_TRACE(); 1510 1511 /** 1512 * return if SRIOV not enabled, VF number not configured or 1513 * no queue assigned. 1514 */ 1515 if(!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 || pf->vf_nb_qps == 0) 1516 return I40E_SUCCESS; 1517 1518 /* Allocate memory to store VF structure */ 1519 pf->vfs = rte_zmalloc("i40e_pf_vf",sizeof(*pf->vfs) * pf->vf_num, 0); 1520 if(pf->vfs == NULL) 1521 return -ENOMEM; 1522 1523 /* Disable irq0 for VFR event */ 1524 i40e_pf_disable_irq0(hw); 1525 1526 /* Disable VF link status interrupt */ 1527 val = I40E_READ_REG(hw, I40E_PFGEN_PORTMDIO_NUM); 1528 val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK; 1529 I40E_WRITE_REG(hw, I40E_PFGEN_PORTMDIO_NUM, val); 1530 I40E_WRITE_FLUSH(hw); 1531 1532 /* calculate the memory size for storing timestamp of messages */ 1533 size = pf->vf_msg_cfg.max_msg * sizeof(uint64_t); 1534 1535 for (i = 0; i < pf->vf_num; i++) { 1536 pf->vfs[i].pf = pf; 1537 pf->vfs[i].state = I40E_VF_INACTIVE; 1538 pf->vfs[i].vf_idx = i; 1539 1540 if (size) { 1541 /* allocate memory for store timestamp of messages */ 1542 pf->vfs[i].msg_timestamps = 1543 rte_zmalloc("i40e_pf_vf", size, 0); 1544 if (pf->vfs[i].msg_timestamps == NULL) { 1545 ret = -ENOMEM; 1546 goto fail; 1547 } 1548 } 1549 1550 ret = i40e_pf_host_vf_reset(&pf->vfs[i], 0); 1551 if (ret != I40E_SUCCESS) 1552 goto fail; 1553 } 1554 1555 RTE_ETH_DEV_SRIOV(dev).active = pf->vf_num; 1556 /* restore irq0 */ 1557 i40e_pf_enable_irq0(hw); 1558 1559 return I40E_SUCCESS; 1560 1561 fail: 1562 for (; i >= 0; i--) 1563 rte_free(pf->vfs[i].msg_timestamps); 1564 rte_free(pf->vfs); 1565 i40e_pf_enable_irq0(hw); 1566 1567 return ret; 1568 } 1569 1570 int 1571 i40e_pf_host_uninit(struct rte_eth_dev *dev) 1572 { 1573 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1574 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 1575 uint32_t val; 1576 int i; 1577 1578 PMD_INIT_FUNC_TRACE(); 1579 1580 /** 1581 * return if SRIOV not enabled, VF number not configured or 1582 * no queue assigned. 1583 */ 1584 if ((!hw->func_caps.sr_iov_1_1) || 1585 (pf->vf_num == 0) || 1586 (pf->vf_nb_qps == 0)) 1587 return I40E_SUCCESS; 1588 1589 /* free memory for store timestamp of messages */ 1590 for (i = 0; i < pf->vf_num; i++) 1591 rte_free(pf->vfs[i].msg_timestamps); 1592 1593 /* free memory to store VF structure */ 1594 rte_free(pf->vfs); 1595 pf->vfs = NULL; 1596 1597 /* Disable irq0 for VFR event */ 1598 i40e_pf_disable_irq0(hw); 1599 1600 /* Disable VF link status interrupt */ 1601 val = I40E_READ_REG(hw, I40E_PFGEN_PORTMDIO_NUM); 1602 val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK; 1603 I40E_WRITE_REG(hw, I40E_PFGEN_PORTMDIO_NUM, val); 1604 I40E_WRITE_FLUSH(hw); 1605 1606 return I40E_SUCCESS; 1607 } 1608