xref: /linux/drivers/net/phy/qcom/qca808x.c (revision 110d3047a3ec033de00322b1a8068b1215efa97a)
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 	struct qca808x_priv *priv = phydev->priv;
294 	int ret;
295 
296 	/* Default to LED Active High if active-low not in DT */
297 	if (priv->led_polarity_mode == -1) {
298 		ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN,
299 				       QCA808X_MMD7_LED_POLARITY_CTRL,
300 				       QCA808X_LED_ACTIVE_HIGH);
301 		if (ret)
302 			return ret;
303 	}
304 
305 	/* Active adc&vga on 802.3az for the link 1000M and 100M */
306 	ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
307 			     QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
308 	if (ret)
309 		return ret;
310 
311 	/* Adjust the threshold on 802.3az for the link 1000M */
312 	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
313 			    QCA808X_PHY_MMD3_AZ_TRAINING_CTRL,
314 			    QCA808X_MMD3_AZ_TRAINING_VAL);
315 	if (ret)
316 		return ret;
317 
318 	if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
319 		/* Config the fast retrain for the link 2500M */
320 		ret = qca808x_phy_fast_retrain_config(phydev);
321 		if (ret)
322 			return ret;
323 
324 		ret = genphy_read_master_slave(phydev);
325 		if (ret < 0)
326 			return ret;
327 
328 		if (!qca808x_is_prefer_master(phydev)) {
329 			/* Enable seed and configure lower ramdom seed to make phy
330 			 * linked as slave mode.
331 			 */
332 			ret = qca808x_phy_ms_seed_enable(phydev, true);
333 			if (ret)
334 				return ret;
335 		}
336 	}
337 
338 	/* Configure adc threshold as 100mv for the link 10M */
339 	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
340 				     QCA808X_ADC_THRESHOLD_MASK,
341 				     QCA808X_ADC_THRESHOLD_100MV);
342 }
343 
344 static int qca808x_read_status(struct phy_device *phydev)
345 {
346 	struct at803x_ss_mask ss_mask = { 0 };
347 	int ret;
348 
349 	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
350 	if (ret < 0)
351 		return ret;
352 
353 	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
354 			 ret & MDIO_AN_10GBT_STAT_LP2_5G);
355 
356 	ret = genphy_read_status(phydev);
357 	if (ret)
358 		return ret;
359 
360 	/* qca8081 takes the different bits for speed value from at803x */
361 	ss_mask.speed_mask = QCA808X_SS_SPEED_MASK;
362 	ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK);
363 	ret = at803x_read_specific_status(phydev, ss_mask);
364 	if (ret < 0)
365 		return ret;
366 
367 	if (phydev->link) {
368 		if (phydev->speed == SPEED_2500)
369 			phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
370 		else
371 			phydev->interface = PHY_INTERFACE_MODE_SGMII;
372 	} else {
373 		/* generate seed as a lower random value to make PHY linked as SLAVE easily,
374 		 * except for master/slave configuration fault detected or the master mode
375 		 * preferred.
376 		 *
377 		 * the reason for not putting this code into the function link_change_notify is
378 		 * the corner case where the link partner is also the qca8081 PHY and the seed
379 		 * value is configured as the same value, the link can't be up and no link change
380 		 * occurs.
381 		 */
382 		if (qca808x_has_fast_retrain_or_slave_seed(phydev)) {
383 			if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR ||
384 			    qca808x_is_prefer_master(phydev)) {
385 				qca808x_phy_ms_seed_enable(phydev, false);
386 			} else {
387 				qca808x_phy_ms_seed_enable(phydev, true);
388 			}
389 		}
390 	}
391 
392 	return 0;
393 }
394 
395 static int qca808x_soft_reset(struct phy_device *phydev)
396 {
397 	int ret;
398 
399 	ret = genphy_soft_reset(phydev);
400 	if (ret < 0)
401 		return ret;
402 
403 	if (qca808x_has_fast_retrain_or_slave_seed(phydev))
404 		ret = qca808x_phy_ms_seed_enable(phydev, true);
405 
406 	return ret;
407 }
408 
409 static bool qca808x_cdt_fault_length_valid(int cdt_code)
410 {
411 	switch (cdt_code) {
412 	case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
413 	case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
414 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
415 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
416 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
417 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
418 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
419 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
420 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
421 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
422 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
423 		return true;
424 	default:
425 		return false;
426 	}
427 }
428 
429 static int qca808x_cable_test_result_trans(int cdt_code)
430 {
431 	switch (cdt_code) {
432 	case QCA808X_CDT_STATUS_STAT_NORMAL:
433 		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
434 	case QCA808X_CDT_STATUS_STAT_SAME_SHORT:
435 		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
436 	case QCA808X_CDT_STATUS_STAT_SAME_OPEN:
437 		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
438 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL:
439 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN:
440 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT:
441 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL:
442 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN:
443 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT:
444 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL:
445 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN:
446 	case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT:
447 		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
448 	case QCA808X_CDT_STATUS_STAT_FAIL:
449 	default:
450 		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
451 	}
452 }
453 
454 static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair,
455 				    int result)
456 {
457 	int val;
458 	u32 cdt_length_reg = 0;
459 
460 	switch (pair) {
461 	case ETHTOOL_A_CABLE_PAIR_A:
462 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
463 		break;
464 	case ETHTOOL_A_CABLE_PAIR_B:
465 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
466 		break;
467 	case ETHTOOL_A_CABLE_PAIR_C:
468 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
469 		break;
470 	case ETHTOOL_A_CABLE_PAIR_D:
471 		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
472 		break;
473 	default:
474 		return -EINVAL;
475 	}
476 
477 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
478 	if (val < 0)
479 		return val;
480 
481 	if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT)
482 		val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val);
483 	else
484 		val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val);
485 
486 	return at803x_cdt_fault_length(val);
487 }
488 
489 static int qca808x_cable_test_start(struct phy_device *phydev)
490 {
491 	int ret;
492 
493 	/* perform CDT with the following configs:
494 	 * 1. disable hibernation.
495 	 * 2. force PHY working in MDI mode.
496 	 * 3. for PHY working in 1000BaseT.
497 	 * 4. configure the threshold.
498 	 */
499 
500 	ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
501 	if (ret < 0)
502 		return ret;
503 
504 	ret = at803x_config_mdix(phydev, ETH_TP_MDI);
505 	if (ret < 0)
506 		return ret;
507 
508 	/* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
509 	phydev->duplex = DUPLEX_FULL;
510 	phydev->speed = SPEED_1000;
511 	ret = genphy_c45_pma_setup_forced(phydev);
512 	if (ret < 0)
513 		return ret;
514 
515 	ret = genphy_setup_forced(phydev);
516 	if (ret < 0)
517 		return ret;
518 
519 	/* configure the thresholds for open, short, pair ok test */
520 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
521 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
522 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
523 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
524 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
525 	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
526 
527 	return 0;
528 }
529 
530 static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair,
531 					      u16 status)
532 {
533 	int length, result;
534 	u16 pair_code;
535 
536 	switch (pair) {
537 	case ETHTOOL_A_CABLE_PAIR_A:
538 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status);
539 		break;
540 	case ETHTOOL_A_CABLE_PAIR_B:
541 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status);
542 		break;
543 	case ETHTOOL_A_CABLE_PAIR_C:
544 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status);
545 		break;
546 	case ETHTOOL_A_CABLE_PAIR_D:
547 		pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status);
548 		break;
549 	default:
550 		return -EINVAL;
551 	}
552 
553 	result = qca808x_cable_test_result_trans(pair_code);
554 	ethnl_cable_test_result(phydev, pair, result);
555 
556 	if (qca808x_cdt_fault_length_valid(pair_code)) {
557 		length = qca808x_cdt_fault_length(phydev, pair, result);
558 		ethnl_cable_test_fault_length(phydev, pair, length);
559 	}
560 
561 	return 0;
562 }
563 
564 static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
565 {
566 	int ret, val;
567 
568 	*finished = false;
569 
570 	val = QCA808X_CDT_ENABLE_TEST |
571 	      QCA808X_CDT_LENGTH_UNIT;
572 	ret = at803x_cdt_start(phydev, val);
573 	if (ret)
574 		return ret;
575 
576 	ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST);
577 	if (ret)
578 		return ret;
579 
580 	val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
581 	if (val < 0)
582 		return val;
583 
584 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val);
585 	if (ret)
586 		return ret;
587 
588 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val);
589 	if (ret)
590 		return ret;
591 
592 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val);
593 	if (ret)
594 		return ret;
595 
596 	ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val);
597 	if (ret)
598 		return ret;
599 
600 	*finished = true;
601 
602 	return 0;
603 }
604 
605 static int qca808x_get_features(struct phy_device *phydev)
606 {
607 	int ret;
608 
609 	ret = genphy_c45_pma_read_abilities(phydev);
610 	if (ret)
611 		return ret;
612 
613 	/* The autoneg ability is not existed in bit3 of MMD7.1,
614 	 * but it is supported by qca808x PHY, so we add it here
615 	 * manually.
616 	 */
617 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
618 
619 	/* As for the qca8081 1G version chip, the 2500baseT ability is also
620 	 * existed in the bit0 of MMD1.21, we need to remove it manually if
621 	 * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d.
622 	 */
623 	ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
624 	if (ret < 0)
625 		return ret;
626 
627 	if (QCA808X_PHY_CHIP_TYPE_1G & ret)
628 		linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
629 
630 	return 0;
631 }
632 
633 static int qca808x_config_aneg(struct phy_device *phydev)
634 {
635 	int phy_ctrl = 0;
636 	int ret;
637 
638 	ret = at803x_prepare_config_aneg(phydev);
639 	if (ret)
640 		return ret;
641 
642 	/* The reg MII_BMCR also needs to be configured for force mode, the
643 	 * genphy_config_aneg is also needed.
644 	 */
645 	if (phydev->autoneg == AUTONEG_DISABLE)
646 		genphy_c45_pma_setup_forced(phydev);
647 
648 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
649 		phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
650 
651 	ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
652 				     MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
653 	if (ret < 0)
654 		return ret;
655 
656 	return __genphy_config_aneg(phydev, ret);
657 }
658 
659 static void qca808x_link_change_notify(struct phy_device *phydev)
660 {
661 	/* Assert interface sgmii fifo on link down, deassert it on link up,
662 	 * the interface device address is always phy address added by 1.
663 	 */
664 	mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1,
665 				   MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL,
666 				   QCA8081_PHY_FIFO_RSTN,
667 				   phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
668 }
669 
670 static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules,
671 				    u16 *offload_trigger)
672 {
673 	/* Parsing specific to netdev trigger */
674 	if (test_bit(TRIGGER_NETDEV_TX, &rules))
675 		*offload_trigger |= QCA808X_LED_TX_BLINK;
676 	if (test_bit(TRIGGER_NETDEV_RX, &rules))
677 		*offload_trigger |= QCA808X_LED_RX_BLINK;
678 	if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
679 		*offload_trigger |= QCA808X_LED_SPEED10_ON;
680 	if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
681 		*offload_trigger |= QCA808X_LED_SPEED100_ON;
682 	if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
683 		*offload_trigger |= QCA808X_LED_SPEED1000_ON;
684 	if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules))
685 		*offload_trigger |= QCA808X_LED_SPEED2500_ON;
686 	if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules))
687 		*offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON;
688 	if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules))
689 		*offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON;
690 
691 	if (rules && !*offload_trigger)
692 		return -EOPNOTSUPP;
693 
694 	/* Enable BLINK_CHECK_BYPASS by default to make the LED
695 	 * blink even with duplex or speed mode not enabled.
696 	 */
697 	*offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS;
698 
699 	return 0;
700 }
701 
702 static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index)
703 {
704 	u16 reg;
705 
706 	if (index > 2)
707 		return -EINVAL;
708 
709 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
710 
711 	return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
712 				  QCA808X_LED_FORCE_EN);
713 }
714 
715 static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index,
716 				       unsigned long rules)
717 {
718 	u16 offload_trigger = 0;
719 
720 	if (index > 2)
721 		return -EINVAL;
722 
723 	return qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
724 }
725 
726 static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index,
727 				      unsigned long rules)
728 {
729 	u16 reg, offload_trigger = 0;
730 	int ret;
731 
732 	if (index > 2)
733 		return -EINVAL;
734 
735 	reg = QCA808X_MMD7_LED_CTRL(index);
736 
737 	ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger);
738 	if (ret)
739 		return ret;
740 
741 	ret = qca808x_led_hw_control_enable(phydev, index);
742 	if (ret)
743 		return ret;
744 
745 	return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
746 			      QCA808X_LED_PATTERN_MASK,
747 			      offload_trigger);
748 }
749 
750 static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index)
751 {
752 	u16 reg;
753 	int val;
754 
755 	if (index > 2)
756 		return false;
757 
758 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
759 
760 	val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
761 
762 	return !(val & QCA808X_LED_FORCE_EN);
763 }
764 
765 static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index,
766 				      unsigned long *rules)
767 {
768 	u16 reg;
769 	int val;
770 
771 	if (index > 2)
772 		return -EINVAL;
773 
774 	/* Check if we have hw control enabled */
775 	if (qca808x_led_hw_control_status(phydev, index))
776 		return -EINVAL;
777 
778 	reg = QCA808X_MMD7_LED_CTRL(index);
779 
780 	val = phy_read_mmd(phydev, MDIO_MMD_AN, reg);
781 	if (val & QCA808X_LED_TX_BLINK)
782 		set_bit(TRIGGER_NETDEV_TX, rules);
783 	if (val & QCA808X_LED_RX_BLINK)
784 		set_bit(TRIGGER_NETDEV_RX, rules);
785 	if (val & QCA808X_LED_SPEED10_ON)
786 		set_bit(TRIGGER_NETDEV_LINK_10, rules);
787 	if (val & QCA808X_LED_SPEED100_ON)
788 		set_bit(TRIGGER_NETDEV_LINK_100, rules);
789 	if (val & QCA808X_LED_SPEED1000_ON)
790 		set_bit(TRIGGER_NETDEV_LINK_1000, rules);
791 	if (val & QCA808X_LED_SPEED2500_ON)
792 		set_bit(TRIGGER_NETDEV_LINK_2500, rules);
793 	if (val & QCA808X_LED_HALF_DUPLEX_ON)
794 		set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules);
795 	if (val & QCA808X_LED_FULL_DUPLEX_ON)
796 		set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules);
797 
798 	return 0;
799 }
800 
801 static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index)
802 {
803 	u16 reg;
804 
805 	if (index > 2)
806 		return -EINVAL;
807 
808 	reg = QCA808X_MMD7_LED_CTRL(index);
809 
810 	return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg,
811 				  QCA808X_LED_PATTERN_MASK);
812 }
813 
814 static int qca808x_led_brightness_set(struct phy_device *phydev,
815 				      u8 index, enum led_brightness value)
816 {
817 	u16 reg;
818 	int ret;
819 
820 	if (index > 2)
821 		return -EINVAL;
822 
823 	if (!value) {
824 		ret = qca808x_led_hw_control_reset(phydev, index);
825 		if (ret)
826 			return ret;
827 	}
828 
829 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
830 
831 	return phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
832 			      QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
833 			      QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON :
834 							     QCA808X_LED_FORCE_OFF));
835 }
836 
837 static int qca808x_led_blink_set(struct phy_device *phydev, u8 index,
838 				 unsigned long *delay_on,
839 				 unsigned long *delay_off)
840 {
841 	int ret;
842 	u16 reg;
843 
844 	if (index > 2)
845 		return -EINVAL;
846 
847 	reg = QCA808X_MMD7_LED_FORCE_CTRL(index);
848 
849 	/* Set blink to 50% off, 50% on at 4Hz by default */
850 	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL,
851 			     QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK,
852 			     QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50);
853 	if (ret)
854 		return ret;
855 
856 	/* We use BLINK_1 for normal blinking */
857 	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg,
858 			     QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK,
859 			     QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1);
860 	if (ret)
861 		return ret;
862 
863 	/* We set blink to 4Hz, aka 250ms */
864 	*delay_on = 250 / 2;
865 	*delay_off = 250 / 2;
866 
867 	return 0;
868 }
869 
870 static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
871 				    unsigned long modes)
872 {
873 	struct qca808x_priv *priv = phydev->priv;
874 	bool active_low = false;
875 	u32 mode;
876 
877 	for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
878 		switch (mode) {
879 		case PHY_LED_ACTIVE_LOW:
880 			active_low = true;
881 			break;
882 		default:
883 			return -EINVAL;
884 		}
885 	}
886 
887 	/* PHY polarity is global and can't be set per LED.
888 	 * To detect this, check if last requested polarity mode
889 	 * match the new one.
890 	 */
891 	if (priv->led_polarity_mode >= 0 &&
892 	    priv->led_polarity_mode != active_low) {
893 		phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
894 		return -EINVAL;
895 	}
896 
897 	/* Save the last PHY polarity mode */
898 	priv->led_polarity_mode = active_low;
899 
900 	return phy_modify_mmd(phydev, MDIO_MMD_AN,
901 			      QCA808X_MMD7_LED_POLARITY_CTRL,
902 			      QCA808X_LED_ACTIVE_HIGH,
903 			      active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
904 }
905 
906 static struct phy_driver qca808x_driver[] = {
907 {
908 	/* Qualcomm QCA8081 */
909 	PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
910 	.name			= "Qualcomm QCA8081",
911 	.flags			= PHY_POLL_CABLE_TEST,
912 	.probe			= qca808x_probe,
913 	.config_intr		= at803x_config_intr,
914 	.handle_interrupt	= at803x_handle_interrupt,
915 	.get_tunable		= at803x_get_tunable,
916 	.set_tunable		= at803x_set_tunable,
917 	.set_wol		= at803x_set_wol,
918 	.get_wol		= at803x_get_wol,
919 	.get_features		= qca808x_get_features,
920 	.config_aneg		= qca808x_config_aneg,
921 	.suspend		= genphy_suspend,
922 	.resume			= genphy_resume,
923 	.read_status		= qca808x_read_status,
924 	.config_init		= qca808x_config_init,
925 	.soft_reset		= qca808x_soft_reset,
926 	.cable_test_start	= qca808x_cable_test_start,
927 	.cable_test_get_status	= qca808x_cable_test_get_status,
928 	.link_change_notify	= qca808x_link_change_notify,
929 	.led_brightness_set	= qca808x_led_brightness_set,
930 	.led_blink_set		= qca808x_led_blink_set,
931 	.led_hw_is_supported	= qca808x_led_hw_is_supported,
932 	.led_hw_control_set	= qca808x_led_hw_control_set,
933 	.led_hw_control_get	= qca808x_led_hw_control_get,
934 	.led_polarity_set	= qca808x_led_polarity_set,
935 }, };
936 
937 module_phy_driver(qca808x_driver);
938 
939 static struct mdio_device_id __maybe_unused qca808x_tbl[] = {
940 	{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
941 	{ }
942 };
943 
944 MODULE_DEVICE_TABLE(mdio, qca808x_tbl);
945