xref: /linux/drivers/net/phy/qcom/qca808x.c (revision bdce82e960d1205d118662f575cec39379984e34)
1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #include <linux/phy.h>
4 #include <linux/module.h>
5 #include <linux/ethtool_netlink.h>
6 
7 #include "qcom.h"
8 
9 /* ADC threshold */
10 #define QCA808X_PHY_DEBUG_ADC_THRESHOLD		0x2c80
11 #define QCA808X_ADC_THRESHOLD_MASK		GENMASK(7, 0)
12 #define QCA808X_ADC_THRESHOLD_80MV		0
13 #define QCA808X_ADC_THRESHOLD_100MV		0xf0
14 #define QCA808X_ADC_THRESHOLD_200MV		0x0f
15 #define QCA808X_ADC_THRESHOLD_300MV		0xff
16 
17 /* CLD control */
18 #define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7		0x8007
19 #define QCA808X_8023AZ_AFE_CTRL_MASK		GENMASK(8, 4)
20 #define QCA808X_8023AZ_AFE_EN			0x90
21 
22 /* AZ control */
23 #define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL	0x8008
24 #define QCA808X_MMD3_AZ_TRAINING_VAL		0x1c32
25 
26 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB	0x8014
27 #define QCA808X_MSE_THRESHOLD_20DB_VALUE	0x529
28 
29 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB	0x800E
30 #define QCA808X_MSE_THRESHOLD_17DB_VALUE	0x341
31 
32 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB	0x801E
33 #define QCA808X_MSE_THRESHOLD_27DB_VALUE	0x419
34 
35 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB	0x8020
36 #define QCA808X_MSE_THRESHOLD_28DB_VALUE	0x341
37 
38 #define QCA808X_PHY_MMD7_TOP_OPTION1		0x901c
39 #define QCA808X_TOP_OPTION1_DATA		0x0
40 
41 #define QCA808X_PHY_MMD3_DEBUG_1		0xa100
42 #define QCA808X_MMD3_DEBUG_1_VALUE		0x9203
43 #define QCA808X_PHY_MMD3_DEBUG_2		0xa101
44 #define QCA808X_MMD3_DEBUG_2_VALUE		0x48ad
45 #define QCA808X_PHY_MMD3_DEBUG_3		0xa103
46 #define QCA808X_MMD3_DEBUG_3_VALUE		0x1698
47 #define QCA808X_PHY_MMD3_DEBUG_4		0xa105
48 #define QCA808X_MMD3_DEBUG_4_VALUE		0x8001
49 #define QCA808X_PHY_MMD3_DEBUG_5		0xa106
50 #define QCA808X_MMD3_DEBUG_5_VALUE		0x1111
51 #define QCA808X_PHY_MMD3_DEBUG_6		0xa011
52 #define QCA808X_MMD3_DEBUG_6_VALUE		0x5f85
53 
54 /* master/slave seed config */
55 #define QCA808X_PHY_DEBUG_LOCAL_SEED		9
56 #define QCA808X_MASTER_SLAVE_SEED_ENABLE	BIT(1)
57 #define QCA808X_MASTER_SLAVE_SEED_CFG		GENMASK(12, 2)
58 #define QCA808X_MASTER_SLAVE_SEED_RANGE		0x32
59 
60 /* Hibernation yields lower power consumpiton in contrast with normal operation mode.
61  * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s.
62  */
63 #define QCA808X_DBG_AN_TEST			0xb
64 #define QCA808X_HIBERNATION_EN			BIT(15)
65 
66 #define QCA808X_CDT_ENABLE_TEST			BIT(15)
67 #define QCA808X_CDT_INTER_CHECK_DIS		BIT(13)
68 #define QCA808X_CDT_STATUS			BIT(11)
69 #define QCA808X_CDT_LENGTH_UNIT			BIT(10)
70 
71 #define QCA808X_MMD3_CDT_STATUS			0x8064
72 #define QCA808X_MMD3_CDT_DIAG_PAIR_A		0x8065
73 #define QCA808X_MMD3_CDT_DIAG_PAIR_B		0x8066
74 #define QCA808X_MMD3_CDT_DIAG_PAIR_C		0x8067
75 #define QCA808X_MMD3_CDT_DIAG_PAIR_D		0x8068
76 #define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT	GENMASK(15, 8)
77 #define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT	GENMASK(7, 0)
78 
79 #define QCA808X_CDT_CODE_PAIR_A			GENMASK(15, 12)
80 #define QCA808X_CDT_CODE_PAIR_B			GENMASK(11, 8)
81 #define QCA808X_CDT_CODE_PAIR_C			GENMASK(7, 4)
82 #define QCA808X_CDT_CODE_PAIR_D			GENMASK(3, 0)
83 
84 #define QCA808X_CDT_STATUS_STAT_TYPE		GENMASK(1, 0)
85 #define QCA808X_CDT_STATUS_STAT_FAIL		FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0)
86 #define QCA808X_CDT_STATUS_STAT_NORMAL		FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1)
87 #define QCA808X_CDT_STATUS_STAT_SAME_OPEN	FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2)
88 #define QCA808X_CDT_STATUS_STAT_SAME_SHORT	FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3)
89 
90 #define QCA808X_CDT_STATUS_STAT_MDI		GENMASK(3, 2)
91 #define QCA808X_CDT_STATUS_STAT_MDI1		FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1)
92 #define QCA808X_CDT_STATUS_STAT_MDI2		FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2)
93 #define QCA808X_CDT_STATUS_STAT_MDI3		FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3)
94 
95 /* NORMAL are MDI with type set to 0 */
96 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL	QCA808X_CDT_STATUS_STAT_MDI1
97 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN		(QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
98 									 QCA808X_CDT_STATUS_STAT_MDI1)
99 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT	(QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
100 									 QCA808X_CDT_STATUS_STAT_MDI1)
101 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL	QCA808X_CDT_STATUS_STAT_MDI2
102 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN		(QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
103 									 QCA808X_CDT_STATUS_STAT_MDI2)
104 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT	(QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
105 									 QCA808X_CDT_STATUS_STAT_MDI2)
106 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL	QCA808X_CDT_STATUS_STAT_MDI3
107 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN		(QCA808X_CDT_STATUS_STAT_SAME_OPEN |\
108 									 QCA808X_CDT_STATUS_STAT_MDI3)
109 #define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT	(QCA808X_CDT_STATUS_STAT_SAME_SHORT |\
110 									 QCA808X_CDT_STATUS_STAT_MDI3)
111 
112 /* Added for reference of existence but should be handled by wait_for_completion already */
113 #define QCA808X_CDT_STATUS_STAT_BUSY		(BIT(1) | BIT(3))
114 
115 #define QCA808X_MMD7_LED_GLOBAL			0x8073
116 #define QCA808X_LED_BLINK_1			GENMASK(11, 6)
117 #define QCA808X_LED_BLINK_2			GENMASK(5, 0)
118 /* Values are the same for both BLINK_1 and BLINK_2 */
119 #define QCA808X_LED_BLINK_FREQ_MASK		GENMASK(5, 3)
120 #define QCA808X_LED_BLINK_FREQ_2HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0)
121 #define QCA808X_LED_BLINK_FREQ_4HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1)
122 #define QCA808X_LED_BLINK_FREQ_8HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2)
123 #define QCA808X_LED_BLINK_FREQ_16HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3)
124 #define QCA808X_LED_BLINK_FREQ_32HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4)
125 #define QCA808X_LED_BLINK_FREQ_64HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5)
126 #define QCA808X_LED_BLINK_FREQ_128HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6)
127 #define QCA808X_LED_BLINK_FREQ_256HZ		FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7)
128 #define QCA808X_LED_BLINK_DUTY_MASK		GENMASK(2, 0)
129 #define QCA808X_LED_BLINK_DUTY_50_50		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0)
130 #define QCA808X_LED_BLINK_DUTY_75_25		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1)
131 #define QCA808X_LED_BLINK_DUTY_25_75		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2)
132 #define QCA808X_LED_BLINK_DUTY_33_67		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3)
133 #define QCA808X_LED_BLINK_DUTY_67_33		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4)
134 #define QCA808X_LED_BLINK_DUTY_17_83		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5)
135 #define QCA808X_LED_BLINK_DUTY_83_17		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6)
136 #define QCA808X_LED_BLINK_DUTY_8_92		FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7)
137 
138 #define QCA808X_MMD7_LED2_CTRL			0x8074
139 #define QCA808X_MMD7_LED2_FORCE_CTRL		0x8075
140 #define QCA808X_MMD7_LED1_CTRL			0x8076
141 #define QCA808X_MMD7_LED1_FORCE_CTRL		0x8077
142 #define QCA808X_MMD7_LED0_CTRL			0x8078
143 #define QCA808X_MMD7_LED_CTRL(x)		(0x8078 - ((x) * 2))
144 
145 /* LED hw control pattern is the same for every LED */
146 #define QCA808X_LED_PATTERN_MASK		GENMASK(15, 0)
147 #define QCA808X_LED_SPEED2500_ON		BIT(15)
148 #define QCA808X_LED_SPEED2500_BLINK		BIT(14)
149 /* Follow blink trigger even if duplex or speed condition doesn't match */
150 #define QCA808X_LED_BLINK_CHECK_BYPASS		BIT(13)
151 #define QCA808X_LED_FULL_DUPLEX_ON		BIT(12)
152 #define QCA808X_LED_HALF_DUPLEX_ON		BIT(11)
153 #define QCA808X_LED_TX_BLINK			BIT(10)
154 #define QCA808X_LED_RX_BLINK			BIT(9)
155 #define QCA808X_LED_TX_ON_10MS			BIT(8)
156 #define QCA808X_LED_RX_ON_10MS			BIT(7)
157 #define QCA808X_LED_SPEED1000_ON		BIT(6)
158 #define QCA808X_LED_SPEED100_ON			BIT(5)
159 #define QCA808X_LED_SPEED10_ON			BIT(4)
160 #define QCA808X_LED_COLLISION_BLINK		BIT(3)
161 #define QCA808X_LED_SPEED1000_BLINK		BIT(2)
162 #define QCA808X_LED_SPEED100_BLINK		BIT(1)
163 #define QCA808X_LED_SPEED10_BLINK		BIT(0)
164 
165 #define QCA808X_MMD7_LED0_FORCE_CTRL		0x8079
166 #define QCA808X_MMD7_LED_FORCE_CTRL(x)		(0x8079 - ((x) * 2))
167 
168 /* LED force ctrl is the same for every LED
169  * No documentation exist for this, not even internal one
170  * with NDA as QCOM gives only info about configuring
171  * hw control pattern rules and doesn't indicate any way
172  * to force the LED to specific mode.
173  * These define comes from reverse and testing and maybe
174  * lack of some info or some info are not entirely correct.
175  * For the basic LED control and hw control these finding
176  * are enough to support LED control in all the required APIs.
177  *
178  * On doing some comparison with implementation with qca807x,
179  * it was found that it's 1:1 equal to it and confirms all the
180  * reverse done. It was also found further specification with the
181  * force mode and the blink modes.
182  */
183 #define QCA808X_LED_FORCE_EN			BIT(15)
184 #define QCA808X_LED_FORCE_MODE_MASK		GENMASK(14, 13)
185 #define QCA808X_LED_FORCE_BLINK_1		FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3)
186 #define QCA808X_LED_FORCE_BLINK_2		FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2)
187 #define QCA808X_LED_FORCE_ON			FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1)
188 #define QCA808X_LED_FORCE_OFF			FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0)
189 
190 #define QCA808X_MMD7_LED_POLARITY_CTRL		0x901a
191 /* QSDK sets by default 0x46 to this reg that sets BIT 6 for
192  * LED to active high. It's not clear what BIT 3 and BIT 4 does.
193  */
194 #define QCA808X_LED_ACTIVE_HIGH			BIT(6)
195 
196 /* QCA808X 1G chip type */
197 #define QCA808X_PHY_MMD7_CHIP_TYPE		0x901d
198 #define QCA808X_PHY_CHIP_TYPE_1G		BIT(0)
199 
200 #define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL	0x9072
201 #define QCA8081_PHY_FIFO_RSTN			BIT(11)
202 
203 #define QCA8081_PHY_ID				0x004dd101
204 
205 MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
206 MODULE_AUTHOR("Matus Ujhelyi");
207 MODULE_LICENSE("GPL");
208 
209 struct qca808x_priv {
210 	int led_polarity_mode;
211 };
212 
213 static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
214 {
215 	int ret;
216 
217 	/* Enable fast retrain */
218 	ret = genphy_c45_fast_retrain(phydev, true);
219 	if (ret)
220 		return ret;
221 
222 	phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
223 		      QCA808X_TOP_OPTION1_DATA);
224 	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
225 		      QCA808X_MSE_THRESHOLD_20DB_VALUE);
226 	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
227 		      QCA808X_MSE_THRESHOLD_17DB_VALUE);
228 	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
229 		      QCA808X_MSE_THRESHOLD_27DB_VALUE);
230 	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
231 		      QCA808X_MSE_THRESHOLD_28DB_VALUE);
232 	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
233 		      QCA808X_MMD3_DEBUG_1_VALUE);
234 	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
235 		      QCA808X_MMD3_DEBUG_4_VALUE);
236 	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
237 		      QCA808X_MMD3_DEBUG_5_VALUE);
238 	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
239 		      QCA808X_MMD3_DEBUG_3_VALUE);
240 	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
241 		      QCA808X_MMD3_DEBUG_6_VALUE);
242 	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
243 		      QCA808X_MMD3_DEBUG_2_VALUE);
244 
245 	return 0;
246 }
247 
248 static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
249 {
250 	u16 seed_value;
251 
252 	if (!enable)
253 		return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
254 				QCA808X_MASTER_SLAVE_SEED_ENABLE, 0);
255 
256 	seed_value = get_random_u32_below(QCA808X_MASTER_SLAVE_SEED_RANGE);
257 	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
258 			QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE,
259 			FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) |
260 			QCA808X_MASTER_SLAVE_SEED_ENABLE);
261 }
262 
263 static bool qca808x_is_prefer_master(struct phy_device *phydev)
264 {
265 	return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) ||
266 		(phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED);
267 }
268 
269 static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
270 {
271 	return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
272 }
273 
274 static int qca808x_probe(struct phy_device *phydev)
275 {
276 	struct device *dev = &phydev->mdio.dev;
277 	struct qca808x_priv *priv;
278 
279 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
280 	if (!priv)
281 		return -ENOMEM;
282 
283 	/* Init LED polarity mode to -1 */
284 	priv->led_polarity_mode = -1;
285 
286 	phydev->priv = priv;
287 
288 	return 0;
289 }
290 
291 static int qca808x_config_init(struct phy_device *phydev)
292 {
293 	int ret;
294 
295 	/* Active adc&vga on 802.3az for the link 1000M and 100M */
296 	ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
297 			     QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
298 	if (ret)
299 		return ret;
300 
301 	/* Adjust the threshold on 802.3az for the link 1000M */
302 	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
303 			    QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
304 			    QCA808X_MMD3_AZ_TRAINING_VAL);
305 	if (ret)
306 		return ret;
307 
308 	if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
309 		/* Config the fast retrain for the link 2500M */
310 		ret = qca808x_phy_fast_retrain_config(phydev);
311 		if (ret)
312 			return ret;
313 
314 		ret = genphy_read_master_slave(phydev);
315 		if (ret < 0)
316 			return ret;
317 
318 		if (!qca808x_is_prefer_master(phydev)) {
319 			/* Enable seed and configure lower ramdom seed to make phy
320 			 * linked as slave mode.
321 			 */
322 			ret = qca808x_phy_ms_seed_enable(phydev, true);
323 			if (ret)
324 				return ret;
325 		}
326 	}
327 
328 	/* Configure adc threshold as 100mv for the link 10M */
329 	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
330 				     QCA808X_ADC_THRESHOLD_MASK,
331 				     QCA808X_ADC_THRESHOLD_100MV);
332 }
333 
334 static int qca808x_read_status(struct phy_device *phydev)
335 {
336 	struct at803x_ss_mask ss_mask = { 0 };
337 	int ret;
338 
339 	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
340 	if (ret < 0)
341 		return ret;
342 
343 	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
344 			 ret & MDIO_AN_10GBT_STAT_LP2_5G);
345 
346 	ret = genphy_read_status(phydev);
347 	if (ret)
348 		return ret;
349 
350 	/* qca8081 takes the different bits for speed value from at803x */
351 	ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
352 	ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
353 	ret = at803x_read_specific_status(phydev, ss_mask);
354 	if (ret < 0)
355 		return ret;
356 
357 	if (phydev->link) {
358 		if (phydev->speed == SPEED_2500)
359 			phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
360 		else
361 			phydev->interface = PHY_INTERFACE_MODE_SGMII;
362 	} else {
363 		/* generate seed as a lower random value to make PHY linked as SLAVE easily,
364 		 * except for master/slave configuration fault detected or the master mode
365 		 * preferred.
366 		 *
367 		 * the reason for not putting this code into the function link_change_notify is
368 		 * the corner case where the link partner is also the qca8081 PHY and the seed
369 		 * value is configured as the same value, the link can't be up and no link change
370 		 * occurs.
371 		 */
372 		if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
373 			if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
374 			    qca808x_is_prefer_master(phydev)) {
375 				qca808x_phy_ms_seed_enable(phydev, false);
376 			} else {
377 				qca808x_phy_ms_seed_enable(phydev, true);
378 			}
379 		}
380 	}
381 
382 	return 0;
383 }
384 
385 static int qca808x_soft_reset(struct phy_device *phydev)
386 {
387 	int ret;
388 
389 	ret = genphy_soft_reset(phydev);
390 	if (ret < 0)
391 		return ret;
392 
393 	if (qca808x_has_fast_retrain_or_slave_seed(phydev))
394 		ret = qca808x_phy_ms_seed_enable(phydev, true);
395 
396 	return ret;
397 }
398 
399 static bool qca808x_cdt_fault_length_valid(int cdt_code)
400 {
401 	switch (cdt_code) {
402 	case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
403 	case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
404 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
405 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
406 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
407 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
408 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
409 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
410 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
411 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
412 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
413 		return true;
414 	default:
415 		return false;
416 	}
417 }
418 
419 static int qca808x_cable_test_result_trans(int cdt_code)
420 {
421 	switch (cdt_code) {
422 	case QCA808X_CDT_STATUS_STAT_NORMAL:
423 		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
424 	case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
425 		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
426 	case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
427 		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
428 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
429 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
430 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
431 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
432 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
433 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
434 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
435 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
436 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
437 		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
438 	case QCA808X_CDT_STATUS_STAT_FAIL:
439 	default:
440 		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
441 	}
442 }
443 
444 static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
445 				    int result)
446 {
447 	int val;
448 	u32 cdt_length_reg = 0;
449 
450 	switch (pair) {
451 	case ETHTOOL_A_CABLE_PAIR_A:
452 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
453 		break;
454 	case ETHTOOL_A_CABLE_PAIR_B:
455 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
456 		break;
457 	case ETHTOOL_A_CABLE_PAIR_C:
458 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
459 		break;
460 	case ETHTOOL_A_CABLE_PAIR_D:
461 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
462 		break;
463 	default:
464 		return -EINVAL;
465 	}
466 
467 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
468 	if (val < 0)
469 		return val;
470 
471 	if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
472 		val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
473 	else
474 		val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
475 
476 	return at803x_cdt_fault_length(val);
477 }
478 
479 static int qca808x_cable_test_start(struct phy_device *phydev)
480 {
481 	int ret;
482 
483 	/* perform CDT with the following configs:
484 	 * 1. disable hibernation.
485 	 * 2. force PHY working in MDI mode.
486 	 * 3. for PHY working in 1000BaseT.
487 	 * 4. configure the threshold.
488 	 */
489 
490 	ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
491 	if (ret < 0)
492 		return ret;
493 
494 	ret = at803x_config_mdix(phydev, ETH_TP_MDI);
495 	if (ret < 0)
496 		return ret;
497 
498 	/* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
499 	phydev->duplex = DUPLEX_FULL;
500 	phydev->speed = SPEED_1000;
501 	ret = genphy_c45_pma_setup_forced(phydev);
502 	if (ret < 0)
503 		return ret;
504 
505 	ret = genphy_setup_forced(phydev);
506 	if (ret < 0)
507 		return ret;
508 
509 	/* configure the thresholds for open, short, pair ok test */
510 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
511 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
512 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
513 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
514 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
515 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
516 
517 	return 0;
518 }
519 
520 static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
521 					      u16 status)
522 {
523 	int length, result;
524 	u16 pair_code;
525 
526 	switch (pair) {
527 	case ETHTOOL_A_CABLE_PAIR_A:
528 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
529 		break;
530 	case ETHTOOL_A_CABLE_PAIR_B:
531 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
532 		break;
533 	case ETHTOOL_A_CABLE_PAIR_C:
534 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
535 		break;
536 	case ETHTOOL_A_CABLE_PAIR_D:
537 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
538 		break;
539 	default:
540 		return -EINVAL;
541 	}
542 
543 	result = qca808x_cable_test_result_trans(pair_code);
544 	ethnl_cable_test_result(phydev, pair, result);
545 
546 	if (qca808x_cdt_fault_length_valid(pair_code)) {
547 		length = qca808x_cdt_fault_length(phydev, pair, result);
548 		ethnl_cable_test_fault_length(phydev, pair, length);
549 	}
550 
551 	return 0;
552 }
553 
554 static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
555 {
556 	int ret, val;
557 
558 	*finished = false;
559 
560 	val = QCA808X_CDT_ENABLE_TEST |
561 	      QCA808X_CDT_LENGTH_UNIT;
562 	ret = at803x_cdt_start(phydev, val);
563 	if (ret)
564 		return ret;
565 
566 	ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
567 	if (ret)
568 		return ret;
569 
570 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
571 	if (val < 0)
572 		return val;
573 
574 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
575 	if (ret)
576 		return ret;
577 
578 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
579 	if (ret)
580 		return ret;
581 
582 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
583 	if (ret)
584 		return ret;
585 
586 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
587 	if (ret)
588 		return ret;
589 
590 	*finished = true;
591 
592 	return 0;
593 }
594 
595 static int qca808x_get_features(struct phy_device *phydev)
596 {
597 	int ret;
598 
599 	ret = genphy_c45_pma_read_abilities(phydev);
600 	if (ret)
601 		return ret;
602 
603 	/* The autoneg ability is not existed in bit3 of MMD7.1,
604 	 * but it is supported by qca808x PHY, so we add it here
605 	 * manually.
606 	 */
607 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
608 
609 	/* As for the qca8081 1G version chip, the 2500baseT ability is also
610 	 * existed in the bit0 of MMD1.21, we need to remove it manually if
611 	 * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
612 	 */
613 	ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
614 	if (ret < 0)
615 		return ret;
616 
617 	if (QCA808X_PHY_CHIP_TYPE_1G & ret)
618 		linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
619 
620 	return 0;
621 }
622 
623 static int qca808x_config_aneg(struct phy_device *phydev)
624 {
625 	int phy_ctrl = 0;
626 	int ret;
627 
628 	ret = at803x_prepare_config_aneg(phydev);
629 	if (ret)
630 		return ret;
631 
632 	/* The reg MII_BMCR also needs to be configured for force mode, the
633 	 * genphy_config_aneg is also needed.
634 	 */
635 	if (phydev->autoneg == AUTONEG_DISABLE)
636 		genphy_c45_pma_setup_forced(phydev);
637 
638 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
639 		phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
640 
641 	ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
642 				     MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
643 	if (ret < 0)
644 		return ret;
645 
646 	return __genphy_config_aneg(phydev, ret);
647 }
648 
649 static void qca808x_link_change_notify(struct phy_device *phydev)
650 {
651 	/* Assert interface sgmii fifo on link down, deassert it on link up,
652 	 * the interface device address is always phy address added by 1.
653 	 */
654 	mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
655 				   MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
656 				   QCA8081_PHY_FIFO_RSTN,
657 				   phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
658 }
659 
660 static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
661 				    u16 *offload_trigger)
662 {
663 	/* Parsing specific to netdev trigger */
664 	if (test_bit(TRIGGER_NETDEV_TX, &rules))
665 		*offload_trigger |= QCA808X_LED_TX_BLINK;
666 	if (test_bit(TRIGGER_NETDEV_RX, &rules))
667 		*offload_trigger |= QCA808X_LED_RX_BLINK;
668 	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
669 		*offload_trigger |= QCA808X_LED_SPEED10_ON;
670 	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
671 		*offload_trigger |= QCA808X_LED_SPEED100_ON;
672 	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
673 		*offload_trigger |= QCA808X_LED_SPEED1000_ON;
674 	if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
675 		*offload_trigger |= QCA808X_LED_SPEED2500_ON;
676 	if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
677 		*offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
678 	if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
679 		*offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
680 
681 	if (rules && !*offload_trigger)
682 		return -EOPNOTSUPP;
683 
684 	/* Enable BLINK_CHECK_BYPASS by default to make the LED
685 	 * blink even with duplex or speed mode not enabled.
686 	 */
687 	*offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
688 
689 	return 0;
690 }
691 
692 static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
693 {
694 	u16 reg;
695 
696 	if (index > 2)
697 		return -EINVAL;
698 
699 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
700 
701 	return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
702 				  QCA808X_LED_FORCE_EN);
703 }
704 
705 static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
706 				       unsigned long rules)
707 {
708 	u16 offload_trigger = 0;
709 
710 	if (index > 2)
711 		return -EINVAL;
712 
713 	return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
714 }
715 
716 static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
717 				      unsigned long rules)
718 {
719 	u16 reg, offload_trigger = 0;
720 	int ret;
721 
722 	if (index > 2)
723 		return -EINVAL;
724 
725 	reg = QCA808X_MMD7_LED_CTRL(index);
726 
727 	ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
728 	if (ret)
729 		return ret;
730 
731 	ret = qca808x_led_hw_control_enable(phydev, index);
732 	if (ret)
733 		return ret;
734 
735 	return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
736 			      QCA808X_LED_PATTERN_MASK,
737 			      offload_trigger);
738 }
739 
740 static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
741 {
742 	u16 reg;
743 	int val;
744 
745 	if (index > 2)
746 		return false;
747 
748 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
749 
750 	val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
751 
752 	return !(val & QCA808X_LED_FORCE_EN);
753 }
754 
755 static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
756 				      unsigned long *rules)
757 {
758 	u16 reg;
759 	int val;
760 
761 	if (index > 2)
762 		return -EINVAL;
763 
764 	/* Check if we have hw control enabled */
765 	if (qca808x_led_hw_control_status(phydev, index))
766 		return -EINVAL;
767 
768 	reg = QCA808X_MMD7_LED_CTRL(index);
769 
770 	val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
771 	if (val & QCA808X_LED_TX_BLINK)
772 		set_bit(TRIGGER_NETDEV_TX, rules);
773 	if (val & QCA808X_LED_RX_BLINK)
774 		set_bit(TRIGGER_NETDEV_RX, rules);
775 	if (val & QCA808X_LED_SPEED10_ON)
776 		set_bit(TRIGGER_NETDEV_LINK_10, rules);
777 	if (val & QCA808X_LED_SPEED100_ON)
778 		set_bit(TRIGGER_NETDEV_LINK_100, rules);
779 	if (val & QCA808X_LED_SPEED1000_ON)
780 		set_bit(TRIGGER_NETDEV_LINK_1000, rules);
781 	if (val & QCA808X_LED_SPEED2500_ON)
782 		set_bit(TRIGGER_NETDEV_LINK_2500, rules);
783 	if (val & QCA808X_LED_HALF_DUPLEX_ON)
784 		set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
785 	if (val & QCA808X_LED_FULL_DUPLEX_ON)
786 		set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
787 
788 	return 0;
789 }
790 
791 static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
792 {
793 	u16 reg;
794 
795 	if (index > 2)
796 		return -EINVAL;
797 
798 	reg = QCA808X_MMD7_LED_CTRL(index);
799 
800 	return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
801 				  QCA808X_LED_PATTERN_MASK);
802 }
803 
804 static int qca808x_led_brightness_set(struct phy_device *phydev,
805 				      u8 index, enum led_brightness value)
806 {
807 	u16 reg;
808 	int ret;
809 
810 	if (index > 2)
811 		return -EINVAL;
812 
813 	if (!value) {
814 		ret = qca808x_led_hw_control_reset(phydev, index);
815 		if (ret)
816 			return ret;
817 	}
818 
819 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
820 
821 	return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
822 			      QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
823 			      QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON :
824 							     QCA808X_LED_FORCE_OFF);
825 }
826 
827 static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
828 				 unsigned long *delay_on,
829 				 unsigned long *delay_off)
830 {
831 	int ret;
832 	u16 reg;
833 
834 	if (index > 2)
835 		return -EINVAL;
836 
837 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
838 
839 	/* Set blink to 50% off, 50% on at 4Hz by default */
840 	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
841 			     QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
842 			     QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
843 	if (ret)
844 		return ret;
845 
846 	/* We use BLINK_1 for normal blinking */
847 	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
848 			     QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
849 			     QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
850 	if (ret)
851 		return ret;
852 
853 	/* We set blink to 4Hz, aka 250ms */
854 	*delay_on = 250 / 2;
855 	*delay_off = 250 / 2;
856 
857 	return 0;
858 }
859 
860 static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
861 				    unsigned long modes)
862 {
863 	struct qca808x_priv *priv = phydev->priv;
864 	bool active_low = false;
865 	u32 mode;
866 
867 	for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
868 		switch (mode) {
869 		case PHY_LED_ACTIVE_LOW:
870 			active_low = true;
871 			break;
872 		default:
873 			return -EINVAL;
874 		}
875 	}
876 
877 	/* PHY polarity is global and can't be set per LED.
878 	 * To detect this, check if last requested polarity mode
879 	 * match the new one.
880 	 */
881 	if (priv->led_polarity_mode >= 0 &&
882 	    priv->led_polarity_mode != active_low) {
883 		phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
884 		return -EINVAL;
885 	}
886 
887 	/* Save the last PHY polarity mode */
888 	priv->led_polarity_mode = active_low;
889 
890 	return phy_modify_mmd(phydev, MDIO_MMD_AN,
891 			      QCA808X_MMD7_LED_POLARITY_CTRL,
892 			      QCA808X_LED_ACTIVE_HIGH,
893 			      active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
894 }
895 
896 static struct phy_driver qca808x_driver[] = {
897 {
898 	/* Qualcomm QCA8081 */
899 	PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
900 	.name			= "Qualcomm QCA8081",
901 	.flags			= PHY_POLL_CABLE_TEST,
902 	.probe			= qca808x_probe,
903 	.config_intr		= at803x_config_intr,
904 	.handle_interrupt	= at803x_handle_interrupt,
905 	.get_tunable		= at803x_get_tunable,
906 	.set_tunable		= at803x_set_tunable,
907 	.set_wol		= at803x_set_wol,
908 	.get_wol		= at803x_get_wol,
909 	.get_features		= qca808x_get_features,
910 	.config_aneg		= qca808x_config_aneg,
911 	.suspend		= genphy_suspend,
912 	.resume			= genphy_resume,
913 	.read_status		= qca808x_read_status,
914 	.config_init		= qca808x_config_init,
915 	.soft_reset		= qca808x_soft_reset,
916 	.cable_test_start	= qca808x_cable_test_start,
917 	.cable_test_get_status	= qca808x_cable_test_get_status,
918 	.link_change_notify	= qca808x_link_change_notify,
919 	.led_brightness_set	= qca808x_led_brightness_set,
920 	.led_blink_set		= qca808x_led_blink_set,
921 	.led_hw_is_supported	= qca808x_led_hw_is_supported,
922 	.led_hw_control_set	= qca808x_led_hw_control_set,
923 	.led_hw_control_get	= qca808x_led_hw_control_get,
924 	.led_polarity_set	= qca808x_led_polarity_set,
925 }, };
926 
927 module_phy_driver(qca808x_driver);
928 
929 static struct mdio_device_id __maybe_unused qca808x_tbl[] = {
930 	{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
931 	{ }
932 };
933 
934 MODULE_DEVICE_TABLE(mdio, qca808x_tbl);
935