Inter-revision diff: patch 3

Comparing v7 (message) to v4 (message)

--- v7
+++ v4
@@ -1,172 +1,69 @@
-PSFP support gate and police action. This patch add the gate and police
-action to flower parse action, check chain ID to determine which block
-to offload. Adding psfp callback functions to add, delete and update gate
-and police in PSFP table if hardware supports it.
+Some chips in the ocelot series such as VSC9959 support Per-Stream
+Filtering and Policing(PSFP), which is processing after VCAP blocks.
+We set this block on chain 30000 and set vcap IS2 chain to goto PSFP
+chain if hardware support.
 
 Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
 ---
- drivers/net/ethernet/mscc/ocelot.c        |  3 ++
- drivers/net/ethernet/mscc/ocelot_flower.c | 52 ++++++++++++++++++++++-
- include/soc/mscc/ocelot.h                 |  5 +++
- include/soc/mscc/ocelot_vcap.h            |  1 +
- 4 files changed, 59 insertions(+), 2 deletions(-)
+ drivers/net/ethernet/mscc/ocelot_flower.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
 
-diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
-index 9e981913d6ba..95920668feb0 100644
---- a/drivers/net/ethernet/mscc/ocelot.c
-+++ b/drivers/net/ethernet/mscc/ocelot.c
-@@ -2352,6 +2352,9 @@ int ocelot_init(struct ocelot *ocelot)
- 	ocelot_vcap_init(ocelot);
- 	ocelot_cpu_port_init(ocelot);
- 
-+	if (ocelot->ops->psfp_init)
-+		ocelot->ops->psfp_init(ocelot);
-+
- 	for (port = 0; port < ocelot->num_phys_ports; port++) {
- 		/* Clear all counters (5 groups) */
- 		ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) |
 diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
-index ed609bc4398e..b22966e15acf 100644
+index 8b843d3c9189..ce812194e44c 100644
 --- a/drivers/net/ethernet/mscc/ocelot_flower.c
 +++ b/drivers/net/ethernet/mscc/ocelot_flower.c
