netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations
@ 2020-07-14 14:20 Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 01/13] mlxsw: reg: Add session_id and pid to MPAT register Ido Schimmel
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

A future patch set will add the ability to trap packets that were
dropped due to buffer related reasons (e.g., early drop). Internally
this is implemented by mirroring these packets towards the CPU port.
This patch set adds the required infrastructure to enable such
mirroring.

Patches #1-#2 extend two registers needed for above mentioned
functionality.

Patches #3-#6 gradually add support for setting the mirroring target of
a SPAN (mirroring) agent as the CPU port. This is only supported from
Spectrum-2 onwards, so an error is returned for Spectrum-1.

Patches #7-#8 add the ability to set a policer on a SPAN agent. This is
required because unlike regularly trapped packets, a policer cannot be
set on the trap group with which the mirroring trap is associated.

Patches #9-#12 parse the mirror reason field from the Completion Queue
Element (CQE). Unlike other trapped packets, the trap identifier of
mirrored packets only indicates that the packet was mirrored, but not
why. The reason (e.g., tail drop) is encoded in the mirror reason field.

Patch #13 utilizes the mirror reason field in order to lookup the
matching Rx listener. This allows us to maintain the abstraction that an
Rx listener is mapped to a single trap reason. Without taking the mirror
reason into account we would need to register a single Rx listener for
all mirrored packets.

Amit Cohen (3):
  mlxsw: reg: Add session_id and pid to MPAT register
  mlxsw: reg: add mirroring_pid_base to MOGCR register
  mlxsw: reg: Increase trap identifier to 10 bits

Ido Schimmel (10):
  mlxsw: spectrum_span: Add per-ASIC SPAN agent operations
  mlxsw: spectrum_span: Add driver private info to parms_set() callback
  mlxsw: spectrum_span: Do not dereference destination netdev
  mlxsw: spectrum_span: Add support for mirroring towards CPU port
  mlxsw: spectrum_span: Allow passing parameters to SPAN agents
  mlxsw: spectrum_span: Allow setting policer on a SPAN agent
  mlxsw: trap: Add trap identifiers for mirrored packets
  mlxsw: pci: Add mirror reason field to CQEv2
  mlxsw: pci: Retrieve mirror reason from CQE during receive
  mlxsw: core: Use mirror reason during Rx listener lookup

 drivers/net/ethernet/mellanox/mlxsw/core.c    |   6 +-
 drivers/net/ethernet/mellanox/mlxsw/core.h    |   2 +
 drivers/net/ethernet/mellanox/mlxsw/pci.c     |   6 +-
 drivers/net/ethernet/mellanox/mlxsw/pci_hw.h  |   7 +-
 drivers/net/ethernet/mellanox/mlxsw/reg.h     |  29 +-
 .../mlxsw/spectrum_acl_flex_actions.c         |   4 +-
 .../mellanox/mlxsw/spectrum_matchall.c        |   6 +-
 .../ethernet/mellanox/mlxsw/spectrum_qdisc.c  |   5 +-
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 257 ++++++++++++++++--
 .../ethernet/mellanox/mlxsw/spectrum_span.h   |  17 +-
 drivers/net/ethernet/mellanox/mlxsw/trap.h    |  10 +-
 11 files changed, 318 insertions(+), 31 deletions(-)

-- 
2.26.2


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

* [PATCH net-next 01/13] mlxsw: reg: Add session_id and pid to MPAT register
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
@ 2020-07-14 14:20 ` Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 02/13] mlxsw: reg: add mirroring_pid_base to MOGCR register Ido Schimmel
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Amit Cohen <amitc@mellanox.com>

Allow setting session_id and pid as part of port analyzer
configurations.

Signed-off-by: Amit Cohen <amitc@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 76f61bef03f8..e460d9d05d81 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -8662,6 +8662,13 @@ MLXSW_REG_DEFINE(mpat, MLXSW_REG_MPAT_ID, MLXSW_REG_MPAT_LEN);
  */
 MLXSW_ITEM32(reg, mpat, pa_id, 0x00, 28, 4);
 
+/* reg_mpat_session_id
+ * Mirror Session ID.
+ * Used for MIRROR_SESSION<i> trap.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpat, session_id, 0x00, 24, 4);
+
 /* reg_mpat_system_port
  * A unique port identifier for the final destination of the packet.
  * Access: RW
@@ -8719,6 +8726,18 @@ enum mlxsw_reg_mpat_span_type {
  */
 MLXSW_ITEM32(reg, mpat, span_type, 0x04, 0, 4);
 
+/* reg_mpat_pide
+ * Policer enable.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpat, pide, 0x0C, 15, 1);
+
+/* reg_mpat_pid
+ * Policer ID.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpat, pid, 0x0C, 0, 14);
+
 /* Remote SPAN - Ethernet VLAN
  * - - - - - - - - - - - - - -
  */
-- 
2.26.2


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

* [PATCH net-next 02/13] mlxsw: reg: add mirroring_pid_base to MOGCR register
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 01/13] mlxsw: reg: Add session_id and pid to MPAT register Ido Schimmel
@ 2020-07-14 14:20 ` Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 03/13] mlxsw: spectrum_span: Add per-ASIC SPAN agent operations Ido Schimmel
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Amit Cohen <amitc@mellanox.com>

Allow setting mirroring_pid_base using MOGCR register.

Signed-off-by: Amit Cohen <amitc@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index e460d9d05d81..6af44aee501d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -9521,6 +9521,14 @@ MLXSW_ITEM32(reg, mogcr, ptp_iftc, 0x00, 1, 1);
  */
 MLXSW_ITEM32(reg, mogcr, ptp_eftc, 0x00, 0, 1);
 
