ice_init_proto_xtr(dev);
+ if (hw->func_caps.fd_fltr_guar > 0 ||
+ hw->func_caps.fd_fltr_best_effort > 0) {
+ pf->flags |= ICE_FLAG_FDIR;
+ pf->fdir_nb_qps = ICE_DEFAULT_QP_NUM_FDIR;
+ pf->lan_nb_qps = pf->lan_nb_qp_max - pf->fdir_nb_qps;
+ } else {
+ pf->fdir_nb_qps = 0;
+ }
+ pf->fdir_qp_offset = 0;
+
return 0;
}
-static struct ice_vsi *
+struct ice_vsi *
ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
{
struct ice_hw *hw = ICE_PF_TO_HW(pf);
struct rte_ether_addr mac_addr;
uint16_t max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
uint8_t tc_bitmap = 0x1;
+ uint16_t cfg;
/* hw->num_lports = 1 in NIC mode */
vsi = rte_zmalloc(NULL, sizeof(struct ice_vsi), 0);
pf->flags |= ICE_FLAG_RSS_AQ_CAPABLE;
memset(&vsi_ctx, 0, sizeof(vsi_ctx));
- /* base_queue in used in queue mapping of VSI add/update command.
- * Suppose vsi->base_queue is 0 now, don't consider SRIOV, VMDQ
- * cases in the first stage. Only Main VSI.
- */
- vsi->base_queue = 0;
switch (type) {
case ICE_VSI_PF:
vsi->nb_qps = pf->lan_nb_qps;
+ vsi->base_queue = 1;
ice_vsi_config_default_rss(&vsi_ctx.info);
vsi_ctx.alloc_from_pool = true;
vsi_ctx.flags = ICE_AQ_VSI_TYPE_PF;
vsi_ctx.info.vlan_flags |= ICE_AQ_VSI_VLAN_EMOD_NOTHING;
vsi_ctx.info.q_opt_rss = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF |
ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
+
+ /* FDIR */
+ cfg = ICE_AQ_VSI_PROP_SECURITY_VALID |
+ ICE_AQ_VSI_PROP_FLOW_DIR_VALID;
+ vsi_ctx.info.valid_sections |= rte_cpu_to_le_16(cfg);
+ cfg = ICE_AQ_VSI_FD_ENABLE | ICE_AQ_VSI_FD_PROG_ENABLE;
+ vsi_ctx.info.fd_options = rte_cpu_to_le_16(cfg);
+ vsi_ctx.info.max_fd_fltr_dedicated =
+ rte_cpu_to_le_16(hw->func_caps.fd_fltr_guar);
+ vsi_ctx.info.max_fd_fltr_shared =
+ rte_cpu_to_le_16(hw->func_caps.fd_fltr_best_effort);
+
/* Enable VLAN/UP trip */
ret = ice_vsi_config_tc_queue_mapping(vsi,
&vsi_ctx.info,
goto fail_mem;
}
+ break;
+ case ICE_VSI_CTRL:
+ vsi->nb_qps = pf->fdir_nb_qps;
+ vsi->base_queue = ICE_FDIR_QUEUE_ID;
+ vsi_ctx.alloc_from_pool = true;
+ vsi_ctx.flags = ICE_AQ_VSI_TYPE_PF;
+
+ cfg = ICE_AQ_VSI_PROP_FLOW_DIR_VALID;
+ vsi_ctx.info.valid_sections |= rte_cpu_to_le_16(cfg);
+ cfg = ICE_AQ_VSI_FD_ENABLE | ICE_AQ_VSI_FD_PROG_ENABLE;
+ vsi_ctx.info.fd_options = rte_cpu_to_le_16(cfg);
+ vsi_ctx.info.sw_id = hw->port_info->sw_id;
+ ret = ice_vsi_config_tc_queue_mapping(vsi,
+ &vsi_ctx.info,
+ ICE_DEFAULT_TCMAP);
+ if (ret) {
+ PMD_INIT_LOG(ERR,
+ "tc queue mapping with vsi failed, "
+ "err = %d",
+ ret);
+ goto fail_mem;
+ }
break;
default:
/* for other types of VSI */
}
vsi->msix_intr = ret;
vsi->nb_msix = RTE_MIN(vsi->nb_qps, RTE_MAX_RXTX_INTR_VEC_ID);
+ } else if (type == ICE_VSI_CTRL) {
+ ret = ice_res_pool_alloc(&pf->msix_pool, 1);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "VSI %d get heap failed %d",
+ vsi->vsi_id, ret);
+ }
+ vsi->msix_intr = ret;
+ vsi->nb_msix = 1;
} else {
vsi->msix_intr = 0;
vsi->nb_msix = 0;
pf->vsis_allocated = vsi_ctx.vsis_allocd;
pf->vsis_unallocated = vsi_ctx.vsis_unallocated;
- /* MAC configuration */
- rte_memcpy(pf->dev_addr.addr_bytes,
- hw->port_info->mac.perm_addr,
- ETH_ADDR_LEN);
+ if (type == ICE_VSI_PF) {
+ /* MAC configuration */
+ rte_memcpy(pf->dev_addr.addr_bytes,
+ hw->port_info->mac.perm_addr,
+ ETH_ADDR_LEN);
- rte_memcpy(&mac_addr, &pf->dev_addr, RTE_ETHER_ADDR_LEN);
- ret = ice_add_mac_filter(vsi, &mac_addr);
- if (ret != ICE_SUCCESS)
- PMD_INIT_LOG(ERR, "Failed to add dflt MAC filter");
+ rte_memcpy(&mac_addr, &pf->dev_addr, RTE_ETHER_ADDR_LEN);
+ ret = ice_add_mac_filter(vsi, &mac_addr);
+ if (ret != ICE_SUCCESS)
+ PMD_INIT_LOG(ERR, "Failed to add dflt MAC filter");
- rte_memcpy(&mac_addr, &broadcast, RTE_ETHER_ADDR_LEN);
- ret = ice_add_mac_filter(vsi, &mac_addr);
- if (ret != ICE_SUCCESS)
- PMD_INIT_LOG(ERR, "Failed to add MAC filter");
+ rte_memcpy(&mac_addr, &broadcast, RTE_ETHER_ADDR_LEN);
+ ret = ice_add_mac_filter(vsi, &mac_addr);
+ if (ret != ICE_SUCCESS)
+ PMD_INIT_LOG(ERR, "Failed to add MAC filter");
+ }
/* At the beginning, only TC0. */
/* What we need here is the maximam number of the TX queues.
static int
ice_pf_setup(struct ice_pf *pf)
{
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
struct ice_vsi *vsi;
+ uint16_t unused;
/* Clear all stats counters */
pf->offset_loaded = FALSE;
memset(&pf->internal_stats, 0, sizeof(struct ice_eth_stats));
memset(&pf->internal_stats_offset, 0, sizeof(struct ice_eth_stats));
+ /* force guaranteed filter pool for PF */
+ ice_alloc_fd_guar_item(hw, &unused,
+ hw->func_caps.fd_fltr_guar);
+ /* force shared filter pool for PF */
+ ice_alloc_fd_shrd_item(hw, &unused,
+ hw->func_caps.fd_fltr_best_effort);
+
vsi = ice_setup_vsi(pf, ICE_VSI_PF);
if (!vsi) {
PMD_INIT_LOG(ERR, "Failed to add vsi for PF");
return ret;
}
-static int
+int
ice_release_vsi(struct ice_vsi *vsi)
{
struct ice_hw *hw;
/* disable all queue interrupts */
ice_vsi_disable_queues_intr(main_vsi);
+ if (pf->fdir.fdir_vsi)
+ ice_vsi_disable_queues_intr(pf->fdir.fdir_vsi);
+
/* Clear all queues and release mbufs */
ice_clear_queues(dev);
/* Enable interrupts for all the queues */
ice_vsi_enable_queues_intr(vsi);
+ /* Enable FDIR MSIX interrupt */
+ if (pf->fdir.fdir_vsi) {
+ ice_vsi_queues_bind_intr(pf->fdir.fdir_vsi);
+ ice_vsi_enable_queues_intr(pf->fdir.fdir_vsi);
+ }
+
rte_intr_enable(intr_handle);
return 0;