netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA
@ 2020-02-29 14:31 Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 01/10] net: mscc: ocelot: make ocelot_ace_rule support multiple ports Vladimir Oltean
                   ` (9 more replies)
  0 siblings, 10 replies; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

This series is a proposal on how to wire up the tc-flower callbacks into
DSA. The example taken is the Microchip Felix switch, whose core
implementation is actually located in drivers/net/ethernet/mscc/.

The proposal is largely a compromise solution. The DSA middle layer
handles just enough to get to the interesting stuff (FLOW_CLS_REPLACE,
FLOW_CLS_DESTROY, FLOW_CLS_STATS), but also thin enough to let drivers
decide what filter keys and actions they support without worrying that
the DSA middle layer will grow exponentially. I am far from being an
expert, so I am asking reviewers to please voice your opinion if you
think it can be done differently, with better results.

The bulk of the work was actually refactoring the ocelot driver enough
to allow the VCAP (Versatile Content-Aware Processor) code for vsc7514
and the vsc9959 switch cores to live together.

Flow block offloads have not been tested yet, only filters attached to a
single port. It might be as simple as replacing ocelot_ace_rule_create
with something smarter, it might be more complicated, I haven't tried
yet.

I should point out that the tc-matchall filter offload is not
implemented in the same manner in current mainline. Florian has already
went all the way down into exposing actual per-action callbacks,
starting with port mirroring. Because currently only mirred is supported
by this DSA mid layer, everything else will return -EOPNOTSUPP. So even
though ocelot supports matchall (aka port-based) policers, we don't have
a call path to call into them.  Personally I think that this is not
going to scale for tc-matchall (there may be policers, traps, drops,
VLAN retagging, etc etc), and that we should consider whether further
matchall filter/action combinations should be just passed on to drivers
with no interpretation instead.
As for the existing mirroring callbacks in DSA, they can either be kept
as-is, or replaced with simple accessors to TC_CLSMATCHALL_REPLACE and
TC_CLSMATCHALL_DESTROY, just like for flower, and drivers which
currently implement the port mirroring callbacks will need to have some
extra "if" conditions now, in order for them to call their port
mirroring implementations.

Vladimir Oltean (9):
  net: mscc: ocelot: simplify tc-flower offload structures
  net: mscc: ocelot: replace "rule" and "ocelot_rule" variable names
    with "ace"
  net: mscc: ocelot: return directly in
    ocelot_cls_flower_{replace,destroy}
  net: mscc: ocelot: spell out full "ocelot" name instead of "oc"
  net: mscc: ocelot: don't rely on preprocessor for vcap key/action
    packing
  net: mscc: ocelot: remove port_pcs_init indirection for VSC7514
  net: mscc: ocelot: parameterize the vcap_is2 properties
  net: dsa: Add bypass operations for the flower classifier-action
    filter
  net: dsa: felix: Wire up the ocelot cls_flower methods

Yangbo Lu (1):
  net: mscc: ocelot: make ocelot_ace_rule support multiple ports

 drivers/net/dsa/ocelot/felix.c            |  31 ++
 drivers/net/dsa/ocelot/felix.h            |   3 +
 drivers/net/dsa/ocelot/felix_vsc9959.c    | 131 +++++
 drivers/net/ethernet/mscc/ocelot.c        |  20 +-
 drivers/net/ethernet/mscc/ocelot_ace.c    | 561 ++++++++++++----------
 drivers/net/ethernet/mscc/ocelot_ace.h    |  26 +-
 drivers/net/ethernet/mscc/ocelot_board.c  | 156 +++++-
 drivers/net/ethernet/mscc/ocelot_flower.c | 256 +++-------
 drivers/net/ethernet/mscc/ocelot_tc.c     |  22 +-
 drivers/net/ethernet/mscc/ocelot_vcap.h   | 403 ----------------
 include/net/dsa.h                         |   6 +
 include/soc/mscc/ocelot.h                 |  20 +-
 include/soc/mscc/ocelot_vcap.h            | 205 ++++++++
 net/dsa/slave.c                           |  60 +++
 14 files changed, 983 insertions(+), 917 deletions(-)
 delete mode 100644 drivers/net/ethernet/mscc/ocelot_vcap.h
 create mode 100644 include/soc/mscc/ocelot_vcap.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 01/10] net: mscc: ocelot: make ocelot_ace_rule support multiple ports
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 02/10] net: mscc: ocelot: simplify tc-flower offload structures Vladimir Oltean
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Yangbo Lu <yangbo.lu@nxp.com>

The ocelot_ace_rule is port specific now. Make it flexible to
be able to support multiple ports too.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
---
Changes in v2:
None.

 drivers/net/ethernet/mscc/ocelot_ace.c    | 14 +++++++-------
 drivers/net/ethernet/mscc/ocelot_ace.h    |  4 ++--
 drivers/net/ethernet/mscc/ocelot_flower.c |  8 ++++----
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index 86fc6e6b46dd..18670645d47f 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -352,7 +352,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 	data.type = IS2_ACTION_TYPE_NORMAL;
 
 	VCAP_KEY_ANY_SET(PAG);
-	VCAP_KEY_SET(IGR_PORT_MASK, 0, ~BIT(ace->chip_port));
+	VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port_mask);
 	VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1);
 	VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY);
 	VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc);
@@ -576,7 +576,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 
 static void is2_entry_get(struct ocelot_ace_rule *rule, int ix)
 {
-	struct ocelot *op = rule->port->ocelot;
+	struct ocelot *op = rule->ocelot;
 	struct vcap_data data;
 	int row = (ix / 2);
 	u32 cnt;
@@ -655,11 +655,11 @@ int ocelot_ace_rule_offload_add(struct ocelot_ace_rule *rule)
 	/* Move down the rules to make place for the new rule */
 	for (i = acl_block->count - 1; i > index; i--) {
 		ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-		is2_entry_set(rule->port->ocelot, i, ace);
+		is2_entry_set(rule->ocelot, i, ace);
 	}
 
 	/* Now insert the new rule */
-	is2_entry_set(rule->port->ocelot, index, rule);
+	is2_entry_set(rule->ocelot, index, rule);
 	return 0;
 }
 
@@ -697,11 +697,11 @@ int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule)
 	/* Move up all the blocks over the deleted rule */
 	for (i = index; i < acl_block->count; i++) {
 		ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-		is2_entry_set(rule->port->ocelot, i, ace);
+		is2_entry_set(rule->ocelot, i, ace);
 	}
 
 	/* Now delete the last rule, because it is duplicated */
-	is2_entry_set(rule->port->ocelot, acl_block->count, &del_ace);
+	is2_entry_set(rule->ocelot, acl_block->count, &del_ace);
 
 	return 0;
 }
@@ -717,7 +717,7 @@ int ocelot_ace_rule_stats_update(struct ocelot_ace_rule *rule)
 	/* After we get the result we need to clear the counters */
 	tmp = ocelot_ace_rule_get_rule_index(acl_block, index);
 	tmp->stats.pkts = 0;
-	is2_entry_set(rule->port->ocelot, index, tmp);
+	is2_entry_set(rule->ocelot, index, tmp);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h
index c08e3e8482e7..2927ac83741b 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -186,14 +186,14 @@ struct ocelot_ace_stats {
 
 struct ocelot_ace_rule {
 	struct list_head list;
-	struct ocelot_port *port;
+	struct ocelot *ocelot;
 
 	u16 prio;
 	u32 id;
 
 	enum ocelot_ace_action action;
 	struct ocelot_ace_stats stats;
-	int chip_port;
+	u16 ingress_port_mask;
 
 	enum ocelot_vcap_bit dmac_mc;
 	enum ocelot_vcap_bit dmac_bc;
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 3d65b99b9734..ffd2bb50cfc3 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -177,8 +177,8 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f,
 	if (!rule)
 		return NULL;
 
-	rule->port = &block->priv->port;
-	rule->chip_port = block->priv->chip_port;
+	rule->ocelot = block->priv->port.ocelot;
+	rule->ingress_port_mask = BIT(block->priv->chip_port);
 	return rule;
 }
 
@@ -213,7 +213,7 @@ static int ocelot_flower_destroy(struct flow_cls_offload *f,
 	int ret;
 
 	rule.prio = f->common.prio;
-	rule.port = &port_block->priv->port;
+	rule.ocelot = port_block->priv->port.ocelot;
 	rule.id = f->cookie;
 
 	ret = ocelot_ace_rule_offload_del(&rule);
@@ -231,7 +231,7 @@ static int ocelot_flower_stats_update(struct flow_cls_offload *f,
 	int ret;
 
 	rule.prio = f->common.prio;
-	rule.port = &port_block->priv->port;
+	rule.ocelot = port_block->priv->port.ocelot;
 	rule.id = f->cookie;
 	ret = ocelot_ace_rule_stats_update(&rule);
 	if (ret)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 02/10] net: mscc: ocelot: simplify tc-flower offload structures
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 01/10] net: mscc: ocelot: make ocelot_ace_rule support multiple ports Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 03/10] net: mscc: ocelot: replace "rule" and "ocelot_rule" variable names with "ace" Vladimir Oltean
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).

But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.

So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.

This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.

Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.

And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
---
Changes in v2:
None.

 drivers/net/ethernet/mscc/ocelot.c        |   1 -
 drivers/net/ethernet/mscc/ocelot_ace.c    |  81 +++++------
 drivers/net/ethernet/mscc/ocelot_ace.h    |  24 ++--
 drivers/net/ethernet/mscc/ocelot_flower.c | 155 ++++------------------
 drivers/net/ethernet/mscc/ocelot_tc.c     |  22 +--
 include/soc/mscc/ocelot.h                 |   7 +
 6 files changed, 75 insertions(+), 215 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 341092f9097c..2c307aa8bf3e 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -2503,7 +2503,6 @@ void ocelot_deinit(struct ocelot *ocelot)
 	cancel_delayed_work(&ocelot->stats_work);
 	destroy_workqueue(ocelot->stats_queue);
 	mutex_destroy(&ocelot->stats_lock);
-	ocelot_ace_deinit();
 	if (ocelot->ptp_clock)
 		ptp_clock_unregister(ocelot->ptp_clock);
 
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index 18670645d47f..375c7c6aa7d5 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -12,8 +12,6 @@
 
 #define OCELOT_POLICER_DISCARD 0x17f
 
-static struct ocelot_acl_block *acl_block;
-
 struct vcap_props {
 	const char *name; /* Symbolic name */
 	u16 tg_width; /* Type-group width (in bits) */
@@ -574,15 +572,15 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 	vcap_row_cmd(ocelot, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
 }
 
-static void is2_entry_get(struct ocelot_ace_rule *rule, int ix)
+static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
+			  int ix)
 {
-	struct ocelot *op = rule->ocelot;
 	struct vcap_data data;
 	int row = (ix / 2);
 	u32 cnt;
 
-	vcap_row_cmd(op, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
-	vcap_cache2action(op, &data);
+	vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
+	vcap_cache2action(ocelot, &data);
 	data.tg_sw = VCAP_TG_HALF;
 	is2_data_get(&data, ix);
 	cnt = vcap_data_get(data.counter, data.counter_offset,
@@ -641,25 +639,27 @@ ocelot_ace_rule_get_rule_index(struct ocelot_acl_block *block, int index)
 	return NULL;
 }
 
-int ocelot_ace_rule_offload_add(struct ocelot_ace_rule *rule)
+int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
+				struct ocelot_ace_rule *rule)
 {
+	struct ocelot_acl_block *block = &ocelot->acl_block;
 	struct ocelot_ace_rule *ace;
 	int i, index;
 
 	/* Add rule to the linked list */
-	ocelot_ace_rule_add(acl_block, rule);
+	ocelot_ace_rule_add(block, rule);
 
 	/* Get the index of the inserted rule */
-	index = ocelot_ace_rule_get_index_id(acl_block, rule);
+	index = ocelot_ace_rule_get_index_id(block, rule);
 
 	/* Move down the rules to make place for the new rule */
-	for (i = acl_block->count - 1; i > index; i--) {
-		ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-		is2_entry_set(rule->ocelot, i, ace);
+	for (i = block->count - 1; i > index; i--) {
+		ace = ocelot_ace_rule_get_rule_index(block, i);
+		is2_entry_set(ocelot, i, ace);
 	}
 
 	/* Now insert the new rule */
-	is2_entry_set(rule->ocelot, index, rule);
+	is2_entry_set(ocelot, index, rule);
 	return 0;
 }
 
@@ -680,8 +680,10 @@ static void ocelot_ace_rule_del(struct ocelot_acl_block *block,
 	block->count--;
 }
 
-int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule)
+int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
+				struct ocelot_ace_rule *rule)
 {
+	struct ocelot_acl_block *block = &ocelot->acl_block;
 	struct ocelot_ace_rule del_ace;
 	struct ocelot_ace_rule *ace;
 	int i, index;
@@ -689,59 +691,41 @@ int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule)
 	memset(&del_ace, 0, sizeof(del_ace));
 
 	/* Gets index of the rule */
-	index = ocelot_ace_rule_get_index_id(acl_block, rule);
+	index = ocelot_ace_rule_get_index_id(block, rule);
 
 	/* Delete rule */
-	ocelot_ace_rule_del(acl_block, rule);
+	ocelot_ace_rule_del(block, rule);
 
 	/* Move up all the blocks over the deleted rule */
-	for (i = index; i < acl_block->count; i++) {
-		ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-		is2_entry_set(rule->ocelot, i, ace);
+	for (i = index; i < block->count; i++) {
+		ace = ocelot_ace_rule_get_rule_index(block, i);
+		is2_entry_set(ocelot, i, ace);
 	}
 
 	/* Now delete the last rule, because it is duplicated */
-	is2_entry_set(rule->ocelot, acl_block->count, &del_ace);
+	is2_entry_set(ocelot, block->count, &del_ace);
 
 	return 0;
 }
 
-int ocelot_ace_rule_stats_update(struct ocelot_ace_rule *rule)
+int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
+				 struct ocelot_ace_rule *rule)
 {
+	struct ocelot_acl_block *block = &ocelot->acl_block;
 	struct ocelot_ace_rule *tmp;
 	int index;
 
-	index = ocelot_ace_rule_get_index_id(acl_block, rule);
-	is2_entry_get(rule, index);
+	index = ocelot_ace_rule_get_index_id(block, rule);
+	is2_entry_get(ocelot, rule, index);
 
 	/* After we get the result we need to clear the counters */
-	tmp = ocelot_ace_rule_get_rule_index(acl_block, index);
+	tmp = ocelot_ace_rule_get_rule_index(block, index);
 	tmp->stats.pkts = 0;
-	is2_entry_set(rule->ocelot, index, tmp);
+	is2_entry_set(ocelot, index, tmp);
 
 	return 0;
 }
 
-static struct ocelot_acl_block *ocelot_acl_block_create(struct ocelot *ocelot)
-{
-	struct ocelot_acl_block *block;
-
-	block = kzalloc(sizeof(*block), GFP_KERNEL);
-	if (!block)
-		return NULL;
-
-	INIT_LIST_HEAD(&block->rules);
-	block->count = 0;
-	block->ocelot = ocelot;
-
-	return block;
-}
-
-static void ocelot_acl_block_destroy(struct ocelot_acl_block *block)
-{
-	kfree(block);
-}
-
 int ocelot_ace_init(struct ocelot *ocelot)
 {
 	struct vcap_data data;
@@ -771,12 +755,7 @@ int ocelot_ace_init(struct ocelot *ocelot)
 	ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_CIR_STATE,
 			 OCELOT_POLICER_DISCARD);
 
-	acl_block = ocelot_acl_block_create(ocelot);
+	INIT_LIST_HEAD(&ocelot->acl_block.rules);
 
 	return 0;
 }
-
-void ocelot_ace_deinit(void)
-{
-	ocelot_acl_block_destroy(acl_block);
-}
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h
index 2927ac83741b..b9a5868e3f15 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -186,7 +186,6 @@ struct ocelot_ace_stats {
 
 struct ocelot_ace_rule {
 	struct list_head list;
-	struct ocelot *ocelot;
 
 	u16 prio;
 	u32 id;
@@ -211,22 +210,17 @@ struct ocelot_ace_rule {
 	} frame;
 };
 
-struct ocelot_acl_block {
-	struct list_head rules;
-	struct ocelot *ocelot;
-	int count;
-};
-
-int ocelot_ace_rule_offload_add(struct ocelot_ace_rule *rule);
-int ocelot_ace_rule_offload_del(struct ocelot_ace_rule *rule);
-int ocelot_ace_rule_stats_update(struct ocelot_ace_rule *rule);
+int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
+				struct ocelot_ace_rule *rule);
+int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
+				struct ocelot_ace_rule *rule);
+int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
+				 struct ocelot_ace_rule *rule);
 
 int ocelot_ace_init(struct ocelot *ocelot);
-void ocelot_ace_deinit(void);
 
-int ocelot_setup_tc_block_flower_bind(struct ocelot_port_private *priv,
-				      struct flow_block_offload *f);
-void ocelot_setup_tc_block_flower_unbind(struct ocelot_port_private *priv,
-					 struct flow_block_offload *f);
+int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
+			       struct flow_cls_offload *f,
+			       bool ingress);
 
 #endif /* _MSCC_OCELOT_ACE_H_ */
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index ffd2bb50cfc3..b9673df6dbc5 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -8,11 +8,6 @@
 
 #include "ocelot_ace.h"
 
-struct ocelot_port_block {
-	struct ocelot_acl_block *block;
-	struct ocelot_port_private *priv;
-};
-
 static int ocelot_flower_parse_action(struct flow_cls_offload *f,
 				      struct ocelot_ace_rule *rule)
 {
@@ -168,8 +163,8 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
 }
 
 static
-struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f,
-					       struct ocelot_port_block *block)
+struct ocelot_ace_rule *ocelot_ace_rule_create(struct ocelot *ocelot, int port,
+					       struct flow_cls_offload *f)
 {
 	struct ocelot_ace_rule *rule;
 
@@ -177,18 +172,17 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f,
 	if (!rule)
 		return NULL;
 
-	rule->ocelot = block->priv->port.ocelot;
-	rule->ingress_port_mask = BIT(block->priv->chip_port);
+	rule->ingress_port_mask = BIT(port);
 	return rule;
 }
 
-static int ocelot_flower_replace(struct flow_cls_offload *f,
-				 struct ocelot_port_block *port_block)
+int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
+			      struct flow_cls_offload *f, bool ingress)
 {
 	struct ocelot_ace_rule *rule;
 	int ret;
 
-	rule = ocelot_ace_rule_create(f, port_block);
+	rule = ocelot_ace_rule_create(ocelot, port, f);
 	if (!rule)
 		return -ENOMEM;
 
@@ -198,159 +192,66 @@ static int ocelot_flower_replace(struct flow_cls_offload *f,
 		return ret;
 	}
 
-	ret = ocelot_ace_rule_offload_add(rule);
+	ret = ocelot_ace_rule_offload_add(ocelot, rule);
 	if (ret)
 		return ret;
 
-	port_block->priv->tc.offload_cnt++;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
 
-static int ocelot_flower_destroy(struct flow_cls_offload *f,
-				 struct ocelot_port_block *port_block)
+int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
+			      struct flow_cls_offload *f, bool ingress)
 {
 	struct ocelot_ace_rule rule;
 	int ret;
 
 	rule.prio = f->common.prio;
-	rule.ocelot = port_block->priv->port.ocelot;
 	rule.id = f->cookie;
 
-	ret = ocelot_ace_rule_offload_del(&rule);
+	ret = ocelot_ace_rule_offload_del(ocelot, &rule);
 	if (ret)
 		return ret;
 
-	port_block->priv->tc.offload_cnt--;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);
 
-static int ocelot_flower_stats_update(struct flow_cls_offload *f,
-				      struct ocelot_port_block *port_block)
+int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
+			    struct flow_cls_offload *f, bool ingress)
 {
 	struct ocelot_ace_rule rule;
 	int ret;
 
 	rule.prio = f->common.prio;
-	rule.ocelot = port_block->priv->port.ocelot;
 	rule.id = f->cookie;
-	ret = ocelot_ace_rule_stats_update(&rule);
+	ret = ocelot_ace_rule_stats_update(ocelot, &rule);
 	if (ret)
 		return ret;
 
 	flow_stats_update(&f->stats, 0x0, rule.stats.pkts, 0x0);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats);
 
-static int ocelot_setup_tc_cls_flower(struct flow_cls_offload *f,
-				      struct ocelot_port_block *port_block)
+int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
+			       struct flow_cls_offload *f,
+			       bool ingress)
 {
+	struct ocelot *ocelot = priv->port.ocelot;
+	int port = priv->chip_port;
+
+	if (!ingress)
+		return -EOPNOTSUPP;
+
 	switch (f->command) {
 	case FLOW_CLS_REPLACE:
-		return ocelot_flower_replace(f, port_block);
+		return ocelot_cls_flower_replace(ocelot, port, f, ingress);
 	case FLOW_CLS_DESTROY:
-		return ocelot_flower_destroy(f, port_block);
+		return ocelot_cls_flower_destroy(ocelot, port, f, ingress);
 	case FLOW_CLS_STATS:
-		return ocelot_flower_stats_update(f, port_block);
+		return ocelot_cls_flower_stats(ocelot, port, f, ingress);
 	default:
 		return -EOPNOTSUPP;
 	}
 }
-
-static int ocelot_setup_tc_block_cb_flower(enum tc_setup_type type,
-					   void *type_data, void *cb_priv)
-{
-	struct ocelot_port_block *port_block = cb_priv;
-
-	if (!tc_cls_can_offload_and_chain0(port_block->priv->dev, type_data))
-		return -EOPNOTSUPP;
-
-	switch (type) {
-	case TC_SETUP_CLSFLOWER:
-		return ocelot_setup_tc_cls_flower(type_data, cb_priv);
-	case TC_SETUP_CLSMATCHALL:
-		return 0;
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
-static struct ocelot_port_block*
-ocelot_port_block_create(struct ocelot_port_private *priv)
-{
-	struct ocelot_port_block *port_block;
-
-	port_block = kzalloc(sizeof(*port_block), GFP_KERNEL);
-	if (!port_block)
-		return NULL;
-
-	port_block->priv = priv;
-
-	return port_block;
-}
-
-static void ocelot_port_block_destroy(struct ocelot_port_block *block)
-{
-	kfree(block);
-}
-
-static void ocelot_tc_block_unbind(void *cb_priv)
-{
-	struct ocelot_port_block *port_block = cb_priv;
-
-	ocelot_port_block_destroy(port_block);
-}
-
-int ocelot_setup_tc_block_flower_bind(struct ocelot_port_private *priv,
-				      struct flow_block_offload *f)
-{
-	struct ocelot_port_block *port_block;
-	struct flow_block_cb *block_cb;
-	int ret;
-
-	if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS)
-		return -EOPNOTSUPP;
-
-	block_cb = flow_block_cb_lookup(f->block,
-					ocelot_setup_tc_block_cb_flower, priv);
-	if (!block_cb) {
-		port_block = ocelot_port_block_create(priv);
-		if (!port_block)
-			return -ENOMEM;
-
-		block_cb = flow_block_cb_alloc(ocelot_setup_tc_block_cb_flower,
-					       priv, port_block,
-					       ocelot_tc_block_unbind);
-		if (IS_ERR(block_cb)) {
-			ret = PTR_ERR(block_cb);
-			goto err_cb_register;
-		}
-		flow_block_cb_add(block_cb, f);
-		list_add_tail(&block_cb->driver_list, f->driver_block_list);
-	} else {
-		port_block = flow_block_cb_priv(block_cb);
-	}
-
-	flow_block_cb_incref(block_cb);
-	return 0;
-
-err_cb_register:
-	ocelot_port_block_destroy(port_block);
-
-	return ret;
-}
-
-void ocelot_setup_tc_block_flower_unbind(struct ocelot_port_private *priv,
-					 struct flow_block_offload *f)
-{
-	struct flow_block_cb *block_cb;
-
-	block_cb = flow_block_cb_lookup(f->block,
-					ocelot_setup_tc_block_cb_flower, priv);
-	if (!block_cb)
-		return;
-
-	if (!flow_block_cb_decref(block_cb)) {
-		flow_block_cb_remove(block_cb, f);
-		list_del(&block_cb->driver_list);
-	}
-}
diff --git a/drivers/net/ethernet/mscc/ocelot_tc.c b/drivers/net/ethernet/mscc/ocelot_tc.c
index a4f7fbd76507..3ff5ef41eccf 100644
--- a/drivers/net/ethernet/mscc/ocelot_tc.c
+++ b/drivers/net/ethernet/mscc/ocelot_tc.c
@@ -20,9 +20,6 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
 	int port = priv->chip_port;
 	int err;
 
-	netdev_dbg(priv->dev, "%s: port %u command %d cookie %lu\n",
-		   __func__, port, f->command, f->cookie);
-
 	if (!ingress) {
 		NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported");
 		return -EOPNOTSUPP;
@@ -99,17 +96,10 @@ static int ocelot_setup_tc_block_cb(enum tc_setup_type type,
 
 	switch (type) {
 	case TC_SETUP_CLSMATCHALL:
-		netdev_dbg(priv->dev, "tc_block_cb: TC_SETUP_CLSMATCHALL %s\n",
-			   ingress ? "ingress" : "egress");
-
 		return ocelot_setup_tc_cls_matchall(priv, type_data, ingress);
 	case TC_SETUP_CLSFLOWER:
-		return 0;
+		return ocelot_setup_tc_cls_flower(priv, type_data, ingress);
 	default:
-		netdev_dbg(priv->dev, "tc_block_cb: type %d %s\n",
-			   type,
-			   ingress ? "ingress" : "egress");
-
 		return -EOPNOTSUPP;
 	}
 }
@@ -137,10 +127,6 @@ static int ocelot_setup_tc_block(struct ocelot_port_private *priv,
 {
 	struct flow_block_cb *block_cb;
 	flow_setup_cb_t *cb;
-	int err;
-
-	netdev_dbg(priv->dev, "tc_block command %d, binder_type %d\n",
-		   f->command, f->binder_type);
 
 	if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
 		cb = ocelot_setup_tc_block_cb_ig;
@@ -162,11 +148,6 @@ static int ocelot_setup_tc_block(struct ocelot_port_private *priv,
 		if (IS_ERR(block_cb))
 			return PTR_ERR(block_cb);
 
-		err = ocelot_setup_tc_block_flower_bind(priv, f);
-		if (err < 0) {
-			flow_block_cb_free(block_cb);
-			return err;
-		}
 		flow_block_cb_add(block_cb, f);
 		list_add_tail(&block_cb->driver_list, f->driver_block_list);
 		return 0;
@@ -175,7 +156,6 @@ static int ocelot_setup_tc_block(struct ocelot_port_private *priv,
 		if (!block_cb)
 			return -ENOENT;
 
-		ocelot_setup_tc_block_flower_unbind(priv, f);
 		flow_block_cb_remove(block_cb, f);
 		list_del(&block_cb->driver_list);
 		return 0;
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 745d3f46ca60..3d9e83e78c59 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -466,6 +466,11 @@ struct ocelot_ops {
 	int (*reset)(struct ocelot *ocelot);
 };
 
+struct ocelot_acl_block {
+	struct list_head rules;
+	int count;
+};
+
 struct ocelot_port {
 	struct ocelot			*ocelot;
 
@@ -514,6 +519,8 @@ struct ocelot {
 
 	struct list_head		multicast;
 
+	struct ocelot_acl_block		acl_block;
+
 	/* Workqueue to check statistics for overflow with its lock */
 	struct mutex			stats_lock;
 	u64				*stats;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 03/10] net: mscc: ocelot: replace "rule" and "ocelot_rule" variable names with "ace"
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 01/10] net: mscc: ocelot: make ocelot_ace_rule support multiple ports Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 02/10] net: mscc: ocelot: simplify tc-flower offload structures Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 04/10] net: mscc: ocelot: return directly in ocelot_cls_flower_{replace,destroy} Vladimir Oltean
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

The "ocelot_rule" variable name is both annoyingly long trying to
distinguish itself from struct flow_rule *rule =
flow_cls_offload_flow_rule(f), as well as actually different from the
"ace" variable name which is used all over the place in ocelot_ace.c and
is referring to the same structure.

And the "rule" variable name is, confusingly, different from f->rule,
but sometimes one has to look up to the beginning of the function to get
an understanding of what structure type is actually being handled.

So let's use the "ace" name wherever possible ("Access Control Entry").

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
---
Changes in v2:
None.

 drivers/net/ethernet/mscc/ocelot_flower.c | 102 +++++++++++-----------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index b9673df6dbc5..698e9fee6b1a 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -9,7 +9,7 @@
 #include "ocelot_ace.h"
 
 static int ocelot_flower_parse_action(struct flow_cls_offload *f,
-				      struct ocelot_ace_rule *rule)
+				      struct ocelot_ace_rule *ace)
 {
 	const struct flow_action_entry *a;
 	int i;
@@ -20,10 +20,10 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
 	flow_action_for_each(i, a, &f->rule->action) {
 		switch (a->id) {
 		case FLOW_ACTION_DROP:
-			rule->action = OCELOT_ACL_ACTION_DROP;
+			ace->action = OCELOT_ACL_ACTION_DROP;
 			break;
 		case FLOW_ACTION_TRAP:
-			rule->action = OCELOT_ACL_ACTION_TRAP;
+			ace->action = OCELOT_ACL_ACTION_TRAP;
 			break;
 		default:
 			return -EOPNOTSUPP;
@@ -34,7 +34,7 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
 }
 
 static int ocelot_flower_parse(struct flow_cls_offload *f,
-			       struct ocelot_ace_rule *ocelot_rule)
+			       struct ocelot_ace_rule *ace)
 {
 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
 	struct flow_dissector *dissector = rule->match.dissector;
@@ -79,14 +79,14 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
 			return -EOPNOTSUPP;
 
 		flow_rule_match_eth_addrs(rule, &match);
-		ocelot_rule->type = OCELOT_ACE_TYPE_ETYPE;
-		ether_addr_copy(ocelot_rule->frame.etype.dmac.value,
+		ace->type = OCELOT_ACE_TYPE_ETYPE;
+		ether_addr_copy(ace->frame.etype.dmac.value,
 				match.key->dst);
-		ether_addr_copy(ocelot_rule->frame.etype.smac.value,
+		ether_addr_copy(ace->frame.etype.smac.value,
 				match.key->src);
-		ether_addr_copy(ocelot_rule->frame.etype.dmac.mask,
+		ether_addr_copy(ace->frame.etype.dmac.mask,
 				match.mask->dst);
-		ether_addr_copy(ocelot_rule->frame.etype.smac.mask,
+		ether_addr_copy(ace->frame.etype.smac.mask,
 				match.mask->src);
 		goto finished_key_parsing;
 	}
@@ -96,17 +96,17 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
 
 		flow_rule_match_basic(rule, &match);
 		if (ntohs(match.key->n_proto) == ETH_P_IP) {
-			ocelot_rule->type = OCELOT_ACE_TYPE_IPV4;
-			ocelot_rule->frame.ipv4.proto.value[0] =
+			ace->type = OCELOT_ACE_TYPE_IPV4;
+			ace->frame.ipv4.proto.value[0] =
 				match.key->ip_proto;
-			ocelot_rule->frame.ipv4.proto.mask[0] =
+			ace->frame.ipv4.proto.mask[0] =
 				match.mask->ip_proto;
 		}
 		if (ntohs(match.key->n_proto) == ETH_P_IPV6) {
-			ocelot_rule->type = OCELOT_ACE_TYPE_IPV6;
-			ocelot_rule->frame.ipv6.proto.value[0] =
+			ace->type = OCELOT_ACE_TYPE_IPV6;
+			ace->frame.ipv6.proto.value[0] =
 				match.key->ip_proto;
-			ocelot_rule->frame.ipv6.proto.mask[0] =
+			ace->frame.ipv6.proto.mask[0] =
 				match.mask->ip_proto;
 		}
 	}
@@ -117,16 +117,16 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
 		u8 *tmp;
 
 		flow_rule_match_ipv4_addrs(rule, &match);
-		tmp = &ocelot_rule->frame.ipv4.sip.value.addr[0];
+		tmp = &ace->frame.ipv4.sip.value.addr[0];
 		memcpy(tmp, &match.key->src, 4);
 
-		tmp = &ocelot_rule->frame.ipv4.sip.mask.addr[0];
+		tmp = &ace->frame.ipv4.sip.mask.addr[0];
 		memcpy(tmp, &match.mask->src, 4);
 
-		tmp = &ocelot_rule->frame.ipv4.dip.value.addr[0];
+		tmp = &ace->frame.ipv4.dip.value.addr[0];
 		memcpy(tmp, &match.key->dst, 4);
 
-		tmp = &ocelot_rule->frame.ipv4.dip.mask.addr[0];
+		tmp = &ace->frame.ipv4.dip.mask.addr[0];
 		memcpy(tmp, &match.mask->dst, 4);
 	}
 
@@ -139,60 +139,60 @@ static int ocelot_flower_parse(struct flow_cls_offload *f,
 		struct flow_match_ports match;
 
 		flow_rule_match_ports(rule, &match);
-		ocelot_rule->frame.ipv4.sport.value = ntohs(match.key->src);
-		ocelot_rule->frame.ipv4.sport.mask = ntohs(match.mask->src);
-		ocelot_rule->frame.ipv4.dport.value = ntohs(match.key->dst);
-		ocelot_rule->frame.ipv4.dport.mask = ntohs(match.mask->dst);
+		ace->frame.ipv4.sport.value = ntohs(match.key->src);
+		ace->frame.ipv4.sport.mask = ntohs(match.mask->src);
+		ace->frame.ipv4.dport.value = ntohs(match.key->dst);
+		ace->frame.ipv4.dport.mask = ntohs(match.mask->dst);
 	}
 
 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
 		struct flow_match_vlan match;
 
 		flow_rule_match_vlan(rule, &match);
-		ocelot_rule->type = OCELOT_ACE_TYPE_ANY;
-		ocelot_rule->vlan.vid.value = match.key->vlan_id;
-		ocelot_rule->vlan.vid.mask = match.mask->vlan_id;
-		ocelot_rule->vlan.pcp.value[0] = match.key->vlan_priority;
-		ocelot_rule->vlan.pcp.mask[0] = match.mask->vlan_priority;
+		ace->type = OCELOT_ACE_TYPE_ANY;
+		ace->vlan.vid.value = match.key->vlan_id;
+		ace->vlan.vid.mask = match.mask->vlan_id;
+		ace->vlan.pcp.value[0] = match.key->vlan_priority;
+		ace->vlan.pcp.mask[0] = match.mask->vlan_priority;
 	}
 
 finished_key_parsing:
-	ocelot_rule->prio = f->common.prio;
-	ocelot_rule->id = f->cookie;
-	return ocelot_flower_parse_action(f, ocelot_rule);
+	ace->prio = f->common.prio;
+	ace->id = f->cookie;
+	return ocelot_flower_parse_action(f, ace);
 }
 
 static
 struct ocelot_ace_rule *ocelot_ace_rule_create(struct ocelot *ocelot, int port,
 					       struct flow_cls_offload *f)
 {
-	struct ocelot_ace_rule *rule;
+	struct ocelot_ace_rule *ace;
 
-	rule = kzalloc(sizeof(*rule), GFP_KERNEL);
-	if (!rule)
+	ace = kzalloc(sizeof(*ace), GFP_KERNEL);
+	if (!ace)
 		return NULL;
 
-	rule->ingress_port_mask = BIT(port);
-	return rule;
+	ace->ingress_port_mask = BIT(port);
+	return ace;
 }
 
 int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
 			      struct flow_cls_offload *f, bool ingress)
 {
-	struct ocelot_ace_rule *rule;
+	struct ocelot_ace_rule *ace;
 	int ret;
 
-	rule = ocelot_ace_rule_create(ocelot, port, f);
-	if (!rule)
+	ace = ocelot_ace_rule_create(ocelot, port, f);
+	if (!ace)
 		return -ENOMEM;
 
-	ret = ocelot_flower_parse(f, rule);
+	ret = ocelot_flower_parse(f, ace);
 	if (ret) {
-		kfree(rule);
+		kfree(ace);
 		return ret;
 	}
 
-	ret = ocelot_ace_rule_offload_add(ocelot, rule);
+	ret = ocelot_ace_rule_offload_add(ocelot, ace);
 	if (ret)
 		return ret;
 
@@ -203,13 +203,13 @@ EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
 int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
 			      struct flow_cls_offload *f, bool ingress)
 {
-	struct ocelot_ace_rule rule;
+	struct ocelot_ace_rule ace;
 	int ret;
 
-	rule.prio = f->common.prio;
-	rule.id = f->cookie;
+	ace.prio = f->common.prio;
+	ace.id = f->cookie;
 
-	ret = ocelot_ace_rule_offload_del(ocelot, &rule);
+	ret = ocelot_ace_rule_offload_del(ocelot, &ace);
 	if (ret)
 		return ret;
 
@@ -220,16 +220,16 @@ EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);
 int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
 			    struct flow_cls_offload *f, bool ingress)
 {
-	struct ocelot_ace_rule rule;
+	struct ocelot_ace_rule ace;
 	int ret;
 
-	rule.prio = f->common.prio;
-	rule.id = f->cookie;
-	ret = ocelot_ace_rule_stats_update(ocelot, &rule);
+	ace.prio = f->common.prio;
+	ace.id = f->cookie;
+	ret = ocelot_ace_rule_stats_update(ocelot, &ace);
 	if (ret)
 		return ret;
 
-	flow_stats_update(&f->stats, 0x0, rule.stats.pkts, 0x0);
+	flow_stats_update(&f->stats, 0x0, ace.stats.pkts, 0x0);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 04/10] net: mscc: ocelot: return directly in ocelot_cls_flower_{replace,destroy}
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (2 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 03/10] net: mscc: ocelot: replace "rule" and "ocelot_rule" variable names with "ace" Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 05/10] net: mscc: ocelot: spell out full "ocelot" name instead of "oc" Vladimir Oltean
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

There is no need to check the "ret" variable, one can just return the
function result back to the caller.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
---
Changes in v2:
None.

 drivers/net/ethernet/mscc/ocelot_flower.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 698e9fee6b1a..8993dadf063c 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -192,11 +192,7 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
 		return ret;
 	}
 
-	ret = ocelot_ace_rule_offload_add(ocelot, ace);
-	if (ret)
-		return ret;
-
-	return 0;
+	return ocelot_ace_rule_offload_add(ocelot, ace);
 }
 EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
 
@@ -204,16 +200,11 @@ int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
 			      struct flow_cls_offload *f, bool ingress)
 {
 	struct ocelot_ace_rule ace;
-	int ret;
 
 	ace.prio = f->common.prio;
 	ace.id = f->cookie;
 
-	ret = ocelot_ace_rule_offload_del(ocelot, &ace);
-	if (ret)
-		return ret;
-
-	return 0;
+	return ocelot_ace_rule_offload_del(ocelot, &ace);
 }
 EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 05/10] net: mscc: ocelot: spell out full "ocelot" name instead of "oc"
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (3 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 04/10] net: mscc: ocelot: return directly in ocelot_cls_flower_{replace,destroy} Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-03-05  7:09   ` Allan W. Nielsen
  2020-02-29 14:31 ` [PATCH v2 net-next 06/10] net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing Vladimir Oltean
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

This is a cosmetic patch that makes the name of the driver private
variable be used uniformly in ocelot_ace.c as in the rest of the driver.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v2:
Patch is new.

 drivers/net/ethernet/mscc/ocelot_ace.c | 45 ++++++++++++++------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index 375c7c6aa7d5..ec86d29d8be4 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -93,12 +93,12 @@ struct vcap_data {
 	u32 tg_mask; /* Current type-group mask */
 };
 
-static u32 vcap_s2_read_update_ctrl(struct ocelot *oc)
+static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot)
 {
-	return ocelot_read(oc, S2_CORE_UPDATE_CTRL);
+	return ocelot_read(ocelot, S2_CORE_UPDATE_CTRL);
 }
 
-static void vcap_cmd(struct ocelot *oc, u16 ix, int cmd, int sel)
+static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
 {
 	u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
 		     S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
@@ -116,42 +116,42 @@ static void vcap_cmd(struct ocelot *oc, u16 ix, int cmd, int sel)
 	if (!(sel & VCAP_SEL_COUNTER))
 		value |= S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS;
 
-	ocelot_write(oc, value, S2_CORE_UPDATE_CTRL);
-	readx_poll_timeout(vcap_s2_read_update_ctrl, oc, value,
+	ocelot_write(ocelot, value, S2_CORE_UPDATE_CTRL);
+	readx_poll_timeout(vcap_s2_read_update_ctrl, ocelot, value,
 				(value & S2_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0,
 				10, 100000);
 }
 
 /* Convert from 0-based row to VCAP entry row and run command */
-static void vcap_row_cmd(struct ocelot *oc, u32 row, int cmd, int sel)
+static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel)
 {
-	vcap_cmd(oc, vcap_is2.entry_count - row - 1, cmd, sel);
+	vcap_cmd(ocelot, vcap_is2.entry_count - row - 1, cmd, sel);
 }
 
-static void vcap_entry2cache(struct ocelot *oc, struct vcap_data *data)
+static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
 {
 	u32 i;
 
 	for (i = 0; i < vcap_is2.entry_words; i++) {
-		ocelot_write_rix(oc, data->entry[i], S2_CACHE_ENTRY_DAT, i);
-		ocelot_write_rix(oc, ~data->mask[i], S2_CACHE_MASK_DAT, i);
+		ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i);
+		ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i);
 	}
-	ocelot_write(oc, data->tg, S2_CACHE_TG_DAT);
+	ocelot_write(ocelot, data->tg, S2_CACHE_TG_DAT);
 }
 
-static void vcap_cache2entry(struct ocelot *oc, struct vcap_data *data)
+static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
 {
 	u32 i;
 
 	for (i = 0; i < vcap_is2.entry_words; i++) {
-		data->entry[i] = ocelot_read_rix(oc, S2_CACHE_ENTRY_DAT, i);
+		data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i);
 		// Invert mask
-		data->mask[i] = ~ocelot_read_rix(oc, S2_CACHE_MASK_DAT, i);
+		data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i);
 	}
-	data->tg = ocelot_read(oc, S2_CACHE_TG_DAT);
+	data->tg = ocelot_read(ocelot, S2_CACHE_TG_DAT);
 }
 
-static void vcap_action2cache(struct ocelot *oc, struct vcap_data *data)
+static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
 {
 	u32 i, width, mask;
 
@@ -163,21 +163,24 @@ static void vcap_action2cache(struct ocelot *oc, struct vcap_data *data)
 	}
 
 	for (i = 0; i < vcap_is2.action_words; i++)
-		ocelot_write_rix(oc, data->action[i], S2_CACHE_ACTION_DAT, i);
+		ocelot_write_rix(ocelot, data->action[i],
+				 S2_CACHE_ACTION_DAT, i);
 
 	for (i = 0; i < vcap_is2.counter_words; i++)
-		ocelot_write_rix(oc, data->counter[i], S2_CACHE_CNT_DAT, i);
+		ocelot_write_rix(ocelot, data->counter[i],
+				 S2_CACHE_CNT_DAT, i);
 }
 
-static void vcap_cache2action(struct ocelot *oc, struct vcap_data *data)
+static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
 {
 	u32 i, width;
 
 	for (i = 0; i < vcap_is2.action_words; i++)
-		data->action[i] = ocelot_read_rix(oc, S2_CACHE_ACTION_DAT, i);
+		data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT,
+						  i);
 
 	for (i = 0; i < vcap_is2.counter_words; i++)
-		data->counter[i] = ocelot_read_rix(oc, S2_CACHE_CNT_DAT, i);
+		data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i);
 
 	/* Extract action type */
 	width = vcap_is2.action_type_width;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 06/10] net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (4 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 05/10] net: mscc: ocelot: spell out full "ocelot" name instead of "oc" Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-03-05  7:15   ` Allan W. Nielsen
  2020-02-29 14:31 ` [PATCH v2 net-next 07/10] net: mscc: ocelot: remove port_pcs_init indirection for VSC7514 Vladimir Oltean
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

The IGR_PORT_MASK key width is different between the 11-port VSC7514 and
the 6-port VSC9959 switches. And since IGR_PORT_MASK is one of the first
fields of a VCAP key entry, it means that all further field
offset/length pairs are shifted between the 2.

The ocelot driver performs packing of VCAP half keys with the help of
some preprocessor macros:

- A set of macros for defining the HKO (Half Key Offset) and HKL (Half
  Key Length) of each possible key field. The offset of each field is
  defined as the sum between the offset and the sum of the previous
  field.

- A set of accessors on top of vcap_key_set for shorter (aka less
  typing) access to the HKO and HKL of each key field.

Since the field offsets and lengths are different between switches,
defining them through the preprocessor isn't going to fly. So introduce
a structure holding (offset, length) pairs and instantiate it in
ocelot_board.c for VSC7514. In a future patch, a similar structure will
be instantiated in felix_vsc9959.c for NXP LS1028A.

The accessors also need to go. They are based on macro name
concatenation, which is horrible to understand and follow.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
Changes in v2:
Added "struct ocelot *ocelot" as argument to all functions that need to
pack VCAP key fields, to avoid passing the ocelot backpointer to struct
vcap_data and cause difficult-to-solve reverse Christmas tree line
ordering issues.

 drivers/net/ethernet/mscc/ocelot_ace.c   | 315 +++++++++++-------
 drivers/net/ethernet/mscc/ocelot_board.c | 102 ++++++
 drivers/net/ethernet/mscc/ocelot_vcap.h  | 403 -----------------------
 include/soc/mscc/ocelot.h                |   3 +
 include/soc/mscc/ocelot_vcap.h           | 184 +++++++++++
 5 files changed, 484 insertions(+), 523 deletions(-)
 delete mode 100644 drivers/net/ethernet/mscc/ocelot_vcap.h
 create mode 100644 include/soc/mscc/ocelot_vcap.h

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index ec86d29d8be4..9922033a2aaf 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -6,8 +6,8 @@
 #include <linux/iopoll.h>
 #include <linux/proc_fs.h>
 
+#include <soc/mscc/ocelot_vcap.h>
 #include "ocelot_ace.h"
-#include "ocelot_vcap.h"
 #include "ocelot_s2.h"
 
 #define OCELOT_POLICER_DISCARD 0x17f
@@ -47,7 +47,7 @@ static const struct vcap_props vcap_is2 = {
 	.action_type_width = 1,
 	.action_table = {
 		{
-			.width = (IS2_AO_ACL_ID + IS2_AL_ACL_ID),
+			.width = 49,
 			.count = 2
 		},
 		{
@@ -243,22 +243,39 @@ static u32 vcap_data_get(u32 *data, u32 offset, u32 len)
 	return value;
 }
 
-static void vcap_key_set(struct vcap_data *data, u32 offset, u32 width,
-			 u32 value, u32 mask)
+static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
+			       u32 value, u32 mask)
 {
 	vcap_data_set(data->entry, offset + data->key_offset, width, value);
 	vcap_data_set(data->mask, offset + data->key_offset, width, mask);
 }
 
-static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val,
-			       u8 *msk, u32 count)
+static void vcap_key_set(struct ocelot *ocelot, struct vcap_data *data,
+			 enum vcap_is2_half_key_field field,
+			 u32 value, u32 mask)
+{
+	u32 offset = ocelot->vcap_is2_keys[field].offset;
+	u32 length = ocelot->vcap_is2_keys[field].length;
+
+	vcap_key_field_set(data, offset, length, value, mask);
+}
+
+static void vcap_key_bytes_set(struct ocelot *ocelot, struct vcap_data *data,
+			       enum vcap_is2_half_key_field field,
+			       u8 *val, u8 *msk)
 {
+	u32 offset = ocelot->vcap_is2_keys[field].offset;
+	u32 count  = ocelot->vcap_is2_keys[field].length;
 	u32 i, j, n = 0, value = 0, mask = 0;
 
+	WARN_ON(count % 8);
+
 	/* Data wider than 32 bits are split up in chunks of maximum 32 bits.
 	 * The 32 LSB of the data are written to the 32 MSB of the TCAM.
 	 */
-	offset += (count * 8);
+	offset += count;
+	count /= 8;
+
 	for (i = 0; i < count; i++) {
 		j = (count - i - 1);
 		value += (val[j] << n);
@@ -266,7 +283,7 @@ static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val,
 		n += 8;
 		if (n == ENTRY_WIDTH || (i + 1) == count) {
 			offset -= n;
-			vcap_key_set(data, offset, n, value, mask);
+			vcap_key_field_set(data, offset, n, value, mask);
 			n = 0;
 			value = 0;
 			mask = 0;
@@ -274,55 +291,62 @@ static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val,
 	}
 }
 
-static void vcap_key_l4_port_set(struct vcap_data *data, u32 offset,
+static void vcap_key_l4_port_set(struct ocelot *ocelot, struct vcap_data *data,
+				 enum vcap_is2_half_key_field field,
 				 struct ocelot_vcap_udp_tcp *port)
 {
-	vcap_key_set(data, offset, 16, port->value, port->mask);
+	u32 offset = ocelot->vcap_is2_keys[field].offset;
+	u32 length = ocelot->vcap_is2_keys[field].length;
+
+	WARN_ON(length != 16);
+
+	vcap_key_field_set(data, offset, length, port->value, port->mask);
 }
 
-static void vcap_key_bit_set(struct vcap_data *data, u32 offset,
+static void vcap_key_bit_set(struct ocelot *ocelot, struct vcap_data *data,
+			     enum vcap_is2_half_key_field field,
 			     enum ocelot_vcap_bit val)
 {
-	vcap_key_set(data, offset, 1, val == OCELOT_VCAP_BIT_1 ? 1 : 0,
-		     val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
-}
+	u32 offset = ocelot->vcap_is2_keys[field].offset;
+	u32 length = ocelot->vcap_is2_keys[field].length;
+	u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0);
+	u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
 
-#define VCAP_KEY_SET(fld, val, msk) \
-	vcap_key_set(&data, IS2_HKO_##fld, IS2_HKL_##fld, val, msk)
-#define VCAP_KEY_ANY_SET(fld) \
-	vcap_key_set(&data, IS2_HKO_##fld, IS2_HKL_##fld, 0, 0)
-#define VCAP_KEY_BIT_SET(fld, val) vcap_key_bit_set(&data, IS2_HKO_##fld, val)
-#define VCAP_KEY_BYTES_SET(fld, val, msk) \
-	vcap_key_bytes_set(&data, IS2_HKO_##fld, val, msk, IS2_HKL_##fld / 8)
+	WARN_ON(length != 1);
 
-static void vcap_action_set(struct vcap_data *data, u32 offset, u32 width,
-			    u32 value)
-{
-	vcap_data_set(data->action, offset + data->action_offset, width, value);
+	vcap_key_field_set(data, offset, length, value, msk);
 }
 
-#define VCAP_ACT_SET(fld, val) \
-	vcap_action_set(data, IS2_AO_##fld, IS2_AL_##fld, val)
+static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data,
+			    enum vcap_is2_action_field field, u32 value)
+{
+	int offset = ocelot->vcap_is2_actions[field].offset;
+	int length = ocelot->vcap_is2_actions[field].length;
+
+	vcap_data_set(data->action, offset + data->action_offset, length,
+		      value);
+}
 
-static void is2_action_set(struct vcap_data *data,
+static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
 			   enum ocelot_ace_action action)
 {
 	switch (action) {
 	case OCELOT_ACL_ACTION_DROP:
-		VCAP_ACT_SET(PORT_MASK, 0x0);
-		VCAP_ACT_SET(MASK_MODE, 0x1);
-		VCAP_ACT_SET(POLICE_ENA, 0x1);
-		VCAP_ACT_SET(POLICE_IDX, OCELOT_POLICER_DISCARD);
-		VCAP_ACT_SET(CPU_QU_NUM, 0x0);
-		VCAP_ACT_SET(CPU_COPY_ENA, 0x0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX,
+				OCELOT_POLICER_DISCARD);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
 		break;
 	case OCELOT_ACL_ACTION_TRAP:
-		VCAP_ACT_SET(PORT_MASK, 0x0);
-		VCAP_ACT_SET(MASK_MODE, 0x1);
-		VCAP_ACT_SET(POLICE_ENA, 0x0);
-		VCAP_ACT_SET(POLICE_IDX, 0x0);
-		VCAP_ACT_SET(CPU_QU_NUM, 0x0);
-		VCAP_ACT_SET(CPU_COPY_ENA, 0x1);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, 0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
+		vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1);
 		break;
 	}
 }
@@ -352,53 +376,69 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 
 	data.type = IS2_ACTION_TYPE_NORMAL;
 
-	VCAP_KEY_ANY_SET(PAG);
-	VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port_mask);
-	VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1);
-	VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY);
-	VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc);
-	VCAP_KEY_BIT_SET(L2_BC, ace->dmac_bc);
-	VCAP_KEY_BIT_SET(VLAN_TAGGED, tag->tagged);
-	VCAP_KEY_SET(VID, tag->vid.value, tag->vid.mask);
-	VCAP_KEY_SET(PCP, tag->pcp.value[0], tag->pcp.mask[0]);
-	VCAP_KEY_BIT_SET(DEI, tag->dei);
+	vcap_key_set(ocelot, &data, VCAP_IS2_HK_PAG, 0, 0);
+	vcap_key_set(ocelot, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
+		     ~ace->ingress_port_mask);
+	vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_1);
+	vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_HOST_MATCH,
+			 OCELOT_VCAP_BIT_ANY);
+	vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc);
+	vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc);
+	vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
+	vcap_key_set(ocelot, &data, VCAP_IS2_HK_VID,
+		     tag->vid.value, tag->vid.mask);
+	vcap_key_set(ocelot, &data, VCAP_IS2_HK_PCP,
+		     tag->pcp.value[0], tag->pcp.mask[0]);
+	vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DEI, tag->dei);
 
 	switch (ace->type) {
 	case OCELOT_ACE_TYPE_ETYPE: {
 		struct ocelot_ace_frame_etype *etype = &ace->frame.etype;
 
 		type = IS2_TYPE_ETYPE;
-		VCAP_KEY_BYTES_SET(L2_DMAC, etype->dmac.value,
-				   etype->dmac.mask);
-		VCAP_KEY_BYTES_SET(L2_SMAC, etype->smac.value,
-				   etype->smac.mask);
-		VCAP_KEY_BYTES_SET(MAC_ETYPE_ETYPE, etype->etype.value,
-				   etype->etype.mask);
-		VCAP_KEY_ANY_SET(MAC_ETYPE_L2_PAYLOAD); // Clear unused bits
-		vcap_key_bytes_set(&data, IS2_HKO_MAC_ETYPE_L2_PAYLOAD,
-				   etype->data.value, etype->data.mask, 2);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
+				   etype->dmac.value, etype->dmac.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
+				   etype->smac.value, etype->smac.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE,
+				   etype->etype.value, etype->etype.mask);
+		/* Clear unused bits */
+		vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
+			     0, 0);
+		vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
+			     0, 0);
+		vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
+			     0, 0);
+		vcap_key_bytes_set(ocelot, &data,
+				   VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
+				   etype->data.value, etype->data.mask);
 		break;
 	}
 	case OCELOT_ACE_TYPE_LLC: {
 		struct ocelot_ace_frame_llc *llc = &ace->frame.llc;
 
 		type = IS2_TYPE_LLC;
-		VCAP_KEY_BYTES_SET(L2_DMAC, llc->dmac.value, llc->dmac.mask);
-		VCAP_KEY_BYTES_SET(L2_SMAC, llc->smac.value, llc->smac.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
+				   llc->dmac.value, llc->dmac.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
+				   llc->smac.value, llc->smac.mask);
 		for (i = 0; i < 4; i++) {
 			payload.value[i] = llc->llc.value[i];
 			payload.mask[i] = llc->llc.mask[i];
 		}
-		VCAP_KEY_BYTES_SET(MAC_LLC_L2_LLC, payload.value, payload.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC,
+				   payload.value, payload.mask);
 		break;
 	}
 	case OCELOT_ACE_TYPE_SNAP: {
 		struct ocelot_ace_frame_snap *snap = &ace->frame.snap;
 
 		type = IS2_TYPE_SNAP;
-		VCAP_KEY_BYTES_SET(L2_DMAC, snap->dmac.value, snap->dmac.mask);
-		VCAP_KEY_BYTES_SET(L2_SMAC, snap->smac.value, snap->smac.mask);
-		VCAP_KEY_BYTES_SET(MAC_SNAP_L2_SNAP,
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
+				   snap->dmac.value, snap->dmac.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
+				   snap->smac.value, snap->smac.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
 				   ace->frame.snap.snap.value,
 				   ace->frame.snap.snap.mask);
 		break;
@@ -407,26 +447,42 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 		struct ocelot_ace_frame_arp *arp = &ace->frame.arp;
 
 		type = IS2_TYPE_ARP;
-		VCAP_KEY_BYTES_SET(MAC_ARP_L2_SMAC, arp->smac.value,
-				   arp->smac.mask);
-		VCAP_KEY_BIT_SET(MAC_ARP_ARP_ADDR_SPACE_OK, arp->ethernet);
-		VCAP_KEY_BIT_SET(MAC_ARP_ARP_PROTO_SPACE_OK, arp->ip);
-		VCAP_KEY_BIT_SET(MAC_ARP_ARP_LEN_OK, arp->length);
-		VCAP_KEY_BIT_SET(MAC_ARP_ARP_TGT_MATCH, arp->dmac_match);
-		VCAP_KEY_BIT_SET(MAC_ARP_ARP_SENDER_MATCH, arp->smac_match);
-		VCAP_KEY_BIT_SET(MAC_ARP_ARP_OPCODE_UNKNOWN, arp->unknown);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
+				   arp->smac.value, arp->smac.mask);
+		vcap_key_bit_set(ocelot, &data,
+				 VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
+				 arp->ethernet);
+		vcap_key_bit_set(ocelot, &data,
+				 VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
+				 arp->ip);
+		vcap_key_bit_set(ocelot, &data,
+				 VCAP_IS2_HK_MAC_ARP_LEN_OK,
+				 arp->length);
+		vcap_key_bit_set(ocelot, &data,
+				 VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
+				 arp->dmac_match);
+		vcap_key_bit_set(ocelot, &data,
+				 VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
+				 arp->smac_match);
+		vcap_key_bit_set(ocelot, &data,
+				 VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
+				 arp->unknown);
 
 		/* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */
 		val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) |
 		       (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0));
 		msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) |
 		       (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2));
-		VCAP_KEY_SET(MAC_ARP_ARP_OPCODE, val, msk);
-		vcap_key_bytes_set(&data, IS2_HKO_MAC_ARP_L3_IP4_DIP,
-				   arp->dip.value.addr, arp->dip.mask.addr, 4);
-		vcap_key_bytes_set(&data, IS2_HKO_MAC_ARP_L3_IP4_SIP,
-				   arp->sip.value.addr, arp->sip.mask.addr, 4);
-		VCAP_KEY_ANY_SET(MAC_ARP_DIP_EQ_SIP);
+		vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_OPCODE,
+			     val, msk);
+		vcap_key_bytes_set(ocelot, &data,
+				   VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
+				   arp->dip.value.addr, arp->dip.mask.addr);
+		vcap_key_bytes_set(ocelot, &data,
+				   VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
+				   arp->sip.value.addr, arp->sip.mask.addr);
+		vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
+			     0, 0);
 		break;
 	}
 	case OCELOT_ACE_TYPE_IPV4:
@@ -494,18 +550,23 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 			seq_zero = ipv6->seq_zero;
 		}
 
-		VCAP_KEY_BIT_SET(IP4,
+		vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4,
 				 ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
-		VCAP_KEY_BIT_SET(L3_FRAGMENT, fragment);
-		VCAP_KEY_ANY_SET(L3_FRAG_OFS_GT0);
-		VCAP_KEY_BIT_SET(L3_OPTIONS, options);
-		VCAP_KEY_BIT_SET(L3_TTL_GT0, ttl);
-		VCAP_KEY_BYTES_SET(L3_TOS, ds.value, ds.mask);
-		vcap_key_bytes_set(&data, IS2_HKO_L3_IP4_DIP, dip.value.addr,
-				   dip.mask.addr, 4);
-		vcap_key_bytes_set(&data, IS2_HKO_L3_IP4_SIP, sip.value.addr,
-				   sip.mask.addr, 4);
-		VCAP_KEY_BIT_SET(DIP_EQ_SIP, sip_eq_dip);
+		vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_FRAGMENT,
+				 fragment);
+		vcap_key_set(ocelot, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0);
+		vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_OPTIONS,
+				 options);
+		vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0,
+				 ttl);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_TOS,
+				   ds.value, ds.mask);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_DIP,
+				   dip.value.addr, dip.mask.addr);
+		vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_SIP,
+				   sip.value.addr, sip.mask.addr);
+		vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DIP_EQ_SIP,
+				 sip_eq_dip);
 		val = proto.value[0];
 		msk = proto.mask[0];
 		type = IS2_TYPE_IP_UDP_TCP;
@@ -513,25 +574,34 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 			/* UDP/TCP protocol match */
 			tcp = (val == 6 ?
 			       OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_TCP, tcp);
-			vcap_key_l4_port_set(&data,
-					     IS2_HKO_IP4_TCP_UDP_L4_DPORT,
-					     dport);
-			vcap_key_l4_port_set(&data,
-					     IS2_HKO_IP4_TCP_UDP_L4_SPORT,
-					     sport);
-			VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_RNG);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_SPORT_EQ_DPORT,
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_TCP, tcp);
+			vcap_key_l4_port_set(ocelot, &data,
+					     VCAP_IS2_HK_L4_DPORT, dport);
+			vcap_key_l4_port_set(ocelot, &data,
+					     VCAP_IS2_HK_L4_SPORT, sport);
+			vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_RNG, 0, 0);
+			vcap_key_bit_set(ocelot, &data,
+					 VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
 					 sport_eq_dport);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_SEQUENCE_EQ0, seq_zero);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_FIN, tcp_fin);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_SYN, tcp_syn);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_RST, tcp_rst);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_PSH, tcp_psh);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_ACK, tcp_ack);
-			VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_URG, tcp_urg);
-			VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_1588_DOM);
-			VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_1588_VER);
+			vcap_key_bit_set(ocelot, &data,
+					 VCAP_IS2_HK_L4_SEQUENCE_EQ0,
+					 seq_zero);
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_FIN,
+					 tcp_fin);
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_SYN,
+					 tcp_syn);
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_RST,
+					 tcp_rst);
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_PSH,
+					 tcp_psh);
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_ACK,
+					 tcp_ack);
+			vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_URG,
+					 tcp_urg);
+			vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_DOM,
+				     0, 0);
+			vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_VER,
+				     0, 0);
 		} else {
 			if (msk == 0) {
 				/* Any IP protocol match */
@@ -544,10 +614,12 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 					payload.mask[i] = ip_data->mask[i];
 				}
 			}
-			VCAP_KEY_BYTES_SET(IP4_OTHER_L3_PROTO, proto.value,
-					   proto.mask);
-			VCAP_KEY_BYTES_SET(IP4_OTHER_L3_PAYLOAD, payload.value,
-					   payload.mask);
+			vcap_key_bytes_set(ocelot, &data,
+					   VCAP_IS2_HK_IP4_L3_PROTO,
+					   proto.value, proto.mask);
+			vcap_key_bytes_set(ocelot, &data,
+					   VCAP_IS2_HK_L3_PAYLOAD,
+					   payload.value, payload.mask);
 		}
 		break;
 	}
@@ -556,18 +628,20 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 		type = 0;
 		type_mask = 0;
 		count = (vcap_is2.entry_width / 2);
-		for (i = (IS2_HKO_PCP + IS2_HKL_PCP); i < count;
-		     i += ENTRY_WIDTH) {
-			/* Clear entry data */
-			vcap_key_set(&data, i, min(32u, count - i), 0, 0);
+		/* Iterate over the non-common part of the key and
+		 * clear entry data
+		 */
+		for (i = ocelot->vcap_is2_keys[VCAP_IS2_HK_L2_DMAC].offset;
+		     i < count; i += ENTRY_WIDTH) {
+			vcap_key_field_set(&data, i, min(32u, count - i), 0, 0);
 		}
 		break;
 	}
 
-	VCAP_KEY_SET(TYPE, type, type_mask);
-	is2_action_set(&data, ace->action);
-	vcap_data_set(data.counter, data.counter_offset, vcap_is2.counter_width,
-		      ace->stats.pkts);
+	vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
+	is2_action_set(ocelot, &data, ace->action);
+	vcap_data_set(data.counter, data.counter_offset,
+		      vcap_is2.counter_width, ace->stats.pkts);
 
 	/* Write row */
 	vcap_entry2cache(ocelot, &data);
@@ -734,6 +808,7 @@ int ocelot_ace_init(struct ocelot *ocelot)
 	struct vcap_data data;
 
 	memset(&data, 0, sizeof(data));
+
 	vcap_entry2cache(ocelot, &data);
 	ocelot_write(ocelot, vcap_is2.entry_count, S2_CORE_MV_CFG);
 	vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index 7c3dae87d505..2f52d2866c9d 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -14,6 +14,7 @@
 #include <linux/skbuff.h>
 #include <net/switchdev.h>
 
+#include <soc/mscc/ocelot_vcap.h>
 #include "ocelot.h"
 
 #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
@@ -262,6 +263,104 @@ static const struct ocelot_ops ocelot_ops = {
 	.reset			= ocelot_reset,
 };
 
+static const struct vcap_field vsc7514_vcap_is2_keys[] = {
+	/* Common: 46 bits */
+	[VCAP_IS2_TYPE]				= {  0,   4},
+	[VCAP_IS2_HK_FIRST]			= {  4,   1},
+	[VCAP_IS2_HK_PAG]			= {  5,   8},
+	[VCAP_IS2_HK_IGR_PORT_MASK]		= { 13,  12},
+	[VCAP_IS2_HK_RSV2]			= { 25,   1},
+	[VCAP_IS2_HK_HOST_MATCH]		= { 26,   1},
+	[VCAP_IS2_HK_L2_MC]			= { 27,   1},
+	[VCAP_IS2_HK_L2_BC]			= { 28,   1},
+	[VCAP_IS2_HK_VLAN_TAGGED]		= { 29,   1},
+	[VCAP_IS2_HK_VID]			= { 30,  12},
+	[VCAP_IS2_HK_DEI]			= { 42,   1},
+	[VCAP_IS2_HK_PCP]			= { 43,   3},
+	/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
+	[VCAP_IS2_HK_L2_DMAC]			= { 46,  48},
+	[VCAP_IS2_HK_L2_SMAC]			= { 94,  48},
+	/* MAC_ETYPE (TYPE=000) */
+	[VCAP_IS2_HK_MAC_ETYPE_ETYPE]		= {142,  16},
+	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]	= {158,  16},
+	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]	= {174,   8},
+	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]	= {182,   3},
+	/* MAC_LLC (TYPE=001) */
+	[VCAP_IS2_HK_MAC_LLC_L2_LLC]		= {142,  40},
+	/* MAC_SNAP (TYPE=010) */
+	[VCAP_IS2_HK_MAC_SNAP_L2_SNAP]		= {142,  40},
+	/* MAC_ARP (TYPE=011) */
+	[VCAP_IS2_HK_MAC_ARP_SMAC]		= { 46,  48},
+	[VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]	= { 94,   1},
+	[VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]	= { 95,   1},
+	[VCAP_IS2_HK_MAC_ARP_LEN_OK]		= { 96,   1},
+	[VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]	= { 97,   1},
+	[VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]	= { 98,   1},
+	[VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]	= { 99,   1},
+	[VCAP_IS2_HK_MAC_ARP_OPCODE]		= {100,   2},
+	[VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]	= {102,  32},
+	[VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]	= {134,  32},
+	[VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]	= {166,   1},
+	/* IP4_TCP_UDP / IP4_OTHER common */
+	[VCAP_IS2_HK_IP4]			= { 46,   1},
+	[VCAP_IS2_HK_L3_FRAGMENT]		= { 47,   1},
+	[VCAP_IS2_HK_L3_FRAG_OFS_GT0]		= { 48,   1},
+	[VCAP_IS2_HK_L3_OPTIONS]		= { 49,   1},
+	[VCAP_IS2_HK_IP4_L3_TTL_GT0]		= { 50,   1},
+	[VCAP_IS2_HK_L3_TOS]			= { 51,   8},
+	[VCAP_IS2_HK_L3_IP4_DIP]		= { 59,  32},
+	[VCAP_IS2_HK_L3_IP4_SIP]		= { 91,  32},
+	[VCAP_IS2_HK_DIP_EQ_SIP]		= {123,   1},
+	/* IP4_TCP_UDP (TYPE=100) */
+	[VCAP_IS2_HK_TCP]			= {124,   1},
+	[VCAP_IS2_HK_L4_SPORT]			= {125,  16},
+	[VCAP_IS2_HK_L4_DPORT]			= {141,  16},
+	[VCAP_IS2_HK_L4_RNG]			= {157,   8},
+	[VCAP_IS2_HK_L4_SPORT_EQ_DPORT]		= {165,   1},
+	[VCAP_IS2_HK_L4_SEQUENCE_EQ0]		= {166,   1},
+	[VCAP_IS2_HK_L4_URG]			= {167,   1},
+	[VCAP_IS2_HK_L4_ACK]			= {168,   1},
+	[VCAP_IS2_HK_L4_PSH]			= {169,   1},
+	[VCAP_IS2_HK_L4_RST]			= {170,   1},
+	[VCAP_IS2_HK_L4_SYN]			= {171,   1},
+	[VCAP_IS2_HK_L4_FIN]			= {172,   1},
+	[VCAP_IS2_HK_L4_1588_DOM]		= {173,   8},
+	[VCAP_IS2_HK_L4_1588_VER]		= {181,   4},
+	/* IP4_OTHER (TYPE=101) */
+	[VCAP_IS2_HK_IP4_L3_PROTO]		= {124,   8},
+	[VCAP_IS2_HK_L3_PAYLOAD]		= {132,  56},
+	/* IP6_STD (TYPE=110) */
+	[VCAP_IS2_HK_IP6_L3_TTL_GT0]		= { 46,   1},
+	[VCAP_IS2_HK_L3_IP6_SIP]		= { 47, 128},
+	[VCAP_IS2_HK_IP6_L3_PROTO]		= {175,   8},
+	/* OAM (TYPE=111) */
+	[VCAP_IS2_HK_OAM_MEL_FLAGS]		= {142,   7},
+	[VCAP_IS2_HK_OAM_VER]			= {149,   5},
+	[VCAP_IS2_HK_OAM_OPCODE]		= {154,   8},
+	[VCAP_IS2_HK_OAM_FLAGS]			= {162,   8},
+	[VCAP_IS2_HK_OAM_MEPID]			= {170,  16},
+	[VCAP_IS2_HK_OAM_CCM_CNTS_EQ0]		= {186,   1},
+	[VCAP_IS2_HK_OAM_IS_Y1731]		= {187,   1},
+};
+
+static const struct vcap_field vsc7514_vcap_is2_actions[] = {
+	[VCAP_IS2_ACT_HIT_ME_ONCE]		= {  0,  1},
+	[VCAP_IS2_ACT_CPU_COPY_ENA]		= {  1,  1},
+	[VCAP_IS2_ACT_CPU_QU_NUM]		= {  2,  3},
+	[VCAP_IS2_ACT_MASK_MODE]		= {  5,  2},
+	[VCAP_IS2_ACT_MIRROR_ENA]		= {  7,  1},
+	[VCAP_IS2_ACT_LRN_DIS]			= {  8,  1},
+	[VCAP_IS2_ACT_POLICE_ENA]		= {  9,  1},
+	[VCAP_IS2_ACT_POLICE_IDX]		= { 10,  9},
+	[VCAP_IS2_ACT_POLICE_VCAP_ONLY]		= { 19,  1},
+	[VCAP_IS2_ACT_PORT_MASK]		= { 20, 11},
+	[VCAP_IS2_ACT_REW_OP]			= { 31,  9},
+	[VCAP_IS2_ACT_SMAC_REPLACE_ENA]		= { 40,  1},
+	[VCAP_IS2_ACT_RSV]			= { 41,  2},
+	[VCAP_IS2_ACT_ACL_ID]			= { 43,  6},
+	[VCAP_IS2_ACT_HIT_CNT]			= { 49, 32},
+};
+
 static int mscc_ocelot_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -362,6 +461,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
 	ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
 				     sizeof(struct ocelot_port *), GFP_KERNEL);
 
+	ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
+	ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
+
 	ocelot_init(ocelot);
 	/* No NPI port */
 	ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.h b/drivers/net/ethernet/mscc/ocelot_vcap.h
deleted file mode 100644
index e22eac1da783..000000000000
--- a/drivers/net/ethernet/mscc/ocelot_vcap.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
- * Microsemi Ocelot Switch driver
- * Copyright (c) 2019 Microsemi Corporation
- */
-
-#ifndef _OCELOT_VCAP_H_
-#define _OCELOT_VCAP_H_
-
-/* =================================================================
- *  VCAP Common
- * =================================================================
- */
-
-/* VCAP Type-Group values */
-#define VCAP_TG_NONE 0 /* Entry is invalid */
-#define VCAP_TG_FULL 1 /* Full entry */
-#define VCAP_TG_HALF 2 /* Half entry */
-#define VCAP_TG_QUARTER 3 /* Quarter entry */
-
-/* =================================================================
- *  VCAP IS2
- * =================================================================
- */
-
-#define VCAP_IS2_CNT 64
-#define VCAP_IS2_ENTRY_WIDTH 376
-#define VCAP_IS2_ACTION_WIDTH 99
-#define VCAP_PORT_CNT 11
-
-/* IS2 half key types */
-#define IS2_TYPE_ETYPE 0
-#define IS2_TYPE_LLC 1
-#define IS2_TYPE_SNAP 2
-#define IS2_TYPE_ARP 3
-#define IS2_TYPE_IP_UDP_TCP 4
-#define IS2_TYPE_IP_OTHER 5
-#define IS2_TYPE_IPV6 6
-#define IS2_TYPE_OAM 7
-#define IS2_TYPE_SMAC_SIP6 8
-#define IS2_TYPE_ANY 100 /* Pseudo type */
-
-/* IS2 half key type mask for matching any IP */
-#define IS2_TYPE_MASK_IP_ANY 0xe
-
-/* IS2 action types */
-#define IS2_ACTION_TYPE_NORMAL 0
-#define IS2_ACTION_TYPE_SMAC_SIP 1
-
-/* IS2 MASK_MODE values */
-#define IS2_ACT_MASK_MODE_NONE 0
-#define IS2_ACT_MASK_MODE_FILTER 1
-#define IS2_ACT_MASK_MODE_POLICY 2
-#define IS2_ACT_MASK_MODE_REDIR 3
-
-/* IS2 REW_OP values */
-#define IS2_ACT_REW_OP_NONE 0
-#define IS2_ACT_REW_OP_PTP_ONE 2
-#define IS2_ACT_REW_OP_PTP_TWO 3
-#define IS2_ACT_REW_OP_SPECIAL 8
-#define IS2_ACT_REW_OP_PTP_ORG 9
-#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_1 (IS2_ACT_REW_OP_PTP_ONE | (1 << 3))
-#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_2 (IS2_ACT_REW_OP_PTP_ONE | (2 << 3))
-#define IS2_ACT_REW_OP_PTP_ONE_ADD_DELAY (IS2_ACT_REW_OP_PTP_ONE | (1 << 5))
-#define IS2_ACT_REW_OP_PTP_ONE_ADD_SUB BIT(7)
-
-#define VCAP_PORT_WIDTH 4
-
-/* IS2 quarter key - SMAC_SIP4 */
-#define IS2_QKO_IGR_PORT 0
-#define IS2_QKL_IGR_PORT VCAP_PORT_WIDTH
-#define IS2_QKO_L2_SMAC (IS2_QKO_IGR_PORT + IS2_QKL_IGR_PORT)
-#define IS2_QKL_L2_SMAC 48
-#define IS2_QKO_L3_IP4_SIP (IS2_QKO_L2_SMAC + IS2_QKL_L2_SMAC)
-#define IS2_QKL_L3_IP4_SIP 32
-
-/* IS2 half key - common */
-#define IS2_HKO_TYPE 0
-#define IS2_HKL_TYPE 4
-#define IS2_HKO_FIRST (IS2_HKO_TYPE + IS2_HKL_TYPE)
-#define IS2_HKL_FIRST 1
-#define IS2_HKO_PAG (IS2_HKO_FIRST + IS2_HKL_FIRST)
-#define IS2_HKL_PAG 8
-#define IS2_HKO_IGR_PORT_MASK (IS2_HKO_PAG + IS2_HKL_PAG)
-#define IS2_HKL_IGR_PORT_MASK (VCAP_PORT_CNT + 1)
-#define IS2_HKO_SERVICE_FRM (IS2_HKO_IGR_PORT_MASK + IS2_HKL_IGR_PORT_MASK)
-#define IS2_HKL_SERVICE_FRM 1
-#define IS2_HKO_HOST_MATCH (IS2_HKO_SERVICE_FRM + IS2_HKL_SERVICE_FRM)
-#define IS2_HKL_HOST_MATCH 1
-#define IS2_HKO_L2_MC (IS2_HKO_HOST_MATCH + IS2_HKL_HOST_MATCH)
-#define IS2_HKL_L2_MC 1
-#define IS2_HKO_L2_BC (IS2_HKO_L2_MC + IS2_HKL_L2_MC)
-#define IS2_HKL_L2_BC 1
-#define IS2_HKO_VLAN_TAGGED (IS2_HKO_L2_BC + IS2_HKL_L2_BC)
-#define IS2_HKL_VLAN_TAGGED 1
-#define IS2_HKO_VID (IS2_HKO_VLAN_TAGGED + IS2_HKL_VLAN_TAGGED)
-#define IS2_HKL_VID 12
-#define IS2_HKO_DEI (IS2_HKO_VID + IS2_HKL_VID)
-#define IS2_HKL_DEI 1
-#define IS2_HKO_PCP (IS2_HKO_DEI + IS2_HKL_DEI)
-#define IS2_HKL_PCP 3
-
-/* IS2 half key - MAC_ETYPE/MAC_LLC/MAC_SNAP/OAM common */
-#define IS2_HKO_L2_DMAC (IS2_HKO_PCP + IS2_HKL_PCP)
-#define IS2_HKL_L2_DMAC 48
-#define IS2_HKO_L2_SMAC (IS2_HKO_L2_DMAC + IS2_HKL_L2_DMAC)
-#define IS2_HKL_L2_SMAC 48
-
-/* IS2 half key - MAC_ETYPE */
-#define IS2_HKO_MAC_ETYPE_ETYPE (IS2_HKO_L2_SMAC + IS2_HKL_L2_SMAC)
-#define IS2_HKL_MAC_ETYPE_ETYPE 16
-#define IS2_HKO_MAC_ETYPE_L2_PAYLOAD                                           \
-	(IS2_HKO_MAC_ETYPE_ETYPE + IS2_HKL_MAC_ETYPE_ETYPE)
-#define IS2_HKL_MAC_ETYPE_L2_PAYLOAD 27
-
-/* IS2 half key - MAC_LLC */
-#define IS2_HKO_MAC_LLC_L2_LLC IS2_HKO_MAC_ETYPE_ETYPE
-#define IS2_HKL_MAC_LLC_L2_LLC 40
-
-/* IS2 half key - MAC_SNAP */
-#define IS2_HKO_MAC_SNAP_L2_SNAP IS2_HKO_MAC_ETYPE_ETYPE
-#define IS2_HKL_MAC_SNAP_L2_SNAP 40
-
-/* IS2 half key - ARP */
-#define IS2_HKO_MAC_ARP_L2_SMAC IS2_HKO_L2_DMAC
-#define IS2_HKL_MAC_ARP_L2_SMAC 48
-#define IS2_HKO_MAC_ARP_ARP_ADDR_SPACE_OK                                      \
-	(IS2_HKO_MAC_ARP_L2_SMAC + IS2_HKL_MAC_ARP_L2_SMAC)
-#define IS2_HKL_MAC_ARP_ARP_ADDR_SPACE_OK 1
-#define IS2_HKO_MAC_ARP_ARP_PROTO_SPACE_OK                                     \
-	(IS2_HKO_MAC_ARP_ARP_ADDR_SPACE_OK + IS2_HKL_MAC_ARP_ARP_ADDR_SPACE_OK)
-#define IS2_HKL_MAC_ARP_ARP_PROTO_SPACE_OK 1
-#define IS2_HKO_MAC_ARP_ARP_LEN_OK                                             \
-	(IS2_HKO_MAC_ARP_ARP_PROTO_SPACE_OK +                                  \
-	 IS2_HKL_MAC_ARP_ARP_PROTO_SPACE_OK)
-#define IS2_HKL_MAC_ARP_ARP_LEN_OK 1
-#define IS2_HKO_MAC_ARP_ARP_TGT_MATCH                                          \
-	(IS2_HKO_MAC_ARP_ARP_LEN_OK + IS2_HKL_MAC_ARP_ARP_LEN_OK)
-#define IS2_HKL_MAC_ARP_ARP_TGT_MATCH 1
-#define IS2_HKO_MAC_ARP_ARP_SENDER_MATCH                                       \
-	(IS2_HKO_MAC_ARP_ARP_TGT_MATCH + IS2_HKL_MAC_ARP_ARP_TGT_MATCH)
-#define IS2_HKL_MAC_ARP_ARP_SENDER_MATCH 1
-#define IS2_HKO_MAC_ARP_ARP_OPCODE_UNKNOWN                                     \
-	(IS2_HKO_MAC_ARP_ARP_SENDER_MATCH + IS2_HKL_MAC_ARP_ARP_SENDER_MATCH)
-#define IS2_HKL_MAC_ARP_ARP_OPCODE_UNKNOWN 1
-#define IS2_HKO_MAC_ARP_ARP_OPCODE                                             \
-	(IS2_HKO_MAC_ARP_ARP_OPCODE_UNKNOWN +                                  \
-	 IS2_HKL_MAC_ARP_ARP_OPCODE_UNKNOWN)
-#define IS2_HKL_MAC_ARP_ARP_OPCODE 2
-#define IS2_HKO_MAC_ARP_L3_IP4_DIP                                             \
-	(IS2_HKO_MAC_ARP_ARP_OPCODE + IS2_HKL_MAC_ARP_ARP_OPCODE)
-#define IS2_HKL_MAC_ARP_L3_IP4_DIP 32
-#define IS2_HKO_MAC_ARP_L3_IP4_SIP                                             \
-	(IS2_HKO_MAC_ARP_L3_IP4_DIP + IS2_HKL_MAC_ARP_L3_IP4_DIP)
-#define IS2_HKL_MAC_ARP_L3_IP4_SIP 32
-#define IS2_HKO_MAC_ARP_DIP_EQ_SIP                                             \
-	(IS2_HKO_MAC_ARP_L3_IP4_SIP + IS2_HKL_MAC_ARP_L3_IP4_SIP)
-#define IS2_HKL_MAC_ARP_DIP_EQ_SIP 1
-
-/* IS2 half key - IP4_TCP_UDP/IP4_OTHER common */
-#define IS2_HKO_IP4 IS2_HKO_L2_DMAC
-#define IS2_HKL_IP4 1
-#define IS2_HKO_L3_FRAGMENT (IS2_HKO_IP4 + IS2_HKL_IP4)
-#define IS2_HKL_L3_FRAGMENT 1
-#define IS2_HKO_L3_FRAG_OFS_GT0 (IS2_HKO_L3_FRAGMENT + IS2_HKL_L3_FRAGMENT)
-#define IS2_HKL_L3_FRAG_OFS_GT0 1
-#define IS2_HKO_L3_OPTIONS (IS2_HKO_L3_FRAG_OFS_GT0 + IS2_HKL_L3_FRAG_OFS_GT0)
-#define IS2_HKL_L3_OPTIONS 1
-#define IS2_HKO_L3_TTL_GT0 (IS2_HKO_L3_OPTIONS + IS2_HKL_L3_OPTIONS)
-#define IS2_HKL_L3_TTL_GT0 1
-#define IS2_HKO_L3_TOS (IS2_HKO_L3_TTL_GT0 + IS2_HKL_L3_TTL_GT0)
-#define IS2_HKL_L3_TOS 8
-#define IS2_HKO_L3_IP4_DIP (IS2_HKO_L3_TOS + IS2_HKL_L3_TOS)
-#define IS2_HKL_L3_IP4_DIP 32
-#define IS2_HKO_L3_IP4_SIP (IS2_HKO_L3_IP4_DIP + IS2_HKL_L3_IP4_DIP)
-#define IS2_HKL_L3_IP4_SIP 32
-#define IS2_HKO_DIP_EQ_SIP (IS2_HKO_L3_IP4_SIP + IS2_HKL_L3_IP4_SIP)
-#define IS2_HKL_DIP_EQ_SIP 1
-
-/* IS2 half key - IP4_TCP_UDP */
-#define IS2_HKO_IP4_TCP_UDP_TCP (IS2_HKO_DIP_EQ_SIP + IS2_HKL_DIP_EQ_SIP)
-#define IS2_HKL_IP4_TCP_UDP_TCP 1
-#define IS2_HKO_IP4_TCP_UDP_L4_DPORT                                           \
-	(IS2_HKO_IP4_TCP_UDP_TCP + IS2_HKL_IP4_TCP_UDP_TCP)
-#define IS2_HKL_IP4_TCP_UDP_L4_DPORT 16
-#define IS2_HKO_IP4_TCP_UDP_L4_SPORT                                           \
-	(IS2_HKO_IP4_TCP_UDP_L4_DPORT + IS2_HKL_IP4_TCP_UDP_L4_DPORT)
-#define IS2_HKL_IP4_TCP_UDP_L4_SPORT 16
-#define IS2_HKO_IP4_TCP_UDP_L4_RNG                                             \
-	(IS2_HKO_IP4_TCP_UDP_L4_SPORT + IS2_HKL_IP4_TCP_UDP_L4_SPORT)
-#define IS2_HKL_IP4_TCP_UDP_L4_RNG 8
-#define IS2_HKO_IP4_TCP_UDP_SPORT_EQ_DPORT                                     \
-	(IS2_HKO_IP4_TCP_UDP_L4_RNG + IS2_HKL_IP4_TCP_UDP_L4_RNG)
-#define IS2_HKL_IP4_TCP_UDP_SPORT_EQ_DPORT 1
-#define IS2_HKO_IP4_TCP_UDP_SEQUENCE_EQ0                                       \
-	(IS2_HKO_IP4_TCP_UDP_SPORT_EQ_DPORT +                                  \
-	 IS2_HKL_IP4_TCP_UDP_SPORT_EQ_DPORT)
-#define IS2_HKL_IP4_TCP_UDP_SEQUENCE_EQ0 1
-#define IS2_HKO_IP4_TCP_UDP_L4_FIN                                             \
-	(IS2_HKO_IP4_TCP_UDP_SEQUENCE_EQ0 + IS2_HKL_IP4_TCP_UDP_SEQUENCE_EQ0)
-#define IS2_HKL_IP4_TCP_UDP_L4_FIN 1
-#define IS2_HKO_IP4_TCP_UDP_L4_SYN                                             \
-	(IS2_HKO_IP4_TCP_UDP_L4_FIN + IS2_HKL_IP4_TCP_UDP_L4_FIN)
-#define IS2_HKL_IP4_TCP_UDP_L4_SYN 1
-#define IS2_HKO_IP4_TCP_UDP_L4_RST                                             \
-	(IS2_HKO_IP4_TCP_UDP_L4_SYN + IS2_HKL_IP4_TCP_UDP_L4_SYN)
-#define IS2_HKL_IP4_TCP_UDP_L4_RST 1
-#define IS2_HKO_IP4_TCP_UDP_L4_PSH                                             \
-	(IS2_HKO_IP4_TCP_UDP_L4_RST + IS2_HKL_IP4_TCP_UDP_L4_RST)
-#define IS2_HKL_IP4_TCP_UDP_L4_PSH 1
-#define IS2_HKO_IP4_TCP_UDP_L4_ACK                                             \
-	(IS2_HKO_IP4_TCP_UDP_L4_PSH + IS2_HKL_IP4_TCP_UDP_L4_PSH)
-#define IS2_HKL_IP4_TCP_UDP_L4_ACK 1
-#define IS2_HKO_IP4_TCP_UDP_L4_URG                                             \
-	(IS2_HKO_IP4_TCP_UDP_L4_ACK + IS2_HKL_IP4_TCP_UDP_L4_ACK)
-#define IS2_HKL_IP4_TCP_UDP_L4_URG 1
-#define IS2_HKO_IP4_TCP_UDP_L4_1588_DOM                                        \
-	(IS2_HKO_IP4_TCP_UDP_L4_URG + IS2_HKL_IP4_TCP_UDP_L4_URG)
-#define IS2_HKL_IP4_TCP_UDP_L4_1588_DOM 8
-#define IS2_HKO_IP4_TCP_UDP_L4_1588_VER                                        \
-	(IS2_HKO_IP4_TCP_UDP_L4_1588_DOM + IS2_HKL_IP4_TCP_UDP_L4_1588_DOM)
-#define IS2_HKL_IP4_TCP_UDP_L4_1588_VER 4
-
-/* IS2 half key - IP4_OTHER */
-#define IS2_HKO_IP4_OTHER_L3_PROTO IS2_HKO_IP4_TCP_UDP_TCP
-#define IS2_HKL_IP4_OTHER_L3_PROTO 8
-#define IS2_HKO_IP4_OTHER_L3_PAYLOAD                                           \
-	(IS2_HKO_IP4_OTHER_L3_PROTO + IS2_HKL_IP4_OTHER_L3_PROTO)
-#define IS2_HKL_IP4_OTHER_L3_PAYLOAD 56
-
-/* IS2 half key - IP6_STD */
-#define IS2_HKO_IP6_STD_L3_TTL_GT0 IS2_HKO_L2_DMAC
-#define IS2_HKL_IP6_STD_L3_TTL_GT0 1
-#define IS2_HKO_IP6_STD_L3_IP6_SIP                                             \
-	(IS2_HKO_IP6_STD_L3_TTL_GT0 + IS2_HKL_IP6_STD_L3_TTL_GT0)
-#define IS2_HKL_IP6_STD_L3_IP6_SIP 128
-#define IS2_HKO_IP6_STD_L3_PROTO                                               \
-	(IS2_HKO_IP6_STD_L3_IP6_SIP + IS2_HKL_IP6_STD_L3_IP6_SIP)
-#define IS2_HKL_IP6_STD_L3_PROTO 8
-
-/* IS2 half key - OAM */
-#define IS2_HKO_OAM_OAM_MEL_FLAGS IS2_HKO_MAC_ETYPE_ETYPE
-#define IS2_HKL_OAM_OAM_MEL_FLAGS 7
-#define IS2_HKO_OAM_OAM_VER                                                    \
-	(IS2_HKO_OAM_OAM_MEL_FLAGS + IS2_HKL_OAM_OAM_MEL_FLAGS)
-#define IS2_HKL_OAM_OAM_VER 5
-#define IS2_HKO_OAM_OAM_OPCODE (IS2_HKO_OAM_OAM_VER + IS2_HKL_OAM_OAM_VER)
-#define IS2_HKL_OAM_OAM_OPCODE 8
-#define IS2_HKO_OAM_OAM_FLAGS (IS2_HKO_OAM_OAM_OPCODE + IS2_HKL_OAM_OAM_OPCODE)
-#define IS2_HKL_OAM_OAM_FLAGS 8
-#define IS2_HKO_OAM_OAM_MEPID (IS2_HKO_OAM_OAM_FLAGS + IS2_HKL_OAM_OAM_FLAGS)
-#define IS2_HKL_OAM_OAM_MEPID 16
-#define IS2_HKO_OAM_OAM_CCM_CNTS_EQ0                                           \
-	(IS2_HKO_OAM_OAM_MEPID + IS2_HKL_OAM_OAM_MEPID)
-#define IS2_HKL_OAM_OAM_CCM_CNTS_EQ0 1
-
-/* IS2 half key - SMAC_SIP6 */
-#define IS2_HKO_SMAC_SIP6_IGR_PORT IS2_HKL_TYPE
-#define IS2_HKL_SMAC_SIP6_IGR_PORT VCAP_PORT_WIDTH
-#define IS2_HKO_SMAC_SIP6_L2_SMAC                                              \
-	(IS2_HKO_SMAC_SIP6_IGR_PORT + IS2_HKL_SMAC_SIP6_IGR_PORT)
-#define IS2_HKL_SMAC_SIP6_L2_SMAC 48
-#define IS2_HKO_SMAC_SIP6_L3_IP6_SIP                                           \
-	(IS2_HKO_SMAC_SIP6_L2_SMAC + IS2_HKL_SMAC_SIP6_L2_SMAC)
-#define IS2_HKL_SMAC_SIP6_L3_IP6_SIP 128
-
-/* IS2 full key - common */
-#define IS2_FKO_TYPE 0
-#define IS2_FKL_TYPE 2
-#define IS2_FKO_FIRST (IS2_FKO_TYPE + IS2_FKL_TYPE)
-#define IS2_FKL_FIRST 1
-#define IS2_FKO_PAG (IS2_FKO_FIRST + IS2_FKL_FIRST)
-#define IS2_FKL_PAG 8
-#define IS2_FKO_IGR_PORT_MASK (IS2_FKO_PAG + IS2_FKL_PAG)
-#define IS2_FKL_IGR_PORT_MASK (VCAP_PORT_CNT + 1)
-#define IS2_FKO_SERVICE_FRM (IS2_FKO_IGR_PORT_MASK + IS2_FKL_IGR_PORT_MASK)
-#define IS2_FKL_SERVICE_FRM 1
-#define IS2_FKO_HOST_MATCH (IS2_FKO_SERVICE_FRM + IS2_FKL_SERVICE_FRM)
-#define IS2_FKL_HOST_MATCH 1
-#define IS2_FKO_L2_MC (IS2_FKO_HOST_MATCH + IS2_FKL_HOST_MATCH)
-#define IS2_FKL_L2_MC 1
-#define IS2_FKO_L2_BC (IS2_FKO_L2_MC + IS2_FKL_L2_MC)
-#define IS2_FKL_L2_BC 1
-#define IS2_FKO_VLAN_TAGGED (IS2_FKO_L2_BC + IS2_FKL_L2_BC)
-#define IS2_FKL_VLAN_TAGGED 1
-#define IS2_FKO_VID (IS2_FKO_VLAN_TAGGED + IS2_FKL_VLAN_TAGGED)
-#define IS2_FKL_VID 12
-#define IS2_FKO_DEI (IS2_FKO_VID + IS2_FKL_VID)
-#define IS2_FKL_DEI 1
-#define IS2_FKO_PCP (IS2_FKO_DEI + IS2_FKL_DEI)
-#define IS2_FKL_PCP 3
-
-/* IS2 full key - IP6_TCP_UDP/IP6_OTHER common */
-#define IS2_FKO_L3_TTL_GT0 (IS2_FKO_PCP + IS2_FKL_PCP)
-#define IS2_FKL_L3_TTL_GT0 1
-#define IS2_FKO_L3_TOS (IS2_FKO_L3_TTL_GT0 + IS2_FKL_L3_TTL_GT0)
-#define IS2_FKL_L3_TOS 8
-#define IS2_FKO_L3_IP6_DIP (IS2_FKO_L3_TOS + IS2_FKL_L3_TOS)
-#define IS2_FKL_L3_IP6_DIP 128
-#define IS2_FKO_L3_IP6_SIP (IS2_FKO_L3_IP6_DIP + IS2_FKL_L3_IP6_DIP)
-#define IS2_FKL_L3_IP6_SIP 128
-#define IS2_FKO_DIP_EQ_SIP (IS2_FKO_L3_IP6_SIP + IS2_FKL_L3_IP6_SIP)
-#define IS2_FKL_DIP_EQ_SIP 1
-
-/* IS2 full key - IP6_TCP_UDP */
-#define IS2_FKO_IP6_TCP_UDP_TCP (IS2_FKO_DIP_EQ_SIP + IS2_FKL_DIP_EQ_SIP)
-#define IS2_FKL_IP6_TCP_UDP_TCP 1
-#define IS2_FKO_IP6_TCP_UDP_L4_DPORT                                           \
-	(IS2_FKO_IP6_TCP_UDP_TCP + IS2_FKL_IP6_TCP_UDP_TCP)
-#define IS2_FKL_IP6_TCP_UDP_L4_DPORT 16
-#define IS2_FKO_IP6_TCP_UDP_L4_SPORT                                           \
-	(IS2_FKO_IP6_TCP_UDP_L4_DPORT + IS2_FKL_IP6_TCP_UDP_L4_DPORT)
-#define IS2_FKL_IP6_TCP_UDP_L4_SPORT 16
-#define IS2_FKO_IP6_TCP_UDP_L4_RNG                                             \
-	(IS2_FKO_IP6_TCP_UDP_L4_SPORT + IS2_FKL_IP6_TCP_UDP_L4_SPORT)
-#define IS2_FKL_IP6_TCP_UDP_L4_RNG 8
-#define IS2_FKO_IP6_TCP_UDP_SPORT_EQ_DPORT                                     \
-	(IS2_FKO_IP6_TCP_UDP_L4_RNG + IS2_FKL_IP6_TCP_UDP_L4_RNG)
-#define IS2_FKL_IP6_TCP_UDP_SPORT_EQ_DPORT 1
-#define IS2_FKO_IP6_TCP_UDP_SEQUENCE_EQ0                                       \
-	(IS2_FKO_IP6_TCP_UDP_SPORT_EQ_DPORT +                                  \
-	 IS2_FKL_IP6_TCP_UDP_SPORT_EQ_DPORT)
-#define IS2_FKL_IP6_TCP_UDP_SEQUENCE_EQ0 1
-#define IS2_FKO_IP6_TCP_UDP_L4_FIN                                             \
-	(IS2_FKO_IP6_TCP_UDP_SEQUENCE_EQ0 + IS2_FKL_IP6_TCP_UDP_SEQUENCE_EQ0)
-#define IS2_FKL_IP6_TCP_UDP_L4_FIN 1
-#define IS2_FKO_IP6_TCP_UDP_L4_SYN                                             \
-	(IS2_FKO_IP6_TCP_UDP_L4_FIN + IS2_FKL_IP6_TCP_UDP_L4_FIN)
-#define IS2_FKL_IP6_TCP_UDP_L4_SYN 1
-#define IS2_FKO_IP6_TCP_UDP_L4_RST                                             \
-	(IS2_FKO_IP6_TCP_UDP_L4_SYN + IS2_FKL_IP6_TCP_UDP_L4_SYN)
-#define IS2_FKL_IP6_TCP_UDP_L4_RST 1
-#define IS2_FKO_IP6_TCP_UDP_L4_PSH                                             \
-	(IS2_FKO_IP6_TCP_UDP_L4_RST + IS2_FKL_IP6_TCP_UDP_L4_RST)
-#define IS2_FKL_IP6_TCP_UDP_L4_PSH 1
-#define IS2_FKO_IP6_TCP_UDP_L4_ACK                                             \
-	(IS2_FKO_IP6_TCP_UDP_L4_PSH + IS2_FKL_IP6_TCP_UDP_L4_PSH)
-#define IS2_FKL_IP6_TCP_UDP_L4_ACK 1
-#define IS2_FKO_IP6_TCP_UDP_L4_URG                                             \
-	(IS2_FKO_IP6_TCP_UDP_L4_ACK + IS2_FKL_IP6_TCP_UDP_L4_ACK)
-#define IS2_FKL_IP6_TCP_UDP_L4_URG 1
-#define IS2_FKO_IP6_TCP_UDP_L4_1588_DOM                                        \
-	(IS2_FKO_IP6_TCP_UDP_L4_URG + IS2_FKL_IP6_TCP_UDP_L4_URG)
-#define IS2_FKL_IP6_TCP_UDP_L4_1588_DOM 8
-#define IS2_FKO_IP6_TCP_UDP_L4_1588_VER                                        \
-	(IS2_FKO_IP6_TCP_UDP_L4_1588_DOM + IS2_FKL_IP6_TCP_UDP_L4_1588_DOM)
-#define IS2_FKL_IP6_TCP_UDP_L4_1588_VER 4
-
-/* IS2 full key - IP6_OTHER */
-#define IS2_FKO_IP6_OTHER_L3_PROTO IS2_FKO_IP6_TCP_UDP_TCP
-#define IS2_FKL_IP6_OTHER_L3_PROTO 8
-#define IS2_FKO_IP6_OTHER_L3_PAYLOAD                                           \
-	(IS2_FKO_IP6_OTHER_L3_PROTO + IS2_FKL_IP6_OTHER_L3_PROTO)
-#define IS2_FKL_IP6_OTHER_L3_PAYLOAD 56
-
-/* IS2 full key - CUSTOM */
-#define IS2_FKO_CUSTOM_CUSTOM_TYPE IS2_FKO_L3_TTL_GT0
-#define IS2_FKL_CUSTOM_CUSTOM_TYPE 1
-#define IS2_FKO_CUSTOM_CUSTOM                                                  \
-	(IS2_FKO_CUSTOM_CUSTOM_TYPE + IS2_FKL_CUSTOM_CUSTOM_TYPE)
-#define IS2_FKL_CUSTOM_CUSTOM 320
-
-/* IS2 action - BASE_TYPE */
-#define IS2_AO_HIT_ME_ONCE 0
-#define IS2_AL_HIT_ME_ONCE 1
-#define IS2_AO_CPU_COPY_ENA (IS2_AO_HIT_ME_ONCE + IS2_AL_HIT_ME_ONCE)
-#define IS2_AL_CPU_COPY_ENA 1
-#define IS2_AO_CPU_QU_NUM (IS2_AO_CPU_COPY_ENA + IS2_AL_CPU_COPY_ENA)
-#define IS2_AL_CPU_QU_NUM 3
-#define IS2_AO_MASK_MODE (IS2_AO_CPU_QU_NUM + IS2_AL_CPU_QU_NUM)
-#define IS2_AL_MASK_MODE 2
-#define IS2_AO_MIRROR_ENA (IS2_AO_MASK_MODE + IS2_AL_MASK_MODE)
-#define IS2_AL_MIRROR_ENA 1
-#define IS2_AO_LRN_DIS (IS2_AO_MIRROR_ENA + IS2_AL_MIRROR_ENA)
-#define IS2_AL_LRN_DIS 1
-#define IS2_AO_POLICE_ENA (IS2_AO_LRN_DIS + IS2_AL_LRN_DIS)
-#define IS2_AL_POLICE_ENA 1
-#define IS2_AO_POLICE_IDX (IS2_AO_POLICE_ENA + IS2_AL_POLICE_ENA)
-#define IS2_AL_POLICE_IDX 9
-#define IS2_AO_POLICE_VCAP_ONLY (IS2_AO_POLICE_IDX + IS2_AL_POLICE_IDX)
-#define IS2_AL_POLICE_VCAP_ONLY 1
-#define IS2_AO_PORT_MASK (IS2_AO_POLICE_VCAP_ONLY + IS2_AL_POLICE_VCAP_ONLY)
-#define IS2_AL_PORT_MASK VCAP_PORT_CNT
-#define IS2_AO_REW_OP (IS2_AO_PORT_MASK + IS2_AL_PORT_MASK)
-#define IS2_AL_REW_OP 9
-#define IS2_AO_LM_CNT_DIS (IS2_AO_REW_OP + IS2_AL_REW_OP)
-#define IS2_AL_LM_CNT_DIS 1
-#define IS2_AO_ISDX_ENA                                                        \
-	(IS2_AO_LM_CNT_DIS + IS2_AL_LM_CNT_DIS + 1) /* Reserved bit */
-#define IS2_AL_ISDX_ENA 1
-#define IS2_AO_ACL_ID (IS2_AO_ISDX_ENA + IS2_AL_ISDX_ENA)
-#define IS2_AL_ACL_ID 6
-
-/* IS2 action - SMAC_SIP */
-#define IS2_AO_SMAC_SIP_CPU_COPY_ENA 0
-#define IS2_AL_SMAC_SIP_CPU_COPY_ENA 1
-#define IS2_AO_SMAC_SIP_CPU_QU_NUM 1
-#define IS2_AL_SMAC_SIP_CPU_QU_NUM 3
-#define IS2_AO_SMAC_SIP_FWD_KILL_ENA 4
-#define IS2_AL_SMAC_SIP_FWD_KILL_ENA 1
-#define IS2_AO_SMAC_SIP_HOST_MATCH 5
-#define IS2_AL_SMAC_SIP_HOST_MATCH 1
-
-#endif /* _OCELOT_VCAP_H_ */
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 3d9e83e78c59..f9da90c5171b 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -521,6 +521,9 @@ struct ocelot {
 
 	struct ocelot_acl_block		acl_block;
 
+	const struct vcap_field		*vcap_is2_keys;
+	const struct vcap_field		*vcap_is2_actions;
+
 	/* Workqueue to check statistics for overflow with its lock */
 	struct mutex			stats_lock;
 	u64				*stats;
diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
new file mode 100644
index 000000000000..0783f0ffc813
--- /dev/null
+++ b/include/soc/mscc/ocelot_vcap.h
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ * Microsemi Ocelot Switch driver
+ * Copyright (c) 2019 Microsemi Corporation
+ */
+
+#ifndef _OCELOT_VCAP_H_
+#define _OCELOT_VCAP_H_
+
+/* =================================================================
+ *  VCAP Common
+ * =================================================================
+ */
+
+/* VCAP Type-Group values */
+#define VCAP_TG_NONE 0 /* Entry is invalid */
+#define VCAP_TG_FULL 1 /* Full entry */
+#define VCAP_TG_HALF 2 /* Half entry */
+#define VCAP_TG_QUARTER 3 /* Quarter entry */
+
+/* =================================================================
+ *  VCAP IS2
+ * =================================================================
+ */
+
+#define VCAP_IS2_CNT 64
+#define VCAP_IS2_ENTRY_WIDTH 376
+#define VCAP_IS2_ACTION_WIDTH 99
+#define VCAP_PORT_CNT 11
+
+/* IS2 half key types */
+#define IS2_TYPE_ETYPE 0
+#define IS2_TYPE_LLC 1
+#define IS2_TYPE_SNAP 2
+#define IS2_TYPE_ARP 3
+#define IS2_TYPE_IP_UDP_TCP 4
+#define IS2_TYPE_IP_OTHER 5
+#define IS2_TYPE_IPV6 6
+#define IS2_TYPE_OAM 7
+#define IS2_TYPE_SMAC_SIP6 8
+#define IS2_TYPE_ANY 100 /* Pseudo type */
+
+/* IS2 half key type mask for matching any IP */
+#define IS2_TYPE_MASK_IP_ANY 0xe
+
+/* IS2 action types */
+#define IS2_ACTION_TYPE_NORMAL 0
+#define IS2_ACTION_TYPE_SMAC_SIP 1
+
+/* IS2 MASK_MODE values */
+#define IS2_ACT_MASK_MODE_NONE 0
+#define IS2_ACT_MASK_MODE_FILTER 1
+#define IS2_ACT_MASK_MODE_POLICY 2
+#define IS2_ACT_MASK_MODE_REDIR 3
+
+/* IS2 REW_OP values */
+#define IS2_ACT_REW_OP_NONE 0
+#define IS2_ACT_REW_OP_PTP_ONE 2
+#define IS2_ACT_REW_OP_PTP_TWO 3
+#define IS2_ACT_REW_OP_SPECIAL 8
+#define IS2_ACT_REW_OP_PTP_ORG 9
+#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_1 (IS2_ACT_REW_OP_PTP_ONE | (1 << 3))
+#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_2 (IS2_ACT_REW_OP_PTP_ONE | (2 << 3))
+#define IS2_ACT_REW_OP_PTP_ONE_ADD_DELAY (IS2_ACT_REW_OP_PTP_ONE | (1 << 5))
+#define IS2_ACT_REW_OP_PTP_ONE_ADD_SUB BIT(7)
+
+#define VCAP_PORT_WIDTH 4
+
+/* IS2 quarter key - SMAC_SIP4 */
+#define IS2_QKO_IGR_PORT 0
+#define IS2_QKL_IGR_PORT VCAP_PORT_WIDTH
+#define IS2_QKO_L2_SMAC (IS2_QKO_IGR_PORT + IS2_QKL_IGR_PORT)
+#define IS2_QKL_L2_SMAC 48
+#define IS2_QKO_L3_IP4_SIP (IS2_QKO_L2_SMAC + IS2_QKL_L2_SMAC)
+#define IS2_QKL_L3_IP4_SIP 32
+
+enum vcap_is2_half_key_field {
+	/* Common */
+	VCAP_IS2_TYPE,
+	VCAP_IS2_HK_FIRST,
+	VCAP_IS2_HK_PAG,
+	VCAP_IS2_HK_RSV1,
+	VCAP_IS2_HK_IGR_PORT_MASK,
+	VCAP_IS2_HK_RSV2,
+	VCAP_IS2_HK_HOST_MATCH,
+	VCAP_IS2_HK_L2_MC,
+	VCAP_IS2_HK_L2_BC,
+	VCAP_IS2_HK_VLAN_TAGGED,
+	VCAP_IS2_HK_VID,
+	VCAP_IS2_HK_DEI,
+	VCAP_IS2_HK_PCP,
+	/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
+	VCAP_IS2_HK_L2_DMAC,
+	VCAP_IS2_HK_L2_SMAC,
+	/* MAC_ETYPE (TYPE=000) */
+	VCAP_IS2_HK_MAC_ETYPE_ETYPE,
+	VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
+	VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
+	VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
+	/* MAC_LLC (TYPE=001) */
+	VCAP_IS2_HK_MAC_LLC_DMAC,
+	VCAP_IS2_HK_MAC_LLC_SMAC,
+	VCAP_IS2_HK_MAC_LLC_L2_LLC,
+	/* MAC_SNAP (TYPE=010) */
+	VCAP_IS2_HK_MAC_SNAP_SMAC,
+	VCAP_IS2_HK_MAC_SNAP_DMAC,
+	VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
+	/* MAC_ARP (TYPE=011) */
+	VCAP_IS2_HK_MAC_ARP_SMAC,
+	VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
+	VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
+	VCAP_IS2_HK_MAC_ARP_LEN_OK,
+	VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
+	VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
+	VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
+	VCAP_IS2_HK_MAC_ARP_OPCODE,
+	VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
+	VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
+	VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
+	/* IP4_TCP_UDP / IP4_OTHER common */
+	VCAP_IS2_HK_IP4,
+	VCAP_IS2_HK_L3_FRAGMENT,
+	VCAP_IS2_HK_L3_FRAG_OFS_GT0,
+	VCAP_IS2_HK_L3_OPTIONS,
+	VCAP_IS2_HK_IP4_L3_TTL_GT0,
+	VCAP_IS2_HK_L3_TOS,
+	VCAP_IS2_HK_L3_IP4_DIP,
+	VCAP_IS2_HK_L3_IP4_SIP,
+	VCAP_IS2_HK_DIP_EQ_SIP,
+	/* IP4_TCP_UDP (TYPE=100) */
+	VCAP_IS2_HK_TCP,
+	VCAP_IS2_HK_L4_SPORT,
+	VCAP_IS2_HK_L4_DPORT,
+	VCAP_IS2_HK_L4_RNG,
+	VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
+	VCAP_IS2_HK_L4_SEQUENCE_EQ0,
+	VCAP_IS2_HK_L4_URG,
+	VCAP_IS2_HK_L4_ACK,
+	VCAP_IS2_HK_L4_PSH,
+	VCAP_IS2_HK_L4_RST,
+	VCAP_IS2_HK_L4_SYN,
+	VCAP_IS2_HK_L4_FIN,
+	VCAP_IS2_HK_L4_1588_DOM,
+	VCAP_IS2_HK_L4_1588_VER,
+	/* IP4_OTHER (TYPE=101) */
+	VCAP_IS2_HK_IP4_L3_PROTO,
+	VCAP_IS2_HK_L3_PAYLOAD,
+	/* IP6_STD (TYPE=110) */
+	VCAP_IS2_HK_IP6_L3_TTL_GT0,
+	VCAP_IS2_HK_IP6_L3_PROTO,
+	VCAP_IS2_HK_L3_IP6_SIP,
+	/* OAM (TYPE=111) */
+	VCAP_IS2_HK_OAM_MEL_FLAGS,
+	VCAP_IS2_HK_OAM_VER,
+	VCAP_IS2_HK_OAM_OPCODE,
+	VCAP_IS2_HK_OAM_FLAGS,
+	VCAP_IS2_HK_OAM_MEPID,
+	VCAP_IS2_HK_OAM_CCM_CNTS_EQ0,
+	VCAP_IS2_HK_OAM_IS_Y1731,
+};
+
+struct vcap_field {
+	int offset;
+	int length;
+};
+
+enum vcap_is2_action_field {
+	VCAP_IS2_ACT_HIT_ME_ONCE,
+	VCAP_IS2_ACT_CPU_COPY_ENA,
+	VCAP_IS2_ACT_CPU_QU_NUM,
+	VCAP_IS2_ACT_MASK_MODE,
+	VCAP_IS2_ACT_MIRROR_ENA,
+	VCAP_IS2_ACT_LRN_DIS,
+	VCAP_IS2_ACT_POLICE_ENA,
+	VCAP_IS2_ACT_POLICE_IDX,
+	VCAP_IS2_ACT_POLICE_VCAP_ONLY,
+	VCAP_IS2_ACT_PORT_MASK,
+	VCAP_IS2_ACT_REW_OP,
+	VCAP_IS2_ACT_SMAC_REPLACE_ENA,
+	VCAP_IS2_ACT_RSV,
+	VCAP_IS2_ACT_ACL_ID,
+	VCAP_IS2_ACT_HIT_CNT,
+};
+
+#endif /* _OCELOT_VCAP_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 07/10] net: mscc: ocelot: remove port_pcs_init indirection for VSC7514
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (5 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 06/10] net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 08/10] net: mscc: ocelot: parameterize the vcap_is2 properties Vladimir Oltean
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

The Felix driver is now using its own PHYLINK instance, not calling into
ocelot_adjust_link. So the port_pcs_init function pointer is an
unnecessary indirection. Remove it.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
---
Changes in v2:
None.

 drivers/net/ethernet/mscc/ocelot.c       | 19 +++++++++++++++++--
 drivers/net/ethernet/mscc/ocelot_board.c | 24 ------------------------
 include/soc/mscc/ocelot.h                |  3 ---
 3 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 2c307aa8bf3e..06f9d013f807 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -442,8 +442,23 @@ void ocelot_adjust_link(struct ocelot *ocelot, int port,
 	ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA |
 			   mode, DEV_MAC_MODE_CFG);
 
-	if (ocelot->ops->pcs_init)
-		ocelot->ops->pcs_init(ocelot, port);
+	/* Disable HDX fast control */
+	ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS,
+			   DEV_PORT_MISC);
+
+	/* SGMII only for now */
+	ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA,
+			   PCS1G_MODE_CFG);
+	ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG);
+
+	/* Enable PCS */
+	ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG);
+
+	/* No aneg on SGMII */
+	ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG);
+
+	/* No loopback */
+	ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
 
 	/* Enable MAC module */
 	ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA |
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index 2f52d2866c9d..8234631a0911 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -212,29 +212,6 @@ static const struct of_device_id mscc_ocelot_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
 
-static void ocelot_port_pcs_init(struct ocelot *ocelot, int port)
-{
-	struct ocelot_port *ocelot_port = ocelot->ports[port];
-
-	/* Disable HDX fast control */
-	ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS,
-			   DEV_PORT_MISC);
-
-	/* SGMII only for now */
-	ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA,
-			   PCS1G_MODE_CFG);
-	ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG);
-
-	/* Enable PCS */
-	ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG);
-
-	/* No aneg on SGMII */
-	ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG);
-
-	/* No loopback */
-	ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
-}
-
 static int ocelot_reset(struct ocelot *ocelot)
 {
 	int retries = 100;
@@ -259,7 +236,6 @@ static int ocelot_reset(struct ocelot *ocelot)
 }
 
 static const struct ocelot_ops ocelot_ops = {
-	.pcs_init		= ocelot_port_pcs_init,
 	.reset			= ocelot_reset,
 };
 
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index f9da90c5171b..ab342eef251c 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -462,7 +462,6 @@ enum ocelot_tag_prefix {
 struct ocelot;
 
 struct ocelot_ops {
-	void (*pcs_init)(struct ocelot *ocelot, int port);
 	int (*reset)(struct ocelot *ocelot);
 };
 
@@ -538,8 +537,6 @@ struct ocelot {
 	struct mutex			ptp_lock;
 	/* Protects the PTP clock */
 	spinlock_t			ptp_clock_lock;
-
-	void (*port_pcs_init)(struct ocelot_port *port);
 };
 
 #define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 08/10] net: mscc: ocelot: parameterize the vcap_is2 properties
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (6 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 07/10] net: mscc: ocelot: remove port_pcs_init indirection for VSC7514 Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-03-05  7:16   ` Allan W. Nielsen
  2020-02-29 14:31 ` [PATCH v2 net-next 09/10] net: dsa: Add bypass operations for the flower classifier-action filter Vladimir Oltean
  2020-02-29 14:31 ` [PATCH v2 net-next 10/10] net: dsa: felix: Wire up the ocelot cls_flower methods Vladimir Oltean
  9 siblings, 1 reply; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