+/* reg_mogcr_mirroring_pid_base
+ * Base policer id for mirroring policers.
+ * Must have an even value (e.g. 1000, not 1001).
+ * Reserved when SwitchX/-2, Switch-IB/2, Spectrum-1 and Quantum.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mogcr, mirroring_pid_base, 0x0C, 0, 14);
+
 /* MPAGR - Monitoring Port Analyzer Global Register
  * ------------------------------------------------
  * This register is used for global port analyzer configurations.
-- 
2.26.2


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

* [PATCH net-next 03/13] mlxsw: spectrum_span: Add per-ASIC SPAN agent operations
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 01/13] mlxsw: reg: Add session_id and pid to MPAT register Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 02/13] mlxsw: reg: add mirroring_pid_base to MOGCR register Ido Schimmel
@ 2020-07-14 14:20 ` Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 04/13] mlxsw: spectrum_span: Add driver private info to parms_set() callback Ido Schimmel
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

The various SPAN agent types differ in their mirror targets (i.e.,
physical port netdev vs. VLAN netdev) and the encapsulation headers that
they need to encapsulate the mirrored packets with.

The Spectrum-2 and Spectrum-3 ASICs support a SPAN agent type that is
able to mirror towards the CPU, whereas the Spectrum-1 ASIC does not.

Prepare for the addition of this new SPAN agent type by splitting the
SPAN agent operations to be per-ASIC.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 31 ++++++++++++++++---
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 6374765a112d..6a257eb0df49 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -22,6 +22,8 @@ struct mlxsw_sp_span {
 	struct work_struct work;
 	struct mlxsw_sp *mlxsw_sp;
 	const struct mlxsw_sp_span_trigger_ops **span_trigger_ops_arr;
+	const struct mlxsw_sp_span_entry_ops **span_entry_ops_arr;
+	size_t span_entry_ops_arr_size;
 	struct list_head analyzed_ports_list;
 	struct mutex analyzed_ports_lock; /* Protects analyzed_ports_list */
 	struct list_head trigger_entries_list;
@@ -626,7 +628,19 @@ struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_vlan = {
 };
 
 static const
-struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = {
+struct mlxsw_sp_span_entry_ops *mlxsw_sp1_span_entry_ops_arr[] = {
+	&mlxsw_sp_span_entry_ops_phys,
+#if IS_ENABLED(CONFIG_NET_IPGRE)
+	&mlxsw_sp_span_entry_ops_gretap4,
+#endif
+#if IS_ENABLED(CONFIG_IPV6_GRE)
+	&mlxsw_sp_span_entry_ops_gretap6,
+#endif
+	&mlxsw_sp_span_entry_ops_vlan,
+};
+
+static const
+struct mlxsw_sp_span_entry_ops *mlxsw_sp2_span_entry_ops_arr[] = {
 	&mlxsw_sp_span_entry_ops_phys,
 #if IS_ENABLED(CONFIG_NET_IPGRE)
 	&mlxsw_sp_span_entry_ops_gretap4,
@@ -894,11 +908,12 @@ static const struct mlxsw_sp_span_entry_ops *
 mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
 			const struct net_device *to_dev)
 {
+	struct mlxsw_sp_span *span = mlxsw_sp->span;
 	size_t i;
 
-	for (i = 0; i < ARRAY_SIZE(mlxsw_sp_span_entry_types); ++i)
-		if (mlxsw_sp_span_entry_types[i]->can_handle(to_dev))
-			return mlxsw_sp_span_entry_types[i];
+	for (i = 0; i < span->span_entry_ops_arr_size; ++i)
+		if (span->span_entry_ops_arr[i]->can_handle(to_dev))
+			return span->span_entry_ops_arr[i];
 
 	return NULL;
 }
@@ -1519,7 +1534,11 @@ void mlxsw_sp_span_trigger_disable(struct mlxsw_sp_port *mlxsw_sp_port,
 
 static int mlxsw_sp1_span_init(struct mlxsw_sp *mlxsw_sp)
 {
+	size_t arr_size = ARRAY_SIZE(mlxsw_sp1_span_entry_ops_arr);
+
 	mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp1_span_trigger_ops_arr;
+	mlxsw_sp->span->span_entry_ops_arr = mlxsw_sp1_span_entry_ops_arr;
+	mlxsw_sp->span->span_entry_ops_arr_size = arr_size;
 
 	return 0;
 }
@@ -1536,7 +1555,11 @@ const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = {
 
 static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
 {
+	size_t arr_size = ARRAY_SIZE(mlxsw_sp2_span_entry_ops_arr);
+
 	mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp2_span_trigger_ops_arr;
+	mlxsw_sp->span->span_entry_ops_arr = mlxsw_sp2_span_entry_ops_arr;
+	mlxsw_sp->span->span_entry_ops_arr_size = arr_size;
 
 	return 0;
 }
-- 
2.26.2


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

* [PATCH net-next 04/13] mlxsw: spectrum_span: Add driver private info to parms_set() callback
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (2 preceding siblings ...)
  2020-07-14 14:20 ` [PATCH net-next 03/13] mlxsw: spectrum_span: Add per-ASIC SPAN agent operations Ido Schimmel
@ 2020-07-14 14:20 ` Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 05/13] mlxsw: spectrum_span: Do not dereference destination netdev Ido Schimmel
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

The parms_set() callback is supposed to fill in the parameters for the
SPAN agent, such as the destination port and encapsulation info, if any.

When mirroring to the CPU port we cannot resolve the destination port
(the CPU port) without access to the driver private info.

Pass the driver private info to parms_set() callback so that it could be
used later on to resolve the CPU port.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 19 ++++++++++++-------
 .../ethernet/mellanox/mlxsw/spectrum_span.h   |  3 ++-
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 6a257eb0df49..40289afdaaa8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -129,7 +129,8 @@ void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
 }
 
 static int
-mlxsw_sp_span_entry_phys_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_phys_parms(struct mlxsw_sp *mlxsw_sp,
+			       const struct net_device *to_dev,
 			       struct mlxsw_sp_span_parms *sparmsp)
 {
 	sparmsp->dest_port = netdev_priv(to_dev);
@@ -405,7 +406,8 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev,
 }
 
 static int
-mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_gretap4_parms(struct mlxsw_sp *mlxsw_sp,
+				  const struct net_device *to_dev,
 				  struct mlxsw_sp_span_parms *sparmsp)
 {
 	struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
@@ -506,7 +508,8 @@ mlxsw_sp_span_gretap6_route(const struct net_device *to_dev,
 }
 
 static int
-mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_gretap6_parms(struct mlxsw_sp *mlxsw_sp,
+				  const struct net_device *to_dev,
 				  struct mlxsw_sp_span_parms *sparmsp)
 {
 	struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(to_dev);
@@ -580,7 +583,8 @@ mlxsw_sp_span_vlan_can_handle(const struct net_device *dev)
 }
 
 static int
-mlxsw_sp_span_entry_vlan_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_vlan_parms(struct mlxsw_sp *mlxsw_sp,
+			       const struct net_device *to_dev,
 			       struct mlxsw_sp_span_parms *sparmsp)
 {
 	struct net_device *real_dev;
@@ -652,7 +656,8 @@ struct mlxsw_sp_span_entry_ops *mlxsw_sp2_span_entry_ops_arr[] = {
 };
 
 static int
-mlxsw_sp_span_entry_nop_parms(const struct net_device *to_dev,
+mlxsw_sp_span_entry_nop_parms(struct mlxsw_sp *mlxsw_sp,
+			      const struct net_device *to_dev,
 			      struct mlxsw_sp_span_parms *sparmsp)
 {
 	return mlxsw_sp_span_entry_unoffloadable(sparmsp);
@@ -935,7 +940,7 @@ static void mlxsw_sp_span_respin_work(struct work_struct *work)
 		if (!refcount_read(&curr->ref_count))
 			continue;
 
-		err = curr->ops->parms_set(curr->to_dev, &sparms);
+		err = curr->ops->parms_set(mlxsw_sp, curr->to_dev, &sparms);
 		if (err)
 			continue;
 
@@ -971,7 +976,7 @@ int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
 	}
 
 	memset(&sparms, 0, sizeof(sparms));
-	err = ops->parms_set(to_dev, &sparms);
+	err = ops->parms_set(mlxsw_sp, to_dev, &sparms);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
index 29b96b222e25..c21d8dfd371b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
@@ -52,7 +52,8 @@ struct mlxsw_sp_span_entry {
 
 struct mlxsw_sp_span_entry_ops {
 	bool (*can_handle)(const struct net_device *to_dev);
-	int (*parms_set)(const struct net_device *to_dev,
+	int (*parms_set)(struct mlxsw_sp *mlxsw_sp,
+			 const struct net_device *to_dev,
 			 struct mlxsw_sp_span_parms *sparmsp);
 	int (*configure)(struct mlxsw_sp_span_entry *span_entry,
 			 struct mlxsw_sp_span_parms sparms);
-- 
2.26.2


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

* [PATCH net-next 05/13] mlxsw: spectrum_span: Do not dereference destination netdev
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (3 preceding siblings ...)
  2020-07-14 14:20 ` [PATCH net-next 04/13] mlxsw: spectrum_span: Add driver private info to parms_set() callback Ido Schimmel
@ 2020-07-14 14:20 ` Ido Schimmel
  2020-07-14 14:20 ` [PATCH net-next 06/13] mlxsw: spectrum_span: Add support for mirroring towards CPU port Ido Schimmel
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Currently, the destination netdev to which we mirror must be a valid
netdev. However, this is going to change with the introduction of
mirroring towards the CPU port, as the CPU port does not have a backing
netdev.

Avoid dereferencing the destination netdev when it is not clear if it is
valid or not.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 40289afdaaa8..0ef9505d336f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -692,16 +692,15 @@ mlxsw_sp_span_entry_configure(struct mlxsw_sp *mlxsw_sp,
 		goto set_parms;
 
 	if (sparms.dest_port->mlxsw_sp != mlxsw_sp) {
-		netdev_err(span_entry->to_dev, "Cannot mirror to %s, which belongs to a different mlxsw instance",
-			   sparms.dest_port->dev->name);
+		dev_err(mlxsw_sp->bus_info->dev,
+			"Cannot mirror to a port which belongs to a different mlxsw instance\n");
 		sparms.dest_port = NULL;
 		goto set_parms;
 	}
 
 	err = span_entry->ops->configure(span_entry, sparms);
 	if (err) {
-		netdev_err(span_entry->to_dev, "Failed to offload mirror to %s",
-			   sparms.dest_port->dev->name);
+		dev_err(mlxsw_sp->bus_info->dev, "Failed to offload mirror\n");
 		sparms.dest_port = NULL;
 		goto set_parms;
 	}
-- 
2.26.2


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

* [PATCH net-next 06/13] mlxsw: spectrum_span: Add support for mirroring towards CPU port
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (4 preceding siblings ...)
  2020-07-14 14:20 ` [PATCH net-next 05/13] mlxsw: spectrum_span: Do not dereference destination netdev Ido Schimmel
@ 2020-07-14 14:20 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 07/13] mlxsw: spectrum_span: Allow passing parameters to SPAN agents Ido Schimmel
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:20 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

The Spectrum-2 and Spectrum-3 ASICs are able to mirror packets towards
the CPU. These packets are then trapped like any other packet, but with
a special packet trap and additional metadata such as why the packet was
mirrored.

The ability to mirror packets towards the CPU will be utilized by a
subsequent patch set that will mirror packets that were dropped by the
ASIC for various buffer-related reasons, such as tail-drop and
early-drop.

Add mirroring towards the CPU as a new SPAN agent type and re-use the
functions that mirror to a physical port where possible.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 0ef9505d336f..0336edb29cc3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -128,6 +128,38 @@ void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
 	kfree(mlxsw_sp->span);
 }
 
+static bool mlxsw_sp1_span_cpu_can_handle(const struct net_device *dev)
+{
+	return !dev;
+}
+
+static int mlxsw_sp1_span_entry_cpu_parms(struct mlxsw_sp *mlxsw_sp,
+					  const struct net_device *to_dev,
+					  struct mlxsw_sp_span_parms *sparmsp)
+{
+	return -EOPNOTSUPP;
+}
+
+static int
+mlxsw_sp1_span_entry_cpu_configure(struct mlxsw_sp_span_entry *span_entry,
+				   struct mlxsw_sp_span_parms sparms)
+{
+	return -EOPNOTSUPP;
+}
+
+static void
+mlxsw_sp1_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
+{
+}
+
+static const
+struct mlxsw_sp_span_entry_ops mlxsw_sp1_span_entry_ops_cpu = {
+	.can_handle = mlxsw_sp1_span_cpu_can_handle,
+	.parms_set = mlxsw_sp1_span_entry_cpu_parms,
+	.configure = mlxsw_sp1_span_entry_cpu_configure,
+	.deconfigure = mlxsw_sp1_span_entry_cpu_deconfigure,
+};
+
 static int
 mlxsw_sp_span_entry_phys_parms(struct mlxsw_sp *mlxsw_sp,
 			       const struct net_device *to_dev,
@@ -633,6 +665,7 @@ struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_vlan = {
 
 static const
 struct mlxsw_sp_span_entry_ops *mlxsw_sp1_span_entry_ops_arr[] = {
+	&mlxsw_sp1_span_entry_ops_cpu,
 	&mlxsw_sp_span_entry_ops_phys,
 #if IS_ENABLED(CONFIG_NET_IPGRE)
 	&mlxsw_sp_span_entry_ops_gretap4,
@@ -643,8 +676,49 @@ struct mlxsw_sp_span_entry_ops *mlxsw_sp1_span_entry_ops_arr[] = {
 	&mlxsw_sp_span_entry_ops_vlan,
 };
 
+static bool mlxsw_sp2_span_cpu_can_handle(const struct net_device *dev)
+{
+	return !dev;
+}
+
+static int mlxsw_sp2_span_entry_cpu_parms(struct mlxsw_sp *mlxsw_sp,
+					  const struct net_device *to_dev,
+					  struct mlxsw_sp_span_parms *sparmsp)
+{
+	sparmsp->dest_port = mlxsw_sp->ports[MLXSW_PORT_CPU_PORT];
+	return 0;
+}
+
+static int
+mlxsw_sp2_span_entry_cpu_configure(struct mlxsw_sp_span_entry *span_entry,
+				   struct mlxsw_sp_span_parms sparms)
+{
+	/* Mirroring to the CPU port is like mirroring to any other physical
+	 * port. Its local port is used instead of that of the physical port.
+	 */
+	return mlxsw_sp_span_entry_phys_configure(span_entry, sparms);
+}
+
+static void
+mlxsw_sp2_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
+{
+	enum mlxsw_reg_mpat_span_type span_type;
+
+	span_type = MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH;
+	mlxsw_sp_span_entry_deconfigure_common(span_entry, span_type);
+}
+
+static const
+struct mlxsw_sp_span_entry_ops mlxsw_sp2_span_entry_ops_cpu = {
+	.can_handle = mlxsw_sp2_span_cpu_can_handle,
+	.parms_set = mlxsw_sp2_span_entry_cpu_parms,
+	.configure = mlxsw_sp2_span_entry_cpu_configure,
+	.deconfigure = mlxsw_sp2_span_entry_cpu_deconfigure,
+};
+
 static const
 struct mlxsw_sp_span_entry_ops *mlxsw_sp2_span_entry_ops_arr[] = {
+	&mlxsw_sp2_span_entry_ops_cpu,
 	&mlxsw_sp_span_entry_ops_phys,
 #if IS_ENABLED(CONFIG_NET_IPGRE)
 	&mlxsw_sp_span_entry_ops_gretap4,
@@ -1540,6 +1614,13 @@ static int mlxsw_sp1_span_init(struct mlxsw_sp *mlxsw_sp)
 {
 	size_t arr_size = ARRAY_SIZE(mlxsw_sp1_span_entry_ops_arr);
 
+	/* Must be first to avoid NULL pointer dereference by subsequent
+	 * can_handle() callbacks.
+	 */
+	if (WARN_ON(mlxsw_sp1_span_entry_ops_arr[0] !=
+		    &mlxsw_sp1_span_entry_ops_cpu))
+		return -EINVAL;
+
 	mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp1_span_trigger_ops_arr;
 	mlxsw_sp->span->span_entry_ops_arr = mlxsw_sp1_span_entry_ops_arr;
 	mlxsw_sp->span->span_entry_ops_arr_size = arr_size;
@@ -1561,6 +1642,13 @@ static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
 {
 	size_t arr_size = ARRAY_SIZE(mlxsw_sp2_span_entry_ops_arr);
 
+	/* Must be first to avoid NULL pointer dereference by subsequent
+	 * can_handle() callbacks.
+	 */
+	if (WARN_ON(mlxsw_sp2_span_entry_ops_arr[0] !=
+		    &mlxsw_sp2_span_entry_ops_cpu))
+		return -EINVAL;
+
 	mlxsw_sp->span->span_trigger_ops_arr = mlxsw_sp2_span_trigger_ops_arr;
 	mlxsw_sp->span->span_entry_ops_arr = mlxsw_sp2_span_entry_ops_arr;
 	mlxsw_sp->span->span_entry_ops_arr_size = arr_size;
-- 
2.26.2


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

* [PATCH net-next 07/13] mlxsw: spectrum_span: Allow passing parameters to SPAN agents
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (5 preceding siblings ...)
  2020-07-14 14:20 ` [PATCH net-next 06/13] mlxsw: spectrum_span: Add support for mirroring towards CPU port Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 08/13] mlxsw: spectrum_span: Allow setting policer on a SPAN agent Ido Schimmel
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Currently, the only parameter of a SPAN agent is the netdev which
the SPAN agent should mirror to.

The next patch will add the ability to request a SPAN agent that mirrors
to a specific netdev and has a specific policer ID bound to it. This is
required when mirroring packets to the CPU port.

Therefore, encapsulate the sole parameter to mlxsw_sp_span_agent_get()
in a structure, so that it could later be extended with policer
information.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c   | 4 +++-
 drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c   | 6 ++++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c      | 5 ++++-
 drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c       | 5 +++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h       | 8 ++++++--
 5 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
index 73d56012654b..0e32123097d8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
@@ -136,11 +136,13 @@ mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port,
 			const struct net_device *out_dev,
 			bool ingress, int *p_span_id)
 {
+	struct mlxsw_sp_span_agent_parms agent_parms;
 	struct mlxsw_sp_port *mlxsw_sp_port;
 	struct mlxsw_sp *mlxsw_sp = priv;
 	int err;
 
-	err = mlxsw_sp_span_agent_get(mlxsw_sp, out_dev, p_span_id);
+	agent_parms.to_dev = out_dev;
+	err = mlxsw_sp_span_agent_get(mlxsw_sp, p_span_id, &agent_parms);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
index 195e28ab8e65..ab4ec44b566a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
@@ -27,6 +27,7 @@ mlxsw_sp_mall_port_mirror_add(struct mlxsw_sp_port *mlxsw_sp_port,
 			      struct mlxsw_sp_mall_entry *mall_entry)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+	struct mlxsw_sp_span_agent_parms agent_parms;
 	struct mlxsw_sp_span_trigger_parms parms;
 	enum mlxsw_sp_span_trigger trigger;
 	int err;
@@ -36,8 +37,9 @@ mlxsw_sp_mall_port_mirror_add(struct mlxsw_sp_port *mlxsw_sp_port,
 		return -EINVAL;
 	}
 
-	err = mlxsw_sp_span_agent_get(mlxsw_sp, mall_entry->mirror.to_dev,
-				      &mall_entry->mirror.span_id);
+	agent_parms.to_dev = mall_entry->mirror.to_dev;
+	err = mlxsw_sp_span_agent_get(mlxsw_sp, &mall_entry->mirror.span_id,
+				      &agent_parms);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
index 901acd87353f..a5ce1eec5418 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
@@ -1295,10 +1295,13 @@ static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port;
 	struct mlxsw_sp_span_trigger_parms trigger_parms = {};
+	struct mlxsw_sp_span_agent_parms agent_parms = {
+		.to_dev = mall_entry->mirror.to_dev,
+	};
 	int span_id;
 	int err;
 
-	err = mlxsw_sp_span_agent_get(mlxsw_sp, mall_entry->mirror.to_dev, &span_id);
+	err = mlxsw_sp_span_agent_get(mlxsw_sp, &span_id, &agent_parms);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 0336edb29cc3..48eb197e649d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -1032,9 +1032,10 @@ void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
 	mlxsw_core_schedule_work(&mlxsw_sp->span->work);
 }
 
-int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
-			    const struct net_device *to_dev, int *p_span_id)
+int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
+			    const struct mlxsw_sp_span_agent_parms *parms)
 {
+	const struct net_device *to_dev = parms->to_dev;
 	const struct mlxsw_sp_span_entry_ops *ops;
 	struct mlxsw_sp_span_entry *span_entry;
 	struct mlxsw_sp_span_parms sparms;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
index c21d8dfd371b..25f73561a9fe 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
@@ -35,6 +35,10 @@ struct mlxsw_sp_span_trigger_parms {
 	int span_id;
 };
 
+struct mlxsw_sp_span_agent_parms {
+	const struct net_device *to_dev;
+};
+
 struct mlxsw_sp_span_entry_ops;
 
 struct mlxsw_sp_span_ops {
@@ -74,8 +78,8 @@ void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
 int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
 void mlxsw_sp_span_speed_update_work(struct work_struct *work);
 
-int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
-			    const struct net_device *to_dev, int *p_span_id);
+int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
+			    const struct mlxsw_sp_span_agent_parms *parms);
 void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id);
 int mlxsw_sp_span_analyzed_port_get(struct mlxsw_sp_port *mlxsw_sp_port,
 				    bool ingress);
-- 
2.26.2


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

* [PATCH net-next 08/13] mlxsw: spectrum_span: Allow setting policer on a SPAN agent
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (6 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 07/13] mlxsw: spectrum_span: Allow passing parameters to SPAN agents Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 09/13] mlxsw: reg: Increase trap identifier to 10 bits Ido Schimmel
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

When mirroring packets to the CPU port the mirrored packets are trapped
to the CPU. However, unlike other traps, it is not possible to set a
policer on the associated trap group. Instead, the policer needs to be
set on the SPAN agent.

Moreover, the policer ID must be within a specified range: From a
configurable (even) base ID to this base plus the maximum number of SPAN
agents.

While the immediate use case is to set the policer on a SPAN agent that
mirrors to the CPU port, a policer can be set on any SPAN agent.
Therefore, the operation is implemented for all SPAN agent types.

Extend the SPAN agent request API to allow passing the desired policer
ID that should be bound to the SPAN agent. Return an error for
Spectrum-1, as it does not support policer setting on a SPAN agent.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../mlxsw/spectrum_acl_flex_actions.c         |   2 +-
 .../mellanox/mlxsw/spectrum_matchall.c        |   2 +-
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 107 +++++++++++++++++-
 .../ethernet/mellanox/mlxsw/spectrum_span.h   |   6 +
 4 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
index 0e32123097d8..18444f675100 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
@@ -136,7 +136,7 @@ mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port,
 			const struct net_device *out_dev,
 			bool ingress, int *p_span_id)
 {
-	struct mlxsw_sp_span_agent_parms agent_parms;
+	struct mlxsw_sp_span_agent_parms agent_parms = {};
 	struct mlxsw_sp_port *mlxsw_sp_port;
 	struct mlxsw_sp *mlxsw_sp = priv;
 	int err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
index ab4ec44b566a..f30599ad6019 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
@@ -27,7 +27,7 @@ mlxsw_sp_mall_port_mirror_add(struct mlxsw_sp_port *mlxsw_sp_port,
 			      struct mlxsw_sp_mall_entry *mall_entry)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-	struct mlxsw_sp_span_agent_parms agent_parms;
+	struct mlxsw_sp_span_agent_parms agent_parms = {};
 	struct mlxsw_sp_span_trigger_parms parms;
 	enum mlxsw_sp_span_trigger trigger;
 	int err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 48eb197e649d..323eaf979aea 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -27,6 +27,8 @@ struct mlxsw_sp_span {
 	struct list_head analyzed_ports_list;
 	struct mutex analyzed_ports_lock; /* Protects analyzed_ports_list */
 	struct list_head trigger_entries_list;
+	u16 policer_id_base;
+	refcount_t policer_id_base_ref_count;
 	atomic_t active_entries_count;
 	int entries_count;
 	struct mlxsw_sp_span_entry entries[];
@@ -88,6 +90,7 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
 	span = kzalloc(struct_size(span, entries, entries_count), GFP_KERNEL);
 	if (!span)
 		return -ENOMEM;
+	refcount_set(&span->policer_id_base_ref_count, 0);
 	span->entries_count = entries_count;
 	atomic_set(&span->active_entries_count, 0);
 	mutex_init(&span->analyzed_ports_lock);
@@ -182,6 +185,8 @@ mlxsw_sp_span_entry_phys_configure(struct mlxsw_sp_span_entry *span_entry,
 	/* Create a new port analayzer entry for local_port. */
 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
 			    MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH);
+	mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+	mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
 
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
 }
@@ -478,6 +483,8 @@ mlxsw_sp_span_entry_gretap4_configure(struct mlxsw_sp_span_entry *span_entry,
 	/* Create a new port analayzer entry for local_port. */
 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
 			    MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
+	mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+	mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
 	mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
 	mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
 				    MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
@@ -580,6 +587,8 @@ mlxsw_sp_span_entry_gretap6_configure(struct mlxsw_sp_span_entry *span_entry,
 	/* Create a new port analayzer entry for local_port. */
 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
 			    MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3);
+	mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+	mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
 	mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
 	mlxsw_reg_mpat_eth_rspan_l2_pack(mpat_pl,
 				    MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER,
@@ -643,6 +652,8 @@ mlxsw_sp_span_entry_vlan_configure(struct mlxsw_sp_span_entry *span_entry,
 
 	mlxsw_reg_mpat_pack(mpat_pl, pa_id, local_port, true,
 			    MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH);
+	mlxsw_reg_mpat_pide_set(mpat_pl, sparms.policer_enable);
+	mlxsw_reg_mpat_pid_set(mpat_pl, sparms.policer_id);
 	mlxsw_reg_mpat_eth_rspan_pack(mpat_pl, sparms.vid);
 
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpat), mpat_pl);
@@ -790,6 +801,45 @@ mlxsw_sp_span_entry_deconfigure(struct mlxsw_sp_span_entry *span_entry)
 		span_entry->ops->deconfigure(span_entry);
 }
 
+static int mlxsw_sp_span_policer_id_base_set(struct mlxsw_sp_span *span,
+					     u16 policer_id)
+{
+	struct mlxsw_sp *mlxsw_sp = span->mlxsw_sp;
+	u16 policer_id_base;
+	int err;
+
+	/* Policers set on SPAN agents must be in the range of
+	 * `policer_id_base .. policer_id_base + max_span_agents - 1`. If the
+	 * base is set and the new policer is not within the range, then we
+	 * must error out.
+	 */
+	if (refcount_read(&span->policer_id_base_ref_count)) {
+		if (policer_id < span->policer_id_base ||
+		    policer_id >= span->policer_id_base + span->entries_count)
+			return -EINVAL;
+
+		refcount_inc(&span->policer_id_base_ref_count);
+		return 0;
+	}
+
+	/* Base must be even. */
+	policer_id_base = policer_id % 2 == 0 ? policer_id : policer_id - 1;
+	err = mlxsw_sp->span_ops->policer_id_base_set(mlxsw_sp,
+						      policer_id_base);
+	if (err)
+		return err;
+
+	span->policer_id_base = policer_id_base;
+	refcount_set(&span->policer_id_base_ref_count, 1);
+
+	return 0;
+}
+
+static void mlxsw_sp_span_policer_id_base_unset(struct mlxsw_sp_span *span)
+{
+	refcount_dec(&span->policer_id_base_ref_count);
+}
+
 static struct mlxsw_sp_span_entry *
 mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
 			   const struct net_device *to_dev,
@@ -809,6 +859,15 @@ mlxsw_sp_span_entry_create(struct mlxsw_sp *mlxsw_sp,
 	if (!span_entry)
 		return NULL;
 
+	if (sparms.policer_enable) {
+		int err;
+
+		err = mlxsw_sp_span_policer_id_base_set(mlxsw_sp->span,
+							sparms.policer_id);
+		if (err)
+			return NULL;
+	}
+
 	atomic_inc(&mlxsw_sp->span->active_entries_count);
 	span_entry->ops = ops;
 	refcount_set(&span_entry->ref_count, 1);
@@ -823,6 +882,8 @@ static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp,
 {
 	mlxsw_sp_span_entry_deconfigure(span_entry);
 	atomic_dec(&mlxsw_sp->span->active_entries_count);
+	if (span_entry->parms.policer_enable)
+		mlxsw_sp_span_policer_id_base_unset(mlxsw_sp->span);
 }
 
 struct mlxsw_sp_span_entry *
@@ -861,6 +922,24 @@ mlxsw_sp_span_entry_find_by_id(struct mlxsw_sp *mlxsw_sp, int span_id)
 	return NULL;
 }
 
+static struct mlxsw_sp_span_entry *
+mlxsw_sp_span_entry_find_by_parms(struct mlxsw_sp *mlxsw_sp,
+				  const struct net_device *to_dev,
+				  const struct mlxsw_sp_span_parms *sparms)
+{
+	int i;
+
+	for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
+		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span->entries[i];
+
+		if (refcount_read(&curr->ref_count) && curr->to_dev == to_dev &&
+		    curr->parms.policer_enable == sparms->policer_enable &&
+		    curr->parms.policer_id == sparms->policer_id)
+			return curr;
+	}
+	return NULL;
+}
+
 static struct mlxsw_sp_span_entry *
 mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
 			const struct net_device *to_dev,
@@ -869,7 +948,8 @@ mlxsw_sp_span_entry_get(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_span_entry *span_entry;
 
-	span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, to_dev);
+	span_entry = mlxsw_sp_span_entry_find_by_parms(mlxsw_sp, to_dev,
+						       &sparms);
 	if (span_entry) {
 		/* Already exists, just take a reference */
 		refcount_inc(&span_entry->ref_count);
@@ -1054,6 +1134,8 @@ int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp, int *p_span_id,
 	if (err)
 		return err;
 
+	sparms.policer_id = parms->policer_id;
+	sparms.policer_enable = parms->policer_enable;
 	span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms);
 	if (!span_entry)
 		return -ENOBUFS;
@@ -1634,9 +1716,16 @@ static u32 mlxsw_sp1_span_buffsize_get(int mtu, u32 speed)
 	return mtu * 5 / 2;
 }
 
+static int mlxsw_sp1_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
+					      u16 policer_id_base)
+{
+	return -EOPNOTSUPP;
+}
+
 const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = {
 	.init = mlxsw_sp1_span_init,
 	.buffsize_get = mlxsw_sp1_span_buffsize_get,
+	.policer_id_base_set = mlxsw_sp1_span_policer_id_base_set,
 };
 
 static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
@@ -1672,9 +1761,24 @@ static u32 mlxsw_sp2_span_buffsize_get(int mtu, u32 speed)
 	return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
 }
 
+static int mlxsw_sp2_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
+					      u16 policer_id_base)
+{
+	char mogcr_pl[MLXSW_REG_MOGCR_LEN];
+	int err;
+
+	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
+	if (err)
+		return err;
+
+	mlxsw_reg_mogcr_mirroring_pid_base_set(mogcr_pl, policer_id_base);
+	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
+}
+
 const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops = {
 	.init = mlxsw_sp2_span_init,
 	.buffsize_get = mlxsw_sp2_span_buffsize_get,
+	.policer_id_base_set = mlxsw_sp2_span_policer_id_base_set,
 };
 
 static u32 mlxsw_sp3_span_buffsize_get(int mtu, u32 speed)
@@ -1687,4 +1791,5 @@ static u32 mlxsw_sp3_span_buffsize_get(int mtu, u32 speed)
 const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops = {
 	.init = mlxsw_sp2_span_init,
 	.buffsize_get = mlxsw_sp3_span_buffsize_get,
+	.policer_id_base_set = mlxsw_sp2_span_policer_id_base_set,
 };
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
index 25f73561a9fe..1c746dd3b1bd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
@@ -21,6 +21,8 @@ struct mlxsw_sp_span_parms {
 	union mlxsw_sp_l3addr daddr;
 	union mlxsw_sp_l3addr saddr;
 	u16 vid;
+	u16 policer_id;
+	bool policer_enable;
 };
 
 enum mlxsw_sp_span_trigger {
@@ -37,6 +39,8 @@ struct mlxsw_sp_span_trigger_parms {
 
 struct mlxsw_sp_span_agent_parms {
 	const struct net_device *to_dev;
+	u16 policer_id;
+	bool policer_enable;
 };
 
 struct mlxsw_sp_span_entry_ops;
@@ -44,6 +48,8 @@ struct mlxsw_sp_span_entry_ops;
 struct mlxsw_sp_span_ops {
 	int (*init)(struct mlxsw_sp *mlxsw_sp);
 	u32 (*buffsize_get)(int mtu, u32 speed);
+	int (*policer_id_base_set)(struct mlxsw_sp *mlxsw_sp,
+				   u16 policer_id_base);
 };
 
 struct mlxsw_sp_span_entry {
-- 
2.26.2


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

* [PATCH net-next 09/13] mlxsw: reg: Increase trap identifier to 10 bits
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (7 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 08/13] mlxsw: spectrum_span: Allow setting policer on a SPAN agent Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 10/13] mlxsw: trap: Add trap identifiers for mirrored packets Ido Schimmel
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Amit Cohen <amitc@mellanox.com>

The trap identifier was increased to 10 bits in new versions of the
Programmer's Reference Manual (PRM).

Increase it accordingly in the Host PacKet Trap (HPKT) register and in
the Completion Queue Element (CQE).

This is significant for subsequent patches that will introduce trap
identifiers which utilize the extended range.

Signed-off-by: Amit Cohen <amitc@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/reg.h    | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/trap.h   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index 32c7cabfb261..697593e44f8a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -176,7 +176,7 @@ MLXSW_ITEM32(pci, cqe, byte_count, 0x04, 0, 14);
 /* pci_cqe_trap_id
  * Trap ID that captured the packet.
  */
-MLXSW_ITEM32(pci, cqe, trap_id, 0x08, 0, 9);
+MLXSW_ITEM32(pci, cqe, trap_id, 0x08, 0, 10);
 
 /* pci_cqe_crc
  * Length include CRC. Indicates the length field includes
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 6af44aee501d..408003520602 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -5778,7 +5778,7 @@ MLXSW_ITEM32(reg, hpkt, trap_group, 0x00, 12, 6);
  * Note: A trap ID can only be associated with a single trap group. The device
  * will associate the trap ID with the last trap group configured.
  */
-MLXSW_ITEM32(reg, hpkt, trap_id, 0x00, 0, 9);
+MLXSW_ITEM32(reg, hpkt, trap_id, 0x00, 0, 10);
 
 enum {
 	MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/trap.h b/drivers/net/ethernet/mellanox/mlxsw/trap.h
index 28e60697d14e..8cbb9cf5b57b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/trap.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/trap.h
@@ -108,7 +108,7 @@ enum {
 	MLXSW_TRAP_ID_DISCARD_INGRESS_ACL = 0x1C3,
 	MLXSW_TRAP_ID_DISCARD_EGRESS_ACL = 0x1C4,
 
-	MLXSW_TRAP_ID_MAX = 0x1FF
+	MLXSW_TRAP_ID_MAX = 0x3FF,
 };
 
 enum mlxsw_event_trap_id {
-- 
2.26.2


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

* [PATCH net-next 10/13] mlxsw: trap: Add trap identifiers for mirrored packets
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (8 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 09/13] mlxsw: reg: Increase trap identifier to 10 bits Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 11/13] mlxsw: pci: Add mirror reason field to CQEv2 Ido Schimmel
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Packets that are mirrored to the CPU port are trapped with one of eight
trap identifiers. Add them.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/trap.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/trap.h b/drivers/net/ethernet/mellanox/mlxsw/trap.h
index 8cbb9cf5b57b..33909887d0ac 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/trap.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/trap.h
@@ -107,6 +107,14 @@ enum {
 	MLXSW_TRAP_ID_ACL2 = 0x1C2,
 	MLXSW_TRAP_ID_DISCARD_INGRESS_ACL = 0x1C3,
 	MLXSW_TRAP_ID_DISCARD_EGRESS_ACL = 0x1C4,
+	MLXSW_TRAP_ID_MIRROR_SESSION0 = 0x220,
+	MLXSW_TRAP_ID_MIRROR_SESSION1 = 0x221,
+	MLXSW_TRAP_ID_MIRROR_SESSION2 = 0x222,
+	MLXSW_TRAP_ID_MIRROR_SESSION3 = 0x223,
+	MLXSW_TRAP_ID_MIRROR_SESSION4 = 0x224,
+	MLXSW_TRAP_ID_MIRROR_SESSION5 = 0x225,
+	MLXSW_TRAP_ID_MIRROR_SESSION6 = 0x226,
+	MLXSW_TRAP_ID_MIRROR_SESSION7 = 0x227,
 
 	MLXSW_TRAP_ID_MAX = 0x3FF,
 };
-- 
2.26.2


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

* [PATCH net-next 11/13] mlxsw: pci: Add mirror reason field to CQEv2
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (9 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 10/13] mlxsw: trap: Add trap identifiers for mirrored packets Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 12/13] mlxsw: pci: Retrieve mirror reason from CQE during receive Ido Schimmel
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

The Completion Queue Element version 2 (CQEv2) includes a field called
'mirror_reason' which indicates why the packet was mirrored to the CPU.

Add the field so that it can be used by a later patch.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index 697593e44f8a..a2c1fbd3e0d1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -213,6 +213,11 @@ mlxsw_pci_cqe_item_helpers(dqn, 0, 12, 12);
  */
 MLXSW_ITEM32(pci, cqe2, user_def_val_orig_pkt_len, 0x14, 0, 20);
 
+/* pci_cqe_mirror_reason
+ * Mirror reason.
+ */
+MLXSW_ITEM32(pci, cqe2, mirror_reason, 0x18, 24, 8);
+
 /* pci_cqe_owner
  * Ownership bit.
  */
-- 
2.26.2


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

* [PATCH net-next 12/13] mlxsw: pci: Retrieve mirror reason from CQE during receive
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (10 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 11/13] mlxsw: pci: Add mirror reason field to CQEv2 Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 14:21 ` [PATCH net-next 13/13] mlxsw: core: Use mirror reason during Rx listener lookup Ido Schimmel
  2020-07-14 21:51 ` [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations David Miller
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

In case the mirror reason is valid, retrieve it into the Rx information
so that it could be used during listener lookup in a later patch.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.h | 1 +
 drivers/net/ethernet/mellanox/mlxsw/pci.c  | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 7d6b0a232789..c736b8673791 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -176,6 +176,7 @@ struct mlxsw_rx_info {
 		u16 lag_id;
 	} u;
 	u8 lag_port_index;
+	u8 mirror_reason;
 	int trap_id;
 };
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index c04ec1a92826..1c64b03ff48e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -547,9 +547,9 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
 {
 	struct pci_dev *pdev = mlxsw_pci->pdev;
 	struct mlxsw_pci_queue_elem_info *elem_info;
+	struct mlxsw_rx_info rx_info = {};
 	char *wqe;
 	struct sk_buff *skb;
-	struct mlxsw_rx_info rx_info;
 	u16 byte_count;
 	int err;
 
@@ -582,6 +582,10 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
 		if (mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2)
 			cookie_index = mlxsw_pci_cqe2_user_def_val_orig_pkt_len_get(cqe);
 		mlxsw_skb_cb(skb)->cookie_index = cookie_index;
+	} else if (rx_info.trap_id >= MLXSW_TRAP_ID_MIRROR_SESSION0 &&
+		   rx_info.trap_id <= MLXSW_TRAP_ID_MIRROR_SESSION7 &&
+		   mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2) {
+		rx_info.mirror_reason = mlxsw_pci_cqe2_mirror_reason_get(cqe);
 	}
 
 	byte_count = mlxsw_pci_cqe_byte_count_get(cqe);
-- 
2.26.2


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

* [PATCH net-next 13/13] mlxsw: core: Use mirror reason during Rx listener lookup
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (11 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 12/13] mlxsw: pci: Retrieve mirror reason from CQE during receive Ido Schimmel
@ 2020-07-14 14:21 ` Ido Schimmel
  2020-07-14 21:51 ` [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations David Miller
  13 siblings, 0 replies; 15+ messages in thread
From: Ido Schimmel @ 2020-07-14 14:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, petrm, amitc, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

The Rx listener abstraction allows the switch driver (e.g.,
mlxsw_spectrum) to register a function that is called when a packet is
received (trapped) for a specific reason.

Up until now, the Rx listener lookup was solely based on the trap
identifier. However, when a packet is mirrored to the CPU the trap
identifier merely indicates that the packet was mirrored, but not why it
was mirrored. This makes it impossible for the switch driver to register
different Rx listeners for different mirror reasons.

Solve this by allowing the switch driver to register a Rx listener with
a mirror reason and by extending the Rx listener lookup to take the
mirror reason into account.

Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c | 6 ++++--
 drivers/net/ethernet/mellanox/mlxsw/core.h | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 8b3791d73c99..1363168b3c82 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -1524,7 +1524,8 @@ static bool __is_rx_listener_equal(const struct mlxsw_rx_listener *rxl_a,
 {
 	return (rxl_a->func == rxl_b->func &&
 		rxl_a->local_port == rxl_b->local_port &&
-		rxl_a->trap_id == rxl_b->trap_id);
+		rxl_a->trap_id == rxl_b->trap_id &&
+		rxl_a->mirror_reason == rxl_b->mirror_reason);
 }
 
 static struct mlxsw_rx_listener_item *
@@ -2044,7 +2045,8 @@ void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
 		rxl = &rxl_item->rxl;
 		if ((rxl->local_port == MLXSW_PORT_DONT_CARE ||
 		     rxl->local_port == local_port) &&
-		    rxl->trap_id == rx_info->trap_id) {
+		    rxl->trap_id == rx_info->trap_id &&
+		    rxl->mirror_reason == rx_info->mirror_reason) {
 			if (rxl_item->enabled)
 				found = true;
 			break;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index c736b8673791..c1c1e039323a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -61,6 +61,7 @@ void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
 struct mlxsw_rx_listener {
 	void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
 	u8 local_port;
+	u8 mirror_reason;
 	u16 trap_id;
 };
 
-- 
2.26.2


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

* Re: [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations
  2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
                   ` (12 preceding siblings ...)
  2020-07-14 14:21 ` [PATCH net-next 13/13] mlxsw: core: Use mirror reason during Rx listener lookup Ido Schimmel
@ 2020-07-14 21:51 ` David Miller
  13 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2020-07-14 21:51 UTC (permalink / raw)
  To: idosch; +Cc: netdev, kuba, jiri, petrm, amitc, mlxsw, idosch

From: Ido Schimmel <idosch@idosch.org>
Date: Tue, 14 Jul 2020 17:20:53 +0300

> From: Ido Schimmel <idosch@mellanox.com>
> 
> A future patch set will add the ability to trap packets that were
> dropped due to buffer related reasons (e.g., early drop). Internally
> this is implemented by mirroring these packets towards the CPU port.
> This patch set adds the required infrastructure to enable such
> mirroring.
> 
> Patches #1-#2 extend two registers needed for above mentioned
> functionality.
> 
> Patches #3-#6 gradually add support for setting the mirroring target of
> a SPAN (mirroring) agent as the CPU port. This is only supported from
> Spectrum-2 onwards, so an error is returned for Spectrum-1.
> 
> Patches #7-#8 add the ability to set a policer on a SPAN agent. This is
> required because unlike regularly trapped packets, a policer cannot be
> set on the trap group with which the mirroring trap is associated.
> 
> Patches #9-#12 parse the mirror reason field from the Completion Queue
> Element (CQE). Unlike other trapped packets, the trap identifier of
> mirrored packets only indicates that the packet was mirrored, but not
> why. The reason (e.g., tail drop) is encoded in the mirror reason field.
> 
> Patch #13 utilizes the mirror reason field in order to lookup the
> matching Rx listener. This allows us to maintain the abstraction that an
> Rx listener is mapped to a single trap reason. Without taking the mirror
> reason into account we would need to register a single Rx listener for
> all mirrored packets.

Series applied, thanks Ido.

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

end of thread, other threads:[~2020-07-14 21:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-14 14:20 [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations Ido Schimmel
2020-07-14 14:20 ` [PATCH net-next 01/13] mlxsw: reg: Add session_id and pid to MPAT register Ido Schimmel
2020-07-14 14:20 ` [PATCH net-next 02/13] mlxsw: reg: add mirroring_pid_base to MOGCR register Ido Schimmel
2020-07-14 14:20 ` [PATCH net-next 03/13] mlxsw: spectrum_span: Add per-ASIC SPAN agent operations Ido Schimmel
2020-07-14 14:20 ` [PATCH net-next 04/13] mlxsw: spectrum_span: Add driver private info to parms_set() callback Ido Schimmel
2020-07-14 14:20 ` [PATCH net-next 05/13] mlxsw: spectrum_span: Do not dereference destination netdev Ido Schimmel
2020-07-14 14:20 ` [PATCH net-next 06/13] mlxsw: spectrum_span: Add support for mirroring towards CPU port Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 07/13] mlxsw: spectrum_span: Allow passing parameters to SPAN agents Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 08/13] mlxsw: spectrum_span: Allow setting policer on a SPAN agent Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 09/13] mlxsw: reg: Increase trap identifier to 10 bits Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 10/13] mlxsw: trap: Add trap identifiers for mirrored packets Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 11/13] mlxsw: pci: Add mirror reason field to CQEv2 Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 12/13] mlxsw: pci: Retrieve mirror reason from CQE during receive Ido Schimmel
2020-07-14 14:21 ` [PATCH net-next 13/13] mlxsw: core: Use mirror reason during Rx listener lookup Ido Schimmel
2020-07-14 21:51 ` [PATCH net-next 00/13] mlxsw: Mirror to CPU preparations David Miller

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).