aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
diff options
context:
space:
mode:
authorPetr Machata <petrm@mellanox.com>2019-06-30 09:04:56 +0300
committerDavid S. Miller <davem@davemloft.net>2019-07-01 18:58:34 -0700
commitd92e4e6e33c8b19635be70fb8935b627d2e4f8fe (patch)
treee7d061f47644998173177687f9cb9013b6c9a85d /drivers/net/ethernet/mellanox/mlxsw/spectrum.c
parentmlxsw: spectrum: PTP: Disable BH when working with PHC (diff)
downloadlinux-dev-d92e4e6e33c8b19635be70fb8935b627d2e4f8fe.tar.xz
linux-dev-d92e4e6e33c8b19635be70fb8935b627d2e4f8fe.zip
mlxsw: spectrum: PTP: Support timestamping on Spectrum-1
On Spectrum-1, timestamps arrive through a pair of dedicated events: MLXSW_TRAP_ID_PTP_ING_FIFO and _EGR_FIFO. The payload delivered with those traps is contents of the timestamp FIFO at a given port in a given direction. Add a Spectrum-1-specific handler for these two events which decodes the timestamps and forwards them to the PTP module. Add a function that parses a packet, dispatching to ptp_classify_raw(), and decodes PTP message type, domain number, and sequence ID. Add a new mlxsw dependency on the PTP classifier. Add helpers that can store and retrieve unmatched timestamps and SKBs to the hash table added in a preceding patch. Add the matching code itself: upon arrival of a timestamp or a packet, look up the corresponding unmatched entry, and match it up. If there is none, add a new unmatched entry. This logic is the same on ingress as on egress. Packets and timestamps that never matched need to be eventually disposed of. A garbage collector added in a follow-up patch will take care of that. Since currently all this code is turned off, no crud will accumulate in the hash table. Signed-off-by: Petr Machata <petrm@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 6cb7aeac0657..bd405c5018de 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3970,6 +3970,46 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
}
}
+static void mlxsw_sp1_ptp_fifo_event_func(struct mlxsw_sp *mlxsw_sp,
+ char *mtpptr_pl, bool ingress)
+{
+ u8 local_port;
+ u8 num_rec;
+ int i;
+
+ local_port = mlxsw_reg_mtpptr_local_port_get(mtpptr_pl);
+ num_rec = mlxsw_reg_mtpptr_num_rec_get(mtpptr_pl);
+ for (i = 0; i < num_rec; i++) {
+ u8 domain_number;
+ u8 message_type;
+ u16 sequence_id;
+ u64 timestamp;
+
+ mlxsw_reg_mtpptr_unpack(mtpptr_pl, i, &message_type,
+ &domain_number, &sequence_id,
+ &timestamp);
+ mlxsw_sp1_ptp_got_timestamp(mlxsw_sp, ingress, local_port,
+ message_type, domain_number,
+ sequence_id, timestamp);
+ }
+}
+
+static void mlxsw_sp1_ptp_ing_fifo_event_func(const struct mlxsw_reg_info *reg,
+ char *mtpptr_pl, void *priv)
+{
+ struct mlxsw_sp *mlxsw_sp = priv;
+
+ mlxsw_sp1_ptp_fifo_event_func(mlxsw_sp, mtpptr_pl, true);
+}
+
+static void mlxsw_sp1_ptp_egr_fifo_event_func(const struct mlxsw_reg_info *reg,
+ char *mtpptr_pl, void *priv)
+{
+ struct mlxsw_sp *mlxsw_sp = priv;
+
+ mlxsw_sp1_ptp_fifo_event_func(mlxsw_sp, mtpptr_pl, false);
+}
+
void mlxsw_sp_rx_listener_no_mark_func(struct sk_buff *skb,
u8 local_port, void *priv)
{
@@ -4151,6 +4191,9 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
};
static const struct mlxsw_listener mlxsw_sp1_listener[] = {
+ /* Events */
+ MLXSW_EVENTL(mlxsw_sp1_ptp_egr_fifo_event_func, PTP_EGR_FIFO, SP_PTP0),
+ MLXSW_EVENTL(mlxsw_sp1_ptp_ing_fifo_event_func, PTP_ING_FIFO, SP_PTP0),
};
static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)