From patchwork Fri Jan 22 19:19:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liron Himi X-Patchwork-Id: 87130 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 34A7EA0A0A; Fri, 22 Jan 2021 20:22:21 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 372FC141110; Fri, 22 Jan 2021 20:20:29 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 51225141110 for ; Fri, 22 Jan 2021 20:20:27 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 10MJB4ik016361 for ; Fri, 22 Jan 2021 11:20:26 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=caI1H23mxEf2yg3Di9YyVaZxNeuGmEDXHqGu4L2cV9w=; b=i1I+1Y/RZAVeyeyySilbl/cmA1XwkQ7mjWxS2Hpn4TPTFhYV3nnbroZ/e8VV82lspFwK y+Fx1xWihQAoDRPzvk7muxrquX5JtjetKKmNnMffk7ydogBI2udtMQPZGUoJTmXrMEa0 diwJdCdWj21pnjoUjdrsFmpnIOTgXjR4DJfksfc0/0ObD4fXL5qPXzPltiYRCTUKXN1W Ng7tMmyffFV59Lg5arYjwVEwIDyBQSx6YWy15TdUW6ahJpr+O0k0LEte++Q+nnSPX5DU xnMA4/2RHtYpwbmMzf0rhKXMtv+t+v8vs1W3oDLOVcCFo0f3hznVm3uhEEkR0G6MUh2k HA== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com with ESMTP id 3668p7tpff-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Fri, 22 Jan 2021 11:20:26 -0800 Received: from SC-EXCH03.marvell.com (10.93.176.83) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 22 Jan 2021 11:20:24 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 22 Jan 2021 11:20:23 -0800 Received: from pt-lxl0023.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 22 Jan 2021 11:20:22 -0800 From: To: CC: , Liron Himi Date: Fri, 22 Jan 2021 21:19:07 +0200 Message-ID: <20210122191925.24308-20-lironh@marvell.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20210122191925.24308-1-lironh@marvell.com> References: <20201202101212.4717-1-lironh@marvell.com> <20210122191925.24308-1-lironh@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343, 18.0.737 definitions=2021-01-22_14:2021-01-22, 2021-01-22 signatures=0 Subject: [dpdk-dev] [PATCH v2 19/37] net/mvpp2: flow: support generic pattern combinations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Liron Himi Currently only specific pattern combinations are supported. this makes it hard to support additional pattern. in addition there is no a real limitation that prevent any combination. This patch iterate the input patterns and convert them to a mvpp2 API. The doc doesn't describes those limitation so just update the action list Signed-off-by: Liron Himi --- doc/guides/nics/mvpp2.rst | 1 + drivers/net/mvpp2/mrvl_flow.c | 1254 +++++---------------------------- 2 files changed, 159 insertions(+), 1096 deletions(-) diff --git a/doc/guides/nics/mvpp2.rst b/doc/guides/nics/mvpp2.rst index 6fbce8358..8cea0097b 100644 --- a/doc/guides/nics/mvpp2.rst +++ b/doc/guides/nics/mvpp2.rst @@ -368,6 +368,7 @@ Following flow action items are supported by the driver: * DROP * QUEUE +* METER Supported flow items ~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c index ea4325528..a1a748529 100644 --- a/drivers/net/mvpp2/mrvl_flow.c +++ b/drivers/net/mvpp2/mrvl_flow.c @@ -20,185 +20,12 @@ /** Size of the classifier key and mask strings. */ #define MRVL_CLS_STR_SIZE_MAX 40 -static const enum rte_flow_item_type pattern_eth[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_vlan[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_vlan_ip[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_vlan_ip6[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_ip4[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_ip4_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_ip4_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_ip6[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_ip6_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_eth_ip6_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan_ip[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan_ip_tcp[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan_ip_udp[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan_ip6[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan_ip6_tcp[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_vlan_ip6_udp[] = { - RTE_FLOW_ITEM_TYPE_VLAN, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_ip[] = { - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_ip6[] = { - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_ip_tcp[] = { - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_ip6_tcp[] = { - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_ip_udp[] = { - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_ip6_udp[] = { - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_tcp[] = { - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END -}; - -static const enum rte_flow_item_type pattern_udp[] = { - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END -}; - #define MRVL_VLAN_ID_MASK 0x0fff #define MRVL_VLAN_PRI_MASK 0x7000 #define MRVL_IPV4_DSCP_MASK 0xfc #define MRVL_IPV4_ADDR_MASK 0xffffffff #define MRVL_IPV6_FLOW_MASK 0x0fffff -/** - * Given a flow item, return the next non-void one. - * - * @param items Pointer to the item in the table. - * @returns Next not-void item, NULL otherwise. - */ -static const struct rte_flow_item * -mrvl_next_item(const struct rte_flow_item *items) -{ - const struct rte_flow_item *item = items; - - for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { - if (item->type != RTE_FLOW_ITEM_TYPE_VOID) - return item; - } - - return NULL; -} - /** * Allocate memory for classifier rule key and mask fields. * @@ -361,9 +188,6 @@ mrvl_parse_mac(const struct rte_flow_item_eth *spec, struct pp2_cls_rule_key_field *key_field; const uint8_t *k, *m; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - if (parse_dst) { k = spec->dst.addr_bytes; m = mask->dst.addr_bytes; @@ -441,9 +265,6 @@ mrvl_parse_type(const struct rte_flow_item_eth *spec, struct pp2_cls_rule_key_field *key_field; uint16_t k; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 2; @@ -475,9 +296,6 @@ mrvl_parse_vlan_id(const struct rte_flow_item_vlan *spec, struct pp2_cls_rule_key_field *key_field; uint16_t k; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 2; @@ -509,9 +327,6 @@ mrvl_parse_vlan_pri(const struct rte_flow_item_vlan *spec, struct pp2_cls_rule_key_field *key_field; uint16_t k; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 1; @@ -543,9 +358,6 @@ mrvl_parse_ip4_dscp(const struct rte_flow_item_ipv4 *spec, struct pp2_cls_rule_key_field *key_field; uint8_t k, m; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 1; @@ -582,9 +394,6 @@ mrvl_parse_ip4_addr(const struct rte_flow_item_ipv4 *spec, struct in_addr k; uint32_t m; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - memset(&k, 0, sizeof(k)); if (parse_dst) { k.s_addr = spec->hdr.dst_addr; @@ -660,9 +469,6 @@ mrvl_parse_ip4_proto(const struct rte_flow_item_ipv4 *spec, struct pp2_cls_rule_key_field *key_field; uint8_t k = spec->hdr.next_proto_id; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 1; @@ -696,9 +502,6 @@ mrvl_parse_ip6_addr(const struct rte_flow_item_ipv6 *spec, int size = sizeof(spec->hdr.dst_addr); struct in6_addr k, m; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - memset(&k, 0, sizeof(k)); if (parse_dst) { memcpy(k.s6_addr, spec->hdr.dst_addr, size); @@ -775,9 +578,6 @@ mrvl_parse_ip6_flow(const struct rte_flow_item_ipv6 *spec, uint32_t k = rte_be_to_cpu_32(spec->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK, m = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 3; @@ -809,9 +609,6 @@ mrvl_parse_ip6_next_hdr(const struct rte_flow_item_ipv6 *spec, struct pp2_cls_rule_key_field *key_field; uint8_t k = spec->hdr.proto; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 1; @@ -844,9 +641,6 @@ mrvl_parse_tcp_port(const struct rte_flow_item_tcp *spec, struct pp2_cls_rule_key_field *key_field; uint16_t k; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 2; @@ -920,9 +714,6 @@ mrvl_parse_udp_port(const struct rte_flow_item_udp *spec, struct pp2_cls_rule_key_field *key_field; uint16_t k; - if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS) - return -ENOSPC; - key_field = &flow->rule.fields[flow->rule.num_fields]; mrvl_alloc_key_mask(key_field); key_field->size = 2; @@ -1243,8 +1034,8 @@ mrvl_parse_tcp(const struct rte_flow_item *item, int ret; ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, - &rte_flow_item_ipv4_mask, - sizeof(struct rte_flow_item_ipv4), error); + &rte_flow_item_tcp_mask, + sizeof(struct rte_flow_item_tcp), error); if (ret) return ret; @@ -1298,8 +1089,8 @@ mrvl_parse_udp(const struct rte_flow_item *item, int ret; ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, - &rte_flow_item_ipv4_mask, - sizeof(struct rte_flow_item_ipv4), error); + &rte_flow_item_udp_mask, + sizeof(struct rte_flow_item_udp), error); if (ret) return ret; @@ -1332,923 +1123,196 @@ mrvl_parse_udp(const struct rte_flow_item *item, } /** - * Parse flow pattern composed of the the eth item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. + * Structure used to map specific flow pattern to the pattern parse callback + * which will iterate over each pattern item and extract relevant data. */ -static int -mrvl_parse_pattern_eth(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_eth(pattern, flow, error); -} +static const struct { + const enum rte_flow_item_type pattern_type; + int (*parse)(const struct rte_flow_item *pattern, + struct rte_flow *flow, + struct rte_flow_error *error); +} mrvl_patterns[] = { + { RTE_FLOW_ITEM_TYPE_ETH, mrvl_parse_eth }, + { RTE_FLOW_ITEM_TYPE_VLAN, mrvl_parse_vlan }, + { RTE_FLOW_ITEM_TYPE_IPV4, mrvl_parse_ip4 }, + { RTE_FLOW_ITEM_TYPE_IPV6, mrvl_parse_ip6 }, + { RTE_FLOW_ITEM_TYPE_TCP, mrvl_parse_tcp }, + { RTE_FLOW_ITEM_TYPE_UDP, mrvl_parse_udp }, + { RTE_FLOW_ITEM_TYPE_END, NULL } +}; /** - * Parse flow pattern composed of the eth and vlan items. + * Parse flow attribute. * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. + * This will check whether the provided attribute's flags are supported. + * + * @param priv Unused + * @param attr Pointer to the flow attribute. + * @param flow Unused * @param error Pointer to the flow error. * @returns 0 in case of success, negative value otherwise. */ static int -mrvl_parse_pattern_eth_vlan(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) +mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused, + const struct rte_flow_attr *attr, + struct rte_flow *flow __rte_unused, + struct rte_flow_error *error) { - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = mrvl_parse_eth(item, flow, error); - if (ret) - return ret; + if (!attr) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR, + NULL, "NULL attribute"); + return -rte_errno; + } - item = mrvl_next_item(item + 1); + if (attr->group) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL, + "Groups are not supported"); + return -rte_errno; + } + if (attr->priority) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL, + "Priorities are not supported"); + return -rte_errno; + } + if (!attr->ingress) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL, + "Only ingress is supported"); + return -rte_errno; + } + if (attr->egress) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, + "Egress is not supported"); + return -rte_errno; + } + if (attr->transfer) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL, + "Transfer is not supported"); + return -rte_errno; + } - return mrvl_parse_vlan(item, flow, error); + return 0; } /** - * Parse flow pattern composed of the eth, vlan and ip4/ip6 items. + * Parse flow pattern. + * + * Specific classifier rule will be created as well. * - * @param pattern Pointer to the flow pattern table. + * @param priv Unused + * @param pattern Pointer to the flow pattern. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. * @returns 0 in case of success, negative value otherwise. */ static int -mrvl_parse_pattern_eth_vlan_ip4_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int ip6) +mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused, + const struct rte_flow_item pattern[], + struct rte_flow *flow, + struct rte_flow_error *error) { - const struct rte_flow_item *item = mrvl_next_item(pattern); + unsigned int i, j; int ret; - ret = mrvl_parse_eth(item, flow, error); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - ret = mrvl_parse_vlan(item, flow, error); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); + for (i = 0; pattern[i].type != RTE_FLOW_ITEM_TYPE_END; i++) { + if (pattern[i].type == RTE_FLOW_ITEM_TYPE_VOID) + continue; + for (j = 0; mrvl_patterns[j].pattern_type != + RTE_FLOW_ITEM_TYPE_END; j++) { + if (mrvl_patterns[j].pattern_type != pattern[i].type) + continue; + + if (flow->rule.num_fields >= + PP2_CLS_TBL_MAX_NUM_FIELDS) { + rte_flow_error_set(error, ENOSPC, + RTE_FLOW_ERROR_TYPE_ITEM_NUM, + NULL, + "too many pattern (max %d)"); + return -rte_errno; + } - return ip6 ? mrvl_parse_ip6(item, flow, error) : - mrvl_parse_ip4(item, flow, error); -} + ret = mrvl_patterns[j].parse(&pattern[i], flow, error); + if (ret) { + mrvl_free_all_key_mask(&flow->rule); + return ret; + } + break; + } + if (mrvl_patterns[j].pattern_type == RTE_FLOW_ITEM_TYPE_END) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "Unsupported pattern"); + return -rte_errno; + } + } -/** - * Parse flow pattern composed of the eth, vlan and ipv4 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_eth_vlan_ip4(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 0); + return 0; } /** - * Parse flow pattern composed of the eth, vlan and ipv6 items. + * Parse flow actions. * - * @param pattern Pointer to the flow pattern table. + * @param priv Pointer to the port's private data. + * @param actions Pointer the action table. * @param flow Pointer to the flow. * @param error Pointer to the flow error. * @returns 0 in case of success, negative value otherwise. */ static int -mrvl_parse_pattern_eth_vlan_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) +mrvl_flow_parse_actions(struct mrvl_priv *priv, + const struct rte_flow_action actions[], + struct rte_flow *flow, + struct rte_flow_error *error) { - return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 1); -} + const struct rte_flow_action *action = actions; + int specified = 0; -/** - * Parse flow pattern composed of the eth and ip4/ip6 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_eth_ip4_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int ip6) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; + for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { + if (action->type == RTE_FLOW_ACTION_TYPE_VOID) + continue; - ret = mrvl_parse_eth(item, flow, error); - if (ret) - return ret; + if (action->type == RTE_FLOW_ACTION_TYPE_DROP) { + flow->cos.ppio = priv->ppio; + flow->cos.tc = 0; + flow->action.type = PP2_CLS_TBL_ACT_DROP; + flow->action.cos = &flow->cos; + specified++; + } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) { + const struct rte_flow_action_queue *q = + (const struct rte_flow_action_queue *) + action->conf; - item = mrvl_next_item(item + 1); + if (q->index > priv->nb_rx_queues) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "Queue index out of range"); + return -rte_errno; + } - return ip6 ? mrvl_parse_ip6(item, flow, error) : - mrvl_parse_ip4(item, flow, error); -} + if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) { + /* + * Unknown TC mapping, mapping will not have + * a correct queue. + */ + MRVL_LOG(ERR, + "Unknown TC mapping for queue %hu eth%hhu", + q->index, priv->ppio_id); -/** - * Parse flow pattern composed of the eth and ipv4 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_eth_ip4(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0); -} + rte_flow_error_set(error, EFAULT, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, NULL); + return -rte_errno; + } -/** - * Parse flow pattern composed of the eth and ipv6 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_eth_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the eth, ip4 and tcp/udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param tcp 1 to parse tcp item, 0 to parse udp item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_eth_ip4_tcp_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int tcp) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - item = mrvl_next_item(item + 1); - - if (tcp) - return mrvl_parse_tcp(item, flow, error); - - return mrvl_parse_udp(item, flow, error); -} - -/** - * Parse flow pattern composed of the eth, ipv4 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_eth_ip4_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the eth, ipv4 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_eth_ip4_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the eth, ipv6 and tcp/udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param tcp 1 to parse tcp item, 0 to parse udp item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_eth_ip6_tcp_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int tcp) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - item = mrvl_next_item(item + 1); - - if (tcp) - return mrvl_parse_tcp(item, flow, error); - - return mrvl_parse_udp(item, flow, error); -} - -/** - * Parse flow pattern composed of the eth, ipv6 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_eth_ip6_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the eth, ipv6 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_eth_ip6_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the vlan item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_vlan(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - - return mrvl_parse_vlan(item, flow, error); -} - -/** - * Parse flow pattern composed of the vlan and ip4/ip6 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_vlan_ip4_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int ip6) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = mrvl_parse_vlan(item, flow, error); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - - return ip6 ? mrvl_parse_ip6(item, flow, error) : - mrvl_parse_ip4(item, flow, error); -} - -/** - * Parse flow pattern composed of the vlan and ipv4 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_vlan_ip4(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the vlan, ipv4 and tcp/udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_vlan_ip_tcp_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int tcp) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - item = mrvl_next_item(item + 1); - - if (tcp) - return mrvl_parse_tcp(item, flow, error); - - return mrvl_parse_udp(item, flow, error); -} - -/** - * Parse flow pattern composed of the vlan, ipv4 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_vlan_ip_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the vlan, ipv4 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_vlan_ip_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the vlan and ipv6 items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_vlan_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the vlan, ipv6 and tcp/udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_vlan_ip6_tcp_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int tcp) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - item = mrvl_next_item(item + 1); - - if (tcp) - return mrvl_parse_tcp(item, flow, error); - - return mrvl_parse_udp(item, flow, error); -} - -/** - * Parse flow pattern composed of the vlan, ipv6 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_vlan_ip6_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the vlan, ipv6 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_vlan_ip6_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the ip4/ip6 item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_ip4_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int ip6) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - - return ip6 ? mrvl_parse_ip6(item, flow, error) : - mrvl_parse_ip4(item, flow, error); -} - -/** - * Parse flow pattern composed of the ipv4 item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_ip4(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the ipv6 item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_ip6(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the ip4/ip6 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_ip4_ip6_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int ip6) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = ip6 ? mrvl_parse_ip6(item, flow, error) : - mrvl_parse_ip4(item, flow, error); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - - return mrvl_parse_tcp(item, flow, error); -} - -/** - * Parse flow pattern composed of the ipv4 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_ip4_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the ipv6 and tcp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_ip6_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the ipv4/ipv6 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @param ip6 1 to parse ip6 item, 0 to parse ip4 item. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_ip4_ip6_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error, int ip6) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - int ret; - - ret = ip6 ? mrvl_parse_ip6(item, flow, error) : - mrvl_parse_ip4(item, flow, error); - if (ret) - return ret; - - item = mrvl_next_item(item + 1); - - return mrvl_parse_udp(item, flow, error); -} - -/** - * Parse flow pattern composed of the ipv4 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_ip4_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 0); -} - -/** - * Parse flow pattern composed of the ipv6 and udp items. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static inline int -mrvl_parse_pattern_ip6_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 1); -} - -/** - * Parse flow pattern composed of the tcp item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_tcp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - - return mrvl_parse_tcp(item, flow, error); -} - -/** - * Parse flow pattern composed of the udp item. - * - * @param pattern Pointer to the flow pattern table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_parse_pattern_udp(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - const struct rte_flow_item *item = mrvl_next_item(pattern); - - return mrvl_parse_udp(item, flow, error); -} - -/** - * Structure used to map specific flow pattern to the pattern parse callback - * which will iterate over each pattern item and extract relevant data. - */ -static const struct { - const enum rte_flow_item_type *pattern; - int (*parse)(const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error); -} mrvl_patterns[] = { - { pattern_eth, mrvl_parse_pattern_eth }, - { pattern_eth_vlan, mrvl_parse_pattern_eth_vlan }, - { pattern_eth_vlan_ip, mrvl_parse_pattern_eth_vlan_ip4 }, - { pattern_eth_vlan_ip6, mrvl_parse_pattern_eth_vlan_ip6 }, - { pattern_eth_ip4, mrvl_parse_pattern_eth_ip4 }, - { pattern_eth_ip4_tcp, mrvl_parse_pattern_eth_ip4_tcp }, - { pattern_eth_ip4_udp, mrvl_parse_pattern_eth_ip4_udp }, - { pattern_eth_ip6, mrvl_parse_pattern_eth_ip6 }, - { pattern_eth_ip6_tcp, mrvl_parse_pattern_eth_ip6_tcp }, - { pattern_eth_ip6_udp, mrvl_parse_pattern_eth_ip6_udp }, - { pattern_vlan, mrvl_parse_pattern_vlan }, - { pattern_vlan_ip, mrvl_parse_pattern_vlan_ip4 }, - { pattern_vlan_ip_tcp, mrvl_parse_pattern_vlan_ip_tcp }, - { pattern_vlan_ip_udp, mrvl_parse_pattern_vlan_ip_udp }, - { pattern_vlan_ip6, mrvl_parse_pattern_vlan_ip6 }, - { pattern_vlan_ip6_tcp, mrvl_parse_pattern_vlan_ip6_tcp }, - { pattern_vlan_ip6_udp, mrvl_parse_pattern_vlan_ip6_udp }, - { pattern_ip, mrvl_parse_pattern_ip4 }, - { pattern_ip_tcp, mrvl_parse_pattern_ip4_tcp }, - { pattern_ip_udp, mrvl_parse_pattern_ip4_udp }, - { pattern_ip6, mrvl_parse_pattern_ip6 }, - { pattern_ip6_tcp, mrvl_parse_pattern_ip6_tcp }, - { pattern_ip6_udp, mrvl_parse_pattern_ip6_udp }, - { pattern_tcp, mrvl_parse_pattern_tcp }, - { pattern_udp, mrvl_parse_pattern_udp } -}; - -/** - * Check whether provided pattern matches any of the supported ones. - * - * @param type_pattern Pointer to the pattern type. - * @param item_pattern Pointer to the flow pattern. - * @returns 1 in case of success, 0 value otherwise. - */ -static int -mrvl_patterns_match(const enum rte_flow_item_type *type_pattern, - const struct rte_flow_item *item_pattern) -{ - const enum rte_flow_item_type *type = type_pattern; - const struct rte_flow_item *item = item_pattern; - - for (;;) { - if (item->type == RTE_FLOW_ITEM_TYPE_VOID) { - item++; - continue; - } - - if (*type == RTE_FLOW_ITEM_TYPE_END || - item->type == RTE_FLOW_ITEM_TYPE_END) - break; - - if (*type != item->type) - break; - - item++; - type++; - } - - return *type == item->type; -} - -/** - * Parse flow attribute. - * - * This will check whether the provided attribute's flags are supported. - * - * @param priv Unused - * @param attr Pointer to the flow attribute. - * @param flow Unused - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused, - const struct rte_flow_attr *attr, - struct rte_flow *flow __rte_unused, - struct rte_flow_error *error) -{ - if (!attr) { - rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR, - NULL, "NULL attribute"); - return -rte_errno; - } - - if (attr->group) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL, - "Groups are not supported"); - return -rte_errno; - } - if (attr->priority) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL, - "Priorities are not supported"); - return -rte_errno; - } - if (!attr->ingress) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL, - "Only ingress is supported"); - return -rte_errno; - } - if (attr->egress) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, - "Egress is not supported"); - return -rte_errno; - } - if (attr->transfer) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL, - "Transfer is not supported"); - return -rte_errno; - } - - return 0; -} - -/** - * Parse flow pattern. - * - * Specific classifier rule will be created as well. - * - * @param priv Unused - * @param pattern Pointer to the flow pattern. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused, - const struct rte_flow_item pattern[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - unsigned int i; - int ret; - - for (i = 0; i < RTE_DIM(mrvl_patterns); i++) { - if (!mrvl_patterns_match(mrvl_patterns[i].pattern, pattern)) - continue; - - ret = mrvl_patterns[i].parse(pattern, flow, error); - if (ret) - mrvl_free_all_key_mask(&flow->rule); - - return ret; - } - - rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, NULL, - "Unsupported pattern"); - - return -rte_errno; -} - -/** - * Parse flow actions. - * - * @param priv Pointer to the port's private data. - * @param actions Pointer the action table. - * @param flow Pointer to the flow. - * @param error Pointer to the flow error. - * @returns 0 in case of success, negative value otherwise. - */ -static int -mrvl_flow_parse_actions(struct mrvl_priv *priv, - const struct rte_flow_action actions[], - struct rte_flow *flow, - struct rte_flow_error *error) -{ - const struct rte_flow_action *action = actions; - int specified = 0; - - for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) { - if (action->type == RTE_FLOW_ACTION_TYPE_VOID) - continue; - - if (action->type == RTE_FLOW_ACTION_TYPE_DROP) { - flow->cos.ppio = priv->ppio; - flow->cos.tc = 0; - flow->action.type = PP2_CLS_TBL_ACT_DROP; - flow->action.cos = &flow->cos; - specified++; - } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) { - const struct rte_flow_action_queue *q = - (const struct rte_flow_action_queue *) - action->conf; - - if (q->index > priv->nb_rx_queues) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - NULL, - "Queue index out of range"); - return -rte_errno; - } - - if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) { - /* - * Unknown TC mapping, mapping will not have - * a correct queue. - */ - MRVL_LOG(ERR, - "Unknown TC mapping for queue %hu eth%hhu", - q->index, priv->ppio_id); - - rte_flow_error_set(error, EFAULT, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, NULL); - return -rte_errno; - } - - MRVL_LOG(DEBUG, - "Action: Assign packets to queue %d, tc:%d, q:%d", - q->index, priv->rxq_map[q->index].tc, - priv->rxq_map[q->index].inq); + MRVL_LOG(DEBUG, + "Action: Assign packets to queue %d, tc:%d, q:%d", + q->index, priv->rxq_map[q->index].tc, + priv->rxq_map[q->index].inq); flow->cos.ppio = priv->ppio; flow->cos.tc = priv->rxq_map[q->index].tc; @@ -2755,6 +1819,11 @@ mrvl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) rte_free(flow); } + if (priv->cls_tbl) { + pp2_cls_tbl_deinit(priv->cls_tbl); + priv->cls_tbl = NULL; + } + return 0; } @@ -2813,12 +1882,5 @@ mrvl_flow_init(struct rte_eth_dev *dev) void mrvl_flow_deinit(struct rte_eth_dev *dev) { - struct mrvl_priv *priv = dev->data->dev_private; - mrvl_flow_flush(dev, NULL); - - if (priv->cls_tbl) { - pp2_cls_tbl_deinit(priv->cls_tbl); - priv->cls_tbl = NULL; - } }