X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Fbnxt_flow.c;h=73fd24cd9a126dd0920ecbd43aa2ee5771ddb131;hb=a0c2315a2a5f0a83d5d77ec745ac1de04a1e962b;hp=84a21dba9e3479330bd6b8683b92242e29d09f94;hpb=1e2f8aca2cc108559fb9d823fc88dc342048500d;p=dpdk.git diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c index 84a21dba9e..73fd24cd9a 100644 --- a/drivers/net/bnxt/bnxt_flow.c +++ b/drivers/net/bnxt/bnxt_flow.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2014-2018 Broadcom + * Copyright(c) 2014-2021 Broadcom * All rights reserved. */ @@ -18,6 +18,7 @@ #include "bnxt_hwrm.h" #include "bnxt_ring.h" #include "bnxt_rxq.h" +#include "bnxt_rxr.h" #include "bnxt_vnic.h" #include "hsi_struct_def_dpdk.h" @@ -187,11 +188,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, PMD_DRV_LOG(DEBUG, "Parse inner header\n"); break; case RTE_FLOW_ITEM_TYPE_ETH: - if (!item->spec || !item->mask) + if (!item->spec) break; eth_spec = item->spec; - eth_mask = item->mask; + + if (item->mask) + eth_mask = item->mask; + else + eth_mask = &rte_flow_item_eth_mask; /* Source MAC address mask cannot be partially set. * Should be All 0's or all 1's. @@ -280,7 +285,12 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, break; case RTE_FLOW_ITEM_TYPE_VLAN: vlan_spec = item->spec; - vlan_mask = item->mask; + + if (item->mask) + vlan_mask = item->mask; + else + vlan_mask = &rte_flow_item_vlan_mask; + if (en & en_ethertype) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, @@ -323,11 +333,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, case RTE_FLOW_ITEM_TYPE_IPV4: /* If mask is not involved, we could use EM filters. */ ipv4_spec = item->spec; - ipv4_mask = item->mask; - if (!item->spec || !item->mask) + if (!item->spec) break; + if (item->mask) + ipv4_mask = item->mask; + else + ipv4_mask = &rte_flow_item_ipv4_mask; + /* Only IP DST and SRC fields are maskable. */ if (ipv4_mask->hdr.version_ihl || ipv4_mask->hdr.type_of_service || @@ -384,11 +398,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, break; case RTE_FLOW_ITEM_TYPE_IPV6: ipv6_spec = item->spec; - ipv6_mask = item->mask; - if (!item->spec || !item->mask) + if (!item->spec) break; + if (item->mask) + ipv6_mask = item->mask; + else + ipv6_mask = &rte_flow_item_ipv6_mask; + /* Only IP DST and SRC fields are maskable. */ if (ipv6_mask->hdr.vtc_flow || ipv6_mask->hdr.payload_len || @@ -436,11 +454,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, break; case RTE_FLOW_ITEM_TYPE_TCP: tcp_spec = item->spec; - tcp_mask = item->mask; - if (!item->spec || !item->mask) + if (!item->spec) break; + if (item->mask) + tcp_mask = item->mask; + else + tcp_mask = &rte_flow_item_tcp_mask; + /* Check TCP mask. Only DST & SRC ports are maskable */ if (tcp_mask->hdr.sent_seq || tcp_mask->hdr.recv_ack || @@ -481,11 +503,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, break; case RTE_FLOW_ITEM_TYPE_UDP: udp_spec = item->spec; - udp_mask = item->mask; - if (!item->spec || !item->mask) + if (!item->spec) break; + if (item->mask) + udp_mask = item->mask; + else + udp_mask = &rte_flow_item_udp_mask; + if (udp_mask->hdr.dgram_len || udp_mask->hdr.dgram_cksum) { rte_flow_error_set(error, @@ -553,7 +579,7 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, } /* Check if VNI is masked. */ - if (vxlan_spec && vxlan_mask) { + if (vxlan_mask != NULL) { vni_masked = !!memcmp(vxlan_mask->vni, vni_mask, RTE_DIM(vni_mask)); @@ -899,6 +925,9 @@ static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic) uint64_t rx_offloads = dev_conf->rxmode.offloads; int rc; + if (bp->nr_vnics > bp->max_vnics - 1) + return -ENOMEM; + rc = bnxt_vnic_grp_alloc(bp, vnic); if (rc) goto ret; @@ -1055,6 +1084,13 @@ start: } PMD_DRV_LOG(DEBUG, "Queue index %d\n", act_q->index); + if (use_ntuple && !BNXT_RFS_NEEDS_VNIC(bp)) { + filter->flags = + HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DEST_RFS_RING_IDX; + filter->dst_id = act_q->index; + goto skip_vnic_alloc; + } + vnic_id = attr->group; if (!vnic_id) { PMD_DRV_LOG(DEBUG, "Group id is 0\n"); @@ -1126,7 +1162,7 @@ use_vnic: PMD_DRV_LOG(DEBUG, "Setting vnic ff_idx %d\n", vnic->ff_pool_idx); filter->dst_id = vnic->fw_vnic_id; - +skip_vnic_alloc: /* For ntuple filter, create the L2 filter with default VNIC. * The user specified redirect queue will be set while creating * the ntuple filter in hardware. @@ -1364,13 +1400,15 @@ use_vnic: if (vnic->rx_queue_cnt > 1) { vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss->types); + vnic->hash_mode = + bnxt_rte_to_hwrm_hash_level(bp, rss->types, rss->level); if (!rss->key_len) { /* If hash key has not been specified, * use random hash key. */ - prandom_bytes(vnic->rss_hash_key, - HW_HASH_KEY_SIZE); + bnxt_prandom_bytes(vnic->rss_hash_key, + HW_HASH_KEY_SIZE); } else { if (rss->key_len > HW_HASH_KEY_SIZE) memcpy(vnic->rss_hash_key, @@ -1403,18 +1441,6 @@ vnic_found: bnxt_update_filter_flags_en(filter, filter1, use_ntuple); break; case RTE_FLOW_ACTION_TYPE_MARK: - if (bp->flags & BNXT_FLAG_RX_VECTOR_PKT_MODE) { - PMD_DRV_LOG(DEBUG, - "Disable vector processing for mark\n"); - rte_flow_error_set(error, - ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - act, - "Disable vector processing for mark"); - rc = -rte_errno; - goto ret; - } - if (bp->mark_table == NULL) { rte_flow_error_set(error, ENOMEM, @@ -1425,6 +1451,13 @@ vnic_found: goto ret; } + if (bp->flags & BNXT_FLAG_RX_VECTOR_PKT_MODE) { + PMD_DRV_LOG(DEBUG, + "Disabling vector processing for mark\n"); + bp->eth_dev->rx_pkt_burst = bnxt_recv_pkts; + bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; + } + filter->valid_flags |= BNXT_FLOW_MARK_FLAG; filter->mark = ((const struct rte_flow_action_mark *) act->conf)->id; @@ -1520,6 +1553,7 @@ bnxt_flow_validate(struct rte_eth_dev *dev, bnxt_hwrm_vnic_ctx_free(bp, vnic); bnxt_hwrm_vnic_free(bp, vnic); vnic->rx_queue_cnt = 0; + bp->nr_vnics--; PMD_DRV_LOG(DEBUG, "Free VNIC\n"); } } @@ -1790,15 +1824,30 @@ bnxt_flow_create(struct rte_eth_dev *dev, filter->enables |= HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID; ret = bnxt_hwrm_set_em_filter(bp, filter->dst_id, filter); + if (ret != 0) { + rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to create EM filter"); + goto free_filter; + } } if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) { filter->enables |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; ret = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id, filter); + if (ret != 0) { + rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "Failed to create ntuple filter"); + goto free_filter; + } } - vnic = find_matching_vnic(bp, filter); + if (BNXT_RFS_NEEDS_VNIC(bp)) + vnic = find_matching_vnic(bp, filter); + else + vnic = BNXT_GET_DEFAULT_VNIC(bp); done: if (!ret || update_flow) { flow->filter = filter; @@ -1808,9 +1857,6 @@ done: goto free_flow; } - STAILQ_INSERT_TAIL(&vnic->filter, filter, next); - PMD_DRV_LOG(DEBUG, "Successfully created flow.\n"); - STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next); if (filter->valid_flags & BNXT_FLOW_MARK_FLAG) { PMD_DRV_LOG(DEBUG, "Mark action: mark id 0x%x, flow id 0x%x\n", @@ -1821,19 +1867,25 @@ done: */ flow_id = filter->flow_id & BNXT_FLOW_ID_MASK; if (bp->mark_table[flow_id].valid) { - PMD_DRV_LOG(ERR, - "Entry for Mark id 0x%x occupied" - " flow id 0x%x\n", - filter->mark, filter->flow_id); + rte_flow_error_set(error, EEXIST, + RTE_FLOW_ERROR_TYPE_HANDLE, + NULL, + "Flow with mark id exists"); + bnxt_clear_one_vnic_filter(bp, filter); goto free_filter; } bp->mark_table[flow_id].valid = true; bp->mark_table[flow_id].mark_id = filter->mark; } + + STAILQ_INSERT_TAIL(&vnic->filter, filter, next); + STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next); + if (BNXT_FLOW_XSTATS_EN(bp)) bp->flow_stat->flow_count++; bnxt_release_flow_lock(bp); bnxt_setup_flow_counter(bp); + PMD_DRV_LOG(DEBUG, "Successfully created flow.\n"); return flow; } @@ -1932,11 +1984,7 @@ _bnxt_flow_destroy(struct bnxt *bp, filter->flow_id = 0; } - if (filter->filter_type == HWRM_CFA_EM_FILTER) - ret = bnxt_hwrm_clear_em_filter(bp, filter); - if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) - ret = bnxt_hwrm_clear_ntuple_filter(bp, filter); - ret = bnxt_hwrm_clear_l2_filter(bp, filter); + ret = bnxt_clear_one_vnic_filter(bp, filter); done: if (!ret) { @@ -1967,6 +2015,7 @@ done: bnxt_hwrm_vnic_free(bp, vnic); vnic->rx_queue_cnt = 0; + bp->nr_vnics--; } } else { rte_flow_error_set(error, -ret,