Remove the definitions for the VCAP IS2 table from ocelot_ace.c, since
it is specific to VSC7514.

The VSC9959 VCAP IS2 table supports more rules (1024 instead of 64) and
has a different width for the action (89 bits instead of 99).

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v2:
Added back macro definitions for VSC7514 port count and rule count.

 drivers/net/ethernet/mscc/ocelot_ace.c   | 134 +++++++++--------------
 drivers/net/ethernet/mscc/ocelot_board.c |  30 +++++
 include/soc/mscc/ocelot.h                |   1 +
 include/soc/mscc/ocelot_vcap.h           |  37 +++++--
 4 files changed, 114 insertions(+), 88 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index 9922033a2aaf..906b54025b17 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -11,53 +11,7 @@
 #include "ocelot_s2.h"
 
 #define OCELOT_POLICER_DISCARD 0x17f
-
-struct vcap_props {
-	const char *name; /* Symbolic name */
-	u16 tg_width; /* Type-group width (in bits) */
-	u16 sw_count; /* Sub word count */
-	u16 entry_count; /* Entry count */
-	u16 entry_words; /* Number of entry words */
-	u16 entry_width; /* Entry width (in bits) */
-	u16 action_count; /* Action count */
-	u16 action_words; /* Number of action words */
-	u16 action_width; /* Action width (in bits) */
-	u16 action_type_width; /* Action type width (in bits) */
-	struct {
-		u16 width; /* Action type width (in bits) */
-		u16 count; /* Action type sub word count */
-	} action_table[2];
-	u16 counter_words; /* Number of counter words */
-	u16 counter_width; /* Counter width (in bits) */
-};
-
 #define ENTRY_WIDTH 32
