X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmvpp2%2Fmrvl_flow.c;h=ea43255284966329e69d10abb768eb44c2752c18;hb=3eca5f8a610eb29365d251b02b7e70461bbcba42;hp=313b9f3510e469e69dc458bb534cd86556d0e26a;hpb=e58638c32411b7ae60ed4dea131728faee962327;p=dpdk.git diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c index 313b9f3510..ea43255284 100644 --- a/drivers/net/mvpp2/mrvl_flow.c +++ b/drivers/net/mvpp2/mrvl_flow.c @@ -11,13 +11,8 @@ #include -#ifdef container_of -#undef container_of -#endif - -#include "mrvl_ethdev.h" +#include "mrvl_flow.h" #include "mrvl_qos.h" -#include "env/mv_common.h" /* for BIT() */ /** Number of rules in the classifier table. */ #define MRVL_CLS_MAX_NUM_RULES 20 @@ -25,46 +20,6 @@ /** Size of the classifier key and mask strings. */ #define MRVL_CLS_STR_SIZE_MAX 40 -/** Parsed fields in processed rte_flow_item. */ -enum mrvl_parsed_fields { - /* eth flags */ - F_DMAC = BIT(0), - F_SMAC = BIT(1), - F_TYPE = BIT(2), - /* vlan flags */ - F_VLAN_ID = BIT(3), - F_VLAN_PRI = BIT(4), - F_VLAN_TCI = BIT(5), /* not supported by MUSDK yet */ - /* ip4 flags */ - F_IP4_TOS = BIT(6), - F_IP4_SIP = BIT(7), - F_IP4_DIP = BIT(8), - F_IP4_PROTO = BIT(9), - /* ip6 flags */ - F_IP6_TC = BIT(10), /* not supported by MUSDK yet */ - F_IP6_SIP = BIT(11), - F_IP6_DIP = BIT(12), - F_IP6_FLOW = BIT(13), - F_IP6_NEXT_HDR = BIT(14), - /* tcp flags */ - F_TCP_SPORT = BIT(15), - F_TCP_DPORT = BIT(16), - /* udp flags */ - F_UDP_SPORT = BIT(17), - F_UDP_DPORT = BIT(18), -}; - -/** PMD-specific definition of a flow rule handle. */ -struct rte_flow { - LIST_ENTRY(rte_flow) next; - - enum mrvl_parsed_fields pattern; - - struct pp2_cls_tbl_rule rule; - struct pp2_cls_cos_desc cos; - struct pp2_cls_tbl_action action; -}; - static const enum rte_flow_item_type pattern_eth[] = { RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_END @@ -394,7 +349,8 @@ mrvl_parse_init(const struct rte_flow_item *item, * * @param spec Pointer to the specific flow item. * @param mask Pointer to the specific flow item's mask. - * @param mask Pointer to the flow. + * @param parse_dst Parse either destination or source mac address. + * @param flow Pointer to the flow. * @return 0 in case of success, negative error value otherwise. */ static int @@ -613,6 +569,7 @@ mrvl_parse_ip4_dscp(const struct rte_flow_item_ipv4 *spec, * * @param spec Pointer to the specific flow item. * @param mask Pointer to the specific flow item's mask. + * @param parse_dst Parse either destination or source ip address. * @param flow Pointer to the flow. * @return 0 in case of success, negative error value otherwise. */ @@ -726,6 +683,7 @@ mrvl_parse_ip4_proto(const struct rte_flow_item_ipv4 *spec, * * @param spec Pointer to the specific flow item. * @param mask Pointer to the specific flow item's mask. + * @param parse_dst Parse either destination or source ipv6 address. * @param flow Pointer to the flow. * @return 0 in case of success, negative error value otherwise. */ @@ -874,6 +832,7 @@ mrvl_parse_ip6_next_hdr(const struct rte_flow_item_ipv6 *spec, * * @param spec Pointer to the specific flow item. * @param mask Pointer to the specific flow item's mask. + * @param parse_dst Parse either destination or source port. * @param flow Pointer to the flow. * @return 0 in case of success, negative error value otherwise. */ @@ -949,6 +908,7 @@ mrvl_parse_tcp_dport(const struct rte_flow_item_tcp *spec, * * @param spec Pointer to the specific flow item. * @param mask Pointer to the specific flow item's mask. + * @param parse_dst Parse either destination or source port. * @param flow Pointer to the flow. * @return 0 in case of success, negative error value otherwise. */ @@ -1022,7 +982,6 @@ mrvl_parse_udp_dport(const struct rte_flow_item_udp *spec, * @param item Pointer to the flow item. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param fields Pointer to the parsed parsed fields enum. * @returns 0 on success, negative value otherwise. */ static int @@ -1030,7 +989,7 @@ mrvl_parse_eth(const struct rte_flow_item *item, struct rte_flow *flow, struct rte_flow_error *error) { const struct rte_flow_item_eth *spec = NULL, *mask = NULL; - struct ether_addr zero; + struct rte_ether_addr zero; int ret; ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask, @@ -1054,7 +1013,7 @@ mrvl_parse_eth(const struct rte_flow_item *item, struct rte_flow *flow, } if (mask->type) { - RTE_LOG(WARNING, PMD, "eth type mask is ignored\n"); + MRVL_LOG(WARNING, "eth type mask is ignored"); ret = mrvl_parse_type(spec, mask, flow); if (ret) goto out; @@ -1073,7 +1032,6 @@ out: * @param item Pointer to the flow item. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param fields Pointer to the parsed parsed fields enum. * @returns 0 on success, negative value otherwise. */ static int @@ -1093,14 +1051,14 @@ mrvl_parse_vlan(const struct rte_flow_item *item, m = rte_be_to_cpu_16(mask->tci); if (m & MRVL_VLAN_ID_MASK) { - RTE_LOG(WARNING, PMD, "vlan id mask is ignored\n"); + MRVL_LOG(WARNING, "vlan id mask is ignored"); ret = mrvl_parse_vlan_id(spec, mask, flow); if (ret) goto out; } if (m & MRVL_VLAN_PRI_MASK) { - RTE_LOG(WARNING, PMD, "vlan pri mask is ignored\n"); + MRVL_LOG(WARNING, "vlan pri mask is ignored"); ret = mrvl_parse_vlan_pri(spec, mask, flow); if (ret) goto out; @@ -1109,7 +1067,7 @@ mrvl_parse_vlan(const struct rte_flow_item *item, if (flow->pattern & F_TYPE) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, - "VLAN TPID matching is not supported\n"); + "VLAN TPID matching is not supported"); return -rte_errno; } if (mask->inner_type) { @@ -1120,7 +1078,7 @@ mrvl_parse_vlan(const struct rte_flow_item *item, .type = mask->inner_type, }; - RTE_LOG(WARNING, PMD, "inner eth type mask is ignored\n"); + MRVL_LOG(WARNING, "inner eth type mask is ignored"); ret = mrvl_parse_type(&spec_eth, &mask_eth, flow); if (ret) goto out; @@ -1139,7 +1097,6 @@ out: * @param item Pointer to the flow item. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param fields Pointer to the parsed parsed fields enum. * @returns 0 on success, negative value otherwise. */ static int @@ -1186,7 +1143,7 @@ mrvl_parse_ip4(const struct rte_flow_item *item, } if (mask->hdr.next_proto_id) { - RTE_LOG(WARNING, PMD, "next proto id mask is ignored\n"); + MRVL_LOG(WARNING, "next proto id mask is ignored"); ret = mrvl_parse_ip4_proto(spec, mask, flow); if (ret) goto out; @@ -1205,7 +1162,6 @@ out: * @param item Pointer to the flow item. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param fields Pointer to the parsed parsed fields enum. * @returns 0 on success, negative value otherwise. */ static int @@ -1214,7 +1170,7 @@ mrvl_parse_ip6(const struct rte_flow_item *item, struct rte_flow_error *error) { const struct rte_flow_item_ipv6 *spec = NULL, *mask = NULL; - struct ipv6_hdr zero; + struct rte_ipv6_hdr zero; uint32_t flow_mask; int ret; @@ -1257,7 +1213,7 @@ mrvl_parse_ip6(const struct rte_flow_item *item, } if (mask->hdr.proto) { - RTE_LOG(WARNING, PMD, "next header mask is ignored\n"); + MRVL_LOG(WARNING, "next header mask is ignored"); ret = mrvl_parse_ip6_next_hdr(spec, mask, flow); if (ret) goto out; @@ -1276,7 +1232,6 @@ out: * @param item Pointer to the flow item. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param fields Pointer to the parsed parsed fields enum. * @returns 0 on success, negative value otherwise. */ static int @@ -1306,14 +1261,14 @@ mrvl_parse_tcp(const struct rte_flow_item *item, } if (mask->hdr.src_port) { - RTE_LOG(WARNING, PMD, "tcp sport mask is ignored\n"); + MRVL_LOG(WARNING, "tcp sport mask is ignored"); ret = mrvl_parse_tcp_sport(spec, mask, flow); if (ret) goto out; } if (mask->hdr.dst_port) { - RTE_LOG(WARNING, PMD, "tcp dport mask is ignored\n"); + MRVL_LOG(WARNING, "tcp dport mask is ignored"); ret = mrvl_parse_tcp_dport(spec, mask, flow); if (ret) goto out; @@ -1332,7 +1287,6 @@ out: * @param item Pointer to the flow item. * @param flow Pointer to the flow. * @param error Pointer to the flow error. - * @param fields Pointer to the parsed parsed fields enum. * @returns 0 on success, negative value otherwise. */ static int @@ -1357,14 +1311,14 @@ mrvl_parse_udp(const struct rte_flow_item *item, } if (mask->hdr.src_port) { - RTE_LOG(WARNING, PMD, "udp sport mask is ignored\n"); + MRVL_LOG(WARNING, "udp sport mask is ignored"); ret = mrvl_parse_udp_sport(spec, mask, flow); if (ret) goto out; } if (mask->hdr.dst_port) { - RTE_LOG(WARNING, PMD, "udp dport mask is ignored\n"); + MRVL_LOG(WARNING, "udp dport mask is ignored"); ret = mrvl_parse_udp_dport(spec, mask, flow); if (ret) goto out; @@ -1981,6 +1935,7 @@ mrvl_parse_pattern_ip6_tcp(const struct rte_flow_item pattern[], * @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 @@ -2187,6 +2142,12 @@ mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused, "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; } @@ -2274,8 +2235,8 @@ mrvl_flow_parse_actions(struct mrvl_priv *priv, * Unknown TC mapping, mapping will not have * a correct queue. */ - RTE_LOG(ERR, PMD, - "Unknown TC mapping for queue %hu eth%hhu\n", + MRVL_LOG(ERR, + "Unknown TC mapping for queue %hu eth%hhu", q->index, priv->ppio_id); rte_flow_error_set(error, EFAULT, @@ -2284,8 +2245,8 @@ mrvl_flow_parse_actions(struct mrvl_priv *priv, return -rte_errno; } - RTE_LOG(DEBUG, PMD, - "Action: Assign packets to queue %d, tc:%d, q:%d\n", + 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); @@ -2294,19 +2255,59 @@ mrvl_flow_parse_actions(struct mrvl_priv *priv, flow->action.type = PP2_CLS_TBL_ACT_DONE; flow->action.cos = &flow->cos; specified++; + } else if (action->type == RTE_FLOW_ACTION_TYPE_METER) { + const struct rte_flow_action_meter *meter; + struct mrvl_mtr *mtr; + + meter = action->conf; + if (!meter) + return -rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "Invalid meter\n"); + + LIST_FOREACH(mtr, &priv->mtrs, next) + if (mtr->mtr_id == meter->mtr_id) + break; + + if (!mtr) + return -rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "Meter id does not exist\n"); + + if (!mtr->shared && mtr->refcnt) + return -rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "Meter cannot be shared\n"); + + /* + * In case cos has already been set + * do not modify it. + */ + if (!flow->cos.ppio) { + flow->cos.ppio = priv->ppio; + flow->cos.tc = 0; + } + + flow->action.type = PP2_CLS_TBL_ACT_DONE; + flow->action.cos = &flow->cos; + flow->action.plcr = mtr->enabled ? mtr->plcr : NULL; + flow->mtr = mtr; + mtr->refcnt++; + specified++; } else { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "Action not supported"); return -rte_errno; } - } if (!specified) { rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, "Action not specified"); + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Action not specified"); return -rte_errno; } @@ -2344,6 +2345,12 @@ mrvl_flow_parse(struct mrvl_priv *priv, const struct rte_flow_attr *attr, return mrvl_flow_parse_actions(priv, actions, flow, error); } +/** + * Get engine type for the given flow. + * + * @param field Pointer to the flow. + * @returns The type of the engine. + */ static inline enum pp2_cls_tbl_type mrvl_engine_type(const struct rte_flow *flow) { @@ -2363,6 +2370,13 @@ mrvl_engine_type(const struct rte_flow *flow) return PP2_CLS_TBL_MASKABLE; } +/** + * Create classifier table. + * + * @param dev Pointer to the device. + * @param flow Pointer to the very first flow. + * @returns 0 in case of success, negative value otherwise. + */ static int mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow) { @@ -2378,7 +2392,7 @@ mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow) memset(&priv->cls_tbl_params, 0, sizeof(priv->cls_tbl_params)); priv->cls_tbl_params.type = mrvl_engine_type(first_flow); - RTE_LOG(INFO, PMD, "Setting cls search engine type to %s\n", + MRVL_LOG(INFO, "Setting cls search engine type to %s", priv->cls_tbl_params.type == PP2_CLS_TBL_EXACT_MATCH ? "exact" : "maskable"); priv->cls_tbl_params.max_num_rules = MRVL_CLS_MAX_NUM_RULES; @@ -2423,7 +2437,8 @@ mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow) if (first_flow->pattern & F_IP4_TOS) { key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4; - key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_TOS; + key->proto_field[key->num_fields].field.ipv4 = + MV_NET_IP4_F_DSCP; key->key_size += 1; key->num_fields += 1; } @@ -2496,14 +2511,14 @@ mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow) if (first_flow->pattern & F_UDP_SPORT) { key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP; - key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP; + key->proto_field[key->num_fields].field.udp = MV_NET_UDP_F_SP; key->key_size += 2; key->num_fields += 1; } if (first_flow->pattern & F_UDP_DPORT) { key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP; - key->proto_field[key->num_fields].field.udp = MV_NET_TCP_F_DP; + key->proto_field[key->num_fields].field.udp = MV_NET_UDP_F_DP; key->key_size += 2; key->num_fields += 1; } @@ -2643,13 +2658,18 @@ mrvl_flow_remove(struct mrvl_priv *priv, struct rte_flow *flow, mrvl_free_all_key_mask(&flow->rule); + if (flow->mtr) { + flow->mtr->refcnt--; + flow->mtr = NULL; + } + return 0; } /** * DPDK flow destroy callback called when flow is to be removed. * - * @param priv Pointer to the port's private data. + * @param dev Pointer to the device. * @param flow Pointer to the flow. * @param error Pointer to the flow error. * @returns 0 in case of success, negative value otherwise. @@ -2771,3 +2791,34 @@ const struct rte_flow_ops mrvl_flow_ops = { .flush = mrvl_flow_flush, .isolate = mrvl_flow_isolate }; + +/** + * Initialize flow resources. + * + * @param dev Pointer to the device. + */ +void +mrvl_flow_init(struct rte_eth_dev *dev) +{ + struct mrvl_priv *priv = dev->data->dev_private; + + LIST_INIT(&priv->flows); +} + +/** + * Cleanup flow resources. + * + * @param dev Pointer to the device. + */ +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; + } +}