Skip to content

Commit

Permalink
Merge branch 'mlxsw-Mirror-to-CPU-preparations'
Browse files Browse the repository at this point in the history
Ido Schimmel says:

====================
mlxsw: Mirror to CPU preparations

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

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 14, 2020
2 parents 8331bbe + 6a8c101 commit 3d12e50
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 31 deletions.
6 changes: 4 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down Expand Up @@ -176,6 +177,7 @@ struct mlxsw_rx_info {
u16 lag_id;
} u;
u8 lag_port_index;
u8 mirror_reason;
int trap_id;
};

Expand Down
6 changes: 5 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
*/
Expand Down
29 changes: 28 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
* - - - - - - - - - - - - - -
*/
Expand Down Expand Up @@ -9502,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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading

0 comments on commit 3d12e50

Please sign in to comment.