-#define BITS_TO_32BIT(x) (1 + (((x) - 1) / ENTRY_WIDTH))
-
-static const struct vcap_props vcap_is2 = {
-	.name = "IS2",
-	.tg_width = 2,
-	.sw_count = 4,
-	.entry_count = VCAP_IS2_CNT,
-	.entry_words = BITS_TO_32BIT(VCAP_IS2_ENTRY_WIDTH),
-	.entry_width = VCAP_IS2_ENTRY_WIDTH,
-	.action_count = (VCAP_IS2_CNT + VCAP_PORT_CNT + 2),
-	.action_words = BITS_TO_32BIT(VCAP_IS2_ACTION_WIDTH),
-	.action_width = (VCAP_IS2_ACTION_WIDTH),
-	.action_type_width = 1,
-	.action_table = {
-		{
-			.width = 49,
-			.count = 2
-		},
-		{
-			.width = 6,
-			.count = 4
-		},
-	},
-	.counter_words = BITS_TO_32BIT(4 * ENTRY_WIDTH),
-	.counter_width = ENTRY_WIDTH,
-};
 
 enum vcap_sel {
 	VCAP_SEL_ENTRY = 0x1,
@@ -100,11 +54,13 @@ static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot)
 
 static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
 {
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+
 	u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
 		     S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
 		     S2_CORE_UPDATE_CTRL_UPDATE_SHOT);
 
