X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmvpp2%2Fmrvl_flow.c;h=73898657531ffa56f5c1f8cda4cbd29389246f31;hb=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1;hp=13295e6539bdfcb0580ee51ad490d6458a0b23ad;hpb=63e0f0170405385551d52d983ddb8c5227178f51;p=dpdk.git diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c index 13295e6539..7389865753 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 @@ -1034,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, @@ -2300,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; } @@ -2442,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; } @@ -2662,6 +2658,11 @@ 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; } @@ -2790,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; + } +}