static int i40e_pf_host_switch_queues(struct i40e_pf_vf *vf, struct i40e_virtchnl_queue_select *qsel, bool on) { int ret = I40E_SUCCESS; int i; struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf); uint16_t baseq = vf->vsi->base_queue; if (qsel->rx_queues + qsel->tx_queues == 0) return I40E_ERR_PARAM; /* always enable RX first and disable last */ /* Enable RX if it's enable */ if (on) { for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++) if (qsel->rx_queues & (1 << i)) { ret = i40e_switch_rx_queue(hw, baseq + i, on); if (ret != I40E_SUCCESS) return ret; } } /* Enable/Disable TX */ for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++) if (qsel->tx_queues & (1 << i)) { ret = i40e_switch_tx_queue(hw, baseq + i, on); if (ret != I40E_SUCCESS) return ret; } /* disable RX last if it's disable */ if (!on) { /* disable RX */ for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++) if (qsel->rx_queues & (1 << i)) { ret = i40e_switch_rx_queue(hw, baseq + i, on); if (ret != I40E_SUCCESS) return ret; } } return ret; }
/* * i40e_fdir_teardown - release the Flow Director resources * @pf: board private structure */ void i40e_fdir_teardown(struct i40e_pf *pf) { struct i40e_hw *hw = I40E_PF_TO_HW(pf); struct i40e_vsi *vsi; vsi = pf->fdir.fdir_vsi; if (!vsi) return; i40e_switch_tx_queue(hw, vsi->base_queue, FALSE); i40e_switch_rx_queue(hw, vsi->base_queue, FALSE); i40e_dev_rx_queue_release(pf->fdir.rxq); pf->fdir.rxq = NULL; i40e_dev_tx_queue_release(pf->fdir.txq); pf->fdir.txq = NULL; i40e_vsi_release(vsi); pf->fdir.fdir_vsi = NULL; }
/* * i40e_fdir_setup - reserve and initialize the Flow Director resources * @pf: board private structure */ int i40e_fdir_setup(struct i40e_pf *pf) { struct i40e_hw *hw = I40E_PF_TO_HW(pf); struct i40e_vsi *vsi; int err = I40E_SUCCESS; char z_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz = NULL; struct rte_eth_dev *eth_dev = pf->adapter->eth_dev; if ((pf->flags & I40E_FLAG_FDIR) == 0) { PMD_INIT_LOG(ERR, "HW doesn't support FDIR"); return I40E_NOT_SUPPORTED; } PMD_DRV_LOG(INFO, "FDIR HW Capabilities: num_filters_guaranteed = %u," " num_filters_best_effort = %u.", hw->func_caps.fd_filters_guaranteed, hw->func_caps.fd_filters_best_effort); vsi = pf->fdir.fdir_vsi; if (vsi) { PMD_DRV_LOG(INFO, "FDIR initialization has been done."); return I40E_SUCCESS; } /* make new FDIR VSI */ vsi = i40e_vsi_setup(pf, I40E_VSI_FDIR, pf->main_vsi, 0); if (!vsi) { PMD_DRV_LOG(ERR, "Couldn't create FDIR VSI."); return I40E_ERR_NO_AVAILABLE_VSI; } pf->fdir.fdir_vsi = vsi; /*Fdir tx queue setup*/ err = i40e_fdir_setup_tx_resources(pf); if (err) { PMD_DRV_LOG(ERR, "Failed to setup FDIR TX resources."); goto fail_setup_tx; } /*Fdir rx queue setup*/ err = i40e_fdir_setup_rx_resources(pf); if (err) { PMD_DRV_LOG(ERR, "Failed to setup FDIR RX resources."); goto fail_setup_rx; } err = i40e_tx_queue_init(pf->fdir.txq); if (err) { PMD_DRV_LOG(ERR, "Failed to do FDIR TX initialization."); goto fail_mem; } /* need switch on before dev start*/ err = i40e_switch_tx_queue(hw, vsi->base_queue, TRUE); if (err) { PMD_DRV_LOG(ERR, "Failed to do fdir TX switch on."); goto fail_mem; } /* Init the rx queue in hardware */ err = i40e_fdir_rx_queue_init(pf->fdir.rxq); if (err) { PMD_DRV_LOG(ERR, "Failed to do FDIR RX initialization."); goto fail_mem; } /* switch on rx queue */ err = i40e_switch_rx_queue(hw, vsi->base_queue, TRUE); if (err) { PMD_DRV_LOG(ERR, "Failed to do FDIR RX switch on."); goto fail_mem; } /* reserve memory for the fdir programming packet */ snprintf(z_name, sizeof(z_name), "%s_%s_%d", eth_dev->driver->pci_drv.name, I40E_FDIR_MZ_NAME, eth_dev->data->port_id); mz = i40e_memzone_reserve(z_name, I40E_FDIR_PKT_LEN, SOCKET_ID_ANY); if (!mz) { PMD_DRV_LOG(ERR, "Cannot init memzone for " "flow director program packet."); err = I40E_ERR_NO_MEMORY; goto fail_mem; } pf->fdir.prg_pkt = mz->addr; pf->fdir.dma_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr); pf->fdir.match_counter_index = I40E_COUNTER_INDEX_FDIR(hw->pf_id); PMD_DRV_LOG(INFO, "FDIR setup successfully, with programming queue %u.", vsi->base_queue); return I40E_SUCCESS; fail_mem: i40e_dev_rx_queue_release(pf->fdir.rxq); pf->fdir.rxq = NULL; fail_setup_rx: i40e_dev_tx_queue_release(pf->fdir.txq); pf->fdir.txq = NULL; fail_setup_tx: i40e_vsi_release(vsi); pf->fdir.fdir_vsi = NULL; return err; }