-	if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2.entry_count)
+	if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2->entry_count)
 		return;
 
 	if (!(sel & VCAP_SEL_ENTRY))
@@ -125,14 +81,19 @@ static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
 /* Convert from 0-based row to VCAP entry row and run command */
 static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel)
 {
-	vcap_cmd(ocelot, vcap_is2.entry_count - row - 1, cmd, sel);
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+
+	vcap_cmd(ocelot, vcap_is2->entry_count - row - 1, cmd, sel);
 }
 
 static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
 {
-	u32 i;
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+	u32 entry_words, i;
+
+	entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH);
 
-	for (i = 0; i < vcap_is2.entry_words; i++) {
+	for (i = 0; i < entry_words; i++) {
 		ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i);
 		ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i);
 	}
@@ -141,9 +102,12 @@ static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
 
 static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
 {
-	u32 i;
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+	u32 entry_words, i;
+
+	entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH);
 
-	for (i = 0; i < vcap_is2.entry_words; i++) {
+	for (i = 0; i < entry_words; i++) {
 		data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i);
 		// Invert mask
 		data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i);
@@ -153,49 +117,56 @@ static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
 
 static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
 {
-	u32 i, width, mask;
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+	u32 action_words, i, width, mask;
 
 	/* Encode action type */
-	width = vcap_is2.action_type_width;
+	width = vcap_is2->action_type_width;
 	if (width) {
 		mask = GENMASK(width, 0);
 		data->action[0] = ((data->action[0] & ~mask) | data->type);
 	}
 
-	for (i = 0; i < vcap_is2.action_words; i++)
-		ocelot_write_rix(ocelot, data->action[i],
-				 S2_CACHE_ACTION_DAT, i);
+	action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
 
-	for (i = 0; i < vcap_is2.counter_words; i++)
-		ocelot_write_rix(ocelot, data->counter[i],
-				 S2_CACHE_CNT_DAT, i);
+	for (i = 0; i < action_words; i++)
+		ocelot_write_rix(ocelot, data->action[i], S2_CACHE_ACTION_DAT,
+				 i);
+
+	for (i = 0; i < vcap_is2->counter_words; i++)
+		ocelot_write_rix(ocelot, data->counter[i], S2_CACHE_CNT_DAT, i);
 }
 
 static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
 {
-	u32 i, width;
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+	u32 action_words, i, width;
+
+	action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
 
-	for (i = 0; i < vcap_is2.action_words; i++)
+	for (i = 0; i < action_words; i++)
 		data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT,
 						  i);
 
-	for (i = 0; i < vcap_is2.counter_words; i++)
+	for (i = 0; i < vcap_is2->counter_words; i++)
 		data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i);
 
 	/* Extract action type */
-	width = vcap_is2.action_type_width;
+	width = vcap_is2->action_type_width;
 	data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0);
 }
 
 /* Calculate offsets for entry */
-static void is2_data_get(struct vcap_data *data, int ix)
+static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix)
 {
-	u32 i, col, offset, count, cnt, base, width = vcap_is2.tg_width;
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+	u32 i, col, offset, count, cnt, base;
+	u32 width = vcap_is2->tg_width;
 
 	count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4);
 	col = (ix % 2);
-	cnt = (vcap_is2.sw_count / count);
-	base = (vcap_is2.sw_count - col * cnt - cnt);
+	cnt = (vcap_is2->sw_count / count);
+	base = (vcap_is2->sw_count - col * cnt - cnt);
 	data->tg_value = 0;
 	data->tg_mask = 0;
 	for (i = 0; i < cnt; i++) {
@@ -206,13 +177,13 @@ static void is2_data_get(struct vcap_data *data, int ix)
 
 	/* Calculate key/action/counter offsets */
 	col = (count - col - 1);
-	data->key_offset = (base * vcap_is2.entry_width) / vcap_is2.sw_count;
-	data->counter_offset = (cnt * col * vcap_is2.counter_width);
+	data->key_offset = (base * vcap_is2->entry_width) / vcap_is2->sw_count;
+	data->counter_offset = (cnt * col * vcap_is2->counter_width);
 	i = data->type;
-	width = vcap_is2.action_table[i].width;
-	cnt = vcap_is2.action_table[i].count;
+	width = vcap_is2->action_table[i].width;
+	cnt = vcap_is2->action_table[i].count;
 	data->action_offset =
-		(((cnt * col * width) / count) + vcap_is2.action_type_width);
+		(((cnt * col * width) / count) + vcap_is2->action_type_width);
 }
 
 static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value)
@@ -354,6 +325,7 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
 static void is2_entry_set(struct ocelot *ocelot, int ix,
 			  struct ocelot_ace_rule *ace)
 {
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
 	u32 val, msk, type, type_mask = 0xf, i, count;
 	struct ocelot_ace_vlan *tag = &ace->vlan;
 	struct ocelot_vcap_u64 payload;
@@ -369,7 +341,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 	vcap_cache2action(ocelot, &data);
 
 	data.tg_sw = VCAP_TG_HALF;
-	is2_data_get(&data, ix);
+	is2_data_get(ocelot, &data, ix);
 	data.tg = (data.tg & ~data.tg_mask);
 	if (ace->prio != 0)
 		data.tg |= data.tg_value;
@@ -627,7 +599,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 	default:
 		type = 0;
 		type_mask = 0;
-		count = (vcap_is2.entry_width / 2);
+		count = vcap_is2->entry_width / 2;
 		/* Iterate over the non-common part of the key and
 		 * clear entry data
 		 */
@@ -641,7 +613,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 	vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
 	is2_action_set(ocelot, &data, ace->action);
 	vcap_data_set(data.counter, data.counter_offset,
-		      vcap_is2.counter_width, ace->stats.pkts);
+		      vcap_is2->counter_width, ace->stats.pkts);
 
 	/* Write row */
 	vcap_entry2cache(ocelot, &data);
@@ -652,6 +624,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
 			  int ix)
 {
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
 	struct vcap_data data;
 	int row = (ix / 2);
 	u32 cnt;
@@ -659,9 +632,9 @@ static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
 	vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
 	vcap_cache2action(ocelot, &data);
 	data.tg_sw = VCAP_TG_HALF;
-	is2_data_get(&data, ix);
+	is2_data_get(ocelot, &data, ix);
 	cnt = vcap_data_get(data.counter, data.counter_offset,
-			    vcap_is2.counter_width);
+			    vcap_is2->counter_width);
 
 	rule->stats.pkts = cnt;
 }
@@ -805,16 +778,17 @@ int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
 
 int ocelot_ace_init(struct ocelot *ocelot)
 {
+	const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
 	struct vcap_data data;
 
 	memset(&data, 0, sizeof(data));
 
 	vcap_entry2cache(ocelot, &data);
-	ocelot_write(ocelot, vcap_is2.entry_count, S2_CORE_MV_CFG);
+	ocelot_write(ocelot, vcap_is2->entry_count, S2_CORE_MV_CFG);
 	vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);
 
 	vcap_action2cache(ocelot, &data);
-	ocelot_write(ocelot, vcap_is2.action_count, S2_CORE_MV_CFG);
+	ocelot_write(ocelot, vcap_is2->action_count, S2_CORE_MV_CFG);
 	vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE,
 		 VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
 
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index 8234631a0911..3eb40a2dd0c9 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -18,6 +18,10 @@
 #include "ocelot.h"
 
 #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
