summaryrefslogtreecommitdiffstats
path: root/drivers/net/mvpp2/mrvl_flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mvpp2/mrvl_flow.c')
-rw-r--r--drivers/net/mvpp2/mrvl_flow.c161
1 files changed, 103 insertions, 58 deletions
diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
index ecc34192..ffd1dab9 100644
--- a/drivers/net/mvpp2/mrvl_flow.c
+++ b/drivers/net/mvpp2/mrvl_flow.c
@@ -11,13 +11,8 @@
#include <arpa/inet.h>
-#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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
}
@@ -2350,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)
{
@@ -2369,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)
{
@@ -2429,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;
}
@@ -2649,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.
@@ -2777,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;
+ }
+}