1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2020 Mellanox Technologies. */
3 
4 #ifndef __MLX5_EN_PTP_H__
5 #define __MLX5_EN_PTP_H__
6 
7 #include "en.h"
8 #include "en_stats.h"
9 #include "en/txrx.h"
10 #include <linux/ptp_classify.h>
11 
12 #define MLX5E_PTP_CHANNEL_IX 0
13 
14 struct mlx5e_ptpsq {
15 	struct mlx5e_txqsq       txqsq;
16 	struct mlx5e_cq          ts_cq;
17 	u16                      skb_fifo_cc;
18 	u16                      skb_fifo_pc;
19 	struct mlx5e_skb_fifo    skb_fifo;
20 	struct mlx5e_ptp_cq_stats *cq_stats;
21 	u16                      ts_cqe_ctr_mask;
22 };
23 
24 enum {
25 	MLX5E_PTP_STATE_TX,
26 	MLX5E_PTP_STATE_RX,
27 	MLX5E_PTP_STATE_NUM_STATES,
28 };
29 
30 struct mlx5e_ptp {
31 	/* data path */
32 	struct mlx5e_ptpsq         ptpsq[MLX5E_MAX_NUM_TC];
33 	struct mlx5e_rq            rq;
34 	struct napi_struct         napi;
35 	struct device             *pdev;
36 	struct net_device         *netdev;
37 	__be32                     mkey_be;
38 	u8                         num_tc;
39 	u8                         lag_port;
40 
41 	/* data path - accessed per napi poll */
42 	struct mlx5e_ch_stats     *stats;
43 
44 	/* control */
45 	struct mlx5e_priv         *priv;
46 	struct mlx5_core_dev      *mdev;
47 	struct hwtstamp_config    *tstamp;
48 	DECLARE_BITMAP(state, MLX5E_PTP_STATE_NUM_STATES);
49 };
50 
51 static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
52 {
53 	struct flow_keys fk;
54 
55 	if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
56 		return false;
57 
58 	if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
59 		return false;
60 
61 	if (fk.basic.n_proto == htons(ETH_P_1588))
62 		return true;
63 
64 	if (fk.basic.n_proto != htons(ETH_P_IP) &&
65 	    fk.basic.n_proto != htons(ETH_P_IPV6))
66 		return false;
67 
68 	return (fk.basic.ip_proto == IPPROTO_UDP &&
69 		fk.ports.dst == htons(PTP_EV_PORT));
70 }
71 
72 static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq)
73 {
74 	if (!sq->ptpsq)
75 		return true;
76 
77 	return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo);
78 }
79 
80 int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
81 		   u8 lag_port, struct mlx5e_ptp **cp);
82 void mlx5e_ptp_close(struct mlx5e_ptp *c);
83 void mlx5e_ptp_activate_channel(struct mlx5e_ptp *c);
84 void mlx5e_ptp_deactivate_channel(struct mlx5e_ptp *c);
85 int mlx5e_ptp_get_rqn(struct mlx5e_ptp *c, u32 *rqn);
86 int mlx5e_ptp_alloc_rx_fs(struct mlx5e_flow_steering *fs,
87 			  const struct mlx5e_profile *profile);
88 void mlx5e_ptp_free_rx_fs(struct mlx5e_flow_steering *fs,
89 			  const struct mlx5e_profile *profile);
90 int mlx5e_ptp_rx_manage_fs(struct mlx5e_priv *priv, bool set);
91 
92 enum {
93 	MLX5E_SKB_CB_CQE_HWTSTAMP  = BIT(0),
94 	MLX5E_SKB_CB_PORT_HWTSTAMP = BIT(1),
95 };
96 
97 void mlx5e_skb_cb_hwtstamp_handler(struct sk_buff *skb, int hwtstamp_type,
98 				   ktime_t hwtstamp,
99 				   struct mlx5e_ptp_cq_stats *cq_stats);
100 
101 void mlx5e_skb_cb_hwtstamp_init(struct sk_buff *skb);
102 #endif /* __MLX5_EN_PTP_H__ */
103