+#define VSC7514_VCAP_IS2_CNT 64
+#define VSC7514_VCAP_IS2_ENTRY_WIDTH 376
+#define VSC7514_VCAP_IS2_ACTION_WIDTH 99
+#define VSC7514_VCAP_PORT_CNT 11
 
 static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
 {
@@ -337,6 +341,31 @@ static const struct vcap_field vsc7514_vcap_is2_actions[] = {
 	[VCAP_IS2_ACT_HIT_CNT]			= { 49, 32},
 };
 
+static const struct vcap_props vsc7514_vcap_props[] = {
+	[VCAP_IS2] = {
+		.tg_width = 2,
+		.sw_count = 4,
+		.entry_count = VSC7514_VCAP_IS2_CNT,
+		.entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH,
+		.action_count = VSC7514_VCAP_IS2_CNT +
+				VSC7514_VCAP_PORT_CNT + 2,
+		.action_width = 99,
+		.action_type_width = 1,
+		.action_table = {
+			[IS2_ACTION_TYPE_NORMAL] = {
+				.width = 49,
+				.count = 2
+			},
+			[IS2_ACTION_TYPE_SMAC_SIP] = {
+				.width = 6,
+				.count = 4
+			},
+		},
+		.counter_words = 4,
+		.counter_width = 32,
+	},
+};
+
 static int mscc_ocelot_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -439,6 +468,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
 
 	ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
 	ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
+	ocelot->vcap = vsc7514_vcap_props;
 
 	ocelot_init(ocelot);
 	/* No NPI port */
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index ab342eef251c..e572c6446df0 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -522,6 +522,7 @@ struct ocelot {
 
 	const struct vcap_field		*vcap_is2_keys;
 	const struct vcap_field		*vcap_is2_actions;
+	const struct vcap_props		*vcap;
 
 	/* Workqueue to check statistics for overflow with its lock */
 	struct mutex			stats_lock;
diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
index 0783f0ffc813..5748373ab4d3 100644
--- a/include/soc/mscc/ocelot_vcap.h
+++ b/include/soc/mscc/ocelot_vcap.h
@@ -11,6 +11,30 @@
  * =================================================================
  */
 
+enum {
+	/* VCAP_IS1, */
+	VCAP_IS2,
+	/* VCAP_ES0, */
+};
+
+struct vcap_props {
+	u16 tg_width; /* Type-group width (in bits) */
+	u16 sw_count; /* Sub word count */
+	u16 entry_count; /* Entry count */
+	u16 entry_words; /* Number of entry words */
+	u16 entry_width; /* Entry width (in bits) */
+	u16 action_count; /* Action count */
+	u16 action_words; /* Number of action words */
+	u16 action_width; /* Action width (in bits) */
+	u16 action_type_width; /* Action type width (in bits) */
+	struct {
+		u16 width; /* Action type width (in bits) */
+		u16 count; /* Action type sub word count */
+	} action_table[2];
+	u16 counter_words; /* Number of counter words */
+	u16 counter_width; /* Counter width (in bits) */
+};
+
 /* VCAP Type-Group values */
 #define VCAP_TG_NONE 0 /* Entry is invalid */
 #define VCAP_TG_FULL 1 /* Full entry */
@@ -22,11 +46,6 @@
  * =================================================================
  */
 
-#define VCAP_IS2_CNT 64
-#define VCAP_IS2_ENTRY_WIDTH 376
-#define VCAP_IS2_ACTION_WIDTH 99
-#define VCAP_PORT_CNT 11
-
 /* IS2 half key types */
 #define IS2_TYPE_ETYPE 0
 #define IS2_TYPE_LLC 1
@@ -42,9 +61,11 @@
 /* IS2 half key type mask for matching any IP */
 #define IS2_TYPE_MASK_IP_ANY 0xe
 
-/* IS2 action types */
-#define IS2_ACTION_TYPE_NORMAL 0
-#define IS2_ACTION_TYPE_SMAC_SIP 1
+enum {
+	IS2_ACTION_TYPE_NORMAL,
+	IS2_ACTION_TYPE_SMAC_SIP,
+	IS2_ACTION_TYPE_MAX,
+};
 
 /* IS2 MASK_MODE values */
 #define IS2_ACT_MASK_MODE_NONE 0
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 09/10] net: dsa: Add bypass operations for the flower classifier-action filter
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (7 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 08/10] net: mscc: ocelot: parameterize the vcap_is2 properties Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-03-03  4:09   ` Florian Fainelli
  2020-02-29 14:31 ` [PATCH v2 net-next 10/10] net: dsa: felix: Wire up the ocelot cls_flower methods Vladimir Oltean
  9 siblings, 1 reply; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

Due to the immense variety of classification keys and actions available
for tc-flower, as well as due to potentially very different DSA switch
capabilities, it doesn't make a lot of sense for the DSA mid layer to
even attempt to interpret these. So just pass them on to the underlying
switch driver.

DSA implements just the standard boilerplate for binding and unbinding
flow blocks to ports, since nobody wants to deal with that.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v2:
None.

 include/net/dsa.h |  6 +++++
 net/dsa/slave.c   | 60 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7d3d84f0ef42..beeb81a532e3 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -540,6 +540,12 @@ struct dsa_switch_ops {
 	/*
 	 * TC integration
 	 */
+	int	(*cls_flower_add)(struct dsa_switch *ds, int port,
+				  struct flow_cls_offload *cls, bool ingress);
+	int	(*cls_flower_del)(struct dsa_switch *ds, int port,
+				  struct flow_cls_offload *cls, bool ingress);
+	int	(*cls_flower_stats)(struct dsa_switch *ds, int port,
+				    struct flow_cls_offload *cls, bool ingress);
 	int	(*port_mirror_add)(struct dsa_switch *ds, int port,
 				   struct dsa_mall_mirror_tc_entry *mirror,
 				   bool ingress);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 088c886e609e..79d9b4384d7b 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -946,6 +946,64 @@ static int dsa_slave_setup_tc_cls_matchall(struct net_device *dev,
 	}
 }
 
+static int dsa_slave_add_cls_flower(struct net_device *dev,
+				    struct flow_cls_offload *cls,
+				    bool ingress)
+{
+	struct dsa_port *dp = dsa_slave_to_port(dev);
+	struct dsa_switch *ds = dp->ds;
+	int port = dp->index;
+
+	if (!ds->ops->cls_flower_add)
+		return -EOPNOTSUPP;
+
+	return ds->ops->cls_flower_add(ds, port, cls, ingress);
+}
+
+static int dsa_slave_del_cls_flower(struct net_device *dev,
+				    struct flow_cls_offload *cls,
+				    bool ingress)
+{
+	struct dsa_port *dp = dsa_slave_to_port(dev);
+	struct dsa_switch *ds = dp->ds;
+	int port = dp->index;
+
+	if (!ds->ops->cls_flower_del)
+		return -EOPNOTSUPP;
+
+	return ds->ops->cls_flower_del(ds, port, cls, ingress);
+}
+
+static int dsa_slave_stats_cls_flower(struct net_device *dev,
+				      struct flow_cls_offload *cls,
+				      bool ingress)
+{
+	struct dsa_port *dp = dsa_slave_to_port(dev);
+	struct dsa_switch *ds = dp->ds;
+	int port = dp->index;
+
+	if (!ds->ops->cls_flower_stats)
+		return -EOPNOTSUPP;
+
+	return ds->ops->cls_flower_stats(ds, port, cls, ingress);
+}
+
+static int dsa_slave_setup_tc_cls_flower(struct net_device *dev,
+					 struct flow_cls_offload *cls,
+					 bool ingress)
+{
+	switch (cls->command) {
+	case FLOW_CLS_REPLACE:
+		return dsa_slave_add_cls_flower(dev, cls, ingress);
+	case FLOW_CLS_DESTROY:
+		return dsa_slave_del_cls_flower(dev, cls, ingress);
+	case FLOW_CLS_STATS:
+		return dsa_slave_stats_cls_flower(dev, cls, ingress);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static int dsa_slave_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
 				       void *cb_priv, bool ingress)
 {
@@ -957,6 +1015,8 @@ static int dsa_slave_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
 	switch (type) {
 	case TC_SETUP_CLSMATCHALL:
 		return dsa_slave_setup_tc_cls_matchall(dev, type_data, ingress);
+	case TC_SETUP_CLSFLOWER:
+		return dsa_slave_setup_tc_cls_flower(dev, type_data, ingress);
 	default:
 		return -EOPNOTSUPP;
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 net-next 10/10] net: dsa: felix: Wire up the ocelot cls_flower methods
  2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
                   ` (8 preceding siblings ...)
  2020-02-29 14:31 ` [PATCH v2 net-next 09/10] net: dsa: Add bypass operations for the flower classifier-action filter Vladimir Oltean
@ 2020-02-29 14:31 ` Vladimir Oltean
  2020-03-05  7:18   ` Allan W. Nielsen
  9 siblings, 1 reply; 16+ messages in thread
From: Vladimir Oltean @ 2020-02-29 14:31 UTC (permalink / raw)
  To: davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, allan.nielsen, claudiu.manoil,
	netdev, UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1,
	yangbo.lu, po.liu, jiri, idosch, kuba

From: Vladimir Oltean <vladimir.oltean@nxp.com>

Export the cls_flower methods from the ocelot driver and hook them up to
the DSA passthrough layer.

Tables for the VCAP IS2 parameters, as well as half key packing (field
offsets and lengths) need to be defined for the VSC9959 core, as they
are different from Ocelot, mainly due to the different port count.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v2:
Defined VSC9959_VCAP_IS2_CNT, VSC9959_VCAP_IS2_ENTRY_WIDTH,
VSC9959_VCAP_PORT_CNT.

 drivers/net/dsa/ocelot/felix.c         |  31 ++++++
 drivers/net/dsa/ocelot/felix.h         |   3 +
 drivers/net/dsa/ocelot/felix_vsc9959.c | 131 +++++++++++++++++++++++++
 include/soc/mscc/ocelot.h              |   6 ++
 4 files changed, 171 insertions(+)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index f14595b8dad5..69546383a382 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -2,6 +2,7 @@
 /* Copyright 2019 NXP Semiconductors
  */
 #include <uapi/linux/if_bridge.h>
+#include <soc/mscc/ocelot_vcap.h>
 #include <soc/mscc/ocelot_qsys.h>
 #include <soc/mscc/ocelot_sys.h>
 #include <soc/mscc/ocelot_dev.h>
@@ -401,6 +402,9 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 	ocelot->stats_layout	= felix->info->stats_layout;
 	ocelot->num_stats	= felix->info->num_stats;
 	ocelot->shared_queue_sz	= felix->info->shared_queue_sz;
+	ocelot->vcap_is2_keys	= felix->info->vcap_is2_keys;
+	ocelot->vcap_is2_actions= felix->info->vcap_is2_actions;
+	ocelot->vcap		= felix->info->vcap;
 	ocelot->ops		= felix->info->ops;
 
 	port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t),
@@ -605,6 +609,30 @@ static bool felix_txtstamp(struct dsa_switch *ds, int port,
 	return false;
 }
 
+static int felix_cls_flower_add(struct dsa_switch *ds, int port,
+				struct flow_cls_offload *cls, bool ingress)
+{
+	struct ocelot *ocelot = ds->priv;
+
+	return ocelot_cls_flower_replace(ocelot, port, cls, ingress);
+}
+
+static int felix_cls_flower_del(struct dsa_switch *ds, int port,
+				struct flow_cls_offload *cls, bool ingress)
+{
+	struct ocelot *ocelot = ds->priv;
+
+	return ocelot_cls_flower_destroy(ocelot, port, cls, ingress);
+}
+
+static int felix_cls_flower_stats(struct dsa_switch *ds, int port,
+				  struct flow_cls_offload *cls, bool ingress)
+{
+	struct ocelot *ocelot = ds->priv;
+
+	return ocelot_cls_flower_stats(ocelot, port, cls, ingress);
+}
+
 static const struct dsa_switch_ops felix_switch_ops = {
 	.get_tag_protocol	= felix_get_tag_protocol,
 	.setup			= felix_setup,
@@ -636,6 +664,9 @@ static const struct dsa_switch_ops felix_switch_ops = {
 	.port_hwtstamp_set	= felix_hwtstamp_set,
 	.port_rxtstamp		= felix_rxtstamp,
 	.port_txtstamp		= felix_txtstamp,
+	.cls_flower_add		= felix_cls_flower_add,
+	.cls_flower_del		= felix_cls_flower_del,
+	.cls_flower_stats	= felix_cls_flower_stats,
 };
 
 static struct felix_info *felix_instance_tbl[] = {
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index 3a7580015b62..82d46f260041 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -18,6 +18,9 @@ struct felix_info {
 	const struct ocelot_stat_layout	*stats_layout;
 	unsigned int			num_stats;
 	int				num_ports;
+	struct vcap_field		*vcap_is2_keys;
+	struct vcap_field		*vcap_is2_actions;
+	const struct vcap_props		*vcap;
 	int				switch_pci_bar;
 	int				imdio_pci_bar;
 	int	(*mdio_bus_alloc)(struct ocelot *ocelot);
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 93800e81cdd4..b4078f3c5c38 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -3,12 +3,17 @@
  * Copyright 2018-2019 NXP Semiconductors
  */
 #include <linux/fsl/enetc_mdio.h>
+#include <soc/mscc/ocelot_vcap.h>
 #include <soc/mscc/ocelot_sys.h>
 #include <soc/mscc/ocelot.h>
 #include <linux/iopoll.h>
 #include <linux/pci.h>
 #include "felix.h"
 
+#define VSC9959_VCAP_IS2_CNT		1024
+#define VSC9959_VCAP_IS2_ENTRY_WIDTH	376
+#define VSC9959_VCAP_PORT_CNT		6
+
 /* TODO: should find a better place for these */
 #define USXGMII_BMCR_RESET		BIT(15)
 #define USXGMII_BMCR_AN_EN		BIT(12)
@@ -547,6 +552,129 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
 	{ .offset = 0x111,	.name = "drop_green_prio_7", },
 };
 
+struct vcap_field vsc9959_vcap_is2_keys[] = {
+	/* Common: 41 bits */
+	[VCAP_IS2_TYPE]				= {  0,   4},
+	[VCAP_IS2_HK_FIRST]			= {  4,   1},
+	[VCAP_IS2_HK_PAG]			= {  5,   8},
+	[VCAP_IS2_HK_IGR_PORT_MASK]		= { 13,   7},
+	[VCAP_IS2_HK_RSV2]			= { 20,   1},
+	[VCAP_IS2_HK_HOST_MATCH]		= { 21,   1},
+	[VCAP_IS2_HK_L2_MC]			= { 22,   1},
+	[VCAP_IS2_HK_L2_BC]			= { 23,   1},
+	[VCAP_IS2_HK_VLAN_TAGGED]		= { 24,   1},
+	[VCAP_IS2_HK_VID]			= { 25,  12},
+	[VCAP_IS2_HK_DEI]			= { 37,   1},
+	[VCAP_IS2_HK_PCP]			= { 38,   3},
+	/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
+	[VCAP_IS2_HK_L2_DMAC]			= { 41,  48},
+	[VCAP_IS2_HK_L2_SMAC]			= { 89,  48},
+	/* MAC_ETYPE (TYPE=000) */
+	[VCAP_IS2_HK_MAC_ETYPE_ETYPE]		= {137,  16},
+	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]	= {153,  16},
+	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]	= {169,   8},
+	[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]	= {177,   3},
+	/* MAC_LLC (TYPE=001) */
+	[VCAP_IS2_HK_MAC_LLC_L2_LLC]		= {137,  40},
+	/* MAC_SNAP (TYPE=010) */
+	[VCAP_IS2_HK_MAC_SNAP_L2_SNAP]		= {137,  40},
+	/* MAC_ARP (TYPE=011) */
+	[VCAP_IS2_HK_MAC_ARP_SMAC]		= { 41,  48},
+	[VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]	= { 89,   1},
+	[VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]	= { 90,   1},
+	[VCAP_IS2_HK_MAC_ARP_LEN_OK]		= { 91,   1},
+	[VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]	= { 92,   1},
+	[VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]	= { 93,   1},
+	[VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]	= { 94,   1},
+	[VCAP_IS2_HK_MAC_ARP_OPCODE]		= { 95,   2},
+	[VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]	= { 97,  32},
+	[VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]	= {129,  32},
+	[VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]	= {161,   1},
+	/* IP4_TCP_UDP / IP4_OTHER common */
+	[VCAP_IS2_HK_IP4]			= { 41,   1},
+	[VCAP_IS2_HK_L3_FRAGMENT]		= { 42,   1},
+	[VCAP_IS2_HK_L3_FRAG_OFS_GT0]		= { 43,   1},
+	[VCAP_IS2_HK_L3_OPTIONS]		= { 44,   1},
+	[VCAP_IS2_HK_IP4_L3_TTL_GT0]		= { 45,   1},
+	[VCAP_IS2_HK_L3_TOS]			= { 46,   8},
+	[VCAP_IS2_HK_L3_IP4_DIP]		= { 54,  32},
+	[VCAP_IS2_HK_L3_IP4_SIP]		= { 86,  32},
+	[VCAP_IS2_HK_DIP_EQ_SIP]		= {118,   1},
+	/* IP4_TCP_UDP (TYPE=100) */
+	[VCAP_IS2_HK_TCP]			= {119,   1},
+	[VCAP_IS2_HK_L4_SPORT]			= {120,  16},
+	[VCAP_IS2_HK_L4_DPORT]			= {136,  16},
+	[VCAP_IS2_HK_L4_RNG]			= {152,   8},
+	[VCAP_IS2_HK_L4_SPORT_EQ_DPORT]		= {160,   1},
+	[VCAP_IS2_HK_L4_SEQUENCE_EQ0]		= {161,   1},
+	[VCAP_IS2_HK_L4_URG]			= {162,   1},
+	[VCAP_IS2_HK_L4_ACK]			= {163,   1},
+	[VCAP_IS2_HK_L4_PSH]			= {164,   1},
+	[VCAP_IS2_HK_L4_RST]			= {165,   1},
+	[VCAP_IS2_HK_L4_SYN]			= {166,   1},
+	[VCAP_IS2_HK_L4_FIN]			= {167,   1},
+	[VCAP_IS2_HK_L4_1588_DOM]		= {168,   8},
+	[VCAP_IS2_HK_L4_1588_VER]		= {176,   4},
+	/* IP4_OTHER (TYPE=101) */
+	[VCAP_IS2_HK_IP4_L3_PROTO]		= {119,   8},
+	[VCAP_IS2_HK_L3_PAYLOAD]		= {127,  56},
+	/* IP6_STD (TYPE=110) */
+	[VCAP_IS2_HK_IP6_L3_TTL_GT0]		= { 41,   1},
+	[VCAP_IS2_HK_L3_IP6_SIP]		= { 42, 128},
+	[VCAP_IS2_HK_IP6_L3_PROTO]		= {170,   8},
+	/* OAM (TYPE=111) */
+	[VCAP_IS2_HK_OAM_MEL_FLAGS]		= {137,   7},
+	[VCAP_IS2_HK_OAM_VER]			= {144,   5},
+	[VCAP_IS2_HK_OAM_OPCODE]		= {149,   8},
+	[VCAP_IS2_HK_OAM_FLAGS]			= {157,   8},
+	[VCAP_IS2_HK_OAM_MEPID]			= {165,  16},
+	[VCAP_IS2_HK_OAM_CCM_CNTS_EQ0]		= {181,   1},
+	[VCAP_IS2_HK_OAM_IS_Y1731]		= {182,   1},
+};
+
+struct vcap_field vsc9959_vcap_is2_actions[] = {
+	[VCAP_IS2_ACT_HIT_ME_ONCE]		= {  0,  1},
+	[VCAP_IS2_ACT_CPU_COPY_ENA]		= {  1,  1},
+	[VCAP_IS2_ACT_CPU_QU_NUM]		= {  2,  3},
+	[VCAP_IS2_ACT_MASK_MODE]		= {  5,  2},
+	[VCAP_IS2_ACT_MIRROR_ENA]		= {  7,  1},
+	[VCAP_IS2_ACT_LRN_DIS]			= {  8,  1},
+	[VCAP_IS2_ACT_POLICE_ENA]		= {  9,  1},
+	[VCAP_IS2_ACT_POLICE_IDX]		= { 10,  9},
+	[VCAP_IS2_ACT_POLICE_VCAP_ONLY]		= { 19,  1},
+	[VCAP_IS2_ACT_PORT_MASK]		= { 20, 11},
+	[VCAP_IS2_ACT_REW_OP]			= { 31,  9},
+	[VCAP_IS2_ACT_SMAC_REPLACE_ENA]		= { 40,  1},
+	[VCAP_IS2_ACT_RSV]			= { 41,  2},
+	[VCAP_IS2_ACT_ACL_ID]			= { 43,  6},
+	[VCAP_IS2_ACT_HIT_CNT]			= { 49, 32},
+};
+
+static const struct vcap_props vsc9959_vcap_props[] = {
+	[VCAP_IS2] = {
+		.tg_width = 2,
+		.sw_count = 4,
+		.entry_count = VSC9959_VCAP_IS2_CNT,
+		.entry_width = VSC9959_VCAP_IS2_ENTRY_WIDTH,
+		.action_count = VSC9959_VCAP_IS2_CNT +
+				VSC9959_VCAP_PORT_CNT + 2,
+		.action_width = 89,
+		.action_type_width = 1,
+		.action_table = {
+			[IS2_ACTION_TYPE_NORMAL] = {
+				.width = 44,
+				.count = 2
+			},
+			[IS2_ACTION_TYPE_SMAC_SIP] = {
+				.width = 6,
+				.count = 4
+			},
+		},
+		.counter_words = 4,
+		.counter_width = 32,
+	},
+};
+
 #define VSC9959_INIT_TIMEOUT			50000
 #define VSC9959_GCB_RST_SLEEP			100
 #define VSC9959_SYS_RAMINIT_SLEEP		80
@@ -1088,6 +1216,9 @@ struct felix_info felix_info_vsc9959 = {
 	.ops			= &vsc9959_ops,
 	.stats_layout		= vsc9959_stats_layout,
 	.num_stats		= ARRAY_SIZE(vsc9959_stats_layout),
+	.vcap_is2_keys		= vsc9959_vcap_is2_keys,
+	.vcap_is2_actions	= vsc9959_vcap_is2_actions,
+	.vcap			= vsc9959_vcap_props,
 	.shared_queue_sz	= 128 * 1024,
 	.num_ports		= 6,
 	.switch_pci_bar		= 4,
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index e572c6446df0..63d93ac1879e 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -608,5 +608,11 @@ int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
 int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
 				 struct sk_buff *skb);
 void ocelot_get_txtstamp(struct ocelot *ocelot);
+int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
+			      struct flow_cls_offload *f, bool ingress);
+int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
+			      struct flow_cls_offload *f, bool ingress);
+int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
+			    struct flow_cls_offload *f, bool ingress);
 
 #endif
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 net-next 09/10] net: dsa: Add bypass operations for the flower classifier-action filter
  2020-02-29 14:31 ` [PATCH v2 net-next 09/10] net: dsa: Add bypass operations for the flower classifier-action filter Vladimir Oltean
@ 2020-03-03  4:09   ` Florian Fainelli
  0 siblings, 0 replies; 16+ messages in thread
From: Florian Fainelli @ 2020-03-03  4:09 UTC (permalink / raw)
  To: Vladimir Oltean, davem
  Cc: horatiu.vultur, alexandre.belloni, andrew, vivien.didelot,
	joergen.andreasen, allan.nielsen, claudiu.manoil, netdev,
	UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1, yangbo.lu,
	po.liu, jiri, idosch, kuba



On 2/29/2020 6:31 AM, Vladimir Oltean wrote:
> From: Vladimir Oltean <vladimir.oltean@nxp.com>
> 
> Due to the immense variety of classification keys and actions available
> for tc-flower, as well as due to potentially very different DSA switch
> capabilities, it doesn't make a lot of sense for the DSA mid layer to
> even attempt to interpret these. So just pass them on to the underlying
> switch driver.
> 
> DSA implements just the standard boilerplate for binding and unbinding
> flow blocks to ports, since nobody wants to deal with that.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 net-next 05/10] net: mscc: ocelot: spell out full "ocelot" name instead of "oc"
  2020-02-29 14:31 ` [PATCH v2 net-next 05/10] net: mscc: ocelot: spell out full "ocelot" name instead of "oc" Vladimir Oltean
@ 2020-03-05  7:09   ` Allan W. Nielsen
  0 siblings, 0 replies; 16+ messages in thread
From: Allan W. Nielsen @ 2020-03-05  7:09 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: davem, horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, claudiu.manoil, netdev,
	UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1, yangbo.lu,
	po.liu, jiri, idosch, kuba

On 29.02.2020 16:31, Vladimir Oltean wrote:
>EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>From: Vladimir Oltean <vladimir.oltean@nxp.com>
>
>This is a cosmetic patch that makes the name of the driver private
>variable be used uniformly in ocelot_ace.c as in the rest of the driver.
>
>Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
>---
>Changes in v2:
>Patch is new.
>
> drivers/net/ethernet/mscc/ocelot_ace.c | 45 ++++++++++++++------------
> 1 file changed, 24 insertions(+), 21 deletions(-)
>
>diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
>index 375c7c6aa7d5..ec86d29d8be4 100644
>--- a/drivers/net/ethernet/mscc/ocelot_ace.c
>+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
>@@ -93,12 +93,12 @@ struct vcap_data {
>        u32 tg_mask; /* Current type-group mask */
> };
>
>-static u32 vcap_s2_read_update_ctrl(struct ocelot *oc)
>+static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot)
> {
>-       return ocelot_read(oc, S2_CORE_UPDATE_CTRL);
>+       return ocelot_read(ocelot, S2_CORE_UPDATE_CTRL);
> }
>
>-static void vcap_cmd(struct ocelot *oc, u16 ix, int cmd, int sel)
>+static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
> {
>        u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
>                     S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
>@@ -116,42 +116,42 @@ static void vcap_cmd(struct ocelot *oc, u16 ix, int cmd, int sel)
>        if (!(sel & VCAP_SEL_COUNTER))
>                value |= S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS;
>
>-       ocelot_write(oc, value, S2_CORE_UPDATE_CTRL);
>-       readx_poll_timeout(vcap_s2_read_update_ctrl, oc, value,
>+       ocelot_write(ocelot, value, S2_CORE_UPDATE_CTRL);
>+       readx_poll_timeout(vcap_s2_read_update_ctrl, ocelot, value,
>                                (value & S2_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0,
>                                10, 100000);
> }
>
> /* Convert from 0-based row to VCAP entry row and run command */
>-static void vcap_row_cmd(struct ocelot *oc, u32 row, int cmd, int sel)
>+static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel)
> {
>-       vcap_cmd(oc, vcap_is2.entry_count - row - 1, cmd, sel);
>+       vcap_cmd(ocelot, vcap_is2.entry_count - row - 1, cmd, sel);
> }
>
>-static void vcap_entry2cache(struct ocelot *oc, struct vcap_data *data)
>+static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
> {
>        u32 i;
>
>        for (i = 0; i < vcap_is2.entry_words; i++) {
>-               ocelot_write_rix(oc, data->entry[i], S2_CACHE_ENTRY_DAT, i);
>-               ocelot_write_rix(oc, ~data->mask[i], S2_CACHE_MASK_DAT, i);
>+               ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i);
>+               ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i);
>        }
>-       ocelot_write(oc, data->tg, S2_CACHE_TG_DAT);
>+       ocelot_write(ocelot, data->tg, S2_CACHE_TG_DAT);
> }
>
>-static void vcap_cache2entry(struct ocelot *oc, struct vcap_data *data)
>+static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
> {
>        u32 i;
>
>        for (i = 0; i < vcap_is2.entry_words; i++) {
>-               data->entry[i] = ocelot_read_rix(oc, S2_CACHE_ENTRY_DAT, i);
>+               data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i);
>                // Invert mask
>-               data->mask[i] = ~ocelot_read_rix(oc, S2_CACHE_MASK_DAT, i);
>+               data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i);
>        }
>-       data->tg = ocelot_read(oc, S2_CACHE_TG_DAT);
>+       data->tg = ocelot_read(ocelot, S2_CACHE_TG_DAT);
> }
>
>-static void vcap_action2cache(struct ocelot *oc, struct vcap_data *data)
>+static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
> {
>        u32 i, width, mask;
>
>@@ -163,21 +163,24 @@ static void vcap_action2cache(struct ocelot *oc, struct vcap_data *data)
>        }
>
>        for (i = 0; i < vcap_is2.action_words; i++)
>-               ocelot_write_rix(oc, data->action[i], S2_CACHE_ACTION_DAT, i);
>+               ocelot_write_rix(ocelot, data->action[i],
>+                                S2_CACHE_ACTION_DAT, i);
>
>        for (i = 0; i < vcap_is2.counter_words; i++)
>-               ocelot_write_rix(oc, data->counter[i], S2_CACHE_CNT_DAT, i);
>+               ocelot_write_rix(ocelot, data->counter[i],
>+                                S2_CACHE_CNT_DAT, i);
> }
>
>-static void vcap_cache2action(struct ocelot *oc, struct vcap_data *data)
>+static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
> {
>        u32 i, width;
>
>        for (i = 0; i < vcap_is2.action_words; i++)
>-               data->action[i] = ocelot_read_rix(oc, S2_CACHE_ACTION_DAT, i);
>+               data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT,
>+                                                 i);
>
>        for (i = 0; i < vcap_is2.counter_words; i++)
>-               data->counter[i] = ocelot_read_rix(oc, S2_CACHE_CNT_DAT, i);
>+               data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i);
>
>        /* Extract action type */
>        width = vcap_is2.action_type_width;
>--
>2.17.1


Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 net-next 06/10] net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing
  2020-02-29 14:31 ` [PATCH v2 net-next 06/10] net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing Vladimir Oltean
@ 2020-03-05  7:15   ` Allan W. Nielsen
  0 siblings, 0 replies; 16+ messages in thread
From: Allan W. Nielsen @ 2020-03-05  7:15 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: davem, horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, claudiu.manoil, netdev,
	UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1, yangbo.lu,
	po.liu, jiri, idosch, kuba

