162306a36Sopenharmony_ci/* Broadcom NetXtreme-C/E network driver.
262306a36Sopenharmony_ci *
362306a36Sopenharmony_ci * Copyright (c) 2021 Broadcom Inc.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
662306a36Sopenharmony_ci * it under the terms of the GNU General Public License as published by
762306a36Sopenharmony_ci * the Free Software Foundation.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef BNXT_PTP_H
1162306a36Sopenharmony_ci#define BNXT_PTP_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/ptp_clock_kernel.h>
1462306a36Sopenharmony_ci#include <linux/timecounter.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define BNXT_PTP_GRC_WIN	6
1762306a36Sopenharmony_ci#define BNXT_PTP_GRC_WIN_BASE	0x6000
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define BNXT_MAX_PHC_DRIFT	31000000
2062306a36Sopenharmony_ci#define BNXT_CYCLES_SHIFT	23
2162306a36Sopenharmony_ci#define BNXT_DEVCLK_FREQ	1000000
2262306a36Sopenharmony_ci#define BNXT_LO_TIMER_MASK	0x0000ffffffffUL
2362306a36Sopenharmony_ci#define BNXT_HI_TIMER_MASK	0xffff00000000UL
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define BNXT_PTP_QTS_TIMEOUT	1000
2662306a36Sopenharmony_ci#define BNXT_PTP_QTS_TX_ENABLES	(PORT_TS_QUERY_REQ_ENABLES_PTP_SEQ_ID |	\
2762306a36Sopenharmony_ci				 PORT_TS_QUERY_REQ_ENABLES_TS_REQ_TIMEOUT | \
2862306a36Sopenharmony_ci				 PORT_TS_QUERY_REQ_ENABLES_PTP_HDR_OFFSET)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistruct pps_pin {
3162306a36Sopenharmony_ci	u8 event;
3262306a36Sopenharmony_ci	u8 usage;
3362306a36Sopenharmony_ci	u8 state;
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define TSIO_PIN_VALID(pin) ((pin) >= 0 && (pin) < (BNXT_MAX_TSIO_PINS))
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define EVENT_DATA2_PPS_EVENT_TYPE(data2)				\
3962306a36Sopenharmony_ci	((data2) & ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define EVENT_DATA2_PPS_PIN_NUM(data2)					\
4262306a36Sopenharmony_ci	(((data2) &							\
4362306a36Sopenharmony_ci	  ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_PIN_NUMBER_MASK) >>\
4462306a36Sopenharmony_ci	 ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_PIN_NUMBER_SFT)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#define BNXT_DATA2_UPPER_MSK						\
4762306a36Sopenharmony_ci	ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_PPS_TIMESTAMP_UPPER_MASK
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define BNXT_DATA2_UPPER_SFT						\
5062306a36Sopenharmony_ci	(32 -								\
5162306a36Sopenharmony_ci	 ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_PPS_TIMESTAMP_UPPER_SFT)
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#define BNXT_DATA1_LOWER_MSK						\
5462306a36Sopenharmony_ci	ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA1_PPS_TIMESTAMP_LOWER_MASK
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define BNXT_DATA1_LOWER_SFT						\
5762306a36Sopenharmony_ci	  ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA1_PPS_TIMESTAMP_LOWER_SFT
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci#define EVENT_PPS_TS(data2, data1)					\
6062306a36Sopenharmony_ci	(((u64)((data2) & BNXT_DATA2_UPPER_MSK) << BNXT_DATA2_UPPER_SFT) |\
6162306a36Sopenharmony_ci	 (((data1) & BNXT_DATA1_LOWER_MSK) >> BNXT_DATA1_LOWER_SFT))
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#define BNXT_PPS_PIN_DISABLE	0
6462306a36Sopenharmony_ci#define BNXT_PPS_PIN_ENABLE	1
6562306a36Sopenharmony_ci#define BNXT_PPS_PIN_NONE	0
6662306a36Sopenharmony_ci#define BNXT_PPS_PIN_PPS_IN	1
6762306a36Sopenharmony_ci#define BNXT_PPS_PIN_PPS_OUT	2
6862306a36Sopenharmony_ci#define BNXT_PPS_PIN_SYNC_IN	3
6962306a36Sopenharmony_ci#define BNXT_PPS_PIN_SYNC_OUT	4
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#define BNXT_PPS_EVENT_INTERNAL	1
7262306a36Sopenharmony_ci#define BNXT_PPS_EVENT_EXTERNAL	2
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistruct bnxt_pps {
7562306a36Sopenharmony_ci	u8 num_pins;
7662306a36Sopenharmony_ci#define BNXT_MAX_TSIO_PINS	4
7762306a36Sopenharmony_ci	struct pps_pin pins[BNXT_MAX_TSIO_PINS];
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistruct bnxt_ptp_cfg {
8162306a36Sopenharmony_ci	struct ptp_clock_info	ptp_info;
8262306a36Sopenharmony_ci	struct ptp_clock	*ptp_clock;
8362306a36Sopenharmony_ci	struct cyclecounter	cc;
8462306a36Sopenharmony_ci	struct timecounter	tc;
8562306a36Sopenharmony_ci	struct bnxt_pps		pps_info;
8662306a36Sopenharmony_ci	/* serialize timecounter access */
8762306a36Sopenharmony_ci	spinlock_t		ptp_lock;
8862306a36Sopenharmony_ci	struct sk_buff		*tx_skb;
8962306a36Sopenharmony_ci	u64			current_time;
9062306a36Sopenharmony_ci	u64			old_time;
9162306a36Sopenharmony_ci	unsigned long		next_period;
9262306a36Sopenharmony_ci	unsigned long		next_overflow_check;
9362306a36Sopenharmony_ci	u32			cmult;
9462306a36Sopenharmony_ci	/* a 23b shift cyclecounter will overflow in ~36 mins.  Check overflow every 18 mins. */
9562306a36Sopenharmony_ci	#define BNXT_PHC_OVERFLOW_PERIOD	(18 * 60 * HZ)
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	u16			tx_seqid;
9862306a36Sopenharmony_ci	u16			tx_hdr_off;
9962306a36Sopenharmony_ci	struct bnxt		*bp;
10062306a36Sopenharmony_ci	atomic_t		tx_avail;
10162306a36Sopenharmony_ci#define BNXT_MAX_TX_TS	1
10262306a36Sopenharmony_ci	u16			rxctl;
10362306a36Sopenharmony_ci#define BNXT_PTP_MSG_SYNC			(1 << 0)
10462306a36Sopenharmony_ci#define BNXT_PTP_MSG_DELAY_REQ			(1 << 1)
10562306a36Sopenharmony_ci#define BNXT_PTP_MSG_PDELAY_REQ			(1 << 2)
10662306a36Sopenharmony_ci#define BNXT_PTP_MSG_PDELAY_RESP		(1 << 3)
10762306a36Sopenharmony_ci#define BNXT_PTP_MSG_FOLLOW_UP			(1 << 8)
10862306a36Sopenharmony_ci#define BNXT_PTP_MSG_DELAY_RESP			(1 << 9)
10962306a36Sopenharmony_ci#define BNXT_PTP_MSG_PDELAY_RESP_FOLLOW_UP	(1 << 10)
11062306a36Sopenharmony_ci#define BNXT_PTP_MSG_ANNOUNCE			(1 << 11)
11162306a36Sopenharmony_ci#define BNXT_PTP_MSG_SIGNALING			(1 << 12)
11262306a36Sopenharmony_ci#define BNXT_PTP_MSG_MANAGEMENT			(1 << 13)
11362306a36Sopenharmony_ci#define BNXT_PTP_MSG_EVENTS		(BNXT_PTP_MSG_SYNC |		\
11462306a36Sopenharmony_ci					 BNXT_PTP_MSG_DELAY_REQ |	\
11562306a36Sopenharmony_ci					 BNXT_PTP_MSG_PDELAY_REQ |	\
11662306a36Sopenharmony_ci					 BNXT_PTP_MSG_PDELAY_RESP)
11762306a36Sopenharmony_ci	u8			tx_tstamp_en:1;
11862306a36Sopenharmony_ci	int			rx_filter;
11962306a36Sopenharmony_ci	u32			tstamp_filters;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	u32			refclk_regs[2];
12262306a36Sopenharmony_ci	u32			refclk_mapped_regs[2];
12362306a36Sopenharmony_ci};
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci#if BITS_PER_LONG == 32
12662306a36Sopenharmony_ci#define BNXT_READ_TIME64(ptp, dst, src)		\
12762306a36Sopenharmony_cido {						\
12862306a36Sopenharmony_ci	spin_lock_bh(&(ptp)->ptp_lock);		\
12962306a36Sopenharmony_ci	(dst) = (src);				\
13062306a36Sopenharmony_ci	spin_unlock_bh(&(ptp)->ptp_lock);	\
13162306a36Sopenharmony_ci} while (0)
13262306a36Sopenharmony_ci#else
13362306a36Sopenharmony_ci#define BNXT_READ_TIME64(ptp, dst, src)		\
13462306a36Sopenharmony_ci	((dst) = READ_ONCE(src))
13562306a36Sopenharmony_ci#endif
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ciint bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off);
13862306a36Sopenharmony_civoid bnxt_ptp_update_current_time(struct bnxt *bp);
13962306a36Sopenharmony_civoid bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2);
14062306a36Sopenharmony_civoid bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp);
14162306a36Sopenharmony_civoid bnxt_ptp_reapply_pps(struct bnxt *bp);
14262306a36Sopenharmony_ciint bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr);
14362306a36Sopenharmony_ciint bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
14462306a36Sopenharmony_ciint bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb);
14562306a36Sopenharmony_ciint bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
14662306a36Sopenharmony_civoid bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns);
14762306a36Sopenharmony_ciint bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg);
14862306a36Sopenharmony_ciint bnxt_ptp_init(struct bnxt *bp, bool phc_cfg);
14962306a36Sopenharmony_civoid bnxt_ptp_clear(struct bnxt *bp);
15062306a36Sopenharmony_ci#endif
151