mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-03 01:36:52 +09:00
mlxsw: pci: Set extra metadata in skb control block
Packets that are mirrored / sampled to the CPU have extra metadata encoded in their corresponding Completion Queue Element (CQE). Retrieve this metadata from the CQE and set it in the skb control block so that it could be accessed by the switch driver (i.e., 'mlxsw_spectrum'). Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
d4cabaadea
commit
5ab6dc9fa2
@@ -60,6 +60,21 @@ struct mlxsw_tx_info {
|
||||
|
||||
struct mlxsw_rx_md_info {
|
||||
u32 cookie_index;
|
||||
u32 latency;
|
||||
u32 tx_congestion;
|
||||
union {
|
||||
/* Valid when 'tx_port_valid' is set. */
|
||||
u16 tx_sys_port;
|
||||
u16 tx_lag_id;
|
||||
};
|
||||
u8 tx_lag_port_index; /* Valid when 'tx_port_is_lag' is set. */
|
||||
u8 tx_tc;
|
||||
u8 latency_valid:1,
|
||||
tx_congestion_valid:1,
|
||||
tx_tc_valid:1,
|
||||
tx_port_valid:1,
|
||||
tx_port_is_lag:1,
|
||||
unused:3;
|
||||
};
|
||||
|
||||
bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
@@ -540,6 +540,55 @@ static void mlxsw_pci_cqe_sdq_handle(struct mlxsw_pci *mlxsw_pci,
|
||||
spin_unlock(&q->lock);
|
||||
}
|
||||
|
||||
static void mlxsw_pci_cqe_rdq_md_tx_port_init(struct sk_buff *skb,
|
||||
const char *cqe)
|
||||
{
|
||||
struct mlxsw_skb_cb *cb = mlxsw_skb_cb(skb);
|
||||
|
||||
if (mlxsw_pci_cqe2_tx_lag_get(cqe)) {
|
||||
cb->rx_md_info.tx_port_is_lag = true;
|
||||
cb->rx_md_info.tx_lag_id = mlxsw_pci_cqe2_tx_lag_id_get(cqe);
|
||||
cb->rx_md_info.tx_lag_port_index =
|
||||
mlxsw_pci_cqe2_tx_lag_subport_get(cqe);
|
||||
} else {
|
||||
cb->rx_md_info.tx_port_is_lag = false;
|
||||
cb->rx_md_info.tx_sys_port =
|
||||
mlxsw_pci_cqe2_tx_system_port_get(cqe);
|
||||
}
|
||||
|
||||
if (cb->rx_md_info.tx_sys_port != MLXSW_PCI_CQE2_TX_PORT_MULTI_PORT &&
|
||||
cb->rx_md_info.tx_sys_port != MLXSW_PCI_CQE2_TX_PORT_INVALID)
|
||||
cb->rx_md_info.tx_port_valid = 1;
|
||||
else
|
||||
cb->rx_md_info.tx_port_valid = 0;
|
||||
}
|
||||
|
||||
static void mlxsw_pci_cqe_rdq_md_init(struct sk_buff *skb, const char *cqe)
|
||||
{
|
||||
struct mlxsw_skb_cb *cb = mlxsw_skb_cb(skb);
|
||||
|
||||
cb->rx_md_info.tx_congestion = mlxsw_pci_cqe2_mirror_cong_get(cqe);
|
||||
if (cb->rx_md_info.tx_congestion != MLXSW_PCI_CQE2_MIRROR_CONG_INVALID)
|
||||
cb->rx_md_info.tx_congestion_valid = 1;
|
||||
else
|
||||
cb->rx_md_info.tx_congestion_valid = 0;
|
||||
cb->rx_md_info.tx_congestion <<= MLXSW_PCI_CQE2_MIRROR_CONG_SHIFT;
|
||||
|
||||
cb->rx_md_info.latency = mlxsw_pci_cqe2_mirror_latency_get(cqe);
|
||||
if (cb->rx_md_info.latency != MLXSW_PCI_CQE2_MIRROR_LATENCY_INVALID)
|
||||
cb->rx_md_info.latency_valid = 1;
|
||||
else
|
||||
cb->rx_md_info.latency_valid = 0;
|
||||
|
||||
cb->rx_md_info.tx_tc = mlxsw_pci_cqe2_mirror_tclass_get(cqe);
|
||||
if (cb->rx_md_info.tx_tc != MLXSW_PCI_CQE2_MIRROR_TCLASS_INVALID)
|
||||
cb->rx_md_info.tx_tc_valid = 1;
|
||||
else
|
||||
cb->rx_md_info.tx_tc_valid = 0;
|
||||
|
||||
mlxsw_pci_cqe_rdq_md_tx_port_init(skb, cqe);
|
||||
}
|
||||
|
||||
static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
|
||||
struct mlxsw_pci_queue *q,
|
||||
u16 consumer_counter_limit,
|
||||
@@ -586,6 +635,10 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
|
||||
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);
|
||||
mlxsw_pci_cqe_rdq_md_init(skb, cqe);
|
||||
} else if (rx_info.trap_id == MLXSW_TRAP_ID_PKT_SAMPLE &&
|
||||
mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2) {
|
||||
mlxsw_pci_cqe_rdq_md_tx_port_init(skb, cqe);
|
||||
}
|
||||
|
||||
byte_count = mlxsw_pci_cqe_byte_count_get(cqe);
|
||||
|
||||
Reference in New Issue
Block a user