On 29.02.2020 16:31, Vladimir Oltean wrote:
>EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>From: Vladimir Oltean <vladimir.oltean@nxp.com>
>
>The IGR_PORT_MASK key width is different between the 11-port VSC7514 and
>the 6-port VSC9959 switches. And since IGR_PORT_MASK is one of the first
>fields of a VCAP key entry, it means that all further field
>offset/length pairs are shifted between the 2.
>
>The ocelot driver performs packing of VCAP half keys with the help of
>some preprocessor macros:
>
>- A set of macros for defining the HKO (Half Key Offset) and HKL (Half
>  Key Length) of each possible key field. The offset of each field is
>  defined as the sum between the offset and the sum of the previous
>  field.
>
>- A set of accessors on top of vcap_key_set for shorter (aka less
>  typing) access to the HKO and HKL of each key field.
>
>Since the field offsets and lengths are different between switches,
>defining them through the preprocessor isn't going to fly. So introduce
>a structure holding (offset, length) pairs and instantiate it in
>ocelot_board.c for VSC7514. In a future patch, a similar structure will
>be instantiated in felix_vsc9959.c for NXP LS1028A.
>
>The accessors also need to go. They are based on macro name
>concatenation, which is horrible to understand and follow.
>
>Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
>Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
>---
>Changes in v2:
>Added "struct ocelot *ocelot" as argument to all functions that need to
>pack VCAP key fields, to avoid passing the ocelot backpointer to struct
>vcap_data and cause difficult-to-solve reverse Christmas tree line
>ordering issues.
>
> drivers/net/ethernet/mscc/ocelot_ace.c   | 315 +++++++++++-------
> drivers/net/ethernet/mscc/ocelot_board.c | 102 ++++++
> drivers/net/ethernet/mscc/ocelot_vcap.h  | 403 -----------------------
> include/soc/mscc/ocelot.h                |   3 +
> include/soc/mscc/ocelot_vcap.h           | 184 +++++++++++
> 5 files changed, 484 insertions(+), 523 deletions(-)
> delete mode 100644 drivers/net/ethernet/mscc/ocelot_vcap.h
> create mode 100644 include/soc/mscc/ocelot_vcap.h
>
>diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
>index ec86d29d8be4..9922033a2aaf 100644
>--- a/drivers/net/ethernet/mscc/ocelot_ace.c
>+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
>@@ -6,8 +6,8 @@
> #include <linux/iopoll.h>
> #include <linux/proc_fs.h>
>
>+#include <soc/mscc/ocelot_vcap.h>
> #include "ocelot_ace.h"
>-#include "ocelot_vcap.h"
> #include "ocelot_s2.h"
>
> #define OCELOT_POLICER_DISCARD 0x17f
>@@ -47,7 +47,7 @@ static const struct vcap_props vcap_is2 = {
>        .action_type_width = 1,
>        .action_table = {
>                {
>-                       .width = (IS2_AO_ACL_ID + IS2_AL_ACL_ID),
>+                       .width = 49,
>                        .count = 2
>                },
>                {
>@@ -243,22 +243,39 @@ static u32 vcap_data_get(u32 *data, u32 offset, u32 len)
>        return value;
> }
>
>-static void vcap_key_set(struct vcap_data *data, u32 offset, u32 width,
>-                        u32 value, u32 mask)
>+static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
>+                              u32 value, u32 mask)
> {
>        vcap_data_set(data->entry, offset + data->key_offset, width, value);
>        vcap_data_set(data->mask, offset + data->key_offset, width, mask);
> }
>
>-static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val,
>-                              u8 *msk, u32 count)
>+static void vcap_key_set(struct ocelot *ocelot, struct vcap_data *data,
>+                        enum vcap_is2_half_key_field field,
>+                        u32 value, u32 mask)
>+{
>+       u32 offset = ocelot->vcap_is2_keys[field].offset;
>+       u32 length = ocelot->vcap_is2_keys[field].length;
>+
>+       vcap_key_field_set(data, offset, length, value, mask);
>+}
>+
>+static void vcap_key_bytes_set(struct ocelot *ocelot, struct vcap_data *data,
>+                              enum vcap_is2_half_key_field field,
>+                              u8 *val, u8 *msk)
> {
>+       u32 offset = ocelot->vcap_is2_keys[field].offset;
>+       u32 count  = ocelot->vcap_is2_keys[field].length;
>        u32 i, j, n = 0, value = 0, mask = 0;
>
>+       WARN_ON(count % 8);
>+
>        /* Data wider than 32 bits are split up in chunks of maximum 32 bits.
>         * The 32 LSB of the data are written to the 32 MSB of the TCAM.
>         */
>-       offset += (count * 8);
>+       offset += count;
>+       count /= 8;
>+
>        for (i = 0; i < count; i++) {
>                j = (count - i - 1);
>                value += (val[j] << n);
>@@ -266,7 +283,7 @@ static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val,
>                n += 8;
>                if (n == ENTRY_WIDTH || (i + 1) == count) {
>                        offset -= n;
>-                       vcap_key_set(data, offset, n, value, mask);
>+                       vcap_key_field_set(data, offset, n, value, mask);
>                        n = 0;
>                        value = 0;
>                        mask = 0;
>@@ -274,55 +291,62 @@ static void vcap_key_bytes_set(struct vcap_data *data, u32 offset, u8 *val,
>        }
> }
>
>-static void vcap_key_l4_port_set(struct vcap_data *data, u32 offset,
>+static void vcap_key_l4_port_set(struct ocelot *ocelot, struct vcap_data *data,
>+                                enum vcap_is2_half_key_field field,
>                                 struct ocelot_vcap_udp_tcp *port)
> {
>-       vcap_key_set(data, offset, 16, port->value, port->mask);
>+       u32 offset = ocelot->vcap_is2_keys[field].offset;
>+       u32 length = ocelot->vcap_is2_keys[field].length;
>+
>+       WARN_ON(length != 16);
>+
>+       vcap_key_field_set(data, offset, length, port->value, port->mask);
> }
>
>-static void vcap_key_bit_set(struct vcap_data *data, u32 offset,
>+static void vcap_key_bit_set(struct ocelot *ocelot, struct vcap_data *data,
>+                            enum vcap_is2_half_key_field field,
>                             enum ocelot_vcap_bit val)
> {
>-       vcap_key_set(data, offset, 1, val == OCELOT_VCAP_BIT_1 ? 1 : 0,
>-                    val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
>-}
>+       u32 offset = ocelot->vcap_is2_keys[field].offset;
>+       u32 length = ocelot->vcap_is2_keys[field].length;
>+       u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0);
>+       u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
>
>-#define VCAP_KEY_SET(fld, val, msk) \
>-       vcap_key_set(&data, IS2_HKO_##fld, IS2_HKL_##fld, val, msk)
>-#define VCAP_KEY_ANY_SET(fld) \
>-       vcap_key_set(&data, IS2_HKO_##fld, IS2_HKL_##fld, 0, 0)
>-#define VCAP_KEY_BIT_SET(fld, val) vcap_key_bit_set(&data, IS2_HKO_##fld, val)
>-#define VCAP_KEY_BYTES_SET(fld, val, msk) \
>-       vcap_key_bytes_set(&data, IS2_HKO_##fld, val, msk, IS2_HKL_##fld / 8)
>+       WARN_ON(length != 1);
>
>-static void vcap_action_set(struct vcap_data *data, u32 offset, u32 width,
>-                           u32 value)
>-{
>-       vcap_data_set(data->action, offset + data->action_offset, width, value);
>+       vcap_key_field_set(data, offset, length, value, msk);
> }
>
>-#define VCAP_ACT_SET(fld, val) \
>-       vcap_action_set(data, IS2_AO_##fld, IS2_AL_##fld, val)
>+static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data,
>+                           enum vcap_is2_action_field field, u32 value)
>+{
>+       int offset = ocelot->vcap_is2_actions[field].offset;
>+       int length = ocelot->vcap_is2_actions[field].length;
>+
>+       vcap_data_set(data->action, offset + data->action_offset, length,
>+                     value);
>+}
>
>-static void is2_action_set(struct vcap_data *data,
>+static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
>                           enum ocelot_ace_action action)
> {
>        switch (action) {
>        case OCELOT_ACL_ACTION_DROP:
>-               VCAP_ACT_SET(PORT_MASK, 0x0);
>-               VCAP_ACT_SET(MASK_MODE, 0x1);
>-               VCAP_ACT_SET(POLICE_ENA, 0x1);
>-               VCAP_ACT_SET(POLICE_IDX, OCELOT_POLICER_DISCARD);
>-               VCAP_ACT_SET(CPU_QU_NUM, 0x0);
>-               VCAP_ACT_SET(CPU_COPY_ENA, 0x0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX,
>+                               OCELOT_POLICER_DISCARD);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
>                break;
>        case OCELOT_ACL_ACTION_TRAP:
>-               VCAP_ACT_SET(PORT_MASK, 0x0);
>-               VCAP_ACT_SET(MASK_MODE, 0x1);
>-               VCAP_ACT_SET(POLICE_ENA, 0x0);
>-               VCAP_ACT_SET(POLICE_IDX, 0x0);
>-               VCAP_ACT_SET(CPU_QU_NUM, 0x0);
>-               VCAP_ACT_SET(CPU_COPY_ENA, 0x1);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, 0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
>+               vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1);
>                break;
>        }
> }
>@@ -352,53 +376,69 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>
>        data.type = IS2_ACTION_TYPE_NORMAL;
>
>-       VCAP_KEY_ANY_SET(PAG);
>-       VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port_mask);
>-       VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1);
>-       VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY);
>-       VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc);
>-       VCAP_KEY_BIT_SET(L2_BC, ace->dmac_bc);
>-       VCAP_KEY_BIT_SET(VLAN_TAGGED, tag->tagged);
>-       VCAP_KEY_SET(VID, tag->vid.value, tag->vid.mask);
>-       VCAP_KEY_SET(PCP, tag->pcp.value[0], tag->pcp.mask[0]);
>-       VCAP_KEY_BIT_SET(DEI, tag->dei);
>+       vcap_key_set(ocelot, &data, VCAP_IS2_HK_PAG, 0, 0);
>+       vcap_key_set(ocelot, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
>+                    ~ace->ingress_port_mask);
>+       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_1);
>+       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_HOST_MATCH,
>+                        OCELOT_VCAP_BIT_ANY);
>+       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc);
>+       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc);
>+       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
>+       vcap_key_set(ocelot, &data, VCAP_IS2_HK_VID,
>+                    tag->vid.value, tag->vid.mask);
>+       vcap_key_set(ocelot, &data, VCAP_IS2_HK_PCP,
>+                    tag->pcp.value[0], tag->pcp.mask[0]);
>+       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DEI, tag->dei);
>
>        switch (ace->type) {
>        case OCELOT_ACE_TYPE_ETYPE: {
>                struct ocelot_ace_frame_etype *etype = &ace->frame.etype;
>
>                type = IS2_TYPE_ETYPE;
>-               VCAP_KEY_BYTES_SET(L2_DMAC, etype->dmac.value,
>-                                  etype->dmac.mask);
>-               VCAP_KEY_BYTES_SET(L2_SMAC, etype->smac.value,
>-                                  etype->smac.mask);
>-               VCAP_KEY_BYTES_SET(MAC_ETYPE_ETYPE, etype->etype.value,
>-                                  etype->etype.mask);
>-               VCAP_KEY_ANY_SET(MAC_ETYPE_L2_PAYLOAD); // Clear unused bits
>-               vcap_key_bytes_set(&data, IS2_HKO_MAC_ETYPE_L2_PAYLOAD,
>-                                  etype->data.value, etype->data.mask, 2);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
>+                                  etype->dmac.value, etype->dmac.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
>+                                  etype->smac.value, etype->smac.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE,
>+                                  etype->etype.value, etype->etype.mask);
>+               /* Clear unused bits */
>+               vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
>+                            0, 0);
>+               vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
>+                            0, 0);
>+               vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
>+                            0, 0);
>+               vcap_key_bytes_set(ocelot, &data,
>+                                  VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
>+                                  etype->data.value, etype->data.mask);
>                break;
>        }
>        case OCELOT_ACE_TYPE_LLC: {
>                struct ocelot_ace_frame_llc *llc = &ace->frame.llc;
>
>                type = IS2_TYPE_LLC;
>-               VCAP_KEY_BYTES_SET(L2_DMAC, llc->dmac.value, llc->dmac.mask);
>-               VCAP_KEY_BYTES_SET(L2_SMAC, llc->smac.value, llc->smac.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
>+                                  llc->dmac.value, llc->dmac.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
>+                                  llc->smac.value, llc->smac.mask);
>                for (i = 0; i < 4; i++) {
>                        payload.value[i] = llc->llc.value[i];
>                        payload.mask[i] = llc->llc.mask[i];
>                }
>-               VCAP_KEY_BYTES_SET(MAC_LLC_L2_LLC, payload.value, payload.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC,
>+                                  payload.value, payload.mask);
>                break;
>        }
>        case OCELOT_ACE_TYPE_SNAP: {
>                struct ocelot_ace_frame_snap *snap = &ace->frame.snap;
>
>                type = IS2_TYPE_SNAP;
>-               VCAP_KEY_BYTES_SET(L2_DMAC, snap->dmac.value, snap->dmac.mask);
>-               VCAP_KEY_BYTES_SET(L2_SMAC, snap->smac.value, snap->smac.mask);
>-               VCAP_KEY_BYTES_SET(MAC_SNAP_L2_SNAP,
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
>+                                  snap->dmac.value, snap->dmac.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
>+                                  snap->smac.value, snap->smac.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
>                                   ace->frame.snap.snap.value,
>                                   ace->frame.snap.snap.mask);
>                break;
>@@ -407,26 +447,42 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>                struct ocelot_ace_frame_arp *arp = &ace->frame.arp;
>
>                type = IS2_TYPE_ARP;
>-               VCAP_KEY_BYTES_SET(MAC_ARP_L2_SMAC, arp->smac.value,
>-                                  arp->smac.mask);
>-               VCAP_KEY_BIT_SET(MAC_ARP_ARP_ADDR_SPACE_OK, arp->ethernet);
>-               VCAP_KEY_BIT_SET(MAC_ARP_ARP_PROTO_SPACE_OK, arp->ip);
>-               VCAP_KEY_BIT_SET(MAC_ARP_ARP_LEN_OK, arp->length);
>-               VCAP_KEY_BIT_SET(MAC_ARP_ARP_TGT_MATCH, arp->dmac_match);
>-               VCAP_KEY_BIT_SET(MAC_ARP_ARP_SENDER_MATCH, arp->smac_match);
>-               VCAP_KEY_BIT_SET(MAC_ARP_ARP_OPCODE_UNKNOWN, arp->unknown);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
>+                                  arp->smac.value, arp->smac.mask);
>+               vcap_key_bit_set(ocelot, &data,
>+                                VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
>+                                arp->ethernet);
>+               vcap_key_bit_set(ocelot, &data,
>+                                VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
>+                                arp->ip);
>+               vcap_key_bit_set(ocelot, &data,
>+                                VCAP_IS2_HK_MAC_ARP_LEN_OK,
>+                                arp->length);
>+               vcap_key_bit_set(ocelot, &data,
>+                                VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
>+                                arp->dmac_match);
>+               vcap_key_bit_set(ocelot, &data,
>+                                VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
>+                                arp->smac_match);
>+               vcap_key_bit_set(ocelot, &data,
>+                                VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
>+                                arp->unknown);
>
>                /* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */
>                val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) |
>                       (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0));
>                msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) |
>                       (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2));
>-               VCAP_KEY_SET(MAC_ARP_ARP_OPCODE, val, msk);
>-               vcap_key_bytes_set(&data, IS2_HKO_MAC_ARP_L3_IP4_DIP,
>-                                  arp->dip.value.addr, arp->dip.mask.addr, 4);
>-               vcap_key_bytes_set(&data, IS2_HKO_MAC_ARP_L3_IP4_SIP,
>-                                  arp->sip.value.addr, arp->sip.mask.addr, 4);
>-               VCAP_KEY_ANY_SET(MAC_ARP_DIP_EQ_SIP);
>+               vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_OPCODE,
>+                            val, msk);
>+               vcap_key_bytes_set(ocelot, &data,
>+                                  VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
>+                                  arp->dip.value.addr, arp->dip.mask.addr);
>+               vcap_key_bytes_set(ocelot, &data,
>+                                  VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
>+                                  arp->sip.value.addr, arp->sip.mask.addr);
>+               vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
>+                            0, 0);
>                break;
>        }
>        case OCELOT_ACE_TYPE_IPV4:
>@@ -494,18 +550,23 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>                        seq_zero = ipv6->seq_zero;
>                }
>
>-               VCAP_KEY_BIT_SET(IP4,
>+               vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4,
>                                 ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
>-               VCAP_KEY_BIT_SET(L3_FRAGMENT, fragment);
>-               VCAP_KEY_ANY_SET(L3_FRAG_OFS_GT0);
>-               VCAP_KEY_BIT_SET(L3_OPTIONS, options);
>-               VCAP_KEY_BIT_SET(L3_TTL_GT0, ttl);
>-               VCAP_KEY_BYTES_SET(L3_TOS, ds.value, ds.mask);
>-               vcap_key_bytes_set(&data, IS2_HKO_L3_IP4_DIP, dip.value.addr,
>-                                  dip.mask.addr, 4);
>-               vcap_key_bytes_set(&data, IS2_HKO_L3_IP4_SIP, sip.value.addr,
>-                                  sip.mask.addr, 4);
>-               VCAP_KEY_BIT_SET(DIP_EQ_SIP, sip_eq_dip);
>+               vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_FRAGMENT,
>+                                fragment);
>+               vcap_key_set(ocelot, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0);
>+               vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_OPTIONS,
>+                                options);
>+               vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0,
>+                                ttl);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_TOS,
>+                                  ds.value, ds.mask);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_DIP,
>+                                  dip.value.addr, dip.mask.addr);
>+               vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_SIP,
>+                                  sip.value.addr, sip.mask.addr);
>+               vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DIP_EQ_SIP,
>+                                sip_eq_dip);
>                val = proto.value[0];
>                msk = proto.mask[0];
>                type = IS2_TYPE_IP_UDP_TCP;
>@@ -513,25 +574,34 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>                        /* UDP/TCP protocol match */
>                        tcp = (val == 6 ?
>                               OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_TCP, tcp);
>-                       vcap_key_l4_port_set(&data,
>-                                            IS2_HKO_IP4_TCP_UDP_L4_DPORT,
>-                                            dport);
>-                       vcap_key_l4_port_set(&data,
>-                                            IS2_HKO_IP4_TCP_UDP_L4_SPORT,
>-                                            sport);
>-                       VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_RNG);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_SPORT_EQ_DPORT,
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_TCP, tcp);
>+                       vcap_key_l4_port_set(ocelot, &data,
>+                                            VCAP_IS2_HK_L4_DPORT, dport);
>+                       vcap_key_l4_port_set(ocelot, &data,
>+                                            VCAP_IS2_HK_L4_SPORT, sport);
>+                       vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_RNG, 0, 0);
>+                       vcap_key_bit_set(ocelot, &data,
>+                                        VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
>                                         sport_eq_dport);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_SEQUENCE_EQ0, seq_zero);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_FIN, tcp_fin);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_SYN, tcp_syn);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_RST, tcp_rst);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_PSH, tcp_psh);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_ACK, tcp_ack);
>-                       VCAP_KEY_BIT_SET(IP4_TCP_UDP_L4_URG, tcp_urg);
>-                       VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_1588_DOM);
>-                       VCAP_KEY_ANY_SET(IP4_TCP_UDP_L4_1588_VER);
>+                       vcap_key_bit_set(ocelot, &data,
>+                                        VCAP_IS2_HK_L4_SEQUENCE_EQ0,
>+                                        seq_zero);
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_FIN,
>+                                        tcp_fin);
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_SYN,
>+                                        tcp_syn);
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_RST,
>+                                        tcp_rst);
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_PSH,
>+                                        tcp_psh);
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_ACK,
>+                                        tcp_ack);
>+                       vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_URG,
>+                                        tcp_urg);
>+                       vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_DOM,
>+                                    0, 0);
>+                       vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_VER,
>+                                    0, 0);
>                } else {
>                        if (msk == 0) {
>                                /* Any IP protocol match */
>@@ -544,10 +614,12 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>                                        payload.mask[i] = ip_data->mask[i];
>                                }
>                        }
>-                       VCAP_KEY_BYTES_SET(IP4_OTHER_L3_PROTO, proto.value,
>-                                          proto.mask);
>-                       VCAP_KEY_BYTES_SET(IP4_OTHER_L3_PAYLOAD, payload.value,
>-                                          payload.mask);
>+                       vcap_key_bytes_set(ocelot, &data,
>+                                          VCAP_IS2_HK_IP4_L3_PROTO,
>+                                          proto.value, proto.mask);
>+                       vcap_key_bytes_set(ocelot, &data,
>+                                          VCAP_IS2_HK_L3_PAYLOAD,
>+                                          payload.value, payload.mask);
>                }
>                break;
>        }
>@@ -556,18 +628,20 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>                type = 0;
>                type_mask = 0;
>                count = (vcap_is2.entry_width / 2);
>-               for (i = (IS2_HKO_PCP + IS2_HKL_PCP); i < count;
>-                    i += ENTRY_WIDTH) {
>-                       /* Clear entry data */
>-                       vcap_key_set(&data, i, min(32u, count - i), 0, 0);
>+               /* Iterate over the non-common part of the key and
>+                * clear entry data
>+                */
>+               for (i = ocelot->vcap_is2_keys[VCAP_IS2_HK_L2_DMAC].offset;
>+                    i < count; i += ENTRY_WIDTH) {
>+                       vcap_key_field_set(&data, i, min(32u, count - i), 0, 0);
>                }
>                break;
>        }
>
>-       VCAP_KEY_SET(TYPE, type, type_mask);
>-       is2_action_set(&data, ace->action);
>-       vcap_data_set(data.counter, data.counter_offset, vcap_is2.counter_width,
>-                     ace->stats.pkts);
>+       vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
>+       is2_action_set(ocelot, &data, ace->action);
>+       vcap_data_set(data.counter, data.counter_offset,
>+                     vcap_is2.counter_width, ace->stats.pkts);
>
>        /* Write row */
>        vcap_entry2cache(ocelot, &data);
>@@ -734,6 +808,7 @@ int ocelot_ace_init(struct ocelot *ocelot)
>        struct vcap_data data;
>
>        memset(&data, 0, sizeof(data));
>+
>        vcap_entry2cache(ocelot, &data);
>        ocelot_write(ocelot, vcap_is2.entry_count, S2_CORE_MV_CFG);
>        vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);
>diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
>index 7c3dae87d505..2f52d2866c9d 100644
>--- a/drivers/net/ethernet/mscc/ocelot_board.c
>+++ b/drivers/net/ethernet/mscc/ocelot_board.c
>@@ -14,6 +14,7 @@
> #include <linux/skbuff.h>
> #include <net/switchdev.h>
>
>+#include <soc/mscc/ocelot_vcap.h>
> #include "ocelot.h"
>
> #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
>@@ -262,6 +263,104 @@ static const struct ocelot_ops ocelot_ops = {
>        .reset                  = ocelot_reset,
> };
>
>+static const struct vcap_field vsc7514_vcap_is2_keys[] = {
>+       /* Common: 46 bits */
>+       [VCAP_IS2_TYPE]                         = {  0,   4},
>+       [VCAP_IS2_HK_FIRST]                     = {  4,   1},
>+       [VCAP_IS2_HK_PAG]                       = {  5,   8},
>+       [VCAP_IS2_HK_IGR_PORT_MASK]             = { 13,  12},
>+       [VCAP_IS2_HK_RSV2]                      = { 25,   1},
>+       [VCAP_IS2_HK_HOST_MATCH]                = { 26,   1},
>+       [VCAP_IS2_HK_L2_MC]                     = { 27,   1},
>+       [VCAP_IS2_HK_L2_BC]                     = { 28,   1},
>+       [VCAP_IS2_HK_VLAN_TAGGED]               = { 29,   1},
>+       [VCAP_IS2_HK_VID]                       = { 30,  12},
>+       [VCAP_IS2_HK_DEI]                       = { 42,   1},
>+       [VCAP_IS2_HK_PCP]                       = { 43,   3},
>+       /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
>+       [VCAP_IS2_HK_L2_DMAC]                   = { 46,  48},
>+       [VCAP_IS2_HK_L2_SMAC]                   = { 94,  48},
>+       /* MAC_ETYPE (TYPE=000) */
>+       [VCAP_IS2_HK_MAC_ETYPE_ETYPE]           = {142,  16},
>+       [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]     = {158,  16},
>+       [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]     = {174,   8},
>+       [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]     = {182,   3},
>+       /* MAC_LLC (TYPE=001) */
>+       [VCAP_IS2_HK_MAC_LLC_L2_LLC]            = {142,  40},
>+       /* MAC_SNAP (TYPE=010) */
>+       [VCAP_IS2_HK_MAC_SNAP_L2_SNAP]          = {142,  40},
>+       /* MAC_ARP (TYPE=011) */
>+       [VCAP_IS2_HK_MAC_ARP_SMAC]              = { 46,  48},
>+       [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]     = { 94,   1},
>+       [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]    = { 95,   1},
>+       [VCAP_IS2_HK_MAC_ARP_LEN_OK]            = { 96,   1},
>+       [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]      = { 97,   1},
>+       [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]      = { 98,   1},
>+       [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]    = { 99,   1},
>+       [VCAP_IS2_HK_MAC_ARP_OPCODE]            = {100,   2},
>+       [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]        = {102,  32},
>+       [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]        = {134,  32},
>+       [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]        = {166,   1},
>+       /* IP4_TCP_UDP / IP4_OTHER common */
>+       [VCAP_IS2_HK_IP4]                       = { 46,   1},
>+       [VCAP_IS2_HK_L3_FRAGMENT]               = { 47,   1},
>+       [VCAP_IS2_HK_L3_FRAG_OFS_GT0]           = { 48,   1},
>+       [VCAP_IS2_HK_L3_OPTIONS]                = { 49,   1},
>+       [VCAP_IS2_HK_IP4_L3_TTL_GT0]            = { 50,   1},
>+       [VCAP_IS2_HK_L3_TOS]                    = { 51,   8},
>+       [VCAP_IS2_HK_L3_IP4_DIP]                = { 59,  32},
>+       [VCAP_IS2_HK_L3_IP4_SIP]                = { 91,  32},
>+       [VCAP_IS2_HK_DIP_EQ_SIP]                = {123,   1},
>+       /* IP4_TCP_UDP (TYPE=100) */
>+       [VCAP_IS2_HK_TCP]                       = {124,   1},
>+       [VCAP_IS2_HK_L4_SPORT]                  = {125,  16},
>+       [VCAP_IS2_HK_L4_DPORT]                  = {141,  16},
>+       [VCAP_IS2_HK_L4_RNG]                    = {157,   8},
>+       [VCAP_IS2_HK_L4_SPORT_EQ_DPORT]         = {165,   1},
>+       [VCAP_IS2_HK_L4_SEQUENCE_EQ0]           = {166,   1},
>+       [VCAP_IS2_HK_L4_URG]                    = {167,   1},
>+       [VCAP_IS2_HK_L4_ACK]                    = {168,   1},
>+       [VCAP_IS2_HK_L4_PSH]                    = {169,   1},
>+       [VCAP_IS2_HK_L4_RST]                    = {170,   1},
>+       [VCAP_IS2_HK_L4_SYN]                    = {171,   1},
>+       [VCAP_IS2_HK_L4_FIN]                    = {172,   1},
>+       [VCAP_IS2_HK_L4_1588_DOM]               = {173,   8},
>+       [VCAP_IS2_HK_L4_1588_VER]               = {181,   4},
>+       /* IP4_OTHER (TYPE=101) */
>+       [VCAP_IS2_HK_IP4_L3_PROTO]              = {124,   8},
>+       [VCAP_IS2_HK_L3_PAYLOAD]                = {132,  56},
>+       /* IP6_STD (TYPE=110) */
>+       [VCAP_IS2_HK_IP6_L3_TTL_GT0]            = { 46,   1},
>+       [VCAP_IS2_HK_L3_IP6_SIP]                = { 47, 128},
>+       [VCAP_IS2_HK_IP6_L3_PROTO]              = {175,   8},
>+       /* OAM (TYPE=111) */
>+       [VCAP_IS2_HK_OAM_MEL_FLAGS]             = {142,   7},
>+       [VCAP_IS2_HK_OAM_VER]                   = {149,   5},
>+       [VCAP_IS2_HK_OAM_OPCODE]                = {154,   8},
>+       [VCAP_IS2_HK_OAM_FLAGS]                 = {162,   8},
>+       [VCAP_IS2_HK_OAM_MEPID]                 = {170,  16},
>+       [VCAP_IS2_HK_OAM_CCM_CNTS_EQ0]          = {186,   1},
>+       [VCAP_IS2_HK_OAM_IS_Y1731]              = {187,   1},
>+};
>+
>+static const struct vcap_field vsc7514_vcap_is2_actions[] = {
>+       [VCAP_IS2_ACT_HIT_ME_ONCE]              = {  0,  1},
>+       [VCAP_IS2_ACT_CPU_COPY_ENA]             = {  1,  1},
>+       [VCAP_IS2_ACT_CPU_QU_NUM]               = {  2,  3},
>+       [VCAP_IS2_ACT_MASK_MODE]                = {  5,  2},
>+       [VCAP_IS2_ACT_MIRROR_ENA]               = {  7,  1},
>+       [VCAP_IS2_ACT_LRN_DIS]                  = {  8,  1},
>+       [VCAP_IS2_ACT_POLICE_ENA]               = {  9,  1},
>+       [VCAP_IS2_ACT_POLICE_IDX]               = { 10,  9},
>+       [VCAP_IS2_ACT_POLICE_VCAP_ONLY]         = { 19,  1},
>+       [VCAP_IS2_ACT_PORT_MASK]                = { 20, 11},
>+       [VCAP_IS2_ACT_REW_OP]                   = { 31,  9},
>+       [VCAP_IS2_ACT_SMAC_REPLACE_ENA]         = { 40,  1},
>+       [VCAP_IS2_ACT_RSV]                      = { 41,  2},
>+       [VCAP_IS2_ACT_ACL_ID]                   = { 43,  6},
>+       [VCAP_IS2_ACT_HIT_CNT]                  = { 49, 32},
>+};
>+
> static int mscc_ocelot_probe(struct platform_device *pdev)
> {
>        struct device_node *np = pdev->dev.of_node;
>@@ -362,6 +461,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
>        ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
>                                     sizeof(struct ocelot_port *), GFP_KERNEL);
>
>+       ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
>+       ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
>+
>        ocelot_init(ocelot);
>        /* No NPI port */
>        ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
>diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.h b/drivers/net/ethernet/mscc/ocelot_vcap.h
>deleted file mode 100644
>index e22eac1da783..000000000000
>--- a/drivers/net/ethernet/mscc/ocelot_vcap.h
>+++ /dev/null
>@@ -1,403 +0,0 @@
>-/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
>- * Microsemi Ocelot Switch driver
>- * Copyright (c) 2019 Microsemi Corporation
>- */
>-
>-#ifndef _OCELOT_VCAP_H_
>-#define _OCELOT_VCAP_H_
>-
>-/* =================================================================
>- *  VCAP Common
>- * =================================================================
>- */
>-
>-/* VCAP Type-Group values */
>-#define VCAP_TG_NONE 0 /* Entry is invalid */
>-#define VCAP_TG_FULL 1 /* Full entry */
>-#define VCAP_TG_HALF 2 /* Half entry */
>-#define VCAP_TG_QUARTER 3 /* Quarter entry */
>-
>-/* =================================================================
>- *  VCAP IS2
>- * =================================================================
>- */
>-
>-#define VCAP_IS2_CNT 64
>-#define VCAP_IS2_ENTRY_WIDTH 376
>-#define VCAP_IS2_ACTION_WIDTH 99
>-#define VCAP_PORT_CNT 11
>-
>-/* IS2 half key types */
>-#define IS2_TYPE_ETYPE 0
>-#define IS2_TYPE_LLC 1
>-#define IS2_TYPE_SNAP 2
>-#define IS2_TYPE_ARP 3
>-#define IS2_TYPE_IP_UDP_TCP 4
>-#define IS2_TYPE_IP_OTHER 5
>-#define IS2_TYPE_IPV6 6
>-#define IS2_TYPE_OAM 7
>-#define IS2_TYPE_SMAC_SIP6 8
>-#define IS2_TYPE_ANY 100 /* Pseudo type */
>-
>-/* IS2 half key type mask for matching any IP */
>-#define IS2_TYPE_MASK_IP_ANY 0xe
>-
>-/* IS2 action types */
>-#define IS2_ACTION_TYPE_NORMAL 0
>-#define IS2_ACTION_TYPE_SMAC_SIP 1
>-
>-/* IS2 MASK_MODE values */
>-#define IS2_ACT_MASK_MODE_NONE 0
>-#define IS2_ACT_MASK_MODE_FILTER 1
>-#define IS2_ACT_MASK_MODE_POLICY 2
>-#define IS2_ACT_MASK_MODE_REDIR 3
>-
>-/* IS2 REW_OP values */
>-#define IS2_ACT_REW_OP_NONE 0
>-#define IS2_ACT_REW_OP_PTP_ONE 2
>-#define IS2_ACT_REW_OP_PTP_TWO 3
>-#define IS2_ACT_REW_OP_SPECIAL 8
>-#define IS2_ACT_REW_OP_PTP_ORG 9
>-#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_1 (IS2_ACT_REW_OP_PTP_ONE | (1 << 3))
>-#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_2 (IS2_ACT_REW_OP_PTP_ONE | (2 << 3))
>-#define IS2_ACT_REW_OP_PTP_ONE_ADD_DELAY (IS2_ACT_REW_OP_PTP_ONE | (1 << 5))
>-#define IS2_ACT_REW_OP_PTP_ONE_ADD_SUB BIT(7)
>-
>-#define VCAP_PORT_WIDTH 4
>-
>-/* IS2 quarter key - SMAC_SIP4 */
>-#define IS2_QKO_IGR_PORT 0
>-#define IS2_QKL_IGR_PORT VCAP_PORT_WIDTH
>-#define IS2_QKO_L2_SMAC (IS2_QKO_IGR_PORT + IS2_QKL_IGR_PORT)
>-#define IS2_QKL_L2_SMAC 48
>-#define IS2_QKO_L3_IP4_SIP (IS2_QKO_L2_SMAC + IS2_QKL_L2_SMAC)
>-#define IS2_QKL_L3_IP4_SIP 32
>-
>-/* IS2 half key - common */
>-#define IS2_HKO_TYPE 0
>-#define IS2_HKL_TYPE 4
>-#define IS2_HKO_FIRST (IS2_HKO_TYPE + IS2_HKL_TYPE)
>-#define IS2_HKL_FIRST 1
>-#define IS2_HKO_PAG (IS2_HKO_FIRST + IS2_HKL_FIRST)
>-#define IS2_HKL_PAG 8
>-#define IS2_HKO_IGR_PORT_MASK (IS2_HKO_PAG + IS2_HKL_PAG)
>-#define IS2_HKL_IGR_PORT_MASK (VCAP_PORT_CNT + 1)
>-#define IS2_HKO_SERVICE_FRM (IS2_HKO_IGR_PORT_MASK + IS2_HKL_IGR_PORT_MASK)
>-#define IS2_HKL_SERVICE_FRM 1
>-#define IS2_HKO_HOST_MATCH (IS2_HKO_SERVICE_FRM + IS2_HKL_SERVICE_FRM)
>-#define IS2_HKL_HOST_MATCH 1
>-#define IS2_HKO_L2_MC (IS2_HKO_HOST_MATCH + IS2_HKL_HOST_MATCH)
>-#define IS2_HKL_L2_MC 1
>-#define IS2_HKO_L2_BC (IS2_HKO_L2_MC + IS2_HKL_L2_MC)
>-#define IS2_HKL_L2_BC 1
>-#define IS2_HKO_VLAN_TAGGED (IS2_HKO_L2_BC + IS2_HKL_L2_BC)
>-#define IS2_HKL_VLAN_TAGGED 1
>-#define IS2_HKO_VID (IS2_HKO_VLAN_TAGGED + IS2_HKL_VLAN_TAGGED)
>-#define IS2_HKL_VID 12
>-#define IS2_HKO_DEI (IS2_HKO_VID + IS2_HKL_VID)
>-#define IS2_HKL_DEI 1
>-#define IS2_HKO_PCP (IS2_HKO_DEI + IS2_HKL_DEI)
>-#define IS2_HKL_PCP 3
>-
>-/* IS2 half key - MAC_ETYPE/MAC_LLC/MAC_SNAP/OAM common */
>-#define IS2_HKO_L2_DMAC (IS2_HKO_PCP + IS2_HKL_PCP)
>-#define IS2_HKL_L2_DMAC 48
>-#define IS2_HKO_L2_SMAC (IS2_HKO_L2_DMAC + IS2_HKL_L2_DMAC)
>-#define IS2_HKL_L2_SMAC 48
>-
>-/* IS2 half key - MAC_ETYPE */
>-#define IS2_HKO_MAC_ETYPE_ETYPE (IS2_HKO_L2_SMAC + IS2_HKL_L2_SMAC)
>-#define IS2_HKL_MAC_ETYPE_ETYPE 16
>-#define IS2_HKO_MAC_ETYPE_L2_PAYLOAD                                           \
>-       (IS2_HKO_MAC_ETYPE_ETYPE + IS2_HKL_MAC_ETYPE_ETYPE)
>-#define IS2_HKL_MAC_ETYPE_L2_PAYLOAD 27
>-
>-/* IS2 half key - MAC_LLC */
>-#define IS2_HKO_MAC_LLC_L2_LLC IS2_HKO_MAC_ETYPE_ETYPE
>-#define IS2_HKL_MAC_LLC_L2_LLC 40
>-
>-/* IS2 half key - MAC_SNAP */
>-#define IS2_HKO_MAC_SNAP_L2_SNAP IS2_HKO_MAC_ETYPE_ETYPE
>-#define IS2_HKL_MAC_SNAP_L2_SNAP 40
>-
>-/* IS2 half key - ARP */
>-#define IS2_HKO_MAC_ARP_L2_SMAC IS2_HKO_L2_DMAC
>-#define IS2_HKL_MAC_ARP_L2_SMAC 48
>-#define IS2_HKO_MAC_ARP_ARP_ADDR_SPACE_OK                                      \
>-       (IS2_HKO_MAC_ARP_L2_SMAC + IS2_HKL_MAC_ARP_L2_SMAC)
>-#define IS2_HKL_MAC_ARP_ARP_ADDR_SPACE_OK 1
>-#define IS2_HKO_MAC_ARP_ARP_PROTO_SPACE_OK                                     \
>-       (IS2_HKO_MAC_ARP_ARP_ADDR_SPACE_OK + IS2_HKL_MAC_ARP_ARP_ADDR_SPACE_OK)
>-#define IS2_HKL_MAC_ARP_ARP_PROTO_SPACE_OK 1
>-#define IS2_HKO_MAC_ARP_ARP_LEN_OK                                             \
>-       (IS2_HKO_MAC_ARP_ARP_PROTO_SPACE_OK +                                  \
>-        IS2_HKL_MAC_ARP_ARP_PROTO_SPACE_OK)
>-#define IS2_HKL_MAC_ARP_ARP_LEN_OK 1
>-#define IS2_HKO_MAC_ARP_ARP_TGT_MATCH                                          \
>-       (IS2_HKO_MAC_ARP_ARP_LEN_OK + IS2_HKL_MAC_ARP_ARP_LEN_OK)
>-#define IS2_HKL_MAC_ARP_ARP_TGT_MATCH 1
>-#define IS2_HKO_MAC_ARP_ARP_SENDER_MATCH                                       \
>-       (IS2_HKO_MAC_ARP_ARP_TGT_MATCH + IS2_HKL_MAC_ARP_ARP_TGT_MATCH)
>-#define IS2_HKL_MAC_ARP_ARP_SENDER_MATCH 1
>-#define IS2_HKO_MAC_ARP_ARP_OPCODE_UNKNOWN                                     \
>-       (IS2_HKO_MAC_ARP_ARP_SENDER_MATCH + IS2_HKL_MAC_ARP_ARP_SENDER_MATCH)
>-#define IS2_HKL_MAC_ARP_ARP_OPCODE_UNKNOWN 1
>-#define IS2_HKO_MAC_ARP_ARP_OPCODE                                             \
>-       (IS2_HKO_MAC_ARP_ARP_OPCODE_UNKNOWN +                                  \
>-        IS2_HKL_MAC_ARP_ARP_OPCODE_UNKNOWN)
>-#define IS2_HKL_MAC_ARP_ARP_OPCODE 2
>-#define IS2_HKO_MAC_ARP_L3_IP4_DIP                                             \
>-       (IS2_HKO_MAC_ARP_ARP_OPCODE + IS2_HKL_MAC_ARP_ARP_OPCODE)
>-#define IS2_HKL_MAC_ARP_L3_IP4_DIP 32
>-#define IS2_HKO_MAC_ARP_L3_IP4_SIP                                             \
>-       (IS2_HKO_MAC_ARP_L3_IP4_DIP + IS2_HKL_MAC_ARP_L3_IP4_DIP)
>-#define IS2_HKL_MAC_ARP_L3_IP4_SIP 32
>-#define IS2_HKO_MAC_ARP_DIP_EQ_SIP                                             \
>-       (IS2_HKO_MAC_ARP_L3_IP4_SIP + IS2_HKL_MAC_ARP_L3_IP4_SIP)
>-#define IS2_HKL_MAC_ARP_DIP_EQ_SIP 1
>-
>-/* IS2 half key - IP4_TCP_UDP/IP4_OTHER common */
>-#define IS2_HKO_IP4 IS2_HKO_L2_DMAC
>-#define IS2_HKL_IP4 1
>-#define IS2_HKO_L3_FRAGMENT (IS2_HKO_IP4 + IS2_HKL_IP4)
>-#define IS2_HKL_L3_FRAGMENT 1
>-#define IS2_HKO_L3_FRAG_OFS_GT0 (IS2_HKO_L3_FRAGMENT + IS2_HKL_L3_FRAGMENT)
>-#define IS2_HKL_L3_FRAG_OFS_GT0 1
>-#define IS2_HKO_L3_OPTIONS (IS2_HKO_L3_FRAG_OFS_GT0 + IS2_HKL_L3_FRAG_OFS_GT0)
>-#define IS2_HKL_L3_OPTIONS 1
>-#define IS2_HKO_L3_TTL_GT0 (IS2_HKO_L3_OPTIONS + IS2_HKL_L3_OPTIONS)
>-#define IS2_HKL_L3_TTL_GT0 1
>-#define IS2_HKO_L3_TOS (IS2_HKO_L3_TTL_GT0 + IS2_HKL_L3_TTL_GT0)
>-#define IS2_HKL_L3_TOS 8
>-#define IS2_HKO_L3_IP4_DIP (IS2_HKO_L3_TOS + IS2_HKL_L3_TOS)
>-#define IS2_HKL_L3_IP4_DIP 32
>-#define IS2_HKO_L3_IP4_SIP (IS2_HKO_L3_IP4_DIP + IS2_HKL_L3_IP4_DIP)
>-#define IS2_HKL_L3_IP4_SIP 32
>-#define IS2_HKO_DIP_EQ_SIP (IS2_HKO_L3_IP4_SIP + IS2_HKL_L3_IP4_SIP)
>-#define IS2_HKL_DIP_EQ_SIP 1
>-
>-/* IS2 half key - IP4_TCP_UDP */
>-#define IS2_HKO_IP4_TCP_UDP_TCP (IS2_HKO_DIP_EQ_SIP + IS2_HKL_DIP_EQ_SIP)
>-#define IS2_HKL_IP4_TCP_UDP_TCP 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_DPORT                                           \
>-       (IS2_HKO_IP4_TCP_UDP_TCP + IS2_HKL_IP4_TCP_UDP_TCP)
>-#define IS2_HKL_IP4_TCP_UDP_L4_DPORT 16
>-#define IS2_HKO_IP4_TCP_UDP_L4_SPORT                                           \
>-       (IS2_HKO_IP4_TCP_UDP_L4_DPORT + IS2_HKL_IP4_TCP_UDP_L4_DPORT)
>-#define IS2_HKL_IP4_TCP_UDP_L4_SPORT 16
>-#define IS2_HKO_IP4_TCP_UDP_L4_RNG                                             \
>-       (IS2_HKO_IP4_TCP_UDP_L4_SPORT + IS2_HKL_IP4_TCP_UDP_L4_SPORT)
>-#define IS2_HKL_IP4_TCP_UDP_L4_RNG 8
>-#define IS2_HKO_IP4_TCP_UDP_SPORT_EQ_DPORT                                     \
>-       (IS2_HKO_IP4_TCP_UDP_L4_RNG + IS2_HKL_IP4_TCP_UDP_L4_RNG)
>-#define IS2_HKL_IP4_TCP_UDP_SPORT_EQ_DPORT 1
>-#define IS2_HKO_IP4_TCP_UDP_SEQUENCE_EQ0                                       \
>-       (IS2_HKO_IP4_TCP_UDP_SPORT_EQ_DPORT +                                  \
>-        IS2_HKL_IP4_TCP_UDP_SPORT_EQ_DPORT)
>-#define IS2_HKL_IP4_TCP_UDP_SEQUENCE_EQ0 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_FIN                                             \
>-       (IS2_HKO_IP4_TCP_UDP_SEQUENCE_EQ0 + IS2_HKL_IP4_TCP_UDP_SEQUENCE_EQ0)
>-#define IS2_HKL_IP4_TCP_UDP_L4_FIN 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_SYN                                             \
>-       (IS2_HKO_IP4_TCP_UDP_L4_FIN + IS2_HKL_IP4_TCP_UDP_L4_FIN)
>-#define IS2_HKL_IP4_TCP_UDP_L4_SYN 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_RST                                             \
>-       (IS2_HKO_IP4_TCP_UDP_L4_SYN + IS2_HKL_IP4_TCP_UDP_L4_SYN)
>-#define IS2_HKL_IP4_TCP_UDP_L4_RST 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_PSH                                             \
>-       (IS2_HKO_IP4_TCP_UDP_L4_RST + IS2_HKL_IP4_TCP_UDP_L4_RST)
>-#define IS2_HKL_IP4_TCP_UDP_L4_PSH 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_ACK                                             \
>-       (IS2_HKO_IP4_TCP_UDP_L4_PSH + IS2_HKL_IP4_TCP_UDP_L4_PSH)
>-#define IS2_HKL_IP4_TCP_UDP_L4_ACK 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_URG                                             \
>-       (IS2_HKO_IP4_TCP_UDP_L4_ACK + IS2_HKL_IP4_TCP_UDP_L4_ACK)
>-#define IS2_HKL_IP4_TCP_UDP_L4_URG 1
>-#define IS2_HKO_IP4_TCP_UDP_L4_1588_DOM                                        \
>-       (IS2_HKO_IP4_TCP_UDP_L4_URG + IS2_HKL_IP4_TCP_UDP_L4_URG)
>-#define IS2_HKL_IP4_TCP_UDP_L4_1588_DOM 8
>-#define IS2_HKO_IP4_TCP_UDP_L4_1588_VER                                        \
>-       (IS2_HKO_IP4_TCP_UDP_L4_1588_DOM + IS2_HKL_IP4_TCP_UDP_L4_1588_DOM)
>-#define IS2_HKL_IP4_TCP_UDP_L4_1588_VER 4
>-
>-/* IS2 half key - IP4_OTHER */
>-#define IS2_HKO_IP4_OTHER_L3_PROTO IS2_HKO_IP4_TCP_UDP_TCP
>-#define IS2_HKL_IP4_OTHER_L3_PROTO 8
>-#define IS2_HKO_IP4_OTHER_L3_PAYLOAD                                           \
>-       (IS2_HKO_IP4_OTHER_L3_PROTO + IS2_HKL_IP4_OTHER_L3_PROTO)
>-#define IS2_HKL_IP4_OTHER_L3_PAYLOAD 56
>-
>-/* IS2 half key - IP6_STD */
>-#define IS2_HKO_IP6_STD_L3_TTL_GT0 IS2_HKO_L2_DMAC
>-#define IS2_HKL_IP6_STD_L3_TTL_GT0 1
>-#define IS2_HKO_IP6_STD_L3_IP6_SIP                                             \
>-       (IS2_HKO_IP6_STD_L3_TTL_GT0 + IS2_HKL_IP6_STD_L3_TTL_GT0)
>-#define IS2_HKL_IP6_STD_L3_IP6_SIP 128
>-#define IS2_HKO_IP6_STD_L3_PROTO                                               \
>-       (IS2_HKO_IP6_STD_L3_IP6_SIP + IS2_HKL_IP6_STD_L3_IP6_SIP)
>-#define IS2_HKL_IP6_STD_L3_PROTO 8
>-
>-/* IS2 half key - OAM */
>-#define IS2_HKO_OAM_OAM_MEL_FLAGS IS2_HKO_MAC_ETYPE_ETYPE
>-#define IS2_HKL_OAM_OAM_MEL_FLAGS 7
>-#define IS2_HKO_OAM_OAM_VER                                                    \
>-       (IS2_HKO_OAM_OAM_MEL_FLAGS + IS2_HKL_OAM_OAM_MEL_FLAGS)
>-#define IS2_HKL_OAM_OAM_VER 5
>-#define IS2_HKO_OAM_OAM_OPCODE (IS2_HKO_OAM_OAM_VER + IS2_HKL_OAM_OAM_VER)
>-#define IS2_HKL_OAM_OAM_OPCODE 8
>-#define IS2_HKO_OAM_OAM_FLAGS (IS2_HKO_OAM_OAM_OPCODE + IS2_HKL_OAM_OAM_OPCODE)
>-#define IS2_HKL_OAM_OAM_FLAGS 8
>-#define IS2_HKO_OAM_OAM_MEPID (IS2_HKO_OAM_OAM_FLAGS + IS2_HKL_OAM_OAM_FLAGS)
>-#define IS2_HKL_OAM_OAM_MEPID 16
>-#define IS2_HKO_OAM_OAM_CCM_CNTS_EQ0                                           \
>-       (IS2_HKO_OAM_OAM_MEPID + IS2_HKL_OAM_OAM_MEPID)
>-#define IS2_HKL_OAM_OAM_CCM_CNTS_EQ0 1
>-
>-/* IS2 half key - SMAC_SIP6 */
>-#define IS2_HKO_SMAC_SIP6_IGR_PORT IS2_HKL_TYPE
>-#define IS2_HKL_SMAC_SIP6_IGR_PORT VCAP_PORT_WIDTH
>-#define IS2_HKO_SMAC_SIP6_L2_SMAC                                              \
>-       (IS2_HKO_SMAC_SIP6_IGR_PORT + IS2_HKL_SMAC_SIP6_IGR_PORT)
>-#define IS2_HKL_SMAC_SIP6_L2_SMAC 48
>-#define IS2_HKO_SMAC_SIP6_L3_IP6_SIP                                           \
>-       (IS2_HKO_SMAC_SIP6_L2_SMAC + IS2_HKL_SMAC_SIP6_L2_SMAC)
>-#define IS2_HKL_SMAC_SIP6_L3_IP6_SIP 128
>-
>-/* IS2 full key - common */
>-#define IS2_FKO_TYPE 0
>-#define IS2_FKL_TYPE 2
>-#define IS2_FKO_FIRST (IS2_FKO_TYPE + IS2_FKL_TYPE)
>-#define IS2_FKL_FIRST 1
>-#define IS2_FKO_PAG (IS2_FKO_FIRST + IS2_FKL_FIRST)
>-#define IS2_FKL_PAG 8
>-#define IS2_FKO_IGR_PORT_MASK (IS2_FKO_PAG + IS2_FKL_PAG)
>-#define IS2_FKL_IGR_PORT_MASK (VCAP_PORT_CNT + 1)
>-#define IS2_FKO_SERVICE_FRM (IS2_FKO_IGR_PORT_MASK + IS2_FKL_IGR_PORT_MASK)
>-#define IS2_FKL_SERVICE_FRM 1
>-#define IS2_FKO_HOST_MATCH (IS2_FKO_SERVICE_FRM + IS2_FKL_SERVICE_FRM)
>-#define IS2_FKL_HOST_MATCH 1
>-#define IS2_FKO_L2_MC (IS2_FKO_HOST_MATCH + IS2_FKL_HOST_MATCH)
>-#define IS2_FKL_L2_MC 1
>-#define IS2_FKO_L2_BC (IS2_FKO_L2_MC + IS2_FKL_L2_MC)
>-#define IS2_FKL_L2_BC 1
>-#define IS2_FKO_VLAN_TAGGED (IS2_FKO_L2_BC + IS2_FKL_L2_BC)
>-#define IS2_FKL_VLAN_TAGGED 1
>-#define IS2_FKO_VID (IS2_FKO_VLAN_TAGGED + IS2_FKL_VLAN_TAGGED)
>-#define IS2_FKL_VID 12
>-#define IS2_FKO_DEI (IS2_FKO_VID + IS2_FKL_VID)
>-#define IS2_FKL_DEI 1
>-#define IS2_FKO_PCP (IS2_FKO_DEI + IS2_FKL_DEI)
>-#define IS2_FKL_PCP 3
>-
>-/* IS2 full key - IP6_TCP_UDP/IP6_OTHER common */
>-#define IS2_FKO_L3_TTL_GT0 (IS2_FKO_PCP + IS2_FKL_PCP)
>-#define IS2_FKL_L3_TTL_GT0 1
>-#define IS2_FKO_L3_TOS (IS2_FKO_L3_TTL_GT0 + IS2_FKL_L3_TTL_GT0)
>-#define IS2_FKL_L3_TOS 8
>-#define IS2_FKO_L3_IP6_DIP (IS2_FKO_L3_TOS + IS2_FKL_L3_TOS)
>-#define IS2_FKL_L3_IP6_DIP 128
>-#define IS2_FKO_L3_IP6_SIP (IS2_FKO_L3_IP6_DIP + IS2_FKL_L3_IP6_DIP)
>-#define IS2_FKL_L3_IP6_SIP 128
>-#define IS2_FKO_DIP_EQ_SIP (IS2_FKO_L3_IP6_SIP + IS2_FKL_L3_IP6_SIP)
>-#define IS2_FKL_DIP_EQ_SIP 1
>-
>-/* IS2 full key - IP6_TCP_UDP */
>-#define IS2_FKO_IP6_TCP_UDP_TCP (IS2_FKO_DIP_EQ_SIP + IS2_FKL_DIP_EQ_SIP)
>-#define IS2_FKL_IP6_TCP_UDP_TCP 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_DPORT                                           \
>-       (IS2_FKO_IP6_TCP_UDP_TCP + IS2_FKL_IP6_TCP_UDP_TCP)
>-#define IS2_FKL_IP6_TCP_UDP_L4_DPORT 16
>-#define IS2_FKO_IP6_TCP_UDP_L4_SPORT                                           \
>-       (IS2_FKO_IP6_TCP_UDP_L4_DPORT + IS2_FKL_IP6_TCP_UDP_L4_DPORT)
>-#define IS2_FKL_IP6_TCP_UDP_L4_SPORT 16
>-#define IS2_FKO_IP6_TCP_UDP_L4_RNG                                             \
>-       (IS2_FKO_IP6_TCP_UDP_L4_SPORT + IS2_FKL_IP6_TCP_UDP_L4_SPORT)
>-#define IS2_FKL_IP6_TCP_UDP_L4_RNG 8
>-#define IS2_FKO_IP6_TCP_UDP_SPORT_EQ_DPORT                                     \
>-       (IS2_FKO_IP6_TCP_UDP_L4_RNG + IS2_FKL_IP6_TCP_UDP_L4_RNG)
>-#define IS2_FKL_IP6_TCP_UDP_SPORT_EQ_DPORT 1
>-#define IS2_FKO_IP6_TCP_UDP_SEQUENCE_EQ0                                       \
>-       (IS2_FKO_IP6_TCP_UDP_SPORT_EQ_DPORT +                                  \
>-        IS2_FKL_IP6_TCP_UDP_SPORT_EQ_DPORT)
>-#define IS2_FKL_IP6_TCP_UDP_SEQUENCE_EQ0 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_FIN                                             \
>-       (IS2_FKO_IP6_TCP_UDP_SEQUENCE_EQ0 + IS2_FKL_IP6_TCP_UDP_SEQUENCE_EQ0)
>-#define IS2_FKL_IP6_TCP_UDP_L4_FIN 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_SYN                                             \
>-       (IS2_FKO_IP6_TCP_UDP_L4_FIN + IS2_FKL_IP6_TCP_UDP_L4_FIN)
>-#define IS2_FKL_IP6_TCP_UDP_L4_SYN 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_RST                                             \
>-       (IS2_FKO_IP6_TCP_UDP_L4_SYN + IS2_FKL_IP6_TCP_UDP_L4_SYN)
>-#define IS2_FKL_IP6_TCP_UDP_L4_RST 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_PSH                                             \
>-       (IS2_FKO_IP6_TCP_UDP_L4_RST + IS2_FKL_IP6_TCP_UDP_L4_RST)
>-#define IS2_FKL_IP6_TCP_UDP_L4_PSH 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_ACK                                             \
>-       (IS2_FKO_IP6_TCP_UDP_L4_PSH + IS2_FKL_IP6_TCP_UDP_L4_PSH)
>-#define IS2_FKL_IP6_TCP_UDP_L4_ACK 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_URG                                             \
>-       (IS2_FKO_IP6_TCP_UDP_L4_ACK + IS2_FKL_IP6_TCP_UDP_L4_ACK)
>-#define IS2_FKL_IP6_TCP_UDP_L4_URG 1
>-#define IS2_FKO_IP6_TCP_UDP_L4_1588_DOM                                        \
>-       (IS2_FKO_IP6_TCP_UDP_L4_URG + IS2_FKL_IP6_TCP_UDP_L4_URG)
>-#define IS2_FKL_IP6_TCP_UDP_L4_1588_DOM 8
>-#define IS2_FKO_IP6_TCP_UDP_L4_1588_VER                                        \
>-       (IS2_FKO_IP6_TCP_UDP_L4_1588_DOM + IS2_FKL_IP6_TCP_UDP_L4_1588_DOM)
>-#define IS2_FKL_IP6_TCP_UDP_L4_1588_VER 4
>-
>-/* IS2 full key - IP6_OTHER */
>-#define IS2_FKO_IP6_OTHER_L3_PROTO IS2_FKO_IP6_TCP_UDP_TCP
>-#define IS2_FKL_IP6_OTHER_L3_PROTO 8
>-#define IS2_FKO_IP6_OTHER_L3_PAYLOAD                                           \
>-       (IS2_FKO_IP6_OTHER_L3_PROTO + IS2_FKL_IP6_OTHER_L3_PROTO)
>-#define IS2_FKL_IP6_OTHER_L3_PAYLOAD 56
>-
>-/* IS2 full key - CUSTOM */
>-#define IS2_FKO_CUSTOM_CUSTOM_TYPE IS2_FKO_L3_TTL_GT0
>-#define IS2_FKL_CUSTOM_CUSTOM_TYPE 1
>-#define IS2_FKO_CUSTOM_CUSTOM                                                  \
>-       (IS2_FKO_CUSTOM_CUSTOM_TYPE + IS2_FKL_CUSTOM_CUSTOM_TYPE)
>-#define IS2_FKL_CUSTOM_CUSTOM 320
>-
>-/* IS2 action - BASE_TYPE */
>-#define IS2_AO_HIT_ME_ONCE 0
>-#define IS2_AL_HIT_ME_ONCE 1
>-#define IS2_AO_CPU_COPY_ENA (IS2_AO_HIT_ME_ONCE + IS2_AL_HIT_ME_ONCE)
>-#define IS2_AL_CPU_COPY_ENA 1
>-#define IS2_AO_CPU_QU_NUM (IS2_AO_CPU_COPY_ENA + IS2_AL_CPU_COPY_ENA)
>-#define IS2_AL_CPU_QU_NUM 3
>-#define IS2_AO_MASK_MODE (IS2_AO_CPU_QU_NUM + IS2_AL_CPU_QU_NUM)
>-#define IS2_AL_MASK_MODE 2
>-#define IS2_AO_MIRROR_ENA (IS2_AO_MASK_MODE + IS2_AL_MASK_MODE)
>-#define IS2_AL_MIRROR_ENA 1
>-#define IS2_AO_LRN_DIS (IS2_AO_MIRROR_ENA + IS2_AL_MIRROR_ENA)
>-#define IS2_AL_LRN_DIS 1
>-#define IS2_AO_POLICE_ENA (IS2_AO_LRN_DIS + IS2_AL_LRN_DIS)
>-#define IS2_AL_POLICE_ENA 1
>-#define IS2_AO_POLICE_IDX (IS2_AO_POLICE_ENA + IS2_AL_POLICE_ENA)
>-#define IS2_AL_POLICE_IDX 9
>-#define IS2_AO_POLICE_VCAP_ONLY (IS2_AO_POLICE_IDX + IS2_AL_POLICE_IDX)
>-#define IS2_AL_POLICE_VCAP_ONLY 1
>-#define IS2_AO_PORT_MASK (IS2_AO_POLICE_VCAP_ONLY + IS2_AL_POLICE_VCAP_ONLY)
>-#define IS2_AL_PORT_MASK VCAP_PORT_CNT
>-#define IS2_AO_REW_OP (IS2_AO_PORT_MASK + IS2_AL_PORT_MASK)
>-#define IS2_AL_REW_OP 9
>-#define IS2_AO_LM_CNT_DIS (IS2_AO_REW_OP + IS2_AL_REW_OP)
>-#define IS2_AL_LM_CNT_DIS 1
>-#define IS2_AO_ISDX_ENA                                                        \
>-       (IS2_AO_LM_CNT_DIS + IS2_AL_LM_CNT_DIS + 1) /* Reserved bit */
>-#define IS2_AL_ISDX_ENA 1
>-#define IS2_AO_ACL_ID (IS2_AO_ISDX_ENA + IS2_AL_ISDX_ENA)
>-#define IS2_AL_ACL_ID 6
>-
>-/* IS2 action - SMAC_SIP */
>-#define IS2_AO_SMAC_SIP_CPU_COPY_ENA 0
>-#define IS2_AL_SMAC_SIP_CPU_COPY_ENA 1
>-#define IS2_AO_SMAC_SIP_CPU_QU_NUM 1
>-#define IS2_AL_SMAC_SIP_CPU_QU_NUM 3
>-#define IS2_AO_SMAC_SIP_FWD_KILL_ENA 4
>-#define IS2_AL_SMAC_SIP_FWD_KILL_ENA 1
>-#define IS2_AO_SMAC_SIP_HOST_MATCH 5
>-#define IS2_AL_SMAC_SIP_HOST_MATCH 1
>-
>-#endif /* _OCELOT_VCAP_H_ */
>diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
>index 3d9e83e78c59..f9da90c5171b 100644
>--- a/include/soc/mscc/ocelot.h
>+++ b/include/soc/mscc/ocelot.h
>@@ -521,6 +521,9 @@ struct ocelot {
>
>        struct ocelot_acl_block         acl_block;
>
>+       const struct vcap_field         *vcap_is2_keys;
>+       const struct vcap_field         *vcap_is2_actions;
>+
>        /* Workqueue to check statistics for overflow with its lock */
>        struct mutex                    stats_lock;
>        u64                             *stats;
>diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
>new file mode 100644
>index 000000000000..0783f0ffc813
>--- /dev/null
>+++ b/include/soc/mscc/ocelot_vcap.h
>@@ -0,0 +1,184 @@
>+/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
>+ * Microsemi Ocelot Switch driver
>+ * Copyright (c) 2019 Microsemi Corporation
>+ */
>+
>+#ifndef _OCELOT_VCAP_H_
>+#define _OCELOT_VCAP_H_
>+
>+/* =================================================================
>+ *  VCAP Common
>+ * =================================================================
>+ */
>+
>+/* VCAP Type-Group values */
>+#define VCAP_TG_NONE 0 /* Entry is invalid */
>+#define VCAP_TG_FULL 1 /* Full entry */
>+#define VCAP_TG_HALF 2 /* Half entry */
>+#define VCAP_TG_QUARTER 3 /* Quarter entry */
>+
>+/* =================================================================
>+ *  VCAP IS2
>+ * =================================================================
>+ */
>+
>+#define VCAP_IS2_CNT 64
>+#define VCAP_IS2_ENTRY_WIDTH 376
>+#define VCAP_IS2_ACTION_WIDTH 99
>+#define VCAP_PORT_CNT 11
>+
>+/* IS2 half key types */
>+#define IS2_TYPE_ETYPE 0
>+#define IS2_TYPE_LLC 1
>+#define IS2_TYPE_SNAP 2
>+#define IS2_TYPE_ARP 3
>+#define IS2_TYPE_IP_UDP_TCP 4
>+#define IS2_TYPE_IP_OTHER 5
>+#define IS2_TYPE_IPV6 6
>+#define IS2_TYPE_OAM 7
>+#define IS2_TYPE_SMAC_SIP6 8
>+#define IS2_TYPE_ANY 100 /* Pseudo type */
>+
>+/* IS2 half key type mask for matching any IP */
>+#define IS2_TYPE_MASK_IP_ANY 0xe
>+
>+/* IS2 action types */
>+#define IS2_ACTION_TYPE_NORMAL 0
>+#define IS2_ACTION_TYPE_SMAC_SIP 1
>+
>+/* IS2 MASK_MODE values */
>+#define IS2_ACT_MASK_MODE_NONE 0
>+#define IS2_ACT_MASK_MODE_FILTER 1
>+#define IS2_ACT_MASK_MODE_POLICY 2
>+#define IS2_ACT_MASK_MODE_REDIR 3
>+
>+/* IS2 REW_OP values */
>+#define IS2_ACT_REW_OP_NONE 0
>+#define IS2_ACT_REW_OP_PTP_ONE 2
>+#define IS2_ACT_REW_OP_PTP_TWO 3
>+#define IS2_ACT_REW_OP_SPECIAL 8
>+#define IS2_ACT_REW_OP_PTP_ORG 9
>+#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_1 (IS2_ACT_REW_OP_PTP_ONE | (1 << 3))
>+#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_2 (IS2_ACT_REW_OP_PTP_ONE | (2 << 3))
>+#define IS2_ACT_REW_OP_PTP_ONE_ADD_DELAY (IS2_ACT_REW_OP_PTP_ONE | (1 << 5))
>+#define IS2_ACT_REW_OP_PTP_ONE_ADD_SUB BIT(7)
>+
>+#define VCAP_PORT_WIDTH 4
>+
>+/* IS2 quarter key - SMAC_SIP4 */
>+#define IS2_QKO_IGR_PORT 0
>+#define IS2_QKL_IGR_PORT VCAP_PORT_WIDTH
>+#define IS2_QKO_L2_SMAC (IS2_QKO_IGR_PORT + IS2_QKL_IGR_PORT)
>+#define IS2_QKL_L2_SMAC 48
>+#define IS2_QKO_L3_IP4_SIP (IS2_QKO_L2_SMAC + IS2_QKL_L2_SMAC)
>+#define IS2_QKL_L3_IP4_SIP 32
>+
>+enum vcap_is2_half_key_field {
>+       /* Common */
>+       VCAP_IS2_TYPE,
>+       VCAP_IS2_HK_FIRST,
>+       VCAP_IS2_HK_PAG,
>+       VCAP_IS2_HK_RSV1,
>+       VCAP_IS2_HK_IGR_PORT_MASK,
>+       VCAP_IS2_HK_RSV2,
>+       VCAP_IS2_HK_HOST_MATCH,
>+       VCAP_IS2_HK_L2_MC,
>+       VCAP_IS2_HK_L2_BC,
>+       VCAP_IS2_HK_VLAN_TAGGED,
>+       VCAP_IS2_HK_VID,
>+       VCAP_IS2_HK_DEI,
>+       VCAP_IS2_HK_PCP,
>+       /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
>+       VCAP_IS2_HK_L2_DMAC,
>+       VCAP_IS2_HK_L2_SMAC,
>+       /* MAC_ETYPE (TYPE=000) */
>+       VCAP_IS2_HK_MAC_ETYPE_ETYPE,
>+       VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
>+       VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
>+       VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
>+       /* MAC_LLC (TYPE=001) */
>+       VCAP_IS2_HK_MAC_LLC_DMAC,
>+       VCAP_IS2_HK_MAC_LLC_SMAC,
>+       VCAP_IS2_HK_MAC_LLC_L2_LLC,
>+       /* MAC_SNAP (TYPE=010) */
>+       VCAP_IS2_HK_MAC_SNAP_SMAC,
>+       VCAP_IS2_HK_MAC_SNAP_DMAC,
>+       VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
>+       /* MAC_ARP (TYPE=011) */
>+       VCAP_IS2_HK_MAC_ARP_SMAC,
>+       VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
>+       VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
>+       VCAP_IS2_HK_MAC_ARP_LEN_OK,
>+       VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
>+       VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
>+       VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
>+       VCAP_IS2_HK_MAC_ARP_OPCODE,
>+       VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
>+       VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
>+       VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
>+       /* IP4_TCP_UDP / IP4_OTHER common */
>+       VCAP_IS2_HK_IP4,
>+       VCAP_IS2_HK_L3_FRAGMENT,
>+       VCAP_IS2_HK_L3_FRAG_OFS_GT0,
>+       VCAP_IS2_HK_L3_OPTIONS,
>+       VCAP_IS2_HK_IP4_L3_TTL_GT0,
>+       VCAP_IS2_HK_L3_TOS,
>+       VCAP_IS2_HK_L3_IP4_DIP,
>+       VCAP_IS2_HK_L3_IP4_SIP,
>+       VCAP_IS2_HK_DIP_EQ_SIP,
>+       /* IP4_TCP_UDP (TYPE=100) */
>+       VCAP_IS2_HK_TCP,
>+       VCAP_IS2_HK_L4_SPORT,
>+       VCAP_IS2_HK_L4_DPORT,
>+       VCAP_IS2_HK_L4_RNG,
>+       VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
>+       VCAP_IS2_HK_L4_SEQUENCE_EQ0,
>+       VCAP_IS2_HK_L4_URG,
>+       VCAP_IS2_HK_L4_ACK,
>+       VCAP_IS2_HK_L4_PSH,
>+       VCAP_IS2_HK_L4_RST,
>+       VCAP_IS2_HK_L4_SYN,
>+       VCAP_IS2_HK_L4_FIN,
>+       VCAP_IS2_HK_L4_1588_DOM,
>+       VCAP_IS2_HK_L4_1588_VER,
>+       /* IP4_OTHER (TYPE=101) */
>+       VCAP_IS2_HK_IP4_L3_PROTO,
>+       VCAP_IS2_HK_L3_PAYLOAD,
>+       /* IP6_STD (TYPE=110) */
>+       VCAP_IS2_HK_IP6_L3_TTL_GT0,
>+       VCAP_IS2_HK_IP6_L3_PROTO,
>+       VCAP_IS2_HK_L3_IP6_SIP,
>+       /* OAM (TYPE=111) */
>+       VCAP_IS2_HK_OAM_MEL_FLAGS,
>+       VCAP_IS2_HK_OAM_VER,
>+       VCAP_IS2_HK_OAM_OPCODE,
>+       VCAP_IS2_HK_OAM_FLAGS,
>+       VCAP_IS2_HK_OAM_MEPID,
>+       VCAP_IS2_HK_OAM_CCM_CNTS_EQ0,
>+       VCAP_IS2_HK_OAM_IS_Y1731,
>+};
>+
>+struct vcap_field {
>+       int offset;
>+       int length;
>+};
>+
>+enum vcap_is2_action_field {
>+       VCAP_IS2_ACT_HIT_ME_ONCE,
>+       VCAP_IS2_ACT_CPU_COPY_ENA,
>+       VCAP_IS2_ACT_CPU_QU_NUM,
>+       VCAP_IS2_ACT_MASK_MODE,
>+       VCAP_IS2_ACT_MIRROR_ENA,
>+       VCAP_IS2_ACT_LRN_DIS,
>+       VCAP_IS2_ACT_POLICE_ENA,
>+       VCAP_IS2_ACT_POLICE_IDX,
>+       VCAP_IS2_ACT_POLICE_VCAP_ONLY,
>+       VCAP_IS2_ACT_PORT_MASK,
>+       VCAP_IS2_ACT_REW_OP,
>+       VCAP_IS2_ACT_SMAC_REPLACE_ENA,
>+       VCAP_IS2_ACT_RSV,
>+       VCAP_IS2_ACT_ACL_ID,
>+       VCAP_IS2_ACT_HIT_CNT,
>+};
>+
>+#endif /* _OCELOT_VCAP_H_ */
>--
>2.17.1
>

Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 net-next 08/10] net: mscc: ocelot: parameterize the vcap_is2 properties
  2020-02-29 14:31 ` [PATCH v2 net-next 08/10] net: mscc: ocelot: parameterize the vcap_is2 properties Vladimir Oltean
@ 2020-03-05  7:16   ` Allan W. Nielsen
  0 siblings, 0 replies; 16+ messages in thread
