summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Boiko <serhiy.boiko@plvision.eu>2022-08-23 14:39:57 +0300
committerDavid S. Miller <davem@davemloft.net>2022-08-26 10:04:54 +0100
commit8c448c2b5fd223d1a694cae1a185aeb9093d1c3c (patch)
tree8ce0d4d6396e961461aea7bd17a1bc7c8ca0081a
parent8afd552db4631a31cbdb628c59ffc66772822251 (diff)
net: prestera: add support for egress traffic mirroring
This enables adding matchall rules for egress: tc filter add .. egress .. matchall skip_sw \ action mirred egress mirror dev .. Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu> Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_hw.c30
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_hw.h5
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_matchall.c7
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_span.c10
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_span.h6
5 files changed, 39 insertions, 19 deletions
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
index 1a68a888d587..5803a28050e1 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
@@ -78,9 +78,11 @@ enum prestera_cmd_type_t {
PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000,
PRESTERA_CMD_TYPE_SPAN_GET = 0x1100,
- PRESTERA_CMD_TYPE_SPAN_BIND = 0x1101,
- PRESTERA_CMD_TYPE_SPAN_UNBIND = 0x1102,
+ PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101,
+ PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102,
PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103,
+ PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND = 0x1104,
+ PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND = 0x1105,
PRESTERA_CMD_TYPE_POLICER_CREATE = 0x1500,
PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501,
@@ -1434,27 +1436,39 @@ int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id)
return 0;
}
-int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id)
+int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
+ bool ingress)
{
struct prestera_msg_span_req req = {
.port = __cpu_to_le32(port->hw_id),
.dev = __cpu_to_le32(port->dev_id),
.id = span_id,
};
+ enum prestera_cmd_type_t cmd_type;
+
+ if (ingress)
+ cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND;
+ else
+ cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND;
+
+ return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
- return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_SPAN_BIND,
- &req.cmd, sizeof(req));
}
-int prestera_hw_span_unbind(const struct prestera_port *port)
+int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress)
{
struct prestera_msg_span_req req = {
.port = __cpu_to_le32(port->hw_id),
.dev = __cpu_to_le32(port->dev_id),
};
+ enum prestera_cmd_type_t cmd_type;
- return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_SPAN_UNBIND,
- &req.cmd, sizeof(req));
+ if (ingress)
+ cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND;
+ else
+ cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND;
+
+ return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
}
int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id)
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.h b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
index 4aca43e72a05..21078a2256b2 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
@@ -245,8 +245,9 @@ int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id,
/* SPAN API */
int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id);
-int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id);
-int prestera_hw_span_unbind(const struct prestera_port *port);
+int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
+ bool ingress);
+int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress);
int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id);
/* Router API */
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
index 54573c6a6fe2..3fc13176e046 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
@@ -43,7 +43,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
port = netdev_priv(act->dev);
list_for_each_entry(binding, &block->binding_list, list) {
- err = prestera_span_rule_add(binding, port);
+ err = prestera_span_rule_add(binding, port, block->ingress);
if (err)
goto rollback;
}
@@ -53,7 +53,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
rollback:
list_for_each_entry_continue_reverse(binding,
&block->binding_list, list)
- prestera_span_rule_del(binding);
+ prestera_span_rule_del(binding, block->ingress);
return err;
}
@@ -62,5 +62,6 @@ void prestera_mall_destroy(struct prestera_flow_block *block)
struct prestera_flow_block_binding *binding;
list_for_each_entry(binding, &block->binding_list, list)
- prestera_span_rule_del(binding);
+ prestera_span_rule_del(binding, block->ingress);
+
}
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.c b/drivers/net/ethernet/marvell/prestera/prestera_span.c
index 766413b9ba1b..f0e9d6ea88c5 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_span.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_span.c
@@ -121,7 +121,8 @@ static int prestera_span_put(struct prestera_switch *sw, u8 span_id)
}
int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
- struct prestera_port *to_port)
+ struct prestera_port *to_port,
+ bool ingress)
{
struct prestera_switch *sw = binding->port->sw;
u8 span_id;
@@ -135,7 +136,7 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
if (err)
return err;
- err = prestera_hw_span_bind(binding->port, span_id);
+ err = prestera_hw_span_bind(binding->port, span_id, ingress);
if (err) {
prestera_span_put(sw, span_id);
return err;
@@ -145,11 +146,12 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
return 0;
}
-int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
+ bool ingress)
{
int err;
- err = prestera_hw_span_unbind(binding->port);
+ err = prestera_hw_span_unbind(binding->port, ingress);
if (err)
return err;
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.h b/drivers/net/ethernet/marvell/prestera/prestera_span.h
index 4958ce820b52..493b68524bcb 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_span.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_span.h
@@ -16,7 +16,9 @@ int prestera_span_init(struct prestera_switch *sw);
void prestera_span_fini(struct prestera_switch *sw);
int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
- struct prestera_port *to_port);
-int prestera_span_rule_del(struct prestera_flow_block_binding *binding);
+ struct prestera_port *to_port,
+ bool ingress);
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
+ bool ingress);
#endif /* _PRESTERA_SPAN_H_ */