xref: /openbmc/linux/drivers/net/phy/nxp-c45-tja11xx.c (revision b0b2247d815d0f6806b702022052e208c3c2d56a)
1b050f2f1SRadu Pirea (NXP OSS) // SPDX-License-Identifier: GPL-2.0
2b050f2f1SRadu Pirea (NXP OSS) /* NXP C45 PHY driver
3b050f2f1SRadu Pirea (NXP OSS)  * Copyright (C) 2021 NXP
4b050f2f1SRadu Pirea (NXP OSS)  * Author: Radu Pirea <radu-nicolae.pirea@oss.nxp.com>
5b050f2f1SRadu Pirea (NXP OSS)  */
6b050f2f1SRadu Pirea (NXP OSS) 
7b050f2f1SRadu Pirea (NXP OSS) #include <linux/delay.h>
8b050f2f1SRadu Pirea (NXP OSS) #include <linux/ethtool.h>
9b050f2f1SRadu Pirea (NXP OSS) #include <linux/ethtool_netlink.h>
10b050f2f1SRadu Pirea (NXP OSS) #include <linux/kernel.h>
11b050f2f1SRadu Pirea (NXP OSS) #include <linux/mii.h>
12b050f2f1SRadu Pirea (NXP OSS) #include <linux/module.h>
13b050f2f1SRadu Pirea (NXP OSS) #include <linux/phy.h>
14b050f2f1SRadu Pirea (NXP OSS) #include <linux/processor.h>
15b050f2f1SRadu Pirea (NXP OSS) #include <linux/property.h>
16514def5dSRadu Pirea (NXP OSS) #include <linux/ptp_classify.h>
17514def5dSRadu Pirea (NXP OSS) #include <linux/ptp_clock_kernel.h>
18514def5dSRadu Pirea (NXP OSS) #include <linux/net_tstamp.h>
19b050f2f1SRadu Pirea (NXP OSS) 
20b050f2f1SRadu Pirea (NXP OSS) #define PHY_ID_TJA_1103			0x001BB010
21f1fe5dffSRadu Pirea (NXP OSS) #define PHY_ID_TJA_1120			0x001BB031
22b050f2f1SRadu Pirea (NXP OSS) 
23b050f2f1SRadu Pirea (NXP OSS) #define VEND1_DEVICE_CONTROL		0x0040
24b050f2f1SRadu Pirea (NXP OSS) #define DEVICE_CONTROL_RESET		BIT(15)
25b050f2f1SRadu Pirea (NXP OSS) #define DEVICE_CONTROL_CONFIG_GLOBAL_EN	BIT(14)
26b050f2f1SRadu Pirea (NXP OSS) #define DEVICE_CONTROL_CONFIG_ALL_EN	BIT(13)
27b050f2f1SRadu Pirea (NXP OSS) 
28f1fe5dffSRadu Pirea (NXP OSS) #define VEND1_DEVICE_CONFIG		0x0048
29f1fe5dffSRadu Pirea (NXP OSS) 
30f1fe5dffSRadu Pirea (NXP OSS) #define TJA1120_VEND1_EXT_TS_MODE	0x1012
31f1fe5dffSRadu Pirea (NXP OSS) 
32b2f0ca00SRadu Pirea (NXP OSS) #define VEND1_PHY_IRQ_ACK		0x80A0
33b2f0ca00SRadu Pirea (NXP OSS) #define VEND1_PHY_IRQ_EN		0x80A1
34b2f0ca00SRadu Pirea (NXP OSS) #define VEND1_PHY_IRQ_STATUS		0x80A2
35b2f0ca00SRadu Pirea (NXP OSS) #define PHY_IRQ_LINK_EVENT		BIT(1)
36b2f0ca00SRadu Pirea (NXP OSS) 
37b050f2f1SRadu Pirea (NXP OSS) #define VEND1_PHY_CONTROL		0x8100
38b050f2f1SRadu Pirea (NXP OSS) #define PHY_CONFIG_EN			BIT(14)
39b050f2f1SRadu Pirea (NXP OSS) #define PHY_START_OP			BIT(0)
40b050f2f1SRadu Pirea (NXP OSS) 
41b050f2f1SRadu Pirea (NXP OSS) #define VEND1_PHY_CONFIG		0x8108
42b050f2f1SRadu Pirea (NXP OSS) #define PHY_CONFIG_AUTO			BIT(0)
43b050f2f1SRadu Pirea (NXP OSS) 
44b050f2f1SRadu Pirea (NXP OSS) #define VEND1_SIGNAL_QUALITY		0x8320
45b050f2f1SRadu Pirea (NXP OSS) #define SQI_VALID			BIT(14)
46b050f2f1SRadu Pirea (NXP OSS) #define SQI_MASK			GENMASK(2, 0)
47b050f2f1SRadu Pirea (NXP OSS) #define MAX_SQI				SQI_MASK
48b050f2f1SRadu Pirea (NXP OSS) 
49b050f2f1SRadu Pirea (NXP OSS) #define CABLE_TEST_ENABLE		BIT(15)
50b050f2f1SRadu Pirea (NXP OSS) #define CABLE_TEST_START		BIT(14)
51b050f2f1SRadu Pirea (NXP OSS) #define CABLE_TEST_OK			0x00
52b050f2f1SRadu Pirea (NXP OSS) #define CABLE_TEST_SHORTED		0x01
53b050f2f1SRadu Pirea (NXP OSS) #define CABLE_TEST_OPEN			0x02
54b050f2f1SRadu Pirea (NXP OSS) #define CABLE_TEST_UNKNOWN		0x07
55b050f2f1SRadu Pirea (NXP OSS) 
56b050f2f1SRadu Pirea (NXP OSS) #define VEND1_PORT_CONTROL		0x8040
57b050f2f1SRadu Pirea (NXP OSS) #define PORT_CONTROL_EN			BIT(14)
58b050f2f1SRadu Pirea (NXP OSS) 
59514def5dSRadu Pirea (NXP OSS) #define VEND1_PORT_ABILITIES		0x8046
60514def5dSRadu Pirea (NXP OSS) #define PTP_ABILITY			BIT(3)
61514def5dSRadu Pirea (NXP OSS) 
62b050f2f1SRadu Pirea (NXP OSS) #define VEND1_PORT_INFRA_CONTROL	0xAC00
63b050f2f1SRadu Pirea (NXP OSS) #define PORT_INFRA_CONTROL_EN		BIT(14)
64b050f2f1SRadu Pirea (NXP OSS) 
65b050f2f1SRadu Pirea (NXP OSS) #define VEND1_RXID			0xAFCC
66b050f2f1SRadu Pirea (NXP OSS) #define VEND1_TXID			0xAFCD
67b050f2f1SRadu Pirea (NXP OSS) #define ID_ENABLE			BIT(15)
68b050f2f1SRadu Pirea (NXP OSS) 
69b050f2f1SRadu Pirea (NXP OSS) #define VEND1_ABILITIES			0xAFC4
70b050f2f1SRadu Pirea (NXP OSS) #define RGMII_ID_ABILITY		BIT(15)
71b050f2f1SRadu Pirea (NXP OSS) #define RGMII_ABILITY			BIT(14)
72b050f2f1SRadu Pirea (NXP OSS) #define RMII_ABILITY			BIT(10)
73b050f2f1SRadu Pirea (NXP OSS) #define REVMII_ABILITY			BIT(9)
74b050f2f1SRadu Pirea (NXP OSS) #define MII_ABILITY			BIT(8)
75b050f2f1SRadu Pirea (NXP OSS) #define SGMII_ABILITY			BIT(0)
76b050f2f1SRadu Pirea (NXP OSS) 
77b050f2f1SRadu Pirea (NXP OSS) #define VEND1_MII_BASIC_CONFIG		0xAFC6
788ba57205SRadu Pirea (OSS) #define MII_BASIC_CONFIG_REV		BIT(4)
79b050f2f1SRadu Pirea (NXP OSS) #define MII_BASIC_CONFIG_SGMII		0x9
80b050f2f1SRadu Pirea (NXP OSS) #define MII_BASIC_CONFIG_RGMII		0x7
81b050f2f1SRadu Pirea (NXP OSS) #define MII_BASIC_CONFIG_RMII		0x5
82b050f2f1SRadu Pirea (NXP OSS) #define MII_BASIC_CONFIG_MII		0x4
83b050f2f1SRadu Pirea (NXP OSS) 
84f1fe5dffSRadu Pirea (NXP OSS) #define VEND1_SYMBOL_ERROR_CNT_XTD	0x8351
85f1fe5dffSRadu Pirea (NXP OSS) #define EXTENDED_CNT_EN			BIT(15)
86f1fe5dffSRadu Pirea (NXP OSS) #define VEND1_MONITOR_STATUS		0xAC80
87f1fe5dffSRadu Pirea (NXP OSS) #define MONITOR_RESET			BIT(15)
88f1fe5dffSRadu Pirea (NXP OSS) #define VEND1_MONITOR_CONFIG		0xAC86
89f1fe5dffSRadu Pirea (NXP OSS) #define LOST_FRAMES_CNT_EN		BIT(9)
90f1fe5dffSRadu Pirea (NXP OSS) #define ALL_FRAMES_CNT_EN		BIT(8)
91f1fe5dffSRadu Pirea (NXP OSS) 
92b050f2f1SRadu Pirea (NXP OSS) #define VEND1_SYMBOL_ERROR_COUNTER	0x8350
93b050f2f1SRadu Pirea (NXP OSS) #define VEND1_LINK_DROP_COUNTER		0x8352
94b050f2f1SRadu Pirea (NXP OSS) #define VEND1_LINK_LOSSES_AND_FAILURES	0x8353
95b050f2f1SRadu Pirea (NXP OSS) #define VEND1_RX_PREAMBLE_COUNT		0xAFCE
96b050f2f1SRadu Pirea (NXP OSS) #define VEND1_TX_PREAMBLE_COUNT		0xAFCF
97b050f2f1SRadu Pirea (NXP OSS) #define VEND1_RX_IPG_LENGTH		0xAFD0
98b050f2f1SRadu Pirea (NXP OSS) #define VEND1_TX_IPG_LENGTH		0xAFD1
99b050f2f1SRadu Pirea (NXP OSS) #define COUNTER_EN			BIT(15)
100b050f2f1SRadu Pirea (NXP OSS) 
1017a71c8aaSRadu Pirea (NXP OSS) #define VEND1_PTP_CONFIG		0x1102
1027a71c8aaSRadu Pirea (NXP OSS) #define EXT_TRG_EDGE			BIT(1)
1037a71c8aaSRadu Pirea (NXP OSS) 
104*b0b2247dSRadu Pirea (NXP OSS) #define TJA1120_SYNC_TRIG_FILTER	0x1010
105*b0b2247dSRadu Pirea (NXP OSS) #define PTP_TRIG_RISE_TS		BIT(3)
106*b0b2247dSRadu Pirea (NXP OSS) #define PTP_TRIG_FALLING_TS		BIT(2)
107*b0b2247dSRadu Pirea (NXP OSS) 
108514def5dSRadu Pirea (NXP OSS) #define CLK_RATE_ADJ_LD			BIT(15)
109514def5dSRadu Pirea (NXP OSS) #define CLK_RATE_ADJ_DIR		BIT(14)
110514def5dSRadu Pirea (NXP OSS) 
111514def5dSRadu Pirea (NXP OSS) #define VEND1_RX_TS_INSRT_CTRL		0x114D
1126c0c85daSRadu Pirea (NXP OSS) #define TJA1103_RX_TS_INSRT_MODE2	0x02
113514def5dSRadu Pirea (NXP OSS) 
114f1fe5dffSRadu Pirea (NXP OSS) #define TJA1120_RX_TS_INSRT_CTRL	0x9012
115f1fe5dffSRadu Pirea (NXP OSS) #define TJA1120_RX_TS_INSRT_EN		BIT(15)
116f1fe5dffSRadu Pirea (NXP OSS) #define TJA1120_TS_INSRT_MODE		BIT(4)
117f1fe5dffSRadu Pirea (NXP OSS) 
118514def5dSRadu Pirea (NXP OSS) #define VEND1_EGR_RING_DATA_0		0x114E
119514def5dSRadu Pirea (NXP OSS) #define VEND1_EGR_RING_CTRL		0x1154
120514def5dSRadu Pirea (NXP OSS) 
121514def5dSRadu Pirea (NXP OSS) #define RING_DATA_0_TS_VALID		BIT(15)
122514def5dSRadu Pirea (NXP OSS) 
123514def5dSRadu Pirea (NXP OSS) #define RING_DONE			BIT(0)
124514def5dSRadu Pirea (NXP OSS) 
125514def5dSRadu Pirea (NXP OSS) #define TS_SEC_MASK			GENMASK(1, 0)
126514def5dSRadu Pirea (NXP OSS) 
127514def5dSRadu Pirea (NXP OSS) #define VEND1_PORT_FUNC_ENABLES		0x8048
128514def5dSRadu Pirea (NXP OSS) #define PTP_ENABLE			BIT(3)
129514def5dSRadu Pirea (NXP OSS) 
130514def5dSRadu Pirea (NXP OSS) #define VEND1_PORT_PTP_CONTROL		0x9000
131514def5dSRadu Pirea (NXP OSS) #define PORT_PTP_CONTROL_BYPASS		BIT(11)
132514def5dSRadu Pirea (NXP OSS) 
133514def5dSRadu Pirea (NXP OSS) #define PTP_CLK_PERIOD_100BT1		15ULL
134f1fe5dffSRadu Pirea (NXP OSS) #define PTP_CLK_PERIOD_1000BT1		8ULL
135514def5dSRadu Pirea (NXP OSS) 
136514def5dSRadu Pirea (NXP OSS) #define EVENT_MSG_FILT_ALL		0x0F
137514def5dSRadu Pirea (NXP OSS) #define EVENT_MSG_FILT_NONE		0x00
138514def5dSRadu Pirea (NXP OSS) 
1397a71c8aaSRadu Pirea (NXP OSS) #define VEND1_GPIO_FUNC_CONFIG_BASE	0x2C40
1407a71c8aaSRadu Pirea (NXP OSS) #define GPIO_FUNC_EN			BIT(15)
1417a71c8aaSRadu Pirea (NXP OSS) #define GPIO_FUNC_PTP			BIT(6)
1427a71c8aaSRadu Pirea (NXP OSS) #define GPIO_SIGNAL_PTP_TRIGGER		0x01
1437a71c8aaSRadu Pirea (NXP OSS) #define GPIO_SIGNAL_PPS_OUT		0x12
1447a71c8aaSRadu Pirea (NXP OSS) #define GPIO_DISABLE			0
1457a71c8aaSRadu Pirea (NXP OSS) #define GPIO_PPS_OUT_CFG		(GPIO_FUNC_EN | GPIO_FUNC_PTP | \
1467a71c8aaSRadu Pirea (NXP OSS) 	GPIO_SIGNAL_PPS_OUT)
1477a71c8aaSRadu Pirea (NXP OSS) #define GPIO_EXTTS_OUT_CFG		(GPIO_FUNC_EN | GPIO_FUNC_PTP | \
1487a71c8aaSRadu Pirea (NXP OSS) 	GPIO_SIGNAL_PTP_TRIGGER)
1497a71c8aaSRadu Pirea (NXP OSS) 
150b050f2f1SRadu Pirea (NXP OSS) #define RGMII_PERIOD_PS			8000U
151b050f2f1SRadu Pirea (NXP OSS) #define PS_PER_DEGREE			div_u64(RGMII_PERIOD_PS, 360)
152b050f2f1SRadu Pirea (NXP OSS) #define MIN_ID_PS			1644U
153b050f2f1SRadu Pirea (NXP OSS) #define MAX_ID_PS			2260U
154b050f2f1SRadu Pirea (NXP OSS) #define DEFAULT_ID_PS			2000U
155b050f2f1SRadu Pirea (NXP OSS) 
1566c0c85daSRadu Pirea (NXP OSS) #define PPM_TO_SUBNS_INC(ppb, ptp_clk_period) div_u64(GENMASK_ULL(31, 0) * \
1576c0c85daSRadu Pirea (NXP OSS) 	(ppb) * (ptp_clk_period), NSEC_PER_SEC)
158514def5dSRadu Pirea (NXP OSS) 
159514def5dSRadu Pirea (NXP OSS) #define NXP_C45_SKB_CB(skb)	((struct nxp_c45_skb_cb *)(skb)->cb)
160514def5dSRadu Pirea (NXP OSS) 
161514def5dSRadu Pirea (NXP OSS) struct nxp_c45_skb_cb {
162514def5dSRadu Pirea (NXP OSS) 	struct ptp_header *header;
163514def5dSRadu Pirea (NXP OSS) 	unsigned int type;
164514def5dSRadu Pirea (NXP OSS) };
165514def5dSRadu Pirea (NXP OSS) 
1666c0c85daSRadu Pirea (NXP OSS) #define NXP_C45_REG_FIELD(_reg, _devad, _offset, _size)	\
1676c0c85daSRadu Pirea (NXP OSS) 	((struct nxp_c45_reg_field) {			\
1686c0c85daSRadu Pirea (NXP OSS) 		.reg = _reg,				\
1696c0c85daSRadu Pirea (NXP OSS) 		.devad =  _devad,			\
1706c0c85daSRadu Pirea (NXP OSS) 		.offset = _offset,			\
1716c0c85daSRadu Pirea (NXP OSS) 		.size = _size,				\
1726c0c85daSRadu Pirea (NXP OSS) 	})
1736c0c85daSRadu Pirea (NXP OSS) 
1746c0c85daSRadu Pirea (NXP OSS) struct nxp_c45_reg_field {
1756c0c85daSRadu Pirea (NXP OSS) 	u16 reg;
1766c0c85daSRadu Pirea (NXP OSS) 	u8 devad;
1776c0c85daSRadu Pirea (NXP OSS) 	u8 offset;
1786c0c85daSRadu Pirea (NXP OSS) 	u8 size;
1796c0c85daSRadu Pirea (NXP OSS) };
1806c0c85daSRadu Pirea (NXP OSS) 
181514def5dSRadu Pirea (NXP OSS) struct nxp_c45_hwts {
182514def5dSRadu Pirea (NXP OSS) 	u32	nsec;
183514def5dSRadu Pirea (NXP OSS) 	u32	sec;
184514def5dSRadu Pirea (NXP OSS) 	u8	domain_number;
185514def5dSRadu Pirea (NXP OSS) 	u16	sequence_id;
186514def5dSRadu Pirea (NXP OSS) 	u8	msg_type;
187514def5dSRadu Pirea (NXP OSS) };
188514def5dSRadu Pirea (NXP OSS) 
1896c0c85daSRadu Pirea (NXP OSS) struct nxp_c45_regmap {
1906c0c85daSRadu Pirea (NXP OSS) 	/* PTP config regs. */
1916c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ptp_clk_period;
1926c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_event_msg_filt;
1936c0c85daSRadu Pirea (NXP OSS) 
1946c0c85daSRadu Pirea (NXP OSS) 	/* LTC bits and regs. */
1956c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field ltc_read;
1966c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field ltc_write;
1976c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field ltc_lock_ctrl;
1986c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_wr_nsec_0;
1996c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_wr_nsec_1;
2006c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_wr_sec_0;
2016c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_wr_sec_1;
2026c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_rd_nsec_0;
2036c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_rd_nsec_1;
2046c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_rd_sec_0;
2056c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ltc_rd_sec_1;
2066c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_rate_adj_subns_0;
2076c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_rate_adj_subns_1;
2086c0c85daSRadu Pirea (NXP OSS) 
2096c0c85daSRadu Pirea (NXP OSS) 	/* External trigger reg fields. */
2106c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field irq_egr_ts_en;
2116c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field irq_egr_ts_status;
2126c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field domain_number;
2136c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field msg_type;
2146c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field sequence_id;
2156c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field sec_1_0;
2166c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field sec_4_2;
2176c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field nsec_15_0;
2186c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field nsec_29_16;
2196c0c85daSRadu Pirea (NXP OSS) 
2206c0c85daSRadu Pirea (NXP OSS) 	/* PPS and EXT Trigger bits and regs. */
2216c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field pps_enable;
2226c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field pps_polarity;
2236c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ext_trg_data_0;
2246c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ext_trg_data_1;
2256c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ext_trg_data_2;
2266c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ext_trg_data_3;
2276c0c85daSRadu Pirea (NXP OSS) 	u16 vend1_ext_trg_ctrl;
2286c0c85daSRadu Pirea (NXP OSS) 
2296c0c85daSRadu Pirea (NXP OSS) 	/* Cable test reg fields. */
2306c0c85daSRadu Pirea (NXP OSS) 	u16 cable_test;
2316c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field cable_test_valid;
2326c0c85daSRadu Pirea (NXP OSS) 	struct nxp_c45_reg_field cable_test_result;
2336c0c85daSRadu Pirea (NXP OSS) };
2346c0c85daSRadu Pirea (NXP OSS) 
2356c0c85daSRadu Pirea (NXP OSS) struct nxp_c45_phy_stats {
2366c0c85daSRadu Pirea (NXP OSS) 	const char	*name;
2376c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_reg_field counter;
2386c0c85daSRadu Pirea (NXP OSS) };
2396c0c85daSRadu Pirea (NXP OSS) 
2406c0c85daSRadu Pirea (NXP OSS) struct nxp_c45_phy_data {
2416c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap;
2426c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_stats *stats;
2436c0c85daSRadu Pirea (NXP OSS) 	int n_stats;
2446c0c85daSRadu Pirea (NXP OSS) 	u8 ptp_clk_period;
245*b0b2247dSRadu Pirea (NXP OSS) 	bool ext_ts_both_edges;
2466c0c85daSRadu Pirea (NXP OSS) 	void (*counters_enable)(struct phy_device *phydev);
2476c0c85daSRadu Pirea (NXP OSS) 	void (*ptp_init)(struct phy_device *phydev);
2486c0c85daSRadu Pirea (NXP OSS) 	void (*ptp_enable)(struct phy_device *phydev, bool enable);
2496c0c85daSRadu Pirea (NXP OSS) };
2506c0c85daSRadu Pirea (NXP OSS) 
251b050f2f1SRadu Pirea (NXP OSS) struct nxp_c45_phy {
2526c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *phy_data;
253514def5dSRadu Pirea (NXP OSS) 	struct phy_device *phydev;
254514def5dSRadu Pirea (NXP OSS) 	struct mii_timestamper mii_ts;
255514def5dSRadu Pirea (NXP OSS) 	struct ptp_clock *ptp_clock;
256514def5dSRadu Pirea (NXP OSS) 	struct ptp_clock_info caps;
257514def5dSRadu Pirea (NXP OSS) 	struct sk_buff_head tx_queue;
258514def5dSRadu Pirea (NXP OSS) 	struct sk_buff_head rx_queue;
259514def5dSRadu Pirea (NXP OSS) 	/* used to access the PTP registers atomic */
260514def5dSRadu Pirea (NXP OSS) 	struct mutex ptp_lock;
261514def5dSRadu Pirea (NXP OSS) 	int hwts_tx;
262514def5dSRadu Pirea (NXP OSS) 	int hwts_rx;
263b050f2f1SRadu Pirea (NXP OSS) 	u32 tx_delay;
264b050f2f1SRadu Pirea (NXP OSS) 	u32 rx_delay;
2657a71c8aaSRadu Pirea (NXP OSS) 	struct timespec64 extts_ts;
2667a71c8aaSRadu Pirea (NXP OSS) 	int extts_index;
2677a71c8aaSRadu Pirea (NXP OSS) 	bool extts;
268b050f2f1SRadu Pirea (NXP OSS) };
269b050f2f1SRadu Pirea (NXP OSS) 
2706c0c85daSRadu Pirea (NXP OSS) static const
2716c0c85daSRadu Pirea (NXP OSS) struct nxp_c45_phy_data *nxp_c45_get_data(struct phy_device *phydev)
2726c0c85daSRadu Pirea (NXP OSS) {
2736c0c85daSRadu Pirea (NXP OSS) 	return phydev->drv->driver_data;
2746c0c85daSRadu Pirea (NXP OSS) }
2756c0c85daSRadu Pirea (NXP OSS) 
2766c0c85daSRadu Pirea (NXP OSS) static const
2776c0c85daSRadu Pirea (NXP OSS) struct nxp_c45_regmap *nxp_c45_get_regmap(struct phy_device *phydev)
2786c0c85daSRadu Pirea (NXP OSS) {
2796c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
2806c0c85daSRadu Pirea (NXP OSS) 
2816c0c85daSRadu Pirea (NXP OSS) 	return phy_data->regmap;
2826c0c85daSRadu Pirea (NXP OSS) }
2836c0c85daSRadu Pirea (NXP OSS) 
2846c0c85daSRadu Pirea (NXP OSS) static int nxp_c45_read_reg_field(struct phy_device *phydev,
2856c0c85daSRadu Pirea (NXP OSS) 				  const struct nxp_c45_reg_field *reg_field)
2866c0c85daSRadu Pirea (NXP OSS) {
287b050f2f1SRadu Pirea (NXP OSS) 	u16 mask;
2886c0c85daSRadu Pirea (NXP OSS) 	int ret;
2896c0c85daSRadu Pirea (NXP OSS) 
2906c0c85daSRadu Pirea (NXP OSS) 	if (reg_field->size == 0) {
2916c0c85daSRadu Pirea (NXP OSS) 		phydev_err(phydev, "Trying to read a reg field of size 0.\n");
2926c0c85daSRadu Pirea (NXP OSS) 		return -EINVAL;
2936c0c85daSRadu Pirea (NXP OSS) 	}
2946c0c85daSRadu Pirea (NXP OSS) 
2956c0c85daSRadu Pirea (NXP OSS) 	ret = phy_read_mmd(phydev, reg_field->devad, reg_field->reg);
2966c0c85daSRadu Pirea (NXP OSS) 	if (ret < 0)
2976c0c85daSRadu Pirea (NXP OSS) 		return ret;
2986c0c85daSRadu Pirea (NXP OSS) 
2996c0c85daSRadu Pirea (NXP OSS) 	mask = reg_field->size == 1 ? BIT(reg_field->offset) :
3006c0c85daSRadu Pirea (NXP OSS) 		GENMASK(reg_field->offset + reg_field->size - 1,
3016c0c85daSRadu Pirea (NXP OSS) 			reg_field->offset);
3026c0c85daSRadu Pirea (NXP OSS) 	ret &= mask;
3036c0c85daSRadu Pirea (NXP OSS) 	ret >>= reg_field->offset;
3046c0c85daSRadu Pirea (NXP OSS) 
3056c0c85daSRadu Pirea (NXP OSS) 	return ret;
3066c0c85daSRadu Pirea (NXP OSS) }
3076c0c85daSRadu Pirea (NXP OSS) 
3086c0c85daSRadu Pirea (NXP OSS) static int nxp_c45_write_reg_field(struct phy_device *phydev,
3096c0c85daSRadu Pirea (NXP OSS) 				   const struct nxp_c45_reg_field *reg_field,
3106c0c85daSRadu Pirea (NXP OSS) 				   u16 val)
3116c0c85daSRadu Pirea (NXP OSS) {
3126c0c85daSRadu Pirea (NXP OSS) 	u16 mask;
3136c0c85daSRadu Pirea (NXP OSS) 	u16 set;
3146c0c85daSRadu Pirea (NXP OSS) 
3156c0c85daSRadu Pirea (NXP OSS) 	if (reg_field->size == 0) {
3166c0c85daSRadu Pirea (NXP OSS) 		phydev_err(phydev, "Trying to write a reg field of size 0.\n");
3176c0c85daSRadu Pirea (NXP OSS) 		return -EINVAL;
3186c0c85daSRadu Pirea (NXP OSS) 	}
3196c0c85daSRadu Pirea (NXP OSS) 
3206c0c85daSRadu Pirea (NXP OSS) 	mask = reg_field->size == 1 ? BIT(reg_field->offset) :
3216c0c85daSRadu Pirea (NXP OSS) 		GENMASK(reg_field->offset + reg_field->size - 1,
3226c0c85daSRadu Pirea (NXP OSS) 			reg_field->offset);
3236c0c85daSRadu Pirea (NXP OSS) 	set = val << reg_field->offset;
3246c0c85daSRadu Pirea (NXP OSS) 
3256c0c85daSRadu Pirea (NXP OSS) 	return phy_modify_mmd_changed(phydev, reg_field->devad,
3266c0c85daSRadu Pirea (NXP OSS) 				      reg_field->reg, mask, set);
3276c0c85daSRadu Pirea (NXP OSS) }
3286c0c85daSRadu Pirea (NXP OSS) 
3296c0c85daSRadu Pirea (NXP OSS) static int nxp_c45_set_reg_field(struct phy_device *phydev,
3306c0c85daSRadu Pirea (NXP OSS) 				 const struct nxp_c45_reg_field *reg_field)
3316c0c85daSRadu Pirea (NXP OSS) {
3326c0c85daSRadu Pirea (NXP OSS) 	if (reg_field->size != 1) {
3336c0c85daSRadu Pirea (NXP OSS) 		phydev_err(phydev, "Trying to set a reg field of size different than 1.\n");
3346c0c85daSRadu Pirea (NXP OSS) 		return -EINVAL;
3356c0c85daSRadu Pirea (NXP OSS) 	}
3366c0c85daSRadu Pirea (NXP OSS) 
3376c0c85daSRadu Pirea (NXP OSS) 	return nxp_c45_write_reg_field(phydev, reg_field, 1);
3386c0c85daSRadu Pirea (NXP OSS) }
3396c0c85daSRadu Pirea (NXP OSS) 
3406c0c85daSRadu Pirea (NXP OSS) static int nxp_c45_clear_reg_field(struct phy_device *phydev,
3416c0c85daSRadu Pirea (NXP OSS) 				   const struct nxp_c45_reg_field *reg_field)
3426c0c85daSRadu Pirea (NXP OSS) {
3436c0c85daSRadu Pirea (NXP OSS) 	if (reg_field->size != 1) {
3446c0c85daSRadu Pirea (NXP OSS) 		phydev_err(phydev, "Trying to set a reg field of size different than 1.\n");
3456c0c85daSRadu Pirea (NXP OSS) 		return -EINVAL;
3466c0c85daSRadu Pirea (NXP OSS) 	}
3476c0c85daSRadu Pirea (NXP OSS) 
3486c0c85daSRadu Pirea (NXP OSS) 	return nxp_c45_write_reg_field(phydev, reg_field, 0);
3496c0c85daSRadu Pirea (NXP OSS) }
350b050f2f1SRadu Pirea (NXP OSS) 
351514def5dSRadu Pirea (NXP OSS) static bool nxp_c45_poll_txts(struct phy_device *phydev)
352514def5dSRadu Pirea (NXP OSS) {
353514def5dSRadu Pirea (NXP OSS) 	return phydev->irq <= 0;
354514def5dSRadu Pirea (NXP OSS) }
355514def5dSRadu Pirea (NXP OSS) 
356514def5dSRadu Pirea (NXP OSS) static int _nxp_c45_ptp_gettimex64(struct ptp_clock_info *ptp,
357514def5dSRadu Pirea (NXP OSS) 				   struct timespec64 *ts,
358514def5dSRadu Pirea (NXP OSS) 				   struct ptp_system_timestamp *sts)
359514def5dSRadu Pirea (NXP OSS) {
360514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
3616c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
362514def5dSRadu Pirea (NXP OSS) 
3636c0c85daSRadu Pirea (NXP OSS) 	nxp_c45_set_reg_field(priv->phydev, &regmap->ltc_read);
364514def5dSRadu Pirea (NXP OSS) 	ts->tv_nsec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
3656c0c85daSRadu Pirea (NXP OSS) 				   regmap->vend1_ltc_rd_nsec_0);
366514def5dSRadu Pirea (NXP OSS) 	ts->tv_nsec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
3676c0c85daSRadu Pirea (NXP OSS) 				    regmap->vend1_ltc_rd_nsec_1) << 16;
368514def5dSRadu Pirea (NXP OSS) 	ts->tv_sec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
3696c0c85daSRadu Pirea (NXP OSS) 				  regmap->vend1_ltc_rd_sec_0);
370514def5dSRadu Pirea (NXP OSS) 	ts->tv_sec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
3716c0c85daSRadu Pirea (NXP OSS) 				   regmap->vend1_ltc_rd_sec_1) << 16;
372514def5dSRadu Pirea (NXP OSS) 
373514def5dSRadu Pirea (NXP OSS) 	return 0;
374514def5dSRadu Pirea (NXP OSS) }
375514def5dSRadu Pirea (NXP OSS) 
376514def5dSRadu Pirea (NXP OSS) static int nxp_c45_ptp_gettimex64(struct ptp_clock_info *ptp,
377514def5dSRadu Pirea (NXP OSS) 				  struct timespec64 *ts,
378514def5dSRadu Pirea (NXP OSS) 				  struct ptp_system_timestamp *sts)
379514def5dSRadu Pirea (NXP OSS) {
380514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
381514def5dSRadu Pirea (NXP OSS) 
382514def5dSRadu Pirea (NXP OSS) 	mutex_lock(&priv->ptp_lock);
383514def5dSRadu Pirea (NXP OSS) 	_nxp_c45_ptp_gettimex64(ptp, ts, sts);
384514def5dSRadu Pirea (NXP OSS) 	mutex_unlock(&priv->ptp_lock);
385514def5dSRadu Pirea (NXP OSS) 
386514def5dSRadu Pirea (NXP OSS) 	return 0;
387514def5dSRadu Pirea (NXP OSS) }
388514def5dSRadu Pirea (NXP OSS) 
389514def5dSRadu Pirea (NXP OSS) static int _nxp_c45_ptp_settime64(struct ptp_clock_info *ptp,
390514def5dSRadu Pirea (NXP OSS) 				  const struct timespec64 *ts)
391514def5dSRadu Pirea (NXP OSS) {
392514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
3936c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
394514def5dSRadu Pirea (NXP OSS) 
3956c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_nsec_0,
396514def5dSRadu Pirea (NXP OSS) 		      ts->tv_nsec);
3976c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_nsec_1,
398514def5dSRadu Pirea (NXP OSS) 		      ts->tv_nsec >> 16);
3996c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_sec_0,
400514def5dSRadu Pirea (NXP OSS) 		      ts->tv_sec);
4016c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_sec_1,
402514def5dSRadu Pirea (NXP OSS) 		      ts->tv_sec >> 16);
4036c0c85daSRadu Pirea (NXP OSS) 	nxp_c45_set_reg_field(priv->phydev, &regmap->ltc_write);
404514def5dSRadu Pirea (NXP OSS) 
405514def5dSRadu Pirea (NXP OSS) 	return 0;
406514def5dSRadu Pirea (NXP OSS) }
407514def5dSRadu Pirea (NXP OSS) 
408514def5dSRadu Pirea (NXP OSS) static int nxp_c45_ptp_settime64(struct ptp_clock_info *ptp,
409514def5dSRadu Pirea (NXP OSS) 				 const struct timespec64 *ts)
410514def5dSRadu Pirea (NXP OSS) {
411514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
412514def5dSRadu Pirea (NXP OSS) 
413514def5dSRadu Pirea (NXP OSS) 	mutex_lock(&priv->ptp_lock);
414514def5dSRadu Pirea (NXP OSS) 	_nxp_c45_ptp_settime64(ptp, ts);
415514def5dSRadu Pirea (NXP OSS) 	mutex_unlock(&priv->ptp_lock);
416514def5dSRadu Pirea (NXP OSS) 
417514def5dSRadu Pirea (NXP OSS) 	return 0;
418514def5dSRadu Pirea (NXP OSS) }
419514def5dSRadu Pirea (NXP OSS) 
420514def5dSRadu Pirea (NXP OSS) static int nxp_c45_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
421514def5dSRadu Pirea (NXP OSS) {
422514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
4236c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *data = nxp_c45_get_data(priv->phydev);
4246c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = data->regmap;
425514def5dSRadu Pirea (NXP OSS) 	s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
426514def5dSRadu Pirea (NXP OSS) 	u64 subns_inc_val;
427514def5dSRadu Pirea (NXP OSS) 	bool inc;
428514def5dSRadu Pirea (NXP OSS) 
429514def5dSRadu Pirea (NXP OSS) 	mutex_lock(&priv->ptp_lock);
430514def5dSRadu Pirea (NXP OSS) 	inc = ppb >= 0;
431514def5dSRadu Pirea (NXP OSS) 	ppb = abs(ppb);
432514def5dSRadu Pirea (NXP OSS) 
4336c0c85daSRadu Pirea (NXP OSS) 	subns_inc_val = PPM_TO_SUBNS_INC(ppb, data->ptp_clk_period);
434514def5dSRadu Pirea (NXP OSS) 
4356c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
4366c0c85daSRadu Pirea (NXP OSS) 		      regmap->vend1_rate_adj_subns_0,
437514def5dSRadu Pirea (NXP OSS) 		      subns_inc_val);
438514def5dSRadu Pirea (NXP OSS) 	subns_inc_val >>= 16;
439514def5dSRadu Pirea (NXP OSS) 	subns_inc_val |= CLK_RATE_ADJ_LD;
440514def5dSRadu Pirea (NXP OSS) 	if (inc)
441514def5dSRadu Pirea (NXP OSS) 		subns_inc_val |= CLK_RATE_ADJ_DIR;
442514def5dSRadu Pirea (NXP OSS) 
4436c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
4446c0c85daSRadu Pirea (NXP OSS) 		      regmap->vend1_rate_adj_subns_1,
445514def5dSRadu Pirea (NXP OSS) 		      subns_inc_val);
446514def5dSRadu Pirea (NXP OSS) 	mutex_unlock(&priv->ptp_lock);
447514def5dSRadu Pirea (NXP OSS) 
448514def5dSRadu Pirea (NXP OSS) 	return 0;
449514def5dSRadu Pirea (NXP OSS) }
450514def5dSRadu Pirea (NXP OSS) 
451514def5dSRadu Pirea (NXP OSS) static int nxp_c45_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
452514def5dSRadu Pirea (NXP OSS) {
453514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
454514def5dSRadu Pirea (NXP OSS) 	struct timespec64 now, then;
455514def5dSRadu Pirea (NXP OSS) 
456514def5dSRadu Pirea (NXP OSS) 	mutex_lock(&priv->ptp_lock);
457514def5dSRadu Pirea (NXP OSS) 	then = ns_to_timespec64(delta);
458514def5dSRadu Pirea (NXP OSS) 	_nxp_c45_ptp_gettimex64(ptp, &now, NULL);
459514def5dSRadu Pirea (NXP OSS) 	now = timespec64_add(now, then);
460514def5dSRadu Pirea (NXP OSS) 	_nxp_c45_ptp_settime64(ptp, &now);
461514def5dSRadu Pirea (NXP OSS) 	mutex_unlock(&priv->ptp_lock);
462514def5dSRadu Pirea (NXP OSS) 
463514def5dSRadu Pirea (NXP OSS) 	return 0;
464514def5dSRadu Pirea (NXP OSS) }
465514def5dSRadu Pirea (NXP OSS) 
466514def5dSRadu Pirea (NXP OSS) static void nxp_c45_reconstruct_ts(struct timespec64 *ts,
467514def5dSRadu Pirea (NXP OSS) 				   struct nxp_c45_hwts *hwts)
468514def5dSRadu Pirea (NXP OSS) {
469514def5dSRadu Pirea (NXP OSS) 	ts->tv_nsec = hwts->nsec;
470514def5dSRadu Pirea (NXP OSS) 	if ((ts->tv_sec & TS_SEC_MASK) < (hwts->sec & TS_SEC_MASK))
471661fef56SVladimir Oltean 		ts->tv_sec -= TS_SEC_MASK + 1;
472514def5dSRadu Pirea (NXP OSS) 	ts->tv_sec &= ~TS_SEC_MASK;
473514def5dSRadu Pirea (NXP OSS) 	ts->tv_sec |= hwts->sec & TS_SEC_MASK;
474514def5dSRadu Pirea (NXP OSS) }
475514def5dSRadu Pirea (NXP OSS) 
476514def5dSRadu Pirea (NXP OSS) static bool nxp_c45_match_ts(struct ptp_header *header,
477514def5dSRadu Pirea (NXP OSS) 			     struct nxp_c45_hwts *hwts,
478514def5dSRadu Pirea (NXP OSS) 			     unsigned int type)
479514def5dSRadu Pirea (NXP OSS) {
480514def5dSRadu Pirea (NXP OSS) 	return ntohs(header->sequence_id) == hwts->sequence_id &&
481514def5dSRadu Pirea (NXP OSS) 	       ptp_get_msgtype(header, type) == hwts->msg_type &&
482514def5dSRadu Pirea (NXP OSS) 	       header->domain_number  == hwts->domain_number;
483514def5dSRadu Pirea (NXP OSS) }
484514def5dSRadu Pirea (NXP OSS) 
4857a71c8aaSRadu Pirea (NXP OSS) static void nxp_c45_get_extts(struct nxp_c45_phy *priv,
4867a71c8aaSRadu Pirea (NXP OSS) 			      struct timespec64 *extts)
4877a71c8aaSRadu Pirea (NXP OSS) {
4886c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
4896c0c85daSRadu Pirea (NXP OSS) 
4907a71c8aaSRadu Pirea (NXP OSS) 	extts->tv_nsec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
4916c0c85daSRadu Pirea (NXP OSS) 				      regmap->vend1_ext_trg_data_0);
4927a71c8aaSRadu Pirea (NXP OSS) 	extts->tv_nsec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
4936c0c85daSRadu Pirea (NXP OSS) 				       regmap->vend1_ext_trg_data_1) << 16;
4947a71c8aaSRadu Pirea (NXP OSS) 	extts->tv_sec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
4956c0c85daSRadu Pirea (NXP OSS) 				     regmap->vend1_ext_trg_data_2);
4967a71c8aaSRadu Pirea (NXP OSS) 	extts->tv_sec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
4976c0c85daSRadu Pirea (NXP OSS) 				      regmap->vend1_ext_trg_data_3) << 16;
4986c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
4996c0c85daSRadu Pirea (NXP OSS) 		      regmap->vend1_ext_trg_ctrl, RING_DONE);
5007a71c8aaSRadu Pirea (NXP OSS) }
5017a71c8aaSRadu Pirea (NXP OSS) 
502514def5dSRadu Pirea (NXP OSS) static bool nxp_c45_get_hwtxts(struct nxp_c45_phy *priv,
503514def5dSRadu Pirea (NXP OSS) 			       struct nxp_c45_hwts *hwts)
504514def5dSRadu Pirea (NXP OSS) {
5056c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
5066c0c85daSRadu Pirea (NXP OSS) 	struct phy_device *phydev = priv->phydev;
507514def5dSRadu Pirea (NXP OSS) 	bool valid;
508514def5dSRadu Pirea (NXP OSS) 	u16 reg;
509514def5dSRadu Pirea (NXP OSS) 
510514def5dSRadu Pirea (NXP OSS) 	mutex_lock(&priv->ptp_lock);
511514def5dSRadu Pirea (NXP OSS) 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_CTRL,
512514def5dSRadu Pirea (NXP OSS) 		      RING_DONE);
513514def5dSRadu Pirea (NXP OSS) 	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_DATA_0);
514514def5dSRadu Pirea (NXP OSS) 	valid = !!(reg & RING_DATA_0_TS_VALID);
515514def5dSRadu Pirea (NXP OSS) 	if (!valid)
516514def5dSRadu Pirea (NXP OSS) 		goto nxp_c45_get_hwtxts_out;
517514def5dSRadu Pirea (NXP OSS) 
5186c0c85daSRadu Pirea (NXP OSS) 	hwts->domain_number =
5196c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_read_reg_field(phydev, &regmap->domain_number);
5206c0c85daSRadu Pirea (NXP OSS) 	hwts->msg_type =
5216c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_read_reg_field(phydev, &regmap->msg_type);
5226c0c85daSRadu Pirea (NXP OSS) 	hwts->sequence_id =
5236c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_read_reg_field(phydev, &regmap->sequence_id);
5246c0c85daSRadu Pirea (NXP OSS) 	hwts->nsec =
5256c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_read_reg_field(phydev, &regmap->nsec_15_0);
5266c0c85daSRadu Pirea (NXP OSS) 	hwts->nsec |=
5276c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_read_reg_field(phydev, &regmap->nsec_29_16) << 16;
5286c0c85daSRadu Pirea (NXP OSS) 	hwts->sec = nxp_c45_read_reg_field(phydev, &regmap->sec_1_0);
5296c0c85daSRadu Pirea (NXP OSS) 	hwts->sec |= nxp_c45_read_reg_field(phydev, &regmap->sec_4_2) << 2;
530514def5dSRadu Pirea (NXP OSS) 
531514def5dSRadu Pirea (NXP OSS) nxp_c45_get_hwtxts_out:
532514def5dSRadu Pirea (NXP OSS) 	mutex_unlock(&priv->ptp_lock);
533514def5dSRadu Pirea (NXP OSS) 	return valid;
534514def5dSRadu Pirea (NXP OSS) }
535514def5dSRadu Pirea (NXP OSS) 
536514def5dSRadu Pirea (NXP OSS) static void nxp_c45_process_txts(struct nxp_c45_phy *priv,
537514def5dSRadu Pirea (NXP OSS) 				 struct nxp_c45_hwts *txts)
538514def5dSRadu Pirea (NXP OSS) {
539514def5dSRadu Pirea (NXP OSS) 	struct sk_buff *skb, *tmp, *skb_match = NULL;
540514def5dSRadu Pirea (NXP OSS) 	struct skb_shared_hwtstamps shhwtstamps;
541514def5dSRadu Pirea (NXP OSS) 	struct timespec64 ts;
542514def5dSRadu Pirea (NXP OSS) 	unsigned long flags;
543514def5dSRadu Pirea (NXP OSS) 	bool ts_match;
544514def5dSRadu Pirea (NXP OSS) 	s64 ts_ns;
545514def5dSRadu Pirea (NXP OSS) 
546514def5dSRadu Pirea (NXP OSS) 	spin_lock_irqsave(&priv->tx_queue.lock, flags);
547514def5dSRadu Pirea (NXP OSS) 	skb_queue_walk_safe(&priv->tx_queue, skb, tmp) {
548514def5dSRadu Pirea (NXP OSS) 		ts_match = nxp_c45_match_ts(NXP_C45_SKB_CB(skb)->header, txts,
549514def5dSRadu Pirea (NXP OSS) 					    NXP_C45_SKB_CB(skb)->type);
550514def5dSRadu Pirea (NXP OSS) 		if (!ts_match)
551514def5dSRadu Pirea (NXP OSS) 			continue;
552514def5dSRadu Pirea (NXP OSS) 		skb_match = skb;
553514def5dSRadu Pirea (NXP OSS) 		__skb_unlink(skb, &priv->tx_queue);
554514def5dSRadu Pirea (NXP OSS) 		break;
555514def5dSRadu Pirea (NXP OSS) 	}
556514def5dSRadu Pirea (NXP OSS) 	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
557514def5dSRadu Pirea (NXP OSS) 
558514def5dSRadu Pirea (NXP OSS) 	if (skb_match) {
559514def5dSRadu Pirea (NXP OSS) 		nxp_c45_ptp_gettimex64(&priv->caps, &ts, NULL);
560514def5dSRadu Pirea (NXP OSS) 		nxp_c45_reconstruct_ts(&ts, txts);
561514def5dSRadu Pirea (NXP OSS) 		memset(&shhwtstamps, 0, sizeof(shhwtstamps));
562514def5dSRadu Pirea (NXP OSS) 		ts_ns = timespec64_to_ns(&ts);
563514def5dSRadu Pirea (NXP OSS) 		shhwtstamps.hwtstamp = ns_to_ktime(ts_ns);
564514def5dSRadu Pirea (NXP OSS) 		skb_complete_tx_timestamp(skb_match, &shhwtstamps);
565514def5dSRadu Pirea (NXP OSS) 	} else {
566514def5dSRadu Pirea (NXP OSS) 		phydev_warn(priv->phydev,
567514def5dSRadu Pirea (NXP OSS) 			    "the tx timestamp doesn't match with any skb\n");
568514def5dSRadu Pirea (NXP OSS) 	}
569514def5dSRadu Pirea (NXP OSS) }
570514def5dSRadu Pirea (NXP OSS) 
571514def5dSRadu Pirea (NXP OSS) static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
572514def5dSRadu Pirea (NXP OSS) {
573514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
574514def5dSRadu Pirea (NXP OSS) 	bool poll_txts = nxp_c45_poll_txts(priv->phydev);
575514def5dSRadu Pirea (NXP OSS) 	struct skb_shared_hwtstamps *shhwtstamps_rx;
5767a71c8aaSRadu Pirea (NXP OSS) 	struct ptp_clock_event event;
577514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_hwts hwts;
578514def5dSRadu Pirea (NXP OSS) 	bool reschedule = false;
579514def5dSRadu Pirea (NXP OSS) 	struct timespec64 ts;
580514def5dSRadu Pirea (NXP OSS) 	struct sk_buff *skb;
581514def5dSRadu Pirea (NXP OSS) 	bool txts_valid;
582514def5dSRadu Pirea (NXP OSS) 	u32 ts_raw;
583514def5dSRadu Pirea (NXP OSS) 
584514def5dSRadu Pirea (NXP OSS) 	while (!skb_queue_empty_lockless(&priv->tx_queue) && poll_txts) {
585514def5dSRadu Pirea (NXP OSS) 		txts_valid = nxp_c45_get_hwtxts(priv, &hwts);
586514def5dSRadu Pirea (NXP OSS) 		if (unlikely(!txts_valid)) {
587514def5dSRadu Pirea (NXP OSS) 			/* Still more skbs in the queue */
588514def5dSRadu Pirea (NXP OSS) 			reschedule = true;
589514def5dSRadu Pirea (NXP OSS) 			break;
590514def5dSRadu Pirea (NXP OSS) 		}
591514def5dSRadu Pirea (NXP OSS) 
592514def5dSRadu Pirea (NXP OSS) 		nxp_c45_process_txts(priv, &hwts);
593514def5dSRadu Pirea (NXP OSS) 	}
594514def5dSRadu Pirea (NXP OSS) 
595514def5dSRadu Pirea (NXP OSS) 	while ((skb = skb_dequeue(&priv->rx_queue)) != NULL) {
596109258edSVladimir Oltean 		nxp_c45_ptp_gettimex64(&priv->caps, &ts, NULL);
597514def5dSRadu Pirea (NXP OSS) 		ts_raw = __be32_to_cpu(NXP_C45_SKB_CB(skb)->header->reserved2);
598514def5dSRadu Pirea (NXP OSS) 		hwts.sec = ts_raw >> 30;
599514def5dSRadu Pirea (NXP OSS) 		hwts.nsec = ts_raw & GENMASK(29, 0);
600514def5dSRadu Pirea (NXP OSS) 		nxp_c45_reconstruct_ts(&ts, &hwts);
601514def5dSRadu Pirea (NXP OSS) 		shhwtstamps_rx = skb_hwtstamps(skb);
602514def5dSRadu Pirea (NXP OSS) 		shhwtstamps_rx->hwtstamp = ns_to_ktime(timespec64_to_ns(&ts));
603514def5dSRadu Pirea (NXP OSS) 		NXP_C45_SKB_CB(skb)->header->reserved2 = 0;
604a3d73e15SSebastian Andrzej Siewior 		netif_rx(skb);
605514def5dSRadu Pirea (NXP OSS) 	}
606514def5dSRadu Pirea (NXP OSS) 
6077a71c8aaSRadu Pirea (NXP OSS) 	if (priv->extts) {
6087a71c8aaSRadu Pirea (NXP OSS) 		nxp_c45_get_extts(priv, &ts);
6097a71c8aaSRadu Pirea (NXP OSS) 		if (timespec64_compare(&ts, &priv->extts_ts) != 0) {
6107a71c8aaSRadu Pirea (NXP OSS) 			priv->extts_ts = ts;
6117a71c8aaSRadu Pirea (NXP OSS) 			event.index = priv->extts_index;
6127a71c8aaSRadu Pirea (NXP OSS) 			event.type = PTP_CLOCK_EXTTS;
6137a71c8aaSRadu Pirea (NXP OSS) 			event.timestamp = ns_to_ktime(timespec64_to_ns(&ts));
6147a71c8aaSRadu Pirea (NXP OSS) 			ptp_clock_event(priv->ptp_clock, &event);
6157a71c8aaSRadu Pirea (NXP OSS) 		}
6167a71c8aaSRadu Pirea (NXP OSS) 		reschedule = true;
6177a71c8aaSRadu Pirea (NXP OSS) 	}
6187a71c8aaSRadu Pirea (NXP OSS) 
619514def5dSRadu Pirea (NXP OSS) 	return reschedule ? 1 : -1;
620514def5dSRadu Pirea (NXP OSS) }
621514def5dSRadu Pirea (NXP OSS) 
6227a71c8aaSRadu Pirea (NXP OSS) static void nxp_c45_gpio_config(struct nxp_c45_phy *priv,
6237a71c8aaSRadu Pirea (NXP OSS) 				int pin, u16 pin_cfg)
6247a71c8aaSRadu Pirea (NXP OSS) {
6257a71c8aaSRadu Pirea (NXP OSS) 	struct phy_device *phydev = priv->phydev;
6267a71c8aaSRadu Pirea (NXP OSS) 
6277a71c8aaSRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1,
6287a71c8aaSRadu Pirea (NXP OSS) 		      VEND1_GPIO_FUNC_CONFIG_BASE + pin, pin_cfg);
6297a71c8aaSRadu Pirea (NXP OSS) }
6307a71c8aaSRadu Pirea (NXP OSS) 
6317a71c8aaSRadu Pirea (NXP OSS) static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
6327a71c8aaSRadu Pirea (NXP OSS) 				 struct ptp_perout_request *perout, int on)
6337a71c8aaSRadu Pirea (NXP OSS) {
6346c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
6357a71c8aaSRadu Pirea (NXP OSS) 	struct phy_device *phydev = priv->phydev;
6367a71c8aaSRadu Pirea (NXP OSS) 	int pin;
6377a71c8aaSRadu Pirea (NXP OSS) 
6387a71c8aaSRadu Pirea (NXP OSS) 	if (perout->flags & ~PTP_PEROUT_PHASE)
6397a71c8aaSRadu Pirea (NXP OSS) 		return -EOPNOTSUPP;
6407a71c8aaSRadu Pirea (NXP OSS) 
6417a71c8aaSRadu Pirea (NXP OSS) 	pin = ptp_find_pin(priv->ptp_clock, PTP_PF_PEROUT, perout->index);
6427a71c8aaSRadu Pirea (NXP OSS) 	if (pin < 0)
6437a71c8aaSRadu Pirea (NXP OSS) 		return pin;
6447a71c8aaSRadu Pirea (NXP OSS) 
6457a71c8aaSRadu Pirea (NXP OSS) 	if (!on) {
6466c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_clear_reg_field(priv->phydev,
6476c0c85daSRadu Pirea (NXP OSS) 					&regmap->pps_enable);
6486c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_clear_reg_field(priv->phydev,
6496c0c85daSRadu Pirea (NXP OSS) 					&regmap->pps_polarity);
6507a71c8aaSRadu Pirea (NXP OSS) 
6517a71c8aaSRadu Pirea (NXP OSS) 		nxp_c45_gpio_config(priv, pin, GPIO_DISABLE);
6527a71c8aaSRadu Pirea (NXP OSS) 
6537a71c8aaSRadu Pirea (NXP OSS) 		return 0;
6547a71c8aaSRadu Pirea (NXP OSS) 	}
6557a71c8aaSRadu Pirea (NXP OSS) 
6567a71c8aaSRadu Pirea (NXP OSS) 	/* The PPS signal is fixed to 1 second and is always generated when the
6577a71c8aaSRadu Pirea (NXP OSS) 	 * seconds counter is incremented. The start time is not configurable.
6587a71c8aaSRadu Pirea (NXP OSS) 	 * If the clock is adjusted, the PPS signal is automatically readjusted.
6597a71c8aaSRadu Pirea (NXP OSS) 	 */
6607a71c8aaSRadu Pirea (NXP OSS) 	if (perout->period.sec != 1 || perout->period.nsec != 0) {
6617a71c8aaSRadu Pirea (NXP OSS) 		phydev_warn(phydev, "The period can be set only to 1 second.");
6627a71c8aaSRadu Pirea (NXP OSS) 		return -EINVAL;
6637a71c8aaSRadu Pirea (NXP OSS) 	}
6647a71c8aaSRadu Pirea (NXP OSS) 
6657a71c8aaSRadu Pirea (NXP OSS) 	if (!(perout->flags & PTP_PEROUT_PHASE)) {
6667a71c8aaSRadu Pirea (NXP OSS) 		if (perout->start.sec != 0 || perout->start.nsec != 0) {
6677a71c8aaSRadu Pirea (NXP OSS) 			phydev_warn(phydev, "The start time is not configurable. Should be set to 0 seconds and 0 nanoseconds.");
6687a71c8aaSRadu Pirea (NXP OSS) 			return -EINVAL;
6697a71c8aaSRadu Pirea (NXP OSS) 		}
6707a71c8aaSRadu Pirea (NXP OSS) 	} else {
6717a71c8aaSRadu Pirea (NXP OSS) 		if (perout->phase.nsec != 0 &&
6727a71c8aaSRadu Pirea (NXP OSS) 		    perout->phase.nsec != (NSEC_PER_SEC >> 1)) {
6737a71c8aaSRadu Pirea (NXP OSS) 			phydev_warn(phydev, "The phase can be set only to 0 or 500000000 nanoseconds.");
6747a71c8aaSRadu Pirea (NXP OSS) 			return -EINVAL;
6757a71c8aaSRadu Pirea (NXP OSS) 		}
6767a71c8aaSRadu Pirea (NXP OSS) 
6777a71c8aaSRadu Pirea (NXP OSS) 		if (perout->phase.nsec == 0)
6786c0c85daSRadu Pirea (NXP OSS) 			nxp_c45_clear_reg_field(priv->phydev,
6796c0c85daSRadu Pirea (NXP OSS) 						&regmap->pps_polarity);
6807a71c8aaSRadu Pirea (NXP OSS) 		else
6816c0c85daSRadu Pirea (NXP OSS) 			nxp_c45_set_reg_field(priv->phydev,
6826c0c85daSRadu Pirea (NXP OSS) 					      &regmap->pps_polarity);
6837a71c8aaSRadu Pirea (NXP OSS) 	}
6847a71c8aaSRadu Pirea (NXP OSS) 
6857a71c8aaSRadu Pirea (NXP OSS) 	nxp_c45_gpio_config(priv, pin, GPIO_PPS_OUT_CFG);
6867a71c8aaSRadu Pirea (NXP OSS) 
6876c0c85daSRadu Pirea (NXP OSS) 	nxp_c45_set_reg_field(priv->phydev, &regmap->pps_enable);
6887a71c8aaSRadu Pirea (NXP OSS) 
6897a71c8aaSRadu Pirea (NXP OSS) 	return 0;
6907a71c8aaSRadu Pirea (NXP OSS) }
6917a71c8aaSRadu Pirea (NXP OSS) 
692*b0b2247dSRadu Pirea (NXP OSS) static void nxp_c45_set_rising_or_falling(struct phy_device *phydev,
693*b0b2247dSRadu Pirea (NXP OSS) 					  struct ptp_extts_request *extts)
694*b0b2247dSRadu Pirea (NXP OSS) {
695*b0b2247dSRadu Pirea (NXP OSS) 	if (extts->flags & PTP_RISING_EDGE)
696*b0b2247dSRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
697*b0b2247dSRadu Pirea (NXP OSS) 				   VEND1_PTP_CONFIG, EXT_TRG_EDGE);
698*b0b2247dSRadu Pirea (NXP OSS) 
699*b0b2247dSRadu Pirea (NXP OSS) 	if (extts->flags & PTP_FALLING_EDGE)
700*b0b2247dSRadu Pirea (NXP OSS) 		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
701*b0b2247dSRadu Pirea (NXP OSS) 				 VEND1_PTP_CONFIG, EXT_TRG_EDGE);
702*b0b2247dSRadu Pirea (NXP OSS) }
703*b0b2247dSRadu Pirea (NXP OSS) 
704*b0b2247dSRadu Pirea (NXP OSS) static void nxp_c45_set_rising_and_falling(struct phy_device *phydev,
705*b0b2247dSRadu Pirea (NXP OSS) 					   struct ptp_extts_request *extts)
706*b0b2247dSRadu Pirea (NXP OSS) {
707*b0b2247dSRadu Pirea (NXP OSS) 	/* PTP_EXTTS_REQUEST may have only the PTP_ENABLE_FEATURE flag set. In
708*b0b2247dSRadu Pirea (NXP OSS) 	 * this case external ts will be enabled on rising edge.
709*b0b2247dSRadu Pirea (NXP OSS) 	 */
710*b0b2247dSRadu Pirea (NXP OSS) 	if (extts->flags & PTP_RISING_EDGE ||
711*b0b2247dSRadu Pirea (NXP OSS) 	    extts->flags == PTP_ENABLE_FEATURE)
712*b0b2247dSRadu Pirea (NXP OSS) 		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
713*b0b2247dSRadu Pirea (NXP OSS) 				 TJA1120_SYNC_TRIG_FILTER,
714*b0b2247dSRadu Pirea (NXP OSS) 				 PTP_TRIG_RISE_TS);
715*b0b2247dSRadu Pirea (NXP OSS) 	else
716*b0b2247dSRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
717*b0b2247dSRadu Pirea (NXP OSS) 				   TJA1120_SYNC_TRIG_FILTER,
718*b0b2247dSRadu Pirea (NXP OSS) 				   PTP_TRIG_RISE_TS);
719*b0b2247dSRadu Pirea (NXP OSS) 
720*b0b2247dSRadu Pirea (NXP OSS) 	if (extts->flags & PTP_FALLING_EDGE)
721*b0b2247dSRadu Pirea (NXP OSS) 		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
722*b0b2247dSRadu Pirea (NXP OSS) 				 TJA1120_SYNC_TRIG_FILTER,
723*b0b2247dSRadu Pirea (NXP OSS) 				 PTP_TRIG_FALLING_TS);
724*b0b2247dSRadu Pirea (NXP OSS) 	else
725*b0b2247dSRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
726*b0b2247dSRadu Pirea (NXP OSS) 				   TJA1120_SYNC_TRIG_FILTER,
727*b0b2247dSRadu Pirea (NXP OSS) 				   PTP_TRIG_FALLING_TS);
728*b0b2247dSRadu Pirea (NXP OSS) }
729*b0b2247dSRadu Pirea (NXP OSS) 
7307a71c8aaSRadu Pirea (NXP OSS) static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
7317a71c8aaSRadu Pirea (NXP OSS) 				struct ptp_extts_request *extts, int on)
7327a71c8aaSRadu Pirea (NXP OSS) {
733*b0b2247dSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *data = nxp_c45_get_data(priv->phydev);
7347a71c8aaSRadu Pirea (NXP OSS) 	int pin;
7357a71c8aaSRadu Pirea (NXP OSS) 
7367a71c8aaSRadu Pirea (NXP OSS) 	if (extts->flags & ~(PTP_ENABLE_FEATURE |
7377a71c8aaSRadu Pirea (NXP OSS) 			      PTP_RISING_EDGE |
7387a71c8aaSRadu Pirea (NXP OSS) 			      PTP_FALLING_EDGE |
7397a71c8aaSRadu Pirea (NXP OSS) 			      PTP_STRICT_FLAGS))
7407a71c8aaSRadu Pirea (NXP OSS) 		return -EOPNOTSUPP;
7417a71c8aaSRadu Pirea (NXP OSS) 
7427a71c8aaSRadu Pirea (NXP OSS) 	/* Sampling on both edges is not supported */
7437a71c8aaSRadu Pirea (NXP OSS) 	if ((extts->flags & PTP_RISING_EDGE) &&
744*b0b2247dSRadu Pirea (NXP OSS) 	    (extts->flags & PTP_FALLING_EDGE) &&
745*b0b2247dSRadu Pirea (NXP OSS) 	    !data->ext_ts_both_edges)
7467a71c8aaSRadu Pirea (NXP OSS) 		return -EOPNOTSUPP;
7477a71c8aaSRadu Pirea (NXP OSS) 
7487a71c8aaSRadu Pirea (NXP OSS) 	pin = ptp_find_pin(priv->ptp_clock, PTP_PF_EXTTS, extts->index);
7497a71c8aaSRadu Pirea (NXP OSS) 	if (pin < 0)
7507a71c8aaSRadu Pirea (NXP OSS) 		return pin;
7517a71c8aaSRadu Pirea (NXP OSS) 
7527a71c8aaSRadu Pirea (NXP OSS) 	if (!on) {
7537a71c8aaSRadu Pirea (NXP OSS) 		nxp_c45_gpio_config(priv, pin, GPIO_DISABLE);
7547a71c8aaSRadu Pirea (NXP OSS) 		priv->extts = false;
7557a71c8aaSRadu Pirea (NXP OSS) 
7567a71c8aaSRadu Pirea (NXP OSS) 		return 0;
7577a71c8aaSRadu Pirea (NXP OSS) 	}
7587a71c8aaSRadu Pirea (NXP OSS) 
759*b0b2247dSRadu Pirea (NXP OSS) 	if (data->ext_ts_both_edges)
760*b0b2247dSRadu Pirea (NXP OSS) 		nxp_c45_set_rising_and_falling(priv->phydev, extts);
761*b0b2247dSRadu Pirea (NXP OSS) 	else
762*b0b2247dSRadu Pirea (NXP OSS) 		nxp_c45_set_rising_or_falling(priv->phydev, extts);
7637a71c8aaSRadu Pirea (NXP OSS) 
7647a71c8aaSRadu Pirea (NXP OSS) 	nxp_c45_gpio_config(priv, pin, GPIO_EXTTS_OUT_CFG);
7657a71c8aaSRadu Pirea (NXP OSS) 	priv->extts = true;
7667a71c8aaSRadu Pirea (NXP OSS) 	priv->extts_index = extts->index;
7677a71c8aaSRadu Pirea (NXP OSS) 	ptp_schedule_worker(priv->ptp_clock, 0);
7687a71c8aaSRadu Pirea (NXP OSS) 
7697a71c8aaSRadu Pirea (NXP OSS) 	return 0;
7707a71c8aaSRadu Pirea (NXP OSS) }
7717a71c8aaSRadu Pirea (NXP OSS) 
7727a71c8aaSRadu Pirea (NXP OSS) static int nxp_c45_ptp_enable(struct ptp_clock_info *ptp,
7737a71c8aaSRadu Pirea (NXP OSS) 			      struct ptp_clock_request *req, int on)
7747a71c8aaSRadu Pirea (NXP OSS) {
7757a71c8aaSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
7767a71c8aaSRadu Pirea (NXP OSS) 
7777a71c8aaSRadu Pirea (NXP OSS) 	switch (req->type) {
7787a71c8aaSRadu Pirea (NXP OSS) 	case PTP_CLK_REQ_EXTTS:
7797a71c8aaSRadu Pirea (NXP OSS) 		return nxp_c45_extts_enable(priv, &req->extts, on);
7807a71c8aaSRadu Pirea (NXP OSS) 	case PTP_CLK_REQ_PEROUT:
7817a71c8aaSRadu Pirea (NXP OSS) 		return nxp_c45_perout_enable(priv, &req->perout, on);
7827a71c8aaSRadu Pirea (NXP OSS) 	default:
7837a71c8aaSRadu Pirea (NXP OSS) 		return -EOPNOTSUPP;
7847a71c8aaSRadu Pirea (NXP OSS) 	}
7857a71c8aaSRadu Pirea (NXP OSS) }
7867a71c8aaSRadu Pirea (NXP OSS) 
7877a71c8aaSRadu Pirea (NXP OSS) static struct ptp_pin_desc nxp_c45_ptp_pins[] = {
7887a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio0", 0, PTP_PF_NONE},
7897a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio1", 1, PTP_PF_NONE},
7907a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio2", 2, PTP_PF_NONE},
7917a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio3", 3, PTP_PF_NONE},
7927a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio4", 4, PTP_PF_NONE},
7937a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio5", 5, PTP_PF_NONE},
7947a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio6", 6, PTP_PF_NONE},
7957a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio7", 7, PTP_PF_NONE},
7967a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio8", 8, PTP_PF_NONE},
7977a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio9", 9, PTP_PF_NONE},
7987a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio10", 10, PTP_PF_NONE},
7997a71c8aaSRadu Pirea (NXP OSS) 	{ "nxp_c45_gpio11", 11, PTP_PF_NONE},
8007a71c8aaSRadu Pirea (NXP OSS) };
8017a71c8aaSRadu Pirea (NXP OSS) 
8027a71c8aaSRadu Pirea (NXP OSS) static int nxp_c45_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin,
8037a71c8aaSRadu Pirea (NXP OSS) 				  enum ptp_pin_function func, unsigned int chan)
8047a71c8aaSRadu Pirea (NXP OSS) {
8057a71c8aaSRadu Pirea (NXP OSS) 	if (pin >= ARRAY_SIZE(nxp_c45_ptp_pins))
8067a71c8aaSRadu Pirea (NXP OSS) 		return -EINVAL;
8077a71c8aaSRadu Pirea (NXP OSS) 
8087a71c8aaSRadu Pirea (NXP OSS) 	switch (func) {
8097a71c8aaSRadu Pirea (NXP OSS) 	case PTP_PF_NONE:
8107a71c8aaSRadu Pirea (NXP OSS) 	case PTP_PF_PEROUT:
8117a71c8aaSRadu Pirea (NXP OSS) 	case PTP_PF_EXTTS:
8127a71c8aaSRadu Pirea (NXP OSS) 		break;
8137a71c8aaSRadu Pirea (NXP OSS) 	default:
8147a71c8aaSRadu Pirea (NXP OSS) 		return -EOPNOTSUPP;
8157a71c8aaSRadu Pirea (NXP OSS) 	}
8167a71c8aaSRadu Pirea (NXP OSS) 
8177a71c8aaSRadu Pirea (NXP OSS) 	return 0;
8187a71c8aaSRadu Pirea (NXP OSS) }
8197a71c8aaSRadu Pirea (NXP OSS) 
820514def5dSRadu Pirea (NXP OSS) static int nxp_c45_init_ptp_clock(struct nxp_c45_phy *priv)
821514def5dSRadu Pirea (NXP OSS) {
822514def5dSRadu Pirea (NXP OSS) 	priv->caps = (struct ptp_clock_info) {
823514def5dSRadu Pirea (NXP OSS) 		.owner		= THIS_MODULE,
824514def5dSRadu Pirea (NXP OSS) 		.name		= "NXP C45 PHC",
825514def5dSRadu Pirea (NXP OSS) 		.max_adj	= 16666666,
826514def5dSRadu Pirea (NXP OSS) 		.adjfine	= nxp_c45_ptp_adjfine,
827514def5dSRadu Pirea (NXP OSS) 		.adjtime	= nxp_c45_ptp_adjtime,
828514def5dSRadu Pirea (NXP OSS) 		.gettimex64	= nxp_c45_ptp_gettimex64,
829514def5dSRadu Pirea (NXP OSS) 		.settime64	= nxp_c45_ptp_settime64,
8307a71c8aaSRadu Pirea (NXP OSS) 		.enable		= nxp_c45_ptp_enable,
8317a71c8aaSRadu Pirea (NXP OSS) 		.verify		= nxp_c45_ptp_verify_pin,
832514def5dSRadu Pirea (NXP OSS) 		.do_aux_work	= nxp_c45_do_aux_work,
8337a71c8aaSRadu Pirea (NXP OSS) 		.pin_config	= nxp_c45_ptp_pins,
8347a71c8aaSRadu Pirea (NXP OSS) 		.n_pins		= ARRAY_SIZE(nxp_c45_ptp_pins),
8357a71c8aaSRadu Pirea (NXP OSS) 		.n_ext_ts	= 1,
8367a71c8aaSRadu Pirea (NXP OSS) 		.n_per_out	= 1,
837514def5dSRadu Pirea (NXP OSS) 	};
838514def5dSRadu Pirea (NXP OSS) 
839514def5dSRadu Pirea (NXP OSS) 	priv->ptp_clock = ptp_clock_register(&priv->caps,
840514def5dSRadu Pirea (NXP OSS) 					     &priv->phydev->mdio.dev);
841514def5dSRadu Pirea (NXP OSS) 
842514def5dSRadu Pirea (NXP OSS) 	if (IS_ERR(priv->ptp_clock))
843514def5dSRadu Pirea (NXP OSS) 		return PTR_ERR(priv->ptp_clock);
844514def5dSRadu Pirea (NXP OSS) 
845514def5dSRadu Pirea (NXP OSS) 	if (!priv->ptp_clock)
846514def5dSRadu Pirea (NXP OSS) 		return -ENOMEM;
847514def5dSRadu Pirea (NXP OSS) 
848514def5dSRadu Pirea (NXP OSS) 	return 0;
849514def5dSRadu Pirea (NXP OSS) }
850514def5dSRadu Pirea (NXP OSS) 
851514def5dSRadu Pirea (NXP OSS) static void nxp_c45_txtstamp(struct mii_timestamper *mii_ts,
852514def5dSRadu Pirea (NXP OSS) 			     struct sk_buff *skb, int type)
853514def5dSRadu Pirea (NXP OSS) {
854514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy,
855514def5dSRadu Pirea (NXP OSS) 						mii_ts);
856514def5dSRadu Pirea (NXP OSS) 
857514def5dSRadu Pirea (NXP OSS) 	switch (priv->hwts_tx) {
858514def5dSRadu Pirea (NXP OSS) 	case HWTSTAMP_TX_ON:
859514def5dSRadu Pirea (NXP OSS) 		NXP_C45_SKB_CB(skb)->type = type;
860514def5dSRadu Pirea (NXP OSS) 		NXP_C45_SKB_CB(skb)->header = ptp_parse_header(skb, type);
861514def5dSRadu Pirea (NXP OSS) 		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
862514def5dSRadu Pirea (NXP OSS) 		skb_queue_tail(&priv->tx_queue, skb);
863514def5dSRadu Pirea (NXP OSS) 		if (nxp_c45_poll_txts(priv->phydev))
864514def5dSRadu Pirea (NXP OSS) 			ptp_schedule_worker(priv->ptp_clock, 0);
865514def5dSRadu Pirea (NXP OSS) 		break;
866514def5dSRadu Pirea (NXP OSS) 	case HWTSTAMP_TX_OFF:
867514def5dSRadu Pirea (NXP OSS) 	default:
868514def5dSRadu Pirea (NXP OSS) 		kfree_skb(skb);
869514def5dSRadu Pirea (NXP OSS) 		break;
870514def5dSRadu Pirea (NXP OSS) 	}
871514def5dSRadu Pirea (NXP OSS) }
872514def5dSRadu Pirea (NXP OSS) 
873514def5dSRadu Pirea (NXP OSS) static bool nxp_c45_rxtstamp(struct mii_timestamper *mii_ts,
874514def5dSRadu Pirea (NXP OSS) 			     struct sk_buff *skb, int type)
875514def5dSRadu Pirea (NXP OSS) {
876514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy,
877514def5dSRadu Pirea (NXP OSS) 						mii_ts);
878514def5dSRadu Pirea (NXP OSS) 	struct ptp_header *header = ptp_parse_header(skb, type);
879514def5dSRadu Pirea (NXP OSS) 
880514def5dSRadu Pirea (NXP OSS) 	if (!header)
881514def5dSRadu Pirea (NXP OSS) 		return false;
882514def5dSRadu Pirea (NXP OSS) 
883514def5dSRadu Pirea (NXP OSS) 	if (!priv->hwts_rx)
884514def5dSRadu Pirea (NXP OSS) 		return false;
885514def5dSRadu Pirea (NXP OSS) 
886514def5dSRadu Pirea (NXP OSS) 	NXP_C45_SKB_CB(skb)->header = header;
887514def5dSRadu Pirea (NXP OSS) 	skb_queue_tail(&priv->rx_queue, skb);
888514def5dSRadu Pirea (NXP OSS) 	ptp_schedule_worker(priv->ptp_clock, 0);
889514def5dSRadu Pirea (NXP OSS) 
890514def5dSRadu Pirea (NXP OSS) 	return true;
891514def5dSRadu Pirea (NXP OSS) }
892514def5dSRadu Pirea (NXP OSS) 
893514def5dSRadu Pirea (NXP OSS) static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
894514def5dSRadu Pirea (NXP OSS) 			    struct ifreq *ifreq)
895514def5dSRadu Pirea (NXP OSS) {
896514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy,
897514def5dSRadu Pirea (NXP OSS) 						mii_ts);
898514def5dSRadu Pirea (NXP OSS) 	struct phy_device *phydev = priv->phydev;
8996c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *data;
900514def5dSRadu Pirea (NXP OSS) 	struct hwtstamp_config cfg;
901514def5dSRadu Pirea (NXP OSS) 
902514def5dSRadu Pirea (NXP OSS) 	if (copy_from_user(&cfg, ifreq->ifr_data, sizeof(cfg)))
903514def5dSRadu Pirea (NXP OSS) 		return -EFAULT;
904514def5dSRadu Pirea (NXP OSS) 
905514def5dSRadu Pirea (NXP OSS) 	if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ON)
906514def5dSRadu Pirea (NXP OSS) 		return -ERANGE;
907514def5dSRadu Pirea (NXP OSS) 
9086c0c85daSRadu Pirea (NXP OSS) 	data = nxp_c45_get_data(phydev);
909514def5dSRadu Pirea (NXP OSS) 	priv->hwts_tx = cfg.tx_type;
910514def5dSRadu Pirea (NXP OSS) 
911514def5dSRadu Pirea (NXP OSS) 	switch (cfg.rx_filter) {
912514def5dSRadu Pirea (NXP OSS) 	case HWTSTAMP_FILTER_NONE:
913514def5dSRadu Pirea (NXP OSS) 		priv->hwts_rx = 0;
914514def5dSRadu Pirea (NXP OSS) 		break;
915514def5dSRadu Pirea (NXP OSS) 	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
916514def5dSRadu Pirea (NXP OSS) 	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
917514def5dSRadu Pirea (NXP OSS) 	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
918514def5dSRadu Pirea (NXP OSS) 		priv->hwts_rx = 1;
919514def5dSRadu Pirea (NXP OSS) 		cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
920514def5dSRadu Pirea (NXP OSS) 		break;
921514def5dSRadu Pirea (NXP OSS) 	default:
922514def5dSRadu Pirea (NXP OSS) 		return -ERANGE;
923514def5dSRadu Pirea (NXP OSS) 	}
924514def5dSRadu Pirea (NXP OSS) 
925514def5dSRadu Pirea (NXP OSS) 	if (priv->hwts_rx || priv->hwts_tx) {
9266c0c85daSRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1,
9276c0c85daSRadu Pirea (NXP OSS) 			      data->regmap->vend1_event_msg_filt,
928514def5dSRadu Pirea (NXP OSS) 			      EVENT_MSG_FILT_ALL);
9296c0c85daSRadu Pirea (NXP OSS) 		data->ptp_enable(phydev, true);
930514def5dSRadu Pirea (NXP OSS) 	} else {
9316c0c85daSRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1,
9326c0c85daSRadu Pirea (NXP OSS) 			      data->regmap->vend1_event_msg_filt,
933514def5dSRadu Pirea (NXP OSS) 			      EVENT_MSG_FILT_NONE);
9346c0c85daSRadu Pirea (NXP OSS) 		data->ptp_enable(phydev, false);
935514def5dSRadu Pirea (NXP OSS) 	}
936514def5dSRadu Pirea (NXP OSS) 
937514def5dSRadu Pirea (NXP OSS) 	if (nxp_c45_poll_txts(priv->phydev))
938514def5dSRadu Pirea (NXP OSS) 		goto nxp_c45_no_ptp_irq;
939514def5dSRadu Pirea (NXP OSS) 
940514def5dSRadu Pirea (NXP OSS) 	if (priv->hwts_tx)
9416c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_set_reg_field(phydev, &data->regmap->irq_egr_ts_en);
942514def5dSRadu Pirea (NXP OSS) 	else
9436c0c85daSRadu Pirea (NXP OSS) 		nxp_c45_clear_reg_field(phydev, &data->regmap->irq_egr_ts_en);
944514def5dSRadu Pirea (NXP OSS) 
945514def5dSRadu Pirea (NXP OSS) nxp_c45_no_ptp_irq:
946514def5dSRadu Pirea (NXP OSS) 	return copy_to_user(ifreq->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
947514def5dSRadu Pirea (NXP OSS) }
948514def5dSRadu Pirea (NXP OSS) 
949514def5dSRadu Pirea (NXP OSS) static int nxp_c45_ts_info(struct mii_timestamper *mii_ts,
950514def5dSRadu Pirea (NXP OSS) 			   struct ethtool_ts_info *ts_info)
951514def5dSRadu Pirea (NXP OSS) {
952514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy,
953514def5dSRadu Pirea (NXP OSS) 						mii_ts);
954514def5dSRadu Pirea (NXP OSS) 
955514def5dSRadu Pirea (NXP OSS) 	ts_info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
956514def5dSRadu Pirea (NXP OSS) 			SOF_TIMESTAMPING_RX_HARDWARE |
957514def5dSRadu Pirea (NXP OSS) 			SOF_TIMESTAMPING_RAW_HARDWARE;
958514def5dSRadu Pirea (NXP OSS) 	ts_info->phc_index = ptp_clock_index(priv->ptp_clock);
959514def5dSRadu Pirea (NXP OSS) 	ts_info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
960514def5dSRadu Pirea (NXP OSS) 	ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
961514def5dSRadu Pirea (NXP OSS) 			(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
962514def5dSRadu Pirea (NXP OSS) 			(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
963514def5dSRadu Pirea (NXP OSS) 			(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT);
964514def5dSRadu Pirea (NXP OSS) 
965514def5dSRadu Pirea (NXP OSS) 	return 0;
966514def5dSRadu Pirea (NXP OSS) }
967514def5dSRadu Pirea (NXP OSS) 
9686c0c85daSRadu Pirea (NXP OSS) static const struct nxp_c45_phy_stats common_hw_stats[] = {
9696c0c85daSRadu Pirea (NXP OSS) 	{ "phy_link_status_drop_cnt",
9706c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8352, MDIO_MMD_VEND1, 8, 6), },
9716c0c85daSRadu Pirea (NXP OSS) 	{ "phy_link_availability_drop_cnt",
9726c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8352, MDIO_MMD_VEND1, 0, 6), },
9736c0c85daSRadu Pirea (NXP OSS) 	{ "phy_link_loss_cnt",
9746c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8353, MDIO_MMD_VEND1, 10, 6), },
9756c0c85daSRadu Pirea (NXP OSS) 	{ "phy_link_failure_cnt",
9766c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8353, MDIO_MMD_VEND1, 0, 10), },
9776c0c85daSRadu Pirea (NXP OSS) 	{ "phy_symbol_error_cnt",
9786c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8350, MDIO_MMD_VEND1, 0, 16) },
9796c0c85daSRadu Pirea (NXP OSS) };
9806c0c85daSRadu Pirea (NXP OSS) 
9816c0c85daSRadu Pirea (NXP OSS) static const struct nxp_c45_phy_stats tja1103_hw_stats[] = {
9826c0c85daSRadu Pirea (NXP OSS) 	{ "rx_preamble_count",
9836c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xAFCE, MDIO_MMD_VEND1, 0, 6), },
9846c0c85daSRadu Pirea (NXP OSS) 	{ "tx_preamble_count",
9856c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xAFCF, MDIO_MMD_VEND1, 0, 6), },
9866c0c85daSRadu Pirea (NXP OSS) 	{ "rx_ipg_length",
9876c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xAFD0, MDIO_MMD_VEND1, 0, 9), },
9886c0c85daSRadu Pirea (NXP OSS) 	{ "tx_ipg_length",
9896c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xAFD1, MDIO_MMD_VEND1, 0, 9), },
990b050f2f1SRadu Pirea (NXP OSS) };
991b050f2f1SRadu Pirea (NXP OSS) 
992f1fe5dffSRadu Pirea (NXP OSS) static const struct nxp_c45_phy_stats tja1120_hw_stats[] = {
993f1fe5dffSRadu Pirea (NXP OSS) 	{ "phy_symbol_error_cnt_ext",
994f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8351, MDIO_MMD_VEND1, 0, 14) },
995f1fe5dffSRadu Pirea (NXP OSS) 	{ "tx_frames_xtd",
996f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA1, MDIO_MMD_VEND1, 0, 8), },
997f1fe5dffSRadu Pirea (NXP OSS) 	{ "tx_frames",
998f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA0, MDIO_MMD_VEND1, 0, 16), },
999f1fe5dffSRadu Pirea (NXP OSS) 	{ "rx_frames_xtd",
1000f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA3, MDIO_MMD_VEND1, 0, 8), },
1001f1fe5dffSRadu Pirea (NXP OSS) 	{ "rx_frames",
1002f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA2, MDIO_MMD_VEND1, 0, 16), },
1003f1fe5dffSRadu Pirea (NXP OSS) 	{ "tx_lost_frames_xtd",
1004f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA5, MDIO_MMD_VEND1, 0, 8), },
1005f1fe5dffSRadu Pirea (NXP OSS) 	{ "tx_lost_frames",
1006f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA4, MDIO_MMD_VEND1, 0, 16), },
1007f1fe5dffSRadu Pirea (NXP OSS) 	{ "rx_lost_frames_xtd",
1008f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA7, MDIO_MMD_VEND1, 0, 8), },
1009f1fe5dffSRadu Pirea (NXP OSS) 	{ "rx_lost_frames",
1010f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0xACA6, MDIO_MMD_VEND1, 0, 16), },
1011f1fe5dffSRadu Pirea (NXP OSS) };
1012f1fe5dffSRadu Pirea (NXP OSS) 
1013b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_get_sset_count(struct phy_device *phydev)
1014b050f2f1SRadu Pirea (NXP OSS) {
10156c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
10166c0c85daSRadu Pirea (NXP OSS) 
10176c0c85daSRadu Pirea (NXP OSS) 	return ARRAY_SIZE(common_hw_stats) + (phy_data ? phy_data->n_stats : 0);
1018b050f2f1SRadu Pirea (NXP OSS) }
1019b050f2f1SRadu Pirea (NXP OSS) 
1020b050f2f1SRadu Pirea (NXP OSS) static void nxp_c45_get_strings(struct phy_device *phydev, u8 *data)
1021b050f2f1SRadu Pirea (NXP OSS) {
10226c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
10236c0c85daSRadu Pirea (NXP OSS) 	size_t count = nxp_c45_get_sset_count(phydev);
10246c0c85daSRadu Pirea (NXP OSS) 	size_t idx;
1025b050f2f1SRadu Pirea (NXP OSS) 	size_t i;
1026b050f2f1SRadu Pirea (NXP OSS) 
10276c0c85daSRadu Pirea (NXP OSS) 	for (i = 0; i < count; i++) {
10286c0c85daSRadu Pirea (NXP OSS) 		if (i < ARRAY_SIZE(common_hw_stats)) {
10296c0c85daSRadu Pirea (NXP OSS) 			strscpy(data + i * ETH_GSTRING_LEN,
10306c0c85daSRadu Pirea (NXP OSS) 				common_hw_stats[i].name, ETH_GSTRING_LEN);
10316c0c85daSRadu Pirea (NXP OSS) 			continue;
10326c0c85daSRadu Pirea (NXP OSS) 		}
10336c0c85daSRadu Pirea (NXP OSS) 		idx = i - ARRAY_SIZE(common_hw_stats);
10346c0c85daSRadu Pirea (NXP OSS) 		strscpy(data + i * ETH_GSTRING_LEN,
10356c0c85daSRadu Pirea (NXP OSS) 			phy_data->stats[idx].name, ETH_GSTRING_LEN);
1036b050f2f1SRadu Pirea (NXP OSS) 	}
1037b050f2f1SRadu Pirea (NXP OSS) }
1038b050f2f1SRadu Pirea (NXP OSS) 
1039b050f2f1SRadu Pirea (NXP OSS) static void nxp_c45_get_stats(struct phy_device *phydev,
1040b050f2f1SRadu Pirea (NXP OSS) 			      struct ethtool_stats *stats, u64 *data)
1041b050f2f1SRadu Pirea (NXP OSS) {
10426c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
10436c0c85daSRadu Pirea (NXP OSS) 	size_t count = nxp_c45_get_sset_count(phydev);
10446c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_reg_field *reg_field;
10456c0c85daSRadu Pirea (NXP OSS) 	size_t idx;
1046b050f2f1SRadu Pirea (NXP OSS) 	size_t i;
1047b050f2f1SRadu Pirea (NXP OSS) 	int ret;
1048b050f2f1SRadu Pirea (NXP OSS) 
10496c0c85daSRadu Pirea (NXP OSS) 	for (i = 0; i < count; i++) {
10506c0c85daSRadu Pirea (NXP OSS) 		if (i < ARRAY_SIZE(common_hw_stats)) {
10516c0c85daSRadu Pirea (NXP OSS) 			reg_field = &common_hw_stats[i].counter;
1052b050f2f1SRadu Pirea (NXP OSS) 		} else {
10536c0c85daSRadu Pirea (NXP OSS) 			idx = i - ARRAY_SIZE(common_hw_stats);
10546c0c85daSRadu Pirea (NXP OSS) 			reg_field = &phy_data->stats[idx].counter;
1055b050f2f1SRadu Pirea (NXP OSS) 		}
10566c0c85daSRadu Pirea (NXP OSS) 
10576c0c85daSRadu Pirea (NXP OSS) 		ret = nxp_c45_read_reg_field(phydev, reg_field);
10586c0c85daSRadu Pirea (NXP OSS) 		if (ret < 0)
10596c0c85daSRadu Pirea (NXP OSS) 			data[i] = U64_MAX;
10606c0c85daSRadu Pirea (NXP OSS) 		else
10616c0c85daSRadu Pirea (NXP OSS) 			data[i] = ret;
1062b050f2f1SRadu Pirea (NXP OSS) 	}
1063b050f2f1SRadu Pirea (NXP OSS) }
1064b050f2f1SRadu Pirea (NXP OSS) 
1065b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_config_enable(struct phy_device *phydev)
1066b050f2f1SRadu Pirea (NXP OSS) {
1067b050f2f1SRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_CONTROL,
1068b050f2f1SRadu Pirea (NXP OSS) 		      DEVICE_CONTROL_CONFIG_GLOBAL_EN |
1069b050f2f1SRadu Pirea (NXP OSS) 		      DEVICE_CONTROL_CONFIG_ALL_EN);
1070b050f2f1SRadu Pirea (NXP OSS) 	usleep_range(400, 450);
1071b050f2f1SRadu Pirea (NXP OSS) 
1072b050f2f1SRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_CONTROL,
1073b050f2f1SRadu Pirea (NXP OSS) 		      PORT_CONTROL_EN);
1074b050f2f1SRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_CONTROL,
1075b050f2f1SRadu Pirea (NXP OSS) 		      PHY_CONFIG_EN);
1076b050f2f1SRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_INFRA_CONTROL,
1077b050f2f1SRadu Pirea (NXP OSS) 		      PORT_INFRA_CONTROL_EN);
1078b050f2f1SRadu Pirea (NXP OSS) 
1079b050f2f1SRadu Pirea (NXP OSS) 	return 0;
1080b050f2f1SRadu Pirea (NXP OSS) }
1081b050f2f1SRadu Pirea (NXP OSS) 
1082b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_start_op(struct phy_device *phydev)
1083b050f2f1SRadu Pirea (NXP OSS) {
1084b050f2f1SRadu Pirea (NXP OSS) 	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_CONTROL,
1085b050f2f1SRadu Pirea (NXP OSS) 				PHY_START_OP);
1086b050f2f1SRadu Pirea (NXP OSS) }
1087b050f2f1SRadu Pirea (NXP OSS) 
1088b2f0ca00SRadu Pirea (NXP OSS) static int nxp_c45_config_intr(struct phy_device *phydev)
1089b2f0ca00SRadu Pirea (NXP OSS) {
1090b2f0ca00SRadu Pirea (NXP OSS) 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
1091b2f0ca00SRadu Pirea (NXP OSS) 		return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
1092b2f0ca00SRadu Pirea (NXP OSS) 					VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
1093b2f0ca00SRadu Pirea (NXP OSS) 	else
1094b2f0ca00SRadu Pirea (NXP OSS) 		return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
1095b2f0ca00SRadu Pirea (NXP OSS) 					  VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
1096b2f0ca00SRadu Pirea (NXP OSS) }
1097b2f0ca00SRadu Pirea (NXP OSS) 
1098b2f0ca00SRadu Pirea (NXP OSS) static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
1099b2f0ca00SRadu Pirea (NXP OSS) {
11006c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *data = nxp_c45_get_data(phydev);
1101514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1102b2f0ca00SRadu Pirea (NXP OSS) 	irqreturn_t ret = IRQ_NONE;
1103514def5dSRadu Pirea (NXP OSS) 	struct nxp_c45_hwts hwts;
1104b2f0ca00SRadu Pirea (NXP OSS) 	int irq;
1105b2f0ca00SRadu Pirea (NXP OSS) 
1106b2f0ca00SRadu Pirea (NXP OSS) 	irq = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_IRQ_STATUS);
1107b2f0ca00SRadu Pirea (NXP OSS) 	if (irq & PHY_IRQ_LINK_EVENT) {
1108b2f0ca00SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_IRQ_ACK,
1109b2f0ca00SRadu Pirea (NXP OSS) 			      PHY_IRQ_LINK_EVENT);
1110b2f0ca00SRadu Pirea (NXP OSS) 		phy_trigger_machine(phydev);
1111b2f0ca00SRadu Pirea (NXP OSS) 		ret = IRQ_HANDLED;
1112b2f0ca00SRadu Pirea (NXP OSS) 	}
1113b2f0ca00SRadu Pirea (NXP OSS) 
1114514def5dSRadu Pirea (NXP OSS) 	/* There is no need for ACK.
1115514def5dSRadu Pirea (NXP OSS) 	 * The irq signal will be asserted until the EGR TS FIFO will be
1116514def5dSRadu Pirea (NXP OSS) 	 * emptied.
1117514def5dSRadu Pirea (NXP OSS) 	 */
11186c0c85daSRadu Pirea (NXP OSS) 	irq = nxp_c45_read_reg_field(phydev, &data->regmap->irq_egr_ts_status);
11196c0c85daSRadu Pirea (NXP OSS) 	if (irq) {
1120514def5dSRadu Pirea (NXP OSS) 		while (nxp_c45_get_hwtxts(priv, &hwts))
1121514def5dSRadu Pirea (NXP OSS) 			nxp_c45_process_txts(priv, &hwts);
1122514def5dSRadu Pirea (NXP OSS) 
1123514def5dSRadu Pirea (NXP OSS) 		ret = IRQ_HANDLED;
1124514def5dSRadu Pirea (NXP OSS) 	}
1125514def5dSRadu Pirea (NXP OSS) 
1126b2f0ca00SRadu Pirea (NXP OSS) 	return ret;
1127b2f0ca00SRadu Pirea (NXP OSS) }
1128b2f0ca00SRadu Pirea (NXP OSS) 
1129b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_soft_reset(struct phy_device *phydev)
1130b050f2f1SRadu Pirea (NXP OSS) {
1131b050f2f1SRadu Pirea (NXP OSS) 	int ret;
1132b050f2f1SRadu Pirea (NXP OSS) 
1133b050f2f1SRadu Pirea (NXP OSS) 	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_CONTROL,
1134b050f2f1SRadu Pirea (NXP OSS) 			    DEVICE_CONTROL_RESET);
1135b050f2f1SRadu Pirea (NXP OSS) 	if (ret)
1136b050f2f1SRadu Pirea (NXP OSS) 		return ret;
1137b050f2f1SRadu Pirea (NXP OSS) 
1138b050f2f1SRadu Pirea (NXP OSS) 	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
1139b050f2f1SRadu Pirea (NXP OSS) 					 VEND1_DEVICE_CONTROL, ret,
1140b050f2f1SRadu Pirea (NXP OSS) 					 !(ret & DEVICE_CONTROL_RESET), 20000,
1141b050f2f1SRadu Pirea (NXP OSS) 					 240000, false);
1142b050f2f1SRadu Pirea (NXP OSS) }
1143b050f2f1SRadu Pirea (NXP OSS) 
1144b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_cable_test_start(struct phy_device *phydev)
1145b050f2f1SRadu Pirea (NXP OSS) {
11466c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(phydev);
11476c0c85daSRadu Pirea (NXP OSS) 
11486c0c85daSRadu Pirea (NXP OSS) 	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, regmap->cable_test,
1149b050f2f1SRadu Pirea (NXP OSS) 				CABLE_TEST_ENABLE | CABLE_TEST_START);
1150b050f2f1SRadu Pirea (NXP OSS) }
1151b050f2f1SRadu Pirea (NXP OSS) 
1152b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_cable_test_get_status(struct phy_device *phydev,
1153b050f2f1SRadu Pirea (NXP OSS) 					 bool *finished)
1154b050f2f1SRadu Pirea (NXP OSS) {
11556c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(phydev);
1156b050f2f1SRadu Pirea (NXP OSS) 	int ret;
1157b050f2f1SRadu Pirea (NXP OSS) 	u8 cable_test_result;
1158b050f2f1SRadu Pirea (NXP OSS) 
11596c0c85daSRadu Pirea (NXP OSS) 	ret = nxp_c45_read_reg_field(phydev, &regmap->cable_test_valid);
11606c0c85daSRadu Pirea (NXP OSS) 	if (!ret) {
1161b050f2f1SRadu Pirea (NXP OSS) 		*finished = false;
1162b050f2f1SRadu Pirea (NXP OSS) 		return 0;
1163b050f2f1SRadu Pirea (NXP OSS) 	}
1164b050f2f1SRadu Pirea (NXP OSS) 
1165b050f2f1SRadu Pirea (NXP OSS) 	*finished = true;
11666c0c85daSRadu Pirea (NXP OSS) 	cable_test_result = nxp_c45_read_reg_field(phydev,
11676c0c85daSRadu Pirea (NXP OSS) 						   &regmap->cable_test_result);
1168b050f2f1SRadu Pirea (NXP OSS) 
1169b050f2f1SRadu Pirea (NXP OSS) 	switch (cable_test_result) {
1170b050f2f1SRadu Pirea (NXP OSS) 	case CABLE_TEST_OK:
1171b050f2f1SRadu Pirea (NXP OSS) 		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
1172b050f2f1SRadu Pirea (NXP OSS) 					ETHTOOL_A_CABLE_RESULT_CODE_OK);
1173b050f2f1SRadu Pirea (NXP OSS) 		break;
1174b050f2f1SRadu Pirea (NXP OSS) 	case CABLE_TEST_SHORTED:
1175b050f2f1SRadu Pirea (NXP OSS) 		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
1176b050f2f1SRadu Pirea (NXP OSS) 					ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT);
1177b050f2f1SRadu Pirea (NXP OSS) 		break;
1178b050f2f1SRadu Pirea (NXP OSS) 	case CABLE_TEST_OPEN:
1179b050f2f1SRadu Pirea (NXP OSS) 		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
1180b050f2f1SRadu Pirea (NXP OSS) 					ETHTOOL_A_CABLE_RESULT_CODE_OPEN);
1181b050f2f1SRadu Pirea (NXP OSS) 		break;
1182b050f2f1SRadu Pirea (NXP OSS) 	default:
1183b050f2f1SRadu Pirea (NXP OSS) 		ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
1184b050f2f1SRadu Pirea (NXP OSS) 					ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC);
1185b050f2f1SRadu Pirea (NXP OSS) 	}
1186b050f2f1SRadu Pirea (NXP OSS) 
11876c0c85daSRadu Pirea (NXP OSS) 	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, regmap->cable_test,
1188b050f2f1SRadu Pirea (NXP OSS) 			   CABLE_TEST_ENABLE);
1189b050f2f1SRadu Pirea (NXP OSS) 
1190b050f2f1SRadu Pirea (NXP OSS) 	return nxp_c45_start_op(phydev);
1191b050f2f1SRadu Pirea (NXP OSS) }
1192b050f2f1SRadu Pirea (NXP OSS) 
1193b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_get_sqi(struct phy_device *phydev)
1194b050f2f1SRadu Pirea (NXP OSS) {
1195b050f2f1SRadu Pirea (NXP OSS) 	int reg;
1196b050f2f1SRadu Pirea (NXP OSS) 
1197b050f2f1SRadu Pirea (NXP OSS) 	reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_SIGNAL_QUALITY);
1198b050f2f1SRadu Pirea (NXP OSS) 	if (!(reg & SQI_VALID))
1199b050f2f1SRadu Pirea (NXP OSS) 		return -EINVAL;
1200b050f2f1SRadu Pirea (NXP OSS) 
1201b050f2f1SRadu Pirea (NXP OSS) 	reg &= SQI_MASK;
1202b050f2f1SRadu Pirea (NXP OSS) 
1203b050f2f1SRadu Pirea (NXP OSS) 	return reg;
1204b050f2f1SRadu Pirea (NXP OSS) }
1205b050f2f1SRadu Pirea (NXP OSS) 
1206b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_get_sqi_max(struct phy_device *phydev)
1207b050f2f1SRadu Pirea (NXP OSS) {
1208b050f2f1SRadu Pirea (NXP OSS) 	return MAX_SQI;
1209b050f2f1SRadu Pirea (NXP OSS) }
1210b050f2f1SRadu Pirea (NXP OSS) 
1211b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_check_delay(struct phy_device *phydev, u32 delay)
1212b050f2f1SRadu Pirea (NXP OSS) {
1213b050f2f1SRadu Pirea (NXP OSS) 	if (delay < MIN_ID_PS) {
1214b050f2f1SRadu Pirea (NXP OSS) 		phydev_err(phydev, "delay value smaller than %u\n", MIN_ID_PS);
1215b050f2f1SRadu Pirea (NXP OSS) 		return -EINVAL;
1216b050f2f1SRadu Pirea (NXP OSS) 	}
1217b050f2f1SRadu Pirea (NXP OSS) 
1218b050f2f1SRadu Pirea (NXP OSS) 	if (delay > MAX_ID_PS) {
1219b050f2f1SRadu Pirea (NXP OSS) 		phydev_err(phydev, "delay value higher than %u\n", MAX_ID_PS);
1220b050f2f1SRadu Pirea (NXP OSS) 		return -EINVAL;
1221b050f2f1SRadu Pirea (NXP OSS) 	}
1222b050f2f1SRadu Pirea (NXP OSS) 
1223b050f2f1SRadu Pirea (NXP OSS) 	return 0;
1224b050f2f1SRadu Pirea (NXP OSS) }
1225b050f2f1SRadu Pirea (NXP OSS) 
12266c0c85daSRadu Pirea (NXP OSS) static void nxp_c45_counters_enable(struct phy_device *phydev)
12276c0c85daSRadu Pirea (NXP OSS) {
12286c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *data = nxp_c45_get_data(phydev);
12296c0c85daSRadu Pirea (NXP OSS) 
12306c0c85daSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_LINK_DROP_COUNTER,
12316c0c85daSRadu Pirea (NXP OSS) 			 COUNTER_EN);
12326c0c85daSRadu Pirea (NXP OSS) 
12336c0c85daSRadu Pirea (NXP OSS) 	data->counters_enable(phydev);
12346c0c85daSRadu Pirea (NXP OSS) }
12356c0c85daSRadu Pirea (NXP OSS) 
12366c0c85daSRadu Pirea (NXP OSS) static void nxp_c45_ptp_init(struct phy_device *phydev)
12376c0c85daSRadu Pirea (NXP OSS) {
12386c0c85daSRadu Pirea (NXP OSS) 	const struct nxp_c45_phy_data *data = nxp_c45_get_data(phydev);
12396c0c85daSRadu Pirea (NXP OSS) 
12406c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1,
12416c0c85daSRadu Pirea (NXP OSS) 		      data->regmap->vend1_ptp_clk_period,
12426c0c85daSRadu Pirea (NXP OSS) 		      data->ptp_clk_period);
12436c0c85daSRadu Pirea (NXP OSS) 	nxp_c45_clear_reg_field(phydev, &data->regmap->ltc_lock_ctrl);
12446c0c85daSRadu Pirea (NXP OSS) 
12456c0c85daSRadu Pirea (NXP OSS) 	data->ptp_init(phydev);
12466c0c85daSRadu Pirea (NXP OSS) }
12476c0c85daSRadu Pirea (NXP OSS) 
1248b050f2f1SRadu Pirea (NXP OSS) static u64 nxp_c45_get_phase_shift(u64 phase_offset_raw)
1249b050f2f1SRadu Pirea (NXP OSS) {
1250b050f2f1SRadu Pirea (NXP OSS) 	/* The delay in degree phase is 73.8 + phase_offset_raw * 0.9.
1251b050f2f1SRadu Pirea (NXP OSS) 	 * To avoid floating point operations we'll multiply by 10
1252b050f2f1SRadu Pirea (NXP OSS) 	 * and get 1 decimal point precision.
1253b050f2f1SRadu Pirea (NXP OSS) 	 */
1254b050f2f1SRadu Pirea (NXP OSS) 	phase_offset_raw *= 10;
12556b3a6310SRadu Pirea (NXP OSS) 	phase_offset_raw -= 738;
1256b050f2f1SRadu Pirea (NXP OSS) 	return div_u64(phase_offset_raw, 9);
1257b050f2f1SRadu Pirea (NXP OSS) }
1258b050f2f1SRadu Pirea (NXP OSS) 
1259b050f2f1SRadu Pirea (NXP OSS) static void nxp_c45_disable_delays(struct phy_device *phydev)
1260b050f2f1SRadu Pirea (NXP OSS) {
1261b050f2f1SRadu Pirea (NXP OSS) 	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TXID, ID_ENABLE);
1262b050f2f1SRadu Pirea (NXP OSS) 	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RXID, ID_ENABLE);
1263b050f2f1SRadu Pirea (NXP OSS) }
1264b050f2f1SRadu Pirea (NXP OSS) 
1265b050f2f1SRadu Pirea (NXP OSS) static void nxp_c45_set_delays(struct phy_device *phydev)
1266b050f2f1SRadu Pirea (NXP OSS) {
1267b050f2f1SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1268b050f2f1SRadu Pirea (NXP OSS) 	u64 tx_delay = priv->tx_delay;
1269b050f2f1SRadu Pirea (NXP OSS) 	u64 rx_delay = priv->rx_delay;
1270b050f2f1SRadu Pirea (NXP OSS) 	u64 degree;
1271b050f2f1SRadu Pirea (NXP OSS) 
1272b050f2f1SRadu Pirea (NXP OSS) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
1273b050f2f1SRadu Pirea (NXP OSS) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
1274b050f2f1SRadu Pirea (NXP OSS) 		degree = div_u64(tx_delay, PS_PER_DEGREE);
1275b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_TXID,
1276b050f2f1SRadu Pirea (NXP OSS) 			      ID_ENABLE | nxp_c45_get_phase_shift(degree));
1277b050f2f1SRadu Pirea (NXP OSS) 	} else {
1278b050f2f1SRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TXID,
1279b050f2f1SRadu Pirea (NXP OSS) 				   ID_ENABLE);
1280b050f2f1SRadu Pirea (NXP OSS) 	}
1281b050f2f1SRadu Pirea (NXP OSS) 
1282b050f2f1SRadu Pirea (NXP OSS) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
1283b050f2f1SRadu Pirea (NXP OSS) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
1284b050f2f1SRadu Pirea (NXP OSS) 		degree = div_u64(rx_delay, PS_PER_DEGREE);
1285b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_RXID,
1286b050f2f1SRadu Pirea (NXP OSS) 			      ID_ENABLE | nxp_c45_get_phase_shift(degree));
1287b050f2f1SRadu Pirea (NXP OSS) 	} else {
1288b050f2f1SRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RXID,
1289b050f2f1SRadu Pirea (NXP OSS) 				   ID_ENABLE);
1290b050f2f1SRadu Pirea (NXP OSS) 	}
1291b050f2f1SRadu Pirea (NXP OSS) }
1292b050f2f1SRadu Pirea (NXP OSS) 
1293b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_get_delays(struct phy_device *phydev)
1294b050f2f1SRadu Pirea (NXP OSS) {
1295b050f2f1SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1296b050f2f1SRadu Pirea (NXP OSS) 	int ret;
1297b050f2f1SRadu Pirea (NXP OSS) 
1298b050f2f1SRadu Pirea (NXP OSS) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
1299b050f2f1SRadu Pirea (NXP OSS) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
1300b050f2f1SRadu Pirea (NXP OSS) 		ret = device_property_read_u32(&phydev->mdio.dev,
1301b050f2f1SRadu Pirea (NXP OSS) 					       "tx-internal-delay-ps",
1302b050f2f1SRadu Pirea (NXP OSS) 					       &priv->tx_delay);
1303b050f2f1SRadu Pirea (NXP OSS) 		if (ret)
1304b050f2f1SRadu Pirea (NXP OSS) 			priv->tx_delay = DEFAULT_ID_PS;
1305b050f2f1SRadu Pirea (NXP OSS) 
1306b050f2f1SRadu Pirea (NXP OSS) 		ret = nxp_c45_check_delay(phydev, priv->tx_delay);
1307b050f2f1SRadu Pirea (NXP OSS) 		if (ret) {
1308b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev,
1309b050f2f1SRadu Pirea (NXP OSS) 				   "tx-internal-delay-ps invalid value\n");
1310b050f2f1SRadu Pirea (NXP OSS) 			return ret;
1311b050f2f1SRadu Pirea (NXP OSS) 		}
1312b050f2f1SRadu Pirea (NXP OSS) 	}
1313b050f2f1SRadu Pirea (NXP OSS) 
1314b050f2f1SRadu Pirea (NXP OSS) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
1315b050f2f1SRadu Pirea (NXP OSS) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
1316b050f2f1SRadu Pirea (NXP OSS) 		ret = device_property_read_u32(&phydev->mdio.dev,
1317b050f2f1SRadu Pirea (NXP OSS) 					       "rx-internal-delay-ps",
1318b050f2f1SRadu Pirea (NXP OSS) 					       &priv->rx_delay);
1319b050f2f1SRadu Pirea (NXP OSS) 		if (ret)
1320b050f2f1SRadu Pirea (NXP OSS) 			priv->rx_delay = DEFAULT_ID_PS;
1321b050f2f1SRadu Pirea (NXP OSS) 
1322b050f2f1SRadu Pirea (NXP OSS) 		ret = nxp_c45_check_delay(phydev, priv->rx_delay);
1323b050f2f1SRadu Pirea (NXP OSS) 		if (ret) {
1324b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev,
1325b050f2f1SRadu Pirea (NXP OSS) 				   "rx-internal-delay-ps invalid value\n");
1326b050f2f1SRadu Pirea (NXP OSS) 			return ret;
1327b050f2f1SRadu Pirea (NXP OSS) 		}
1328b050f2f1SRadu Pirea (NXP OSS) 	}
1329b050f2f1SRadu Pirea (NXP OSS) 
1330b050f2f1SRadu Pirea (NXP OSS) 	return 0;
1331b050f2f1SRadu Pirea (NXP OSS) }
1332b050f2f1SRadu Pirea (NXP OSS) 
1333b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_set_phy_mode(struct phy_device *phydev)
1334b050f2f1SRadu Pirea (NXP OSS) {
1335b050f2f1SRadu Pirea (NXP OSS) 	int ret;
1336b050f2f1SRadu Pirea (NXP OSS) 
1337b050f2f1SRadu Pirea (NXP OSS) 	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_ABILITIES);
1338b050f2f1SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "Clause 45 managed PHY abilities 0x%x\n", ret);
1339b050f2f1SRadu Pirea (NXP OSS) 
1340b050f2f1SRadu Pirea (NXP OSS) 	switch (phydev->interface) {
1341b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_RGMII:
1342b050f2f1SRadu Pirea (NXP OSS) 		if (!(ret & RGMII_ABILITY)) {
1343b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev, "rgmii mode not supported\n");
1344b050f2f1SRadu Pirea (NXP OSS) 			return -EINVAL;
1345b050f2f1SRadu Pirea (NXP OSS) 		}
1346b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
1347b050f2f1SRadu Pirea (NXP OSS) 			      MII_BASIC_CONFIG_RGMII);
1348b050f2f1SRadu Pirea (NXP OSS) 		nxp_c45_disable_delays(phydev);
1349b050f2f1SRadu Pirea (NXP OSS) 		break;
1350b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_RGMII_ID:
1351b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_RGMII_TXID:
1352b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_RGMII_RXID:
1353b050f2f1SRadu Pirea (NXP OSS) 		if (!(ret & RGMII_ID_ABILITY)) {
1354b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev, "rgmii-id, rgmii-txid, rgmii-rxid modes are not supported\n");
1355b050f2f1SRadu Pirea (NXP OSS) 			return -EINVAL;
1356b050f2f1SRadu Pirea (NXP OSS) 		}
1357b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
1358b050f2f1SRadu Pirea (NXP OSS) 			      MII_BASIC_CONFIG_RGMII);
1359b050f2f1SRadu Pirea (NXP OSS) 		ret = nxp_c45_get_delays(phydev);
1360b050f2f1SRadu Pirea (NXP OSS) 		if (ret)
1361b050f2f1SRadu Pirea (NXP OSS) 			return ret;
1362b050f2f1SRadu Pirea (NXP OSS) 
1363b050f2f1SRadu Pirea (NXP OSS) 		nxp_c45_set_delays(phydev);
1364b050f2f1SRadu Pirea (NXP OSS) 		break;
1365b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_MII:
1366b050f2f1SRadu Pirea (NXP OSS) 		if (!(ret & MII_ABILITY)) {
1367b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev, "mii mode not supported\n");
1368b050f2f1SRadu Pirea (NXP OSS) 			return -EINVAL;
1369b050f2f1SRadu Pirea (NXP OSS) 		}
1370b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
1371b050f2f1SRadu Pirea (NXP OSS) 			      MII_BASIC_CONFIG_MII);
1372b050f2f1SRadu Pirea (NXP OSS) 		break;
1373b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_REVMII:
1374b050f2f1SRadu Pirea (NXP OSS) 		if (!(ret & REVMII_ABILITY)) {
1375b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev, "rev-mii mode not supported\n");
1376b050f2f1SRadu Pirea (NXP OSS) 			return -EINVAL;
1377b050f2f1SRadu Pirea (NXP OSS) 		}
1378b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
1379b050f2f1SRadu Pirea (NXP OSS) 			      MII_BASIC_CONFIG_MII | MII_BASIC_CONFIG_REV);
1380b050f2f1SRadu Pirea (NXP OSS) 		break;
1381b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_RMII:
1382b050f2f1SRadu Pirea (NXP OSS) 		if (!(ret & RMII_ABILITY)) {
1383b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev, "rmii mode not supported\n");
1384b050f2f1SRadu Pirea (NXP OSS) 			return -EINVAL;
1385b050f2f1SRadu Pirea (NXP OSS) 		}
1386b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
1387b050f2f1SRadu Pirea (NXP OSS) 			      MII_BASIC_CONFIG_RMII);
1388b050f2f1SRadu Pirea (NXP OSS) 		break;
1389b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_SGMII:
1390b050f2f1SRadu Pirea (NXP OSS) 		if (!(ret & SGMII_ABILITY)) {
1391b050f2f1SRadu Pirea (NXP OSS) 			phydev_err(phydev, "sgmii mode not supported\n");
1392b050f2f1SRadu Pirea (NXP OSS) 			return -EINVAL;
1393b050f2f1SRadu Pirea (NXP OSS) 		}
1394b050f2f1SRadu Pirea (NXP OSS) 		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_MII_BASIC_CONFIG,
1395b050f2f1SRadu Pirea (NXP OSS) 			      MII_BASIC_CONFIG_SGMII);
1396b050f2f1SRadu Pirea (NXP OSS) 		break;
1397b050f2f1SRadu Pirea (NXP OSS) 	case PHY_INTERFACE_MODE_INTERNAL:
1398b050f2f1SRadu Pirea (NXP OSS) 		break;
1399b050f2f1SRadu Pirea (NXP OSS) 	default:
1400b050f2f1SRadu Pirea (NXP OSS) 		return -EINVAL;
1401b050f2f1SRadu Pirea (NXP OSS) 	}
1402b050f2f1SRadu Pirea (NXP OSS) 
1403b050f2f1SRadu Pirea (NXP OSS) 	return 0;
1404b050f2f1SRadu Pirea (NXP OSS) }
1405b050f2f1SRadu Pirea (NXP OSS) 
1406b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_config_init(struct phy_device *phydev)
1407b050f2f1SRadu Pirea (NXP OSS) {
1408b050f2f1SRadu Pirea (NXP OSS) 	int ret;
1409b050f2f1SRadu Pirea (NXP OSS) 
1410b050f2f1SRadu Pirea (NXP OSS) 	ret = nxp_c45_config_enable(phydev);
1411b050f2f1SRadu Pirea (NXP OSS) 	if (ret) {
1412b050f2f1SRadu Pirea (NXP OSS) 		phydev_err(phydev, "Failed to enable config\n");
1413b050f2f1SRadu Pirea (NXP OSS) 		return ret;
1414b050f2f1SRadu Pirea (NXP OSS) 	}
1415b050f2f1SRadu Pirea (NXP OSS) 
14160b5f0f29SVladimir Oltean 	/* Bug workaround for SJA1110 rev B: enable write access
14170b5f0f29SVladimir Oltean 	 * to MDIO_MMD_PMAPMD
14180b5f0f29SVladimir Oltean 	 */
14190b5f0f29SVladimir Oltean 	phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F8, 1);
14200b5f0f29SVladimir Oltean 	phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F9, 2);
14210b5f0f29SVladimir Oltean 
1422b050f2f1SRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_CONFIG,
1423b050f2f1SRadu Pirea (NXP OSS) 			 PHY_CONFIG_AUTO);
1424b050f2f1SRadu Pirea (NXP OSS) 
1425b050f2f1SRadu Pirea (NXP OSS) 	ret = nxp_c45_set_phy_mode(phydev);
1426b050f2f1SRadu Pirea (NXP OSS) 	if (ret)
1427b050f2f1SRadu Pirea (NXP OSS) 		return ret;
1428b050f2f1SRadu Pirea (NXP OSS) 
1429b050f2f1SRadu Pirea (NXP OSS) 	phydev->autoneg = AUTONEG_DISABLE;
1430b050f2f1SRadu Pirea (NXP OSS) 
14316c0c85daSRadu Pirea (NXP OSS) 	nxp_c45_counters_enable(phydev);
14326c0c85daSRadu Pirea (NXP OSS) 	nxp_c45_ptp_init(phydev);
1433514def5dSRadu Pirea (NXP OSS) 
1434b050f2f1SRadu Pirea (NXP OSS) 	return nxp_c45_start_op(phydev);
1435b050f2f1SRadu Pirea (NXP OSS) }
1436b050f2f1SRadu Pirea (NXP OSS) 
1437369da333SRadu Pirea (NXP OSS) static int nxp_c45_get_features(struct phy_device *phydev)
1438369da333SRadu Pirea (NXP OSS) {
1439369da333SRadu Pirea (NXP OSS) 	linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, phydev->supported);
1440369da333SRadu Pirea (NXP OSS) 	linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, phydev->supported);
1441369da333SRadu Pirea (NXP OSS) 
1442369da333SRadu Pirea (NXP OSS) 	return genphy_c45_pma_read_abilities(phydev);
1443369da333SRadu Pirea (NXP OSS) }
1444369da333SRadu Pirea (NXP OSS) 
1445b050f2f1SRadu Pirea (NXP OSS) static int nxp_c45_probe(struct phy_device *phydev)
1446b050f2f1SRadu Pirea (NXP OSS) {
1447b050f2f1SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv;
1448514def5dSRadu Pirea (NXP OSS) 	int ptp_ability;
1449514def5dSRadu Pirea (NXP OSS) 	int ret = 0;
1450b050f2f1SRadu Pirea (NXP OSS) 
1451b050f2f1SRadu Pirea (NXP OSS) 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
1452b050f2f1SRadu Pirea (NXP OSS) 	if (!priv)
1453b050f2f1SRadu Pirea (NXP OSS) 		return -ENOMEM;
1454b050f2f1SRadu Pirea (NXP OSS) 
1455514def5dSRadu Pirea (NXP OSS) 	skb_queue_head_init(&priv->tx_queue);
1456514def5dSRadu Pirea (NXP OSS) 	skb_queue_head_init(&priv->rx_queue);
1457514def5dSRadu Pirea (NXP OSS) 
1458514def5dSRadu Pirea (NXP OSS) 	priv->phydev = phydev;
1459514def5dSRadu Pirea (NXP OSS) 
1460b050f2f1SRadu Pirea (NXP OSS) 	phydev->priv = priv;
1461b050f2f1SRadu Pirea (NXP OSS) 
1462514def5dSRadu Pirea (NXP OSS) 	mutex_init(&priv->ptp_lock);
1463514def5dSRadu Pirea (NXP OSS) 
1464514def5dSRadu Pirea (NXP OSS) 	ptp_ability = phy_read_mmd(phydev, MDIO_MMD_VEND1,
1465514def5dSRadu Pirea (NXP OSS) 				   VEND1_PORT_ABILITIES);
1466514def5dSRadu Pirea (NXP OSS) 	ptp_ability = !!(ptp_ability & PTP_ABILITY);
1467514def5dSRadu Pirea (NXP OSS) 	if (!ptp_ability) {
1468565c6d8cSVladimir Oltean 		phydev_dbg(phydev, "the phy does not support PTP");
1469514def5dSRadu Pirea (NXP OSS) 		goto no_ptp_support;
1470514def5dSRadu Pirea (NXP OSS) 	}
1471514def5dSRadu Pirea (NXP OSS) 
1472514def5dSRadu Pirea (NXP OSS) 	if (IS_ENABLED(CONFIG_PTP_1588_CLOCK) &&
1473514def5dSRadu Pirea (NXP OSS) 	    IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING)) {
1474514def5dSRadu Pirea (NXP OSS) 		priv->mii_ts.rxtstamp = nxp_c45_rxtstamp;
1475514def5dSRadu Pirea (NXP OSS) 		priv->mii_ts.txtstamp = nxp_c45_txtstamp;
1476514def5dSRadu Pirea (NXP OSS) 		priv->mii_ts.hwtstamp = nxp_c45_hwtstamp;
1477514def5dSRadu Pirea (NXP OSS) 		priv->mii_ts.ts_info = nxp_c45_ts_info;
1478514def5dSRadu Pirea (NXP OSS) 		phydev->mii_ts = &priv->mii_ts;
1479514def5dSRadu Pirea (NXP OSS) 		ret = nxp_c45_init_ptp_clock(priv);
1480514def5dSRadu Pirea (NXP OSS) 	} else {
1481514def5dSRadu Pirea (NXP OSS) 		phydev_dbg(phydev, "PTP support not enabled even if the phy supports it");
1482514def5dSRadu Pirea (NXP OSS) 	}
1483514def5dSRadu Pirea (NXP OSS) 
1484514def5dSRadu Pirea (NXP OSS) no_ptp_support:
1485514def5dSRadu Pirea (NXP OSS) 
1486514def5dSRadu Pirea (NXP OSS) 	return ret;
1487b050f2f1SRadu Pirea (NXP OSS) }
1488b050f2f1SRadu Pirea (NXP OSS) 
1489a4506722SRadu Pirea (OSS) static void nxp_c45_remove(struct phy_device *phydev)
1490a4506722SRadu Pirea (OSS) {
1491a4506722SRadu Pirea (OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1492a4506722SRadu Pirea (OSS) 
1493a4506722SRadu Pirea (OSS) 	if (priv->ptp_clock)
1494a4506722SRadu Pirea (OSS) 		ptp_clock_unregister(priv->ptp_clock);
1495a4506722SRadu Pirea (OSS) 
1496a4506722SRadu Pirea (OSS) 	skb_queue_purge(&priv->tx_queue);
1497a4506722SRadu Pirea (OSS) 	skb_queue_purge(&priv->rx_queue);
1498a4506722SRadu Pirea (OSS) }
1499a4506722SRadu Pirea (OSS) 
15006c0c85daSRadu Pirea (NXP OSS) static void tja1103_counters_enable(struct phy_device *phydev)
15016c0c85daSRadu Pirea (NXP OSS) {
15026c0c85daSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_PREAMBLE_COUNT,
15036c0c85daSRadu Pirea (NXP OSS) 			 COUNTER_EN);
15046c0c85daSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TX_PREAMBLE_COUNT,
15056c0c85daSRadu Pirea (NXP OSS) 			 COUNTER_EN);
15066c0c85daSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_IPG_LENGTH,
15076c0c85daSRadu Pirea (NXP OSS) 			 COUNTER_EN);
15086c0c85daSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TX_IPG_LENGTH,
15096c0c85daSRadu Pirea (NXP OSS) 			 COUNTER_EN);
15106c0c85daSRadu Pirea (NXP OSS) }
15116c0c85daSRadu Pirea (NXP OSS) 
15126c0c85daSRadu Pirea (NXP OSS) static void tja1103_ptp_init(struct phy_device *phydev)
15136c0c85daSRadu Pirea (NXP OSS) {
15146c0c85daSRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_TS_INSRT_CTRL,
15156c0c85daSRadu Pirea (NXP OSS) 		      TJA1103_RX_TS_INSRT_MODE2);
15166c0c85daSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_FUNC_ENABLES,
15176c0c85daSRadu Pirea (NXP OSS) 			 PTP_ENABLE);
15186c0c85daSRadu Pirea (NXP OSS) }
15196c0c85daSRadu Pirea (NXP OSS) 
15206c0c85daSRadu Pirea (NXP OSS) static void tja1103_ptp_enable(struct phy_device *phydev, bool enable)
15216c0c85daSRadu Pirea (NXP OSS) {
15226c0c85daSRadu Pirea (NXP OSS) 	if (enable)
15236c0c85daSRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
15246c0c85daSRadu Pirea (NXP OSS) 				   VEND1_PORT_PTP_CONTROL,
15256c0c85daSRadu Pirea (NXP OSS) 				   PORT_PTP_CONTROL_BYPASS);
15266c0c85daSRadu Pirea (NXP OSS) 	else
15276c0c85daSRadu Pirea (NXP OSS) 		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
15286c0c85daSRadu Pirea (NXP OSS) 				 VEND1_PORT_PTP_CONTROL,
15296c0c85daSRadu Pirea (NXP OSS) 				 PORT_PTP_CONTROL_BYPASS);
15306c0c85daSRadu Pirea (NXP OSS) }
15316c0c85daSRadu Pirea (NXP OSS) 
15326c0c85daSRadu Pirea (NXP OSS) static const struct nxp_c45_regmap tja1103_regmap = {
15336c0c85daSRadu Pirea (NXP OSS) 	.vend1_ptp_clk_period	= 0x1104,
15346c0c85daSRadu Pirea (NXP OSS) 	.vend1_event_msg_filt	= 0x1148,
15356c0c85daSRadu Pirea (NXP OSS) 	.pps_enable		=
15366c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1102, MDIO_MMD_VEND1, 3, 1),
15376c0c85daSRadu Pirea (NXP OSS) 	.pps_polarity		=
15386c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1102, MDIO_MMD_VEND1, 2, 1),
15396c0c85daSRadu Pirea (NXP OSS) 	.ltc_lock_ctrl		=
15406c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1115, MDIO_MMD_VEND1, 0, 1),
15416c0c85daSRadu Pirea (NXP OSS) 	.ltc_read		=
15426c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1105, MDIO_MMD_VEND1, 2, 1),
15436c0c85daSRadu Pirea (NXP OSS) 	.ltc_write		=
15446c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1105, MDIO_MMD_VEND1, 0, 1),
15456c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_nsec_0	= 0x1106,
15466c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_nsec_1	= 0x1107,
15476c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_sec_0	= 0x1108,
15486c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_sec_1	= 0x1109,
15496c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_nsec_0	= 0x110A,
15506c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_nsec_1	= 0x110B,
15516c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_sec_0	= 0x110C,
15526c0c85daSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_sec_1	= 0x110D,
15536c0c85daSRadu Pirea (NXP OSS) 	.vend1_rate_adj_subns_0	= 0x110F,
15546c0c85daSRadu Pirea (NXP OSS) 	.vend1_rate_adj_subns_1	= 0x1110,
15556c0c85daSRadu Pirea (NXP OSS) 	.irq_egr_ts_en		=
15566c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1131, MDIO_MMD_VEND1, 0, 1),
15576c0c85daSRadu Pirea (NXP OSS) 	.irq_egr_ts_status	=
15586c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1132, MDIO_MMD_VEND1, 0, 1),
15596c0c85daSRadu Pirea (NXP OSS) 	.domain_number		=
15606c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x114E, MDIO_MMD_VEND1, 0, 8),
15616c0c85daSRadu Pirea (NXP OSS) 	.msg_type		=
15626c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x114E, MDIO_MMD_VEND1, 8, 4),
15636c0c85daSRadu Pirea (NXP OSS) 	.sequence_id		=
15646c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x114F, MDIO_MMD_VEND1, 0, 16),
15656c0c85daSRadu Pirea (NXP OSS) 	.sec_1_0		=
15666c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1151, MDIO_MMD_VEND1, 14, 2),
15676c0c85daSRadu Pirea (NXP OSS) 	.sec_4_2		=
15686c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x114E, MDIO_MMD_VEND1, 12, 3),
15696c0c85daSRadu Pirea (NXP OSS) 	.nsec_15_0		=
15706c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1150, MDIO_MMD_VEND1, 0, 16),
15716c0c85daSRadu Pirea (NXP OSS) 	.nsec_29_16		=
15726c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1151, MDIO_MMD_VEND1, 0, 14),
15736c0c85daSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_0	= 0x1121,
15746c0c85daSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_1	= 0x1122,
15756c0c85daSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_2	= 0x1123,
15766c0c85daSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_3	= 0x1124,
15776c0c85daSRadu Pirea (NXP OSS) 	.vend1_ext_trg_ctrl	= 0x1126,
15786c0c85daSRadu Pirea (NXP OSS) 	.cable_test		= 0x8330,
15796c0c85daSRadu Pirea (NXP OSS) 	.cable_test_valid	=
15806c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8330, MDIO_MMD_VEND1, 13, 1),
15816c0c85daSRadu Pirea (NXP OSS) 	.cable_test_result	=
15826c0c85daSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8330, MDIO_MMD_VEND1, 0, 3),
15836c0c85daSRadu Pirea (NXP OSS) };
15846c0c85daSRadu Pirea (NXP OSS) 
15856c0c85daSRadu Pirea (NXP OSS) static const struct nxp_c45_phy_data tja1103_phy_data = {
15866c0c85daSRadu Pirea (NXP OSS) 	.regmap = &tja1103_regmap,
15876c0c85daSRadu Pirea (NXP OSS) 	.stats = tja1103_hw_stats,
15886c0c85daSRadu Pirea (NXP OSS) 	.n_stats = ARRAY_SIZE(tja1103_hw_stats),
15896c0c85daSRadu Pirea (NXP OSS) 	.ptp_clk_period = PTP_CLK_PERIOD_100BT1,
1590*b0b2247dSRadu Pirea (NXP OSS) 	.ext_ts_both_edges = false,
15916c0c85daSRadu Pirea (NXP OSS) 	.counters_enable = tja1103_counters_enable,
15926c0c85daSRadu Pirea (NXP OSS) 	.ptp_init = tja1103_ptp_init,
15936c0c85daSRadu Pirea (NXP OSS) 	.ptp_enable = tja1103_ptp_enable,
15946c0c85daSRadu Pirea (NXP OSS) };
15956c0c85daSRadu Pirea (NXP OSS) 
1596f1fe5dffSRadu Pirea (NXP OSS) static void tja1120_counters_enable(struct phy_device *phydev)
1597f1fe5dffSRadu Pirea (NXP OSS) {
1598f1fe5dffSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_SYMBOL_ERROR_CNT_XTD,
1599f1fe5dffSRadu Pirea (NXP OSS) 			 EXTENDED_CNT_EN);
1600f1fe5dffSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_MONITOR_STATUS,
1601f1fe5dffSRadu Pirea (NXP OSS) 			 MONITOR_RESET);
1602f1fe5dffSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_MONITOR_CONFIG,
1603f1fe5dffSRadu Pirea (NXP OSS) 			 ALL_FRAMES_CNT_EN | LOST_FRAMES_CNT_EN);
1604f1fe5dffSRadu Pirea (NXP OSS) }
1605f1fe5dffSRadu Pirea (NXP OSS) 
1606f1fe5dffSRadu Pirea (NXP OSS) static void tja1120_ptp_init(struct phy_device *phydev)
1607f1fe5dffSRadu Pirea (NXP OSS) {
1608f1fe5dffSRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, TJA1120_RX_TS_INSRT_CTRL,
1609f1fe5dffSRadu Pirea (NXP OSS) 		      TJA1120_RX_TS_INSRT_EN | TJA1120_TS_INSRT_MODE);
1610f1fe5dffSRadu Pirea (NXP OSS) 	phy_write_mmd(phydev, MDIO_MMD_VEND1, TJA1120_VEND1_EXT_TS_MODE,
1611f1fe5dffSRadu Pirea (NXP OSS) 		      TJA1120_TS_INSRT_MODE);
1612f1fe5dffSRadu Pirea (NXP OSS) 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_CONFIG,
1613f1fe5dffSRadu Pirea (NXP OSS) 			 PTP_ENABLE);
1614f1fe5dffSRadu Pirea (NXP OSS) }
1615f1fe5dffSRadu Pirea (NXP OSS) 
1616f1fe5dffSRadu Pirea (NXP OSS) static void tja1120_ptp_enable(struct phy_device *phydev, bool enable)
1617f1fe5dffSRadu Pirea (NXP OSS) {
1618f1fe5dffSRadu Pirea (NXP OSS) 	if (enable)
1619f1fe5dffSRadu Pirea (NXP OSS) 		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
1620f1fe5dffSRadu Pirea (NXP OSS) 				 VEND1_PORT_FUNC_ENABLES,
1621f1fe5dffSRadu Pirea (NXP OSS) 				 PTP_ENABLE);
1622f1fe5dffSRadu Pirea (NXP OSS) 	else
1623f1fe5dffSRadu Pirea (NXP OSS) 		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
1624f1fe5dffSRadu Pirea (NXP OSS) 				   VEND1_PORT_FUNC_ENABLES,
1625f1fe5dffSRadu Pirea (NXP OSS) 				   PTP_ENABLE);
1626f1fe5dffSRadu Pirea (NXP OSS) }
1627f1fe5dffSRadu Pirea (NXP OSS) 
1628f1fe5dffSRadu Pirea (NXP OSS) static const struct nxp_c45_regmap tja1120_regmap = {
1629f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ptp_clk_period	= 0x1020,
1630f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_event_msg_filt	= 0x9010,
1631f1fe5dffSRadu Pirea (NXP OSS) 	.pps_enable		=
1632f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 4, 1),
1633f1fe5dffSRadu Pirea (NXP OSS) 	.pps_polarity		=
1634f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 5, 1),
1635f1fe5dffSRadu Pirea (NXP OSS) 	.ltc_lock_ctrl		=
1636f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 2, 1),
1637f1fe5dffSRadu Pirea (NXP OSS) 	.ltc_read		=
1638f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1000, MDIO_MMD_VEND1, 1, 1),
1639f1fe5dffSRadu Pirea (NXP OSS) 	.ltc_write		=
1640f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x1000, MDIO_MMD_VEND1, 2, 1),
1641f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_nsec_0	= 0x1040,
1642f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_nsec_1	= 0x1041,
1643f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_sec_0	= 0x1042,
1644f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_wr_sec_1	= 0x1043,
1645f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_nsec_0	= 0x1048,
1646f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_nsec_1	= 0x1049,
1647f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_sec_0	= 0x104A,
1648f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ltc_rd_sec_1	= 0x104B,
1649f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_rate_adj_subns_0	= 0x1030,
1650f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_rate_adj_subns_1	= 0x1031,
1651f1fe5dffSRadu Pirea (NXP OSS) 	.irq_egr_ts_en		=
1652f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x900A, MDIO_MMD_VEND1, 1, 1),
1653f1fe5dffSRadu Pirea (NXP OSS) 	.irq_egr_ts_status	=
1654f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x900C, MDIO_MMD_VEND1, 1, 1),
1655f1fe5dffSRadu Pirea (NXP OSS) 	.domain_number		=
1656f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9061, MDIO_MMD_VEND1, 8, 8),
1657f1fe5dffSRadu Pirea (NXP OSS) 	.msg_type		=
1658f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9061, MDIO_MMD_VEND1, 4, 4),
1659f1fe5dffSRadu Pirea (NXP OSS) 	.sequence_id		=
1660f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9062, MDIO_MMD_VEND1, 0, 16),
1661f1fe5dffSRadu Pirea (NXP OSS) 	.sec_1_0		=
1662f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9065, MDIO_MMD_VEND1, 0, 2),
1663f1fe5dffSRadu Pirea (NXP OSS) 	.sec_4_2		=
1664f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9065, MDIO_MMD_VEND1, 2, 3),
1665f1fe5dffSRadu Pirea (NXP OSS) 	.nsec_15_0		=
1666f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9063, MDIO_MMD_VEND1, 0, 16),
1667f1fe5dffSRadu Pirea (NXP OSS) 	.nsec_29_16		=
1668f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x9064, MDIO_MMD_VEND1, 0, 14),
1669f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_0	= 0x1071,
1670f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_1	= 0x1072,
1671f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_2	= 0x1073,
1672f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ext_trg_data_3	= 0x1074,
1673f1fe5dffSRadu Pirea (NXP OSS) 	.vend1_ext_trg_ctrl	= 0x1075,
1674f1fe5dffSRadu Pirea (NXP OSS) 	.cable_test		= 0x8360,
1675f1fe5dffSRadu Pirea (NXP OSS) 	.cable_test_valid	=
1676f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8361, MDIO_MMD_VEND1, 15, 1),
1677f1fe5dffSRadu Pirea (NXP OSS) 	.cable_test_result	=
1678f1fe5dffSRadu Pirea (NXP OSS) 		NXP_C45_REG_FIELD(0x8361, MDIO_MMD_VEND1, 0, 3),
1679f1fe5dffSRadu Pirea (NXP OSS) };
1680f1fe5dffSRadu Pirea (NXP OSS) 
1681f1fe5dffSRadu Pirea (NXP OSS) static const struct nxp_c45_phy_data tja1120_phy_data = {
1682f1fe5dffSRadu Pirea (NXP OSS) 	.regmap = &tja1120_regmap,
1683f1fe5dffSRadu Pirea (NXP OSS) 	.stats = tja1120_hw_stats,
1684f1fe5dffSRadu Pirea (NXP OSS) 	.n_stats = ARRAY_SIZE(tja1120_hw_stats),
1685f1fe5dffSRadu Pirea (NXP OSS) 	.ptp_clk_period = PTP_CLK_PERIOD_1000BT1,
1686*b0b2247dSRadu Pirea (NXP OSS) 	.ext_ts_both_edges = true,
1687f1fe5dffSRadu Pirea (NXP OSS) 	.counters_enable = tja1120_counters_enable,
1688f1fe5dffSRadu Pirea (NXP OSS) 	.ptp_init = tja1120_ptp_init,
1689f1fe5dffSRadu Pirea (NXP OSS) 	.ptp_enable = tja1120_ptp_enable,
1690f1fe5dffSRadu Pirea (NXP OSS) };
1691f1fe5dffSRadu Pirea (NXP OSS) 
1692b050f2f1SRadu Pirea (NXP OSS) static struct phy_driver nxp_c45_driver[] = {
1693b050f2f1SRadu Pirea (NXP OSS) 	{
1694b050f2f1SRadu Pirea (NXP OSS) 		PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
1695b050f2f1SRadu Pirea (NXP OSS) 		.name			= "NXP C45 TJA1103",
1696369da333SRadu Pirea (NXP OSS) 		.get_features		= nxp_c45_get_features,
16976c0c85daSRadu Pirea (NXP OSS) 		.driver_data		= &tja1103_phy_data,
1698b050f2f1SRadu Pirea (NXP OSS) 		.probe			= nxp_c45_probe,
1699b050f2f1SRadu Pirea (NXP OSS) 		.soft_reset		= nxp_c45_soft_reset,
1700ac0687e8SRadu Pirea (NXP OSS) 		.config_aneg		= genphy_c45_config_aneg,
1701b050f2f1SRadu Pirea (NXP OSS) 		.config_init		= nxp_c45_config_init,
1702b2f0ca00SRadu Pirea (NXP OSS) 		.config_intr		= nxp_c45_config_intr,
1703b2f0ca00SRadu Pirea (NXP OSS) 		.handle_interrupt	= nxp_c45_handle_interrupt,
1704ac0687e8SRadu Pirea (NXP OSS) 		.read_status		= genphy_c45_read_status,
1705b050f2f1SRadu Pirea (NXP OSS) 		.suspend		= genphy_c45_pma_suspend,
1706b050f2f1SRadu Pirea (NXP OSS) 		.resume			= genphy_c45_pma_resume,
1707b050f2f1SRadu Pirea (NXP OSS) 		.get_sset_count		= nxp_c45_get_sset_count,
1708b050f2f1SRadu Pirea (NXP OSS) 		.get_strings		= nxp_c45_get_strings,
1709b050f2f1SRadu Pirea (NXP OSS) 		.get_stats		= nxp_c45_get_stats,
1710b050f2f1SRadu Pirea (NXP OSS) 		.cable_test_start	= nxp_c45_cable_test_start,
1711b050f2f1SRadu Pirea (NXP OSS) 		.cable_test_get_status	= nxp_c45_cable_test_get_status,
1712b050f2f1SRadu Pirea (NXP OSS) 		.set_loopback		= genphy_c45_loopback,
1713b050f2f1SRadu Pirea (NXP OSS) 		.get_sqi		= nxp_c45_get_sqi,
1714b050f2f1SRadu Pirea (NXP OSS) 		.get_sqi_max		= nxp_c45_get_sqi_max,
1715a4506722SRadu Pirea (OSS) 		.remove			= nxp_c45_remove,
1716b050f2f1SRadu Pirea (NXP OSS) 	},
1717f1fe5dffSRadu Pirea (NXP OSS) 	{
1718f1fe5dffSRadu Pirea (NXP OSS) 		PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120),
1719f1fe5dffSRadu Pirea (NXP OSS) 		.name			= "NXP C45 TJA1120",
1720f1fe5dffSRadu Pirea (NXP OSS) 		.get_features		= nxp_c45_get_features,
1721f1fe5dffSRadu Pirea (NXP OSS) 		.driver_data		= &tja1120_phy_data,
1722f1fe5dffSRadu Pirea (NXP OSS) 		.probe			= nxp_c45_probe,
1723f1fe5dffSRadu Pirea (NXP OSS) 		.soft_reset		= nxp_c45_soft_reset,
1724f1fe5dffSRadu Pirea (NXP OSS) 		.config_aneg		= genphy_c45_config_aneg,
1725f1fe5dffSRadu Pirea (NXP OSS) 		.config_init		= nxp_c45_config_init,
1726f1fe5dffSRadu Pirea (NXP OSS) 		.config_intr		= nxp_c45_config_intr,
1727f1fe5dffSRadu Pirea (NXP OSS) 		.handle_interrupt	= nxp_c45_handle_interrupt,
1728f1fe5dffSRadu Pirea (NXP OSS) 		.read_status		= genphy_c45_read_status,
1729f1fe5dffSRadu Pirea (NXP OSS) 		.suspend		= genphy_c45_pma_suspend,
1730f1fe5dffSRadu Pirea (NXP OSS) 		.resume			= genphy_c45_pma_resume,
1731f1fe5dffSRadu Pirea (NXP OSS) 		.get_sset_count		= nxp_c45_get_sset_count,
1732f1fe5dffSRadu Pirea (NXP OSS) 		.get_strings		= nxp_c45_get_strings,
1733f1fe5dffSRadu Pirea (NXP OSS) 		.get_stats		= nxp_c45_get_stats,
1734f1fe5dffSRadu Pirea (NXP OSS) 		.cable_test_start	= nxp_c45_cable_test_start,
1735f1fe5dffSRadu Pirea (NXP OSS) 		.cable_test_get_status	= nxp_c45_cable_test_get_status,
1736f1fe5dffSRadu Pirea (NXP OSS) 		.set_loopback		= genphy_c45_loopback,
1737f1fe5dffSRadu Pirea (NXP OSS) 		.get_sqi		= nxp_c45_get_sqi,
1738f1fe5dffSRadu Pirea (NXP OSS) 		.get_sqi_max		= nxp_c45_get_sqi_max,
1739f1fe5dffSRadu Pirea (NXP OSS) 		.remove			= nxp_c45_remove,
1740f1fe5dffSRadu Pirea (NXP OSS) 	},
1741b050f2f1SRadu Pirea (NXP OSS) };
1742b050f2f1SRadu Pirea (NXP OSS) 
1743b050f2f1SRadu Pirea (NXP OSS) module_phy_driver(nxp_c45_driver);
1744b050f2f1SRadu Pirea (NXP OSS) 
1745b050f2f1SRadu Pirea (NXP OSS) static struct mdio_device_id __maybe_unused nxp_c45_tbl[] = {
1746b050f2f1SRadu Pirea (NXP OSS) 	{ PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103) },
1747f1fe5dffSRadu Pirea (NXP OSS) 	{ PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120) },
1748b050f2f1SRadu Pirea (NXP OSS) 	{ /*sentinel*/ },
1749b050f2f1SRadu Pirea (NXP OSS) };
1750b050f2f1SRadu Pirea (NXP OSS) 
1751b050f2f1SRadu Pirea (NXP OSS) MODULE_DEVICE_TABLE(mdio, nxp_c45_tbl);
1752b050f2f1SRadu Pirea (NXP OSS) 
1753b050f2f1SRadu Pirea (NXP OSS) MODULE_AUTHOR("Radu Pirea <radu-nicolae.pirea@oss.nxp.com>");
1754b050f2f1SRadu Pirea (NXP OSS) MODULE_DESCRIPTION("NXP C45 PHY driver");
1755b050f2f1SRadu Pirea (NXP OSS) MODULE_LICENSE("GPL v2");
1756