From: Allan W. Nielsen @ 2020-03-05  7:16 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: davem, horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, claudiu.manoil, netdev,
	UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1, yangbo.lu,
	po.liu, jiri, idosch, kuba

On 29.02.2020 16:31, Vladimir Oltean wrote:
>EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>From: Vladimir Oltean <vladimir.oltean@nxp.com>
>
>Remove the definitions for the VCAP IS2 table from ocelot_ace.c, since
>it is specific to VSC7514.
>
>The VSC9959 VCAP IS2 table supports more rules (1024 instead of 64) and
>has a different width for the action (89 bits instead of 99).
>
>Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
>---
>Changes in v2:
>Added back macro definitions for VSC7514 port count and rule count.
>
> drivers/net/ethernet/mscc/ocelot_ace.c   | 134 +++++++++--------------
> drivers/net/ethernet/mscc/ocelot_board.c |  30 +++++
> include/soc/mscc/ocelot.h                |   1 +
> include/soc/mscc/ocelot_vcap.h           |  37 +++++--
> 4 files changed, 114 insertions(+), 88 deletions(-)
>
>diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
>index 9922033a2aaf..906b54025b17 100644
>--- a/drivers/net/ethernet/mscc/ocelot_ace.c
>+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
>@@ -11,53 +11,7 @@
> #include "ocelot_s2.h"
>
> #define OCELOT_POLICER_DISCARD 0x17f
>-
>-struct vcap_props {
>-       const char *name; /* Symbolic name */
>-       u16 tg_width; /* Type-group width (in bits) */
>-       u16 sw_count; /* Sub word count */
>-       u16 entry_count; /* Entry count */
>-       u16 entry_words; /* Number of entry words */
>-       u16 entry_width; /* Entry width (in bits) */
>-       u16 action_count; /* Action count */
>-       u16 action_words; /* Number of action words */
>-       u16 action_width; /* Action width (in bits) */
>-       u16 action_type_width; /* Action type width (in bits) */
>-       struct {
>-               u16 width; /* Action type width (in bits) */
>-               u16 count; /* Action type sub word count */
>-       } action_table[2];
>-       u16 counter_words; /* Number of counter words */
>-       u16 counter_width; /* Counter width (in bits) */
>-};
>-
> #define ENTRY_WIDTH 32
>-#define BITS_TO_32BIT(x) (1 + (((x) - 1) / ENTRY_WIDTH))
>-
>-static const struct vcap_props vcap_is2 = {
>-       .name = "IS2",
>-       .tg_width = 2,
>-       .sw_count = 4,
>-       .entry_count = VCAP_IS2_CNT,
>-       .entry_words = BITS_TO_32BIT(VCAP_IS2_ENTRY_WIDTH),
>-       .entry_width = VCAP_IS2_ENTRY_WIDTH,
>-       .action_count = (VCAP_IS2_CNT + VCAP_PORT_CNT + 2),
>-       .action_words = BITS_TO_32BIT(VCAP_IS2_ACTION_WIDTH),
>-       .action_width = (VCAP_IS2_ACTION_WIDTH),
>-       .action_type_width = 1,
>-       .action_table = {
>-               {
>-                       .width = 49,
>-                       .count = 2
>-               },
>-               {
>-                       .width = 6,
>-                       .count = 4
>-               },
>-       },
>-       .counter_words = BITS_TO_32BIT(4 * ENTRY_WIDTH),
>-       .counter_width = ENTRY_WIDTH,
>-};
>
> enum vcap_sel {
>        VCAP_SEL_ENTRY = 0x1,
>@@ -100,11 +54,13 @@ static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot)
>
> static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
> {
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+
>        u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
>                     S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
>                     S2_CORE_UPDATE_CTRL_UPDATE_SHOT);
>
>-       if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2.entry_count)
>+       if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2->entry_count)
>                return;
>
>        if (!(sel & VCAP_SEL_ENTRY))
>@@ -125,14 +81,19 @@ static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
> /* Convert from 0-based row to VCAP entry row and run command */
> static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel)
> {
>-       vcap_cmd(ocelot, vcap_is2.entry_count - row - 1, cmd, sel);
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+
>+       vcap_cmd(ocelot, vcap_is2->entry_count - row - 1, cmd, sel);
> }
>
> static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
> {
>-       u32 i;
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+       u32 entry_words, i;
>+
>+       entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH);
>
>-       for (i = 0; i < vcap_is2.entry_words; i++) {
>+       for (i = 0; i < entry_words; i++) {
>                ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i);
>                ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i);
>        }
>@@ -141,9 +102,12 @@ static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
>
> static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
> {
>-       u32 i;
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+       u32 entry_words, i;
>+
>+       entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH);
>
>-       for (i = 0; i < vcap_is2.entry_words; i++) {
>+       for (i = 0; i < entry_words; i++) {
>                data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i);
>                // Invert mask
>                data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i);
>@@ -153,49 +117,56 @@ static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
>
> static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
> {
>-       u32 i, width, mask;
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+       u32 action_words, i, width, mask;
>
>        /* Encode action type */
>-       width = vcap_is2.action_type_width;
>+       width = vcap_is2->action_type_width;
>        if (width) {
>                mask = GENMASK(width, 0);
>                data->action[0] = ((data->action[0] & ~mask) | data->type);
>        }
>
>-       for (i = 0; i < vcap_is2.action_words; i++)
>-               ocelot_write_rix(ocelot, data->action[i],
>-                                S2_CACHE_ACTION_DAT, i);
>+       action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
>
>-       for (i = 0; i < vcap_is2.counter_words; i++)
>-               ocelot_write_rix(ocelot, data->counter[i],
>-                                S2_CACHE_CNT_DAT, i);
>+       for (i = 0; i < action_words; i++)
>+               ocelot_write_rix(ocelot, data->action[i], S2_CACHE_ACTION_DAT,
>+                                i);
>+
>+       for (i = 0; i < vcap_is2->counter_words; i++)
>+               ocelot_write_rix(ocelot, data->counter[i], S2_CACHE_CNT_DAT, i);
> }
>
> static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
> {
>-       u32 i, width;
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+       u32 action_words, i, width;
>+
>+       action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
>
>-       for (i = 0; i < vcap_is2.action_words; i++)
>+       for (i = 0; i < action_words; i++)
>                data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT,
>                                                  i);
>
>-       for (i = 0; i < vcap_is2.counter_words; i++)
>+       for (i = 0; i < vcap_is2->counter_words; i++)
>                data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i);
>
>        /* Extract action type */
>-       width = vcap_is2.action_type_width;
>+       width = vcap_is2->action_type_width;
>        data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0);
> }
>
> /* Calculate offsets for entry */
>-static void is2_data_get(struct vcap_data *data, int ix)
>+static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix)
> {
>-       u32 i, col, offset, count, cnt, base, width = vcap_is2.tg_width;
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>+       u32 i, col, offset, count, cnt, base;
>+       u32 width = vcap_is2->tg_width;
>
>        count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4);
>        col = (ix % 2);
>-       cnt = (vcap_is2.sw_count / count);
>-       base = (vcap_is2.sw_count - col * cnt - cnt);
>+       cnt = (vcap_is2->sw_count / count);
>+       base = (vcap_is2->sw_count - col * cnt - cnt);
>        data->tg_value = 0;
>        data->tg_mask = 0;
>        for (i = 0; i < cnt; i++) {
>@@ -206,13 +177,13 @@ static void is2_data_get(struct vcap_data *data, int ix)
>
>        /* Calculate key/action/counter offsets */
>        col = (count - col - 1);
>-       data->key_offset = (base * vcap_is2.entry_width) / vcap_is2.sw_count;
>-       data->counter_offset = (cnt * col * vcap_is2.counter_width);
>+       data->key_offset = (base * vcap_is2->entry_width) / vcap_is2->sw_count;
>+       data->counter_offset = (cnt * col * vcap_is2->counter_width);
>        i = data->type;
>-       width = vcap_is2.action_table[i].width;
>-       cnt = vcap_is2.action_table[i].count;
>+       width = vcap_is2->action_table[i].width;
>+       cnt = vcap_is2->action_table[i].count;
>        data->action_offset =
>-               (((cnt * col * width) / count) + vcap_is2.action_type_width);
>+               (((cnt * col * width) / count) + vcap_is2->action_type_width);
> }
>
> static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value)
>@@ -354,6 +325,7 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
> static void is2_entry_set(struct ocelot *ocelot, int ix,
>                          struct ocelot_ace_rule *ace)
> {
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>        u32 val, msk, type, type_mask = 0xf, i, count;
>        struct ocelot_ace_vlan *tag = &ace->vlan;
>        struct ocelot_vcap_u64 payload;
>@@ -369,7 +341,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>        vcap_cache2action(ocelot, &data);
>
>        data.tg_sw = VCAP_TG_HALF;
>-       is2_data_get(&data, ix);
>+       is2_data_get(ocelot, &data, ix);
>        data.tg = (data.tg & ~data.tg_mask);
>        if (ace->prio != 0)
>                data.tg |= data.tg_value;
>@@ -627,7 +599,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>        default:
>                type = 0;
>                type_mask = 0;
>-               count = (vcap_is2.entry_width / 2);
>+               count = vcap_is2->entry_width / 2;
>                /* Iterate over the non-common part of the key and
>                 * clear entry data
>                 */
>@@ -641,7 +613,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
>        vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
>        is2_action_set(ocelot, &data, ace->action);
>        vcap_data_set(data.counter, data.counter_offset,
>-                     vcap_is2.counter_width, ace->stats.pkts);
>+                     vcap_is2->counter_width, ace->stats.pkts);
>
>        /* Write row */
>        vcap_entry2cache(ocelot, &data);
>@@ -652,6 +624,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
> static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
>                          int ix)
> {
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>        struct vcap_data data;
>        int row = (ix / 2);
>        u32 cnt;
>@@ -659,9 +632,9 @@ static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
>        vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
>        vcap_cache2action(ocelot, &data);
>        data.tg_sw = VCAP_TG_HALF;
>-       is2_data_get(&data, ix);
>+       is2_data_get(ocelot, &data, ix);
>        cnt = vcap_data_get(data.counter, data.counter_offset,
>-                           vcap_is2.counter_width);
>+                           vcap_is2->counter_width);
>
>        rule->stats.pkts = cnt;
> }
>@@ -805,16 +778,17 @@ int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
>
> int ocelot_ace_init(struct ocelot *ocelot)
> {
>+       const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
>        struct vcap_data data;
>
>        memset(&data, 0, sizeof(data));
>
>        vcap_entry2cache(ocelot, &data);
>-       ocelot_write(ocelot, vcap_is2.entry_count, S2_CORE_MV_CFG);
>+       ocelot_write(ocelot, vcap_is2->entry_count, S2_CORE_MV_CFG);
>        vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);
>
>        vcap_action2cache(ocelot, &data);
>-       ocelot_write(ocelot, vcap_is2.action_count, S2_CORE_MV_CFG);
>+       ocelot_write(ocelot, vcap_is2->action_count, S2_CORE_MV_CFG);
>        vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE,
>                 VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
>
>diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
>index 8234631a0911..3eb40a2dd0c9 100644
>--- a/drivers/net/ethernet/mscc/ocelot_board.c
>+++ b/drivers/net/ethernet/mscc/ocelot_board.c
>@@ -18,6 +18,10 @@
> #include "ocelot.h"
>
> #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
>+#define VSC7514_VCAP_IS2_CNT 64
>+#define VSC7514_VCAP_IS2_ENTRY_WIDTH 376
>+#define VSC7514_VCAP_IS2_ACTION_WIDTH 99
>+#define VSC7514_VCAP_PORT_CNT 11
>
> static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
> {
>@@ -337,6 +341,31 @@ static const struct vcap_field vsc7514_vcap_is2_actions[] = {
>        [VCAP_IS2_ACT_HIT_CNT]                  = { 49, 32},
> };
>
>+static const struct vcap_props vsc7514_vcap_props[] = {
>+       [VCAP_IS2] = {
>+               .tg_width = 2,
>+               .sw_count = 4,
>+               .entry_count = VSC7514_VCAP_IS2_CNT,
>+               .entry_width = VSC7514_VCAP_IS2_ENTRY_WIDTH,
>+               .action_count = VSC7514_VCAP_IS2_CNT +
>+                               VSC7514_VCAP_PORT_CNT + 2,
>+               .action_width = 99,
>+               .action_type_width = 1,
>+               .action_table = {
>+                       [IS2_ACTION_TYPE_NORMAL] = {
>+                               .width = 49,
>+                               .count = 2
>+                       },
>+                       [IS2_ACTION_TYPE_SMAC_SIP] = {
>+                               .width = 6,
>+                               .count = 4
>+                       },
>+               },
>+               .counter_words = 4,
>+               .counter_width = 32,
>+       },
>+};
>+
> static int mscc_ocelot_probe(struct platform_device *pdev)
> {
>        struct device_node *np = pdev->dev.of_node;
>@@ -439,6 +468,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
>
>        ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
>        ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
>+       ocelot->vcap = vsc7514_vcap_props;
>
>        ocelot_init(ocelot);
>        /* No NPI port */
>diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
>index ab342eef251c..e572c6446df0 100644
>--- a/include/soc/mscc/ocelot.h
>+++ b/include/soc/mscc/ocelot.h
>@@ -522,6 +522,7 @@ struct ocelot {
>
>        const struct vcap_field         *vcap_is2_keys;
>        const struct vcap_field         *vcap_is2_actions;
>+       const struct vcap_props         *vcap;
>
>        /* Workqueue to check statistics for overflow with its lock */
>        struct mutex                    stats_lock;
>diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
>index 0783f0ffc813..5748373ab4d3 100644
>--- a/include/soc/mscc/ocelot_vcap.h
>+++ b/include/soc/mscc/ocelot_vcap.h
>@@ -11,6 +11,30 @@
>  * =================================================================
>  */
>
>+enum {
>+       /* VCAP_IS1, */
>+       VCAP_IS2,
>+       /* VCAP_ES0, */
>+};
>+
>+struct vcap_props {
>+       u16 tg_width; /* Type-group width (in bits) */
>+       u16 sw_count; /* Sub word count */
>+       u16 entry_count; /* Entry count */
>+       u16 entry_words; /* Number of entry words */
>+       u16 entry_width; /* Entry width (in bits) */
>+       u16 action_count; /* Action count */
>+       u16 action_words; /* Number of action words */
>+       u16 action_width; /* Action width (in bits) */
>+       u16 action_type_width; /* Action type width (in bits) */
>+       struct {
>+               u16 width; /* Action type width (in bits) */
>+               u16 count; /* Action type sub word count */
>+       } action_table[2];
>+       u16 counter_words; /* Number of counter words */
>+       u16 counter_width; /* Counter width (in bits) */
>+};
>+
> /* VCAP Type-Group values */
> #define VCAP_TG_NONE 0 /* Entry is invalid */
> #define VCAP_TG_FULL 1 /* Full entry */
>@@ -22,11 +46,6 @@
>  * =================================================================
>  */
>
>-#define VCAP_IS2_CNT 64
>-#define VCAP_IS2_ENTRY_WIDTH 376
>-#define VCAP_IS2_ACTION_WIDTH 99
>-#define VCAP_PORT_CNT 11
>-
> /* IS2 half key types */
> #define IS2_TYPE_ETYPE 0
> #define IS2_TYPE_LLC 1
>@@ -42,9 +61,11 @@
> /* IS2 half key type mask for matching any IP */
> #define IS2_TYPE_MASK_IP_ANY 0xe
>
>-/* IS2 action types */
>-#define IS2_ACTION_TYPE_NORMAL 0
>-#define IS2_ACTION_TYPE_SMAC_SIP 1
>+enum {
>+       IS2_ACTION_TYPE_NORMAL,
>+       IS2_ACTION_TYPE_SMAC_SIP,
>+       IS2_ACTION_TYPE_MAX,
>+};
>
> /* IS2 MASK_MODE values */
> #define IS2_ACT_MASK_MODE_NONE 0
>--
>2.17.1
>
/Allan

Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 net-next 10/10] net: dsa: felix: Wire up the ocelot cls_flower methods
  2020-02-29 14:31 ` [PATCH v2 net-next 10/10] net: dsa: felix: Wire up the ocelot cls_flower methods Vladimir Oltean
@ 2020-03-05  7:18   ` Allan W. Nielsen
  0 siblings, 0 replies; 16+ messages in thread
From: Allan W. Nielsen @ 2020-03-05  7:18 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: davem, horatiu.vultur, alexandre.belloni, andrew, f.fainelli,
	vivien.didelot, joergen.andreasen, claudiu.manoil, netdev,
	UNGLinuxDriver, alexandru.marginean, xiaoliang.yang_1, yangbo.lu,
	po.liu, jiri, idosch, kuba

On 29.02.2020 16:31, Vladimir Oltean wrote:
>EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>From: Vladimir Oltean <vladimir.oltean@nxp.com>
>
>Export the cls_flower methods from the ocelot driver and hook them up to
>the DSA passthrough layer.
>
>Tables for the VCAP IS2 parameters, as well as half key packing (field
>offsets and lengths) need to be defined for the VSC9959 core, as they
>are different from Ocelot, mainly due to the different port count.
>
>Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
>---
>Changes in v2:
>Defined VSC9959_VCAP_IS2_CNT, VSC9959_VCAP_IS2_ENTRY_WIDTH,
>VSC9959_VCAP_PORT_CNT.
>
> drivers/net/dsa/ocelot/felix.c         |  31 ++++++
> drivers/net/dsa/ocelot/felix.h         |   3 +
> drivers/net/dsa/ocelot/felix_vsc9959.c | 131 +++++++++++++++++++++++++
> include/soc/mscc/ocelot.h              |   6 ++
> 4 files changed, 171 insertions(+)
>
>diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
>index f14595b8dad5..69546383a382 100644
>--- a/drivers/net/dsa/ocelot/felix.c
>+++ b/drivers/net/dsa/ocelot/felix.c
>@@ -2,6 +2,7 @@
> /* Copyright 2019 NXP Semiconductors
>  */
> #include <uapi/linux/if_bridge.h>
>+#include <soc/mscc/ocelot_vcap.h>
> #include <soc/mscc/ocelot_qsys.h>
> #include <soc/mscc/ocelot_sys.h>
> #include <soc/mscc/ocelot_dev.h>
>@@ -401,6 +402,9 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
>        ocelot->stats_layout    = felix->info->stats_layout;
>        ocelot->num_stats       = felix->info->num_stats;
>        ocelot->shared_queue_sz = felix->info->shared_queue_sz;
>+       ocelot->vcap_is2_keys   = felix->info->vcap_is2_keys;
>+       ocelot->vcap_is2_actions= felix->info->vcap_is2_actions;
>+       ocelot->vcap            = felix->info->vcap;
>        ocelot->ops             = felix->info->ops;
>
>        port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t),
>@@ -605,6 +609,30 @@ static bool felix_txtstamp(struct dsa_switch *ds, int port,
>        return false;
> }
>
>+static int felix_cls_flower_add(struct dsa_switch *ds, int port,
>+                               struct flow_cls_offload *cls, bool ingress)
>+{
>+       struct ocelot *ocelot = ds->priv;
>+
>+       return ocelot_cls_flower_replace(ocelot, port, cls, ingress);
>+}
>+
>+static int felix_cls_flower_del(struct dsa_switch *ds, int port,
>+                               struct flow_cls_offload *cls, bool ingress)
>+{
>+       struct ocelot *ocelot = ds->priv;
>+
>+       return ocelot_cls_flower_destroy(ocelot, port, cls, ingress);
>+}
>+
>+static int felix_cls_flower_stats(struct dsa_switch *ds, int port,
>+                                 struct flow_cls_offload *cls, bool ingress)
>+{
>+       struct ocelot *ocelot = ds->priv;
>+
>+       return ocelot_cls_flower_stats(ocelot, port, cls, ingress);
>+}
>+
> static const struct dsa_switch_ops felix_switch_ops = {
>        .get_tag_protocol       = felix_get_tag_protocol,
>        .setup                  = felix_setup,
>@@ -636,6 +664,9 @@ static const struct dsa_switch_ops felix_switch_ops = {
>        .port_hwtstamp_set      = felix_hwtstamp_set,
>        .port_rxtstamp          = felix_rxtstamp,
>        .port_txtstamp          = felix_txtstamp,
>+       .cls_flower_add         = felix_cls_flower_add,
>+       .cls_flower_del         = felix_cls_flower_del,
>+       .cls_flower_stats       = felix_cls_flower_stats,
> };
>
> static struct felix_info *felix_instance_tbl[] = {
>diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
>index 3a7580015b62..82d46f260041 100644
>--- a/drivers/net/dsa/ocelot/felix.h
>+++ b/drivers/net/dsa/ocelot/felix.h
>@@ -18,6 +18,9 @@ struct felix_info {
>        const struct ocelot_stat_layout *stats_layout;
>        unsigned int                    num_stats;
>        int                             num_ports;
>+       struct vcap_field               *vcap_is2_keys;
>+       struct vcap_field               *vcap_is2_actions;
>+       const struct vcap_props         *vcap;
>        int                             switch_pci_bar;
>        int                             imdio_pci_bar;
>        int     (*mdio_bus_alloc)(struct ocelot *ocelot);
>diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
>index 93800e81cdd4..b4078f3c5c38 100644
>--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
>+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
>@@ -3,12 +3,17 @@
>  * Copyright 2018-2019 NXP Semiconductors
>  */
> #include <linux/fsl/enetc_mdio.h>
>+#include <soc/mscc/ocelot_vcap.h>
> #include <soc/mscc/ocelot_sys.h>
> #include <soc/mscc/ocelot.h>
> #include <linux/iopoll.h>
> #include <linux/pci.h>
> #include "felix.h"
>
>+#define VSC9959_VCAP_IS2_CNT           1024
>+#define VSC9959_VCAP_IS2_ENTRY_WIDTH   376
>+#define VSC9959_VCAP_PORT_CNT          6
>+
> /* TODO: should find a better place for these */
> #define USXGMII_BMCR_RESET             BIT(15)
> #define USXGMII_BMCR_AN_EN             BIT(12)
>@@ -547,6 +552,129 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
>        { .offset = 0x111,      .name = "drop_green_prio_7", },
> };
>
>+struct vcap_field vsc9959_vcap_is2_keys[] = {
>+       /* Common: 41 bits */
>+       [VCAP_IS2_TYPE]                         = {  0,   4},
>+       [VCAP_IS2_HK_FIRST]                     = {  4,   1},
>+       [VCAP_IS2_HK_PAG]                       = {  5,   8},
>+       [VCAP_IS2_HK_IGR_PORT_MASK]             = { 13,   7},
>+       [VCAP_IS2_HK_RSV2]                      = { 20,   1},
>+       [VCAP_IS2_HK_HOST_MATCH]                = { 21,   1},
>+       [VCAP_IS2_HK_L2_MC]                     = { 22,   1},
>+       [VCAP_IS2_HK_L2_BC]                     = { 23,   1},
>+       [VCAP_IS2_HK_VLAN_TAGGED]               = { 24,   1},
>+       [VCAP_IS2_HK_VID]                       = { 25,  12},
>+       [VCAP_IS2_HK_DEI]                       = { 37,   1},
>+       [VCAP_IS2_HK_PCP]                       = { 38,   3},
>+       /* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
>+       [VCAP_IS2_HK_L2_DMAC]                   = { 41,  48},
>+       [VCAP_IS2_HK_L2_SMAC]                   = { 89,  48},
>+       /* MAC_ETYPE (TYPE=000) */
>+       [VCAP_IS2_HK_MAC_ETYPE_ETYPE]           = {137,  16},
>+       [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0]     = {153,  16},
>+       [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1]     = {169,   8},
>+       [VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2]     = {177,   3},
>+       /* MAC_LLC (TYPE=001) */
>+       [VCAP_IS2_HK_MAC_LLC_L2_LLC]            = {137,  40},
>+       /* MAC_SNAP (TYPE=010) */
>+       [VCAP_IS2_HK_MAC_SNAP_L2_SNAP]          = {137,  40},
>+       /* MAC_ARP (TYPE=011) */
>+       [VCAP_IS2_HK_MAC_ARP_SMAC]              = { 41,  48},
>+       [VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK]     = { 89,   1},
>+       [VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK]    = { 90,   1},
>+       [VCAP_IS2_HK_MAC_ARP_LEN_OK]            = { 91,   1},
>+       [VCAP_IS2_HK_MAC_ARP_TARGET_MATCH]      = { 92,   1},
>+       [VCAP_IS2_HK_MAC_ARP_SENDER_MATCH]      = { 93,   1},
>+       [VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN]    = { 94,   1},
>+       [VCAP_IS2_HK_MAC_ARP_OPCODE]            = { 95,   2},
>+       [VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP]        = { 97,  32},
>+       [VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP]        = {129,  32},
>+       [VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP]        = {161,   1},
>+       /* IP4_TCP_UDP / IP4_OTHER common */
>+       [VCAP_IS2_HK_IP4]                       = { 41,   1},
>+       [VCAP_IS2_HK_L3_FRAGMENT]               = { 42,   1},
>+       [VCAP_IS2_HK_L3_FRAG_OFS_GT0]           = { 43,   1},
>+       [VCAP_IS2_HK_L3_OPTIONS]                = { 44,   1},
>+       [VCAP_IS2_HK_IP4_L3_TTL_GT0]            = { 45,   1},
>+       [VCAP_IS2_HK_L3_TOS]                    = { 46,   8},
>+       [VCAP_IS2_HK_L3_IP4_DIP]                = { 54,  32},
>+       [VCAP_IS2_HK_L3_IP4_SIP]                = { 86,  32},
>+       [VCAP_IS2_HK_DIP_EQ_SIP]                = {118,   1},
>+       /* IP4_TCP_UDP (TYPE=100) */
>+       [VCAP_IS2_HK_TCP]                       = {119,   1},
>+       [VCAP_IS2_HK_L4_SPORT]                  = {120,  16},
>+       [VCAP_IS2_HK_L4_DPORT]                  = {136,  16},
>+       [VCAP_IS2_HK_L4_RNG]                    = {152,   8},
>+       [VCAP_IS2_HK_L4_SPORT_EQ_DPORT]         = {160,   1},
>+       [VCAP_IS2_HK_L4_SEQUENCE_EQ0]           = {161,   1},
>+       [VCAP_IS2_HK_L4_URG]                    = {162,   1},
>+       [VCAP_IS2_HK_L4_ACK]                    = {163,   1},
>+       [VCAP_IS2_HK_L4_PSH]                    = {164,   1},
>+       [VCAP_IS2_HK_L4_RST]                    = {165,   1},
>+       [VCAP_IS2_HK_L4_SYN]                    = {166,   1},
>+       [VCAP_IS2_HK_L4_FIN]                    = {167,   1},
>+       [VCAP_IS2_HK_L4_1588_DOM]               = {168,   8},
>+       [VCAP_IS2_HK_L4_1588_VER]               = {176,   4},
>+       /* IP4_OTHER (TYPE=101) */
>+       [VCAP_IS2_HK_IP4_L3_PROTO]              = {119,   8},
>+       [VCAP_IS2_HK_L3_PAYLOAD]                = {127,  56},
>+       /* IP6_STD (TYPE=110) */
>+       [VCAP_IS2_HK_IP6_L3_TTL_GT0]            = { 41,   1},
>+       [VCAP_IS2_HK_L3_IP6_SIP]                = { 42, 128},
>+       [VCAP_IS2_HK_IP6_L3_PROTO]              = {170,   8},
>+       /* OAM (TYPE=111) */
>+       [VCAP_IS2_HK_OAM_MEL_FLAGS]             = {137,   7},
>+       [VCAP_IS2_HK_OAM_VER]                   = {144,   5},
>+       [VCAP_IS2_HK_OAM_OPCODE]                = {149,   8},
>+       [VCAP_IS2_HK_OAM_FLAGS]                 = {157,   8},
>+       [VCAP_IS2_HK_OAM_MEPID]                 = {165,  16},
>+       [VCAP_IS2_HK_OAM_CCM_CNTS_EQ0]          = {181,   1},
>+       [VCAP_IS2_HK_OAM_IS_Y1731]              = {182,   1},
>+};
>+
>+struct vcap_field vsc9959_vcap_is2_actions[] = {
>+       [VCAP_IS2_ACT_HIT_ME_ONCE]              = {  0,  1},
>+       [VCAP_IS2_ACT_CPU_COPY_ENA]             = {  1,  1},
>+       [VCAP_IS2_ACT_CPU_QU_NUM]               = {  2,  3},
>+       [VCAP_IS2_ACT_MASK_MODE]                = {  5,  2},
>+       [VCAP_IS2_ACT_MIRROR_ENA]               = {  7,  1},
>+       [VCAP_IS2_ACT_LRN_DIS]                  = {  8,  1},
>+       [VCAP_IS2_ACT_POLICE_ENA]               = {  9,  1},
>+       [VCAP_IS2_ACT_POLICE_IDX]               = { 10,  9},
>+       [VCAP_IS2_ACT_POLICE_VCAP_ONLY]         = { 19,  1},
>+       [VCAP_IS2_ACT_PORT_MASK]                = { 20, 11},
>+       [VCAP_IS2_ACT_REW_OP]                   = { 31,  9},
>+       [VCAP_IS2_ACT_SMAC_REPLACE_ENA]         = { 40,  1},
>+       [VCAP_IS2_ACT_RSV]                      = { 41,  2},
>+       [VCAP_IS2_ACT_ACL_ID]                   = { 43,  6},
>+       [VCAP_IS2_ACT_HIT_CNT]                  = { 49, 32},
>+};
>+
>+static const struct vcap_props vsc9959_vcap_props[] = {
>+       [VCAP_IS2] = {
>+               .tg_width = 2,
>+               .sw_count = 4,
>+               .entry_count = VSC9959_VCAP_IS2_CNT,
>+               .entry_width = VSC9959_VCAP_IS2_ENTRY_WIDTH,
>+               .action_count = VSC9959_VCAP_IS2_CNT +
>+                               VSC9959_VCAP_PORT_CNT + 2,
>+               .action_width = 89,
>+               .action_type_width = 1,
>+               .action_table = {
>+                       [IS2_ACTION_TYPE_NORMAL] = {
>+                               .width = 44,
>+                               .count = 2
>+                       },
>+                       [IS2_ACTION_TYPE_SMAC_SIP] = {
>+                               .width = 6,
>+                               .count = 4
>+                       },
>+               },
>+               .counter_words = 4,
>+               .counter_width = 32,
>+       },
>+};
>+
> #define VSC9959_INIT_TIMEOUT                   50000
> #define VSC9959_GCB_RST_SLEEP                  100
> #define VSC9959_SYS_RAMINIT_SLEEP              80
>@@ -1088,6 +1216,9 @@ struct felix_info felix_info_vsc9959 = {
>        .ops                    = &vsc9959_ops,
>        .stats_layout           = vsc9959_stats_layout,
>        .num_stats              = ARRAY_SIZE(vsc9959_stats_layout),
>+       .vcap_is2_keys          = vsc9959_vcap_is2_keys,
>+       .vcap_is2_actions       = vsc9959_vcap_is2_actions,
>+       .vcap                   = vsc9959_vcap_props,
>        .shared_queue_sz        = 128 * 1024,
>        .num_ports              = 6,
>        .switch_pci_bar         = 4,
>diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
>index e572c6446df0..63d93ac1879e 100644
>--- a/include/soc/mscc/ocelot.h
>+++ b/include/soc/mscc/ocelot.h
>@@ -608,5 +608,11 @@ int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
> int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
>                                 struct sk_buff *skb);
> void ocelot_get_txtstamp(struct ocelot *ocelot);
>+int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
>+                             struct flow_cls_offload *f, bool ingress);
>+int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
>+                             struct flow_cls_offload *f, bool ingress);
>+int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
>+                           struct flow_cls_offload *f, bool ingress);
>
> #endif
>--
>2.17.1
>

Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-03-05  7:18 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-29 14:31 [PATCH v2 net-next 00/10] Wire up Ocelot tc-flower to Felix DSA Vladimir Oltean
2020-02-29 14:31 ` [PATCH v2 net-next 01/10] net: mscc: ocelot: make ocelot_ace_rule support multiple ports Vladimir Oltean
2020-02-29 14:31 ` [PATCH v2 net-next 02/10] net: mscc: ocelot: simplify tc-flower offload structures Vladimir Oltean
2020-02-29 14:31 ` [PATCH v2 net-next 03/10] net: mscc: ocelot: replace "rule" and "ocelot_rule" variable names with "ace" Vladimir Oltean
2020-02-29 14:31 ` [PATCH v2 net-next 04/10] net: mscc: ocelot: return directly in ocelot_cls_flower_{replace,destroy} Vladimir Oltean
2020-02-29 14:31 ` [PATCH v2 net-next 05/10] net: mscc: ocelot: spell out full "ocelot" name instead of "oc" Vladimir Oltean
2020-03-05  7:09   ` Allan W. Nielsen
2020-02-29 14:31 ` [PATCH v2 net-next 06/10] net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing Vladimir Oltean
2020-03-05  7:15   ` Allan W. Nielsen
2020-02-29 14:31 ` [PATCH v2 net-next 07/10] net: mscc: ocelot: remove port_pcs_init indirection for VSC7514 Vladimir Oltean
2020-02-29 14:31 ` [PATCH v2 net-next 08/10] net: mscc: ocelot: parameterize the vcap_is2 properties Vladimir Oltean
2020-03-05  7:16   ` Allan W. Nielsen
2020-02-29 14:31 ` [PATCH v2 net-next 09/10] net: dsa: Add bypass operations for the flower classifier-action filter Vladimir Oltean
2020-03-03  4:09   ` Florian Fainelli
2020-02-29 14:31 ` [PATCH v2 net-next 10/10] net: dsa: felix: Wire up the ocelot cls_flower methods Vladimir Oltean
2020-03-05  7:18   ` Allan W. Nielsen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).