-@@ -280,10 +280,14 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
- 			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
- 			break;
- 		case FLOW_ACTION_POLICE:
-+			if (filter->block_id == PSFP_BLOCK_ID) {
-+				filter->type = OCELOT_PSFP_FILTER_OFFLOAD;
-+				break;
-+			}
- 			if (filter->block_id != VCAP_IS2 ||
- 			    filter->lookup != 0) {
- 				NL_SET_ERR_MSG_MOD(extack,
--						   "Police action can only be offloaded to VCAP IS2 lookup 0");
-+						   "Police action can only be offloaded to VCAP IS2 lookup 0 or PSFP");
- 				return -EOPNOTSUPP;
- 			}
- 			if (filter->goto_target != -1) {
-@@ -410,6 +414,14 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
- 			filter->action.pcp_a_val = a->vlan.prio;
- 			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
- 			break;
-+		case FLOW_ACTION_GATE:
-+			if (filter->block_id != PSFP_BLOCK_ID) {
-+				NL_SET_ERR_MSG_MOD(extack,
-+						   "Gate action can only be offloaded to PSFP chain");
-+				return -EOPNOTSUPP;
-+			}
-+			filter->type = OCELOT_PSFP_FILTER_OFFLOAD;
-+			break;
- 		default:
- 			NL_SET_ERR_MSG_MOD(extack, "Cannot offload action");
- 			return -EOPNOTSUPP;
-@@ -700,6 +712,10 @@ static int ocelot_flower_parse(struct ocelot *ocelot, int port, bool ingress,
- 	if (ret)
- 		return ret;
+@@ -20,6 +20,9 @@
+ 	(1 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP)
+ #define VCAP_IS2_CHAIN(lookup, pag)	\
+ 	(2 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP + (pag))
++/* PSFP chain and block ID */
++#define PSFP_BLOCK_ID			OCELOT_NUM_VCAP_BLOCKS
++#define OCELOT_PSFP_CHAIN		(3 * VCAP_BLOCK)
  
-+	/* PSFP filter need to parse key by stream identification function. */
-+	if (filter->type == OCELOT_PSFP_FILTER_OFFLOAD)
-+		return 0;
+ static int ocelot_chain_to_block(int chain, bool ingress)
+ {
+@@ -46,6 +49,9 @@ static int ocelot_chain_to_block(int chain, bool ingress)
+ 			if (chain == VCAP_IS2_CHAIN(lookup, pag))
+ 				return VCAP_IS2;
+ 
++	if (chain == OCELOT_PSFP_CHAIN)
++		return PSFP_BLOCK_ID;
 +
- 	return ocelot_flower_parse_key(ocelot, port, ingress, f, filter);
+ 	return -EOPNOTSUPP;
  }
  
-@@ -803,6 +819,15 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
- 	if (filter->type == OCELOT_VCAP_FILTER_DUMMY)
- 		return ocelot_vcap_dummy_filter_add(ocelot, filter);
+@@ -84,7 +90,8 @@ static bool ocelot_is_goto_target_valid(int goto_target, int chain,
+ 			goto_target == VCAP_IS1_CHAIN(1) ||
+ 			goto_target == VCAP_IS1_CHAIN(2) ||
+ 			goto_target == VCAP_IS2_CHAIN(0, 0) ||
+-			goto_target == VCAP_IS2_CHAIN(1, 0));
++			goto_target == VCAP_IS2_CHAIN(1, 0) ||
++			goto_target == OCELOT_PSFP_CHAIN);
  
-+	if (filter->type == OCELOT_PSFP_FILTER_OFFLOAD) {
-+		kfree(filter);
-+		if (ocelot->ops->psfp_filter_add)
-+			return ocelot->ops->psfp_filter_add(ocelot, f);
+ 	if (chain == VCAP_IS1_CHAIN(0))
+ 		return (goto_target == VCAP_IS1_CHAIN(1));
+@@ -111,7 +118,11 @@ static bool ocelot_is_goto_target_valid(int goto_target, int chain,
+ 		if (chain == VCAP_IS2_CHAIN(0, pag))
+ 			return (goto_target == VCAP_IS2_CHAIN(1, pag));
+ 
+-	/* VCAP IS2 lookup 1 cannot jump anywhere */
++	/* VCAP IS2 lookup 1 can goto to PSFP block if hardware support */
++	for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
++		if (chain == VCAP_IS2_CHAIN(1, pag))
++			return (goto_target == OCELOT_PSFP_CHAIN);
 +
-+		NL_SET_ERR_MSG_MOD(extack, "PSFP chain is not supported in HW");
-+		return -EOPNOTSUPP;
-+	}
-+
- 	return ocelot_vcap_filter_add(ocelot, filter, f->common.extack);
+ 	return false;
  }
- EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
-@@ -818,6 +843,13 @@ int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
- 	if (block_id < 0)
- 		return 0;
  
-+	if (block_id == PSFP_BLOCK_ID) {
-+		if (ocelot->ops->psfp_filter_del)
-+			return ocelot->ops->psfp_filter_del(ocelot, f);
-+
-+		return -EOPNOTSUPP;
-+	}
-+
- 	block = &ocelot->block[block_id];
+@@ -353,7 +364,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
  
- 	filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie, true);
-@@ -836,12 +868,25 @@ int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
- {
- 	struct ocelot_vcap_filter *filter;
- 	struct ocelot_vcap_block *block;
-+	struct flow_stats stats = {0};
- 	int block_id, ret;
- 
- 	block_id = ocelot_chain_to_block(f->common.chain_index, ingress);
- 	if (block_id < 0)
- 		return 0;
- 
-+	if (block_id == PSFP_BLOCK_ID) {
-+		if (ocelot->ops->psfp_stats_get) {
-+			ret = ocelot->ops->psfp_stats_get(ocelot, f, &stats);
-+			if (ret)
-+				return ret;
-+
-+			goto stats_update;
-+		}
-+
-+		return -EOPNOTSUPP;
-+	}
-+
- 	block = &ocelot->block[block_id];
- 
- 	filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie, true);
-@@ -852,7 +897,10 @@ int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
- 	if (ret)
- 		return ret;
- 
--	flow_stats_update(&f->stats, 0x0, filter->stats.pkts, 0, 0x0,
-+	stats.pkts = filter->stats.pkts;
-+
-+stats_update:
-+	flow_stats_update(&f->stats, 0x0, stats.pkts, stats.drops, 0x0,
- 			  FLOW_ACTION_HW_STATS_IMMEDIATE);
- 	return 0;
- }
-diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
-index 1d5ff11e4100..e9985ace59c0 100644
---- a/include/soc/mscc/ocelot.h
-+++ b/include/soc/mscc/ocelot.h
-@@ -555,6 +555,11 @@ struct ocelot_ops {
- 	u16 (*wm_enc)(u16 value);
- 	u16 (*wm_dec)(u16 value);
- 	void (*wm_stat)(u32 val, u32 *inuse, u32 *maxuse);
-+	void (*psfp_init)(struct ocelot *ocelot);
-+	int (*psfp_filter_add)(struct ocelot *ocelot, struct flow_cls_offload *f);
-+	int (*psfp_filter_del)(struct ocelot *ocelot, struct flow_cls_offload *f);
-+	int (*psfp_stats_get)(struct ocelot *ocelot, struct flow_cls_offload *f,
-+			      struct flow_stats *stats);
- };
- 
- struct ocelot_vcap_block {
-diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
-index eeb1142aa1b1..9cca2f8e61a2 100644
---- a/include/soc/mscc/ocelot_vcap.h
-+++ b/include/soc/mscc/ocelot_vcap.h
-@@ -656,6 +656,7 @@ enum ocelot_vcap_filter_type {
- 	OCELOT_VCAP_FILTER_DUMMY,
- 	OCELOT_VCAP_FILTER_PAG,
- 	OCELOT_VCAP_FILTER_OFFLOAD,
-+	OCELOT_PSFP_FILTER_OFFLOAD,
- };
- 
- struct ocelot_vcap_id {
+ 	if (filter->goto_target == -1) {
+ 		if ((filter->block_id == VCAP_IS2 && filter->lookup == 1) ||
+-		    chain == 0) {
++		    chain == 0 || filter->block_id == PSFP_BLOCK_ID) {
+ 			allow_missing_goto_target = true;
+ 		} else {
+ 			NL_SET_ERR_MSG_MOD(extack, "Missing GOTO action");
 -- 
 2.17.1
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help