Skip to content

Commit

Permalink
net/bnxt: allow flow creation when RSS is enabled
Browse files Browse the repository at this point in the history
Currently flow creation is allowed with queue action only
when RSS is disabled. Remove this restriction. Flows can be
created when RSS is enabled.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Rahul Gupta <rahul.gupta@broadcom.com>
Reviewed-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
  • Loading branch information
ajitkhaparde authored and Ferruh Yigit committed Oct 8, 2019
1 parent 36024b2 commit d24610f
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 33 deletions.
1 change: 1 addition & 0 deletions drivers/net/bnxt/bnxt.h
Expand Up @@ -554,6 +554,7 @@ struct bnxt {
int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
int is_bnxt_in_error(struct bnxt *bp);
uint16_t bnxt_rss_ctxts(const struct bnxt *bp);

int bnxt_map_fw_health_status_regs(struct bnxt *bp);
uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/bnxt/bnxt_ethdev.c
Expand Up @@ -189,7 +189,7 @@ int is_bnxt_in_error(struct bnxt *bp)
* High level utility functions
*/

static uint16_t bnxt_rss_ctxts(const struct bnxt *bp)
uint16_t bnxt_rss_ctxts(const struct bnxt *bp)
{
if (!BNXT_CHIP_THOR(bp))
return 1;
Expand Down
176 changes: 144 additions & 32 deletions drivers/net/bnxt/bnxt_flow.c
Expand Up @@ -14,6 +14,8 @@
#include "bnxt.h"
#include "bnxt_filter.h"
#include "bnxt_hwrm.h"
#include "bnxt_ring.h"
#include "bnxt_rxq.h"
#include "bnxt_vnic.h"
#include "bnxt_util.h"
#include "hsi_struct_def_dpdk.h"
Expand Down Expand Up @@ -151,23 +153,13 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp,
int use_ntuple;
uint32_t en = 0;
uint32_t en_ethertype;
int dflt_vnic, rc = 0;
int dflt_vnic;

use_ntuple = bnxt_filter_type_check(pattern, error);
PMD_DRV_LOG(DEBUG, "Use NTUPLE %d\n", use_ntuple);
if (use_ntuple < 0)
return use_ntuple;

if (use_ntuple && (bp->eth_dev->data->dev_conf.rxmode.mq_mode &
ETH_MQ_RX_RSS)) {
PMD_DRV_LOG(ERR, "Cannot create ntuple flow on RSS queues\n");
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
"Cannot create flow on RSS queues");
rc = -rte_errno;
return rc;
}

filter->filter_type = use_ntuple ?
HWRM_CFA_NTUPLE_FILTER : HWRM_CFA_EM_FILTER;
en_ethertype = use_ntuple ?
Expand Down Expand Up @@ -715,17 +707,6 @@ bnxt_flow_parse_attr(const struct rte_flow_attr *attr,
"No support for priority.");
return -rte_errno;
}

/* Not supported */
if (attr->group) {
rte_flow_error_set(error,
EINVAL,
RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
attr,
"No support for group.");
return -rte_errno;
}

return 0;
}

Expand Down Expand Up @@ -764,6 +745,50 @@ bnxt_get_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf,
return filter1;
}

static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic)
{
struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
uint64_t rx_offloads = dev_conf->rxmode.offloads;
int rc;

rc = bnxt_vnic_grp_alloc(bp, vnic);
if (rc)
goto ret;

rc = bnxt_hwrm_vnic_alloc(bp, vnic);
if (rc) {
PMD_DRV_LOG(ERR, "HWRM vnic alloc failure rc: %x\n", rc);
goto ret;
}
bp->nr_vnics++;

/* RSS context is required only when there is more than one RSS ring */
if (vnic->rx_queue_cnt > 1) {
rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 0 /* ctx_idx 0 */);
if (rc) {
PMD_DRV_LOG(ERR,
"HWRM vnic ctx alloc failure: %x\n", rc);
goto ret;
}
} else {
PMD_DRV_LOG(DEBUG, "No RSS context required\n");
}

if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
vnic->vlan_strip = true;
else
vnic->vlan_strip = false;

rc = bnxt_hwrm_vnic_cfg(bp, vnic);
if (rc)
goto ret;

bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);

ret:
return rc;
}

static int
bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
const struct rte_flow_item pattern[],
Expand All @@ -775,12 +800,14 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
const struct rte_flow_action *act =
bnxt_flow_non_void_action(actions);
struct bnxt *bp = dev->data->dev_private;
struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
const struct rte_flow_action_queue *act_q;
const struct rte_flow_action_vf *act_vf;
struct bnxt_vnic_info *vnic, *vnic0;
struct bnxt_filter_info *filter1;
struct bnxt_rx_queue *rxq = NULL;
int dflt_vnic, vnic_id;
uint32_t vf = 0;
int dflt_vnic;
int rc;

rc =
Expand All @@ -800,7 +827,7 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_QUEUE:
/* Allow this flow. Redirect to a VNIC. */
act_q = (const struct rte_flow_action_queue *)act->conf;
if (act_q->index >= bp->rx_nr_rings) {
if (!act_q->index || act_q->index >= bp->rx_nr_rings) {
rte_flow_error_set(error,
EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
Expand All @@ -811,18 +838,77 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
}
PMD_DRV_LOG(DEBUG, "Queue index %d\n", act_q->index);

vnic0 = &bp->vnic_info[0];
vnic = &bp->vnic_info[act_q->index];
vnic_id = attr->group;
if (!vnic_id) {
PMD_DRV_LOG(DEBUG, "Group id is 0\n");
vnic_id = act_q->index;
}

vnic = &bp->vnic_info[vnic_id];
if (vnic == NULL) {
rte_flow_error_set(error,
EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
act,
"No matching VNIC for queue ID.");
"No matching VNIC found.");
rc = -rte_errno;
goto ret;
}
if (vnic->rx_queue_cnt) {
if (vnic->start_grp_id != act_q->index) {
PMD_DRV_LOG(ERR,
"VNIC already in use\n");
rte_flow_error_set(error,
EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
act,
"VNIC already in use");
rc = -rte_errno;
goto ret;
}
goto use_vnic;
}

rxq = bp->rx_queues[act_q->index];

if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) && rxq)
goto use_vnic;

if (!rxq ||
bp->vnic_info[0].fw_grp_ids[act_q->index] !=
INVALID_HW_RING_ID ||
!rxq->rx_deferred_start) {
PMD_DRV_LOG(ERR,
"Queue invalid or used with other VNIC\n");
rte_flow_error_set(error,
EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION,
act,
"Queue invalid queue or in use");
rc = -rte_errno;
goto ret;
}

use_vnic:
rxq->vnic = vnic;
vnic->rx_queue_cnt++;
vnic->start_grp_id = act_q->index;
vnic->end_grp_id = act_q->index;
vnic->func_default = 0; //This is not a default VNIC.

PMD_DRV_LOG(DEBUG, "VNIC found\n");

rc = bnxt_vnic_prep(bp, vnic);
if (rc)
goto ret;

PMD_DRV_LOG(DEBUG,
"vnic[%d] = %p vnic->fw_grp_ids = %p\n",
act_q->index, vnic, vnic->fw_grp_ids);

vnic->ff_pool_idx = vnic_id;
PMD_DRV_LOG(DEBUG,
"Setting vnic ff_idx %d\n", vnic->ff_pool_idx);
filter->dst_id = vnic->fw_vnic_id;
filter1 = bnxt_get_l2_filter(bp, filter, vnic);
if (filter1 == NULL) {
Expand Down Expand Up @@ -989,9 +1075,12 @@ bnxt_match_filter(struct bnxt *bp, struct bnxt_filter_info *nf)
struct rte_flow *flow;
int i;

for (i = bp->nr_vnics - 1; i >= 0; i--) {
for (i = bp->max_vnics; i >= 0; i--) {
struct bnxt_vnic_info *vnic = &bp->vnic_info[i];

if (vnic->fw_vnic_id == INVALID_VNIC_ID)
continue;

STAILQ_FOREACH(flow, &vnic->flow_list, next) {
mf = flow->filter;

Expand Down Expand Up @@ -1063,8 +1152,8 @@ bnxt_flow_create(struct rte_eth_dev *dev,
struct rte_flow_error *error)
{
struct bnxt *bp = dev->data->dev_private;
struct bnxt_filter_info *filter;
struct bnxt_vnic_info *vnic = NULL;
struct bnxt_filter_info *filter;
bool update_flow = false;
struct rte_flow *flow;
unsigned int i;
Expand Down Expand Up @@ -1168,12 +1257,35 @@ bnxt_flow_create(struct rte_eth_dev *dev,
ret = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id, filter);
}

for (i = 0; i < bp->nr_vnics; i++) {
for (i = 0; i < bp->max_vnics; i++) {
vnic = &bp->vnic_info[i];
if (filter->dst_id == vnic->fw_vnic_id)
if (vnic->fw_vnic_id != INVALID_VNIC_ID &&
filter->dst_id == vnic->fw_vnic_id) {
PMD_DRV_LOG(ERR, "Found matching VNIC Id %d\n",
vnic->ff_pool_idx);
break;
}
}
done:
if (!ret) {
flow->filter = filter;
flow->vnic = vnic;
/* VNIC is set only in case of queue or RSS action */
if (vnic) {
/*
* RxQ0 is not used for flow filters.
*/

if (update_flow) {
ret = -EXDEV;
goto free_flow;
}
STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
}
PMD_DRV_LOG(ERR, "Successfully created flow.\n");
STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next);
return flow;
}
if (!ret) {
flow->filter = filter;
flow->vnic = vnic;
Expand All @@ -1196,7 +1308,7 @@ bnxt_flow_create(struct rte_eth_dev *dev,
rte_flow_error_set(error, ret,
RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
"Flow with pattern exists, updating destination queue");
else
else if (!rte_errno)
rte_flow_error_set(error, -ret,
RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
"Failed to create flow.");
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/bnxt/bnxt_vnic.h
Expand Up @@ -9,6 +9,8 @@
#include <sys/queue.h>
#include <stdbool.h>

#define INVALID_VNIC_ID ((uint16_t)-1)

struct bnxt_vnic_info {
STAILQ_ENTRY(bnxt_vnic_info) next;
uint8_t ff_pool_idx;
Expand Down

0 comments on commit d24610f

Please sign in to comment.