1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Driver for the Airoha EN8811H 2.5 Gigabit PHY.
4 *
5 * Limitations of the EN8811H:
6 * - Only full duplex supported
7 * - Forced speed (AN off) is not supported by hardware (100Mbps)
8 *
9 * Source originated from airoha's en8811h.c and en8811h.h v1.2.1
10 *
11 * Copyright (C) 2023 Airoha Technology Corp.
12 */
13
14 #include <linux/clk.h>
15 #include <linux/clk-provider.h>
16 #include <linux/phy.h>
17 #include <linux/firmware.h>
18 #include <linux/property.h>
19 #include <linux/wordpart.h>
20 #include <linux/unaligned.h>
21
22 #define EN8811H_PHY_ID 0x03a2a411
23
24 #define EN8811H_MD32_DM "airoha/EthMD32.dm.bin"
25 #define EN8811H_MD32_DSP "airoha/EthMD32.DSP.bin"
26
27 #define AIR_FW_ADDR_DM 0x00000000
28 #define AIR_FW_ADDR_DSP 0x00100000
29
30 /* MII Registers */
31 #define AIR_AUX_CTRL_STATUS 0x1d
32 #define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2)
33 #define AIR_AUX_CTRL_STATUS_SPEED_100 0x4
34 #define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8
35 #define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc
36
37 #define AIR_EXT_PAGE_ACCESS 0x1f
38 #define AIR_PHY_PAGE_STANDARD 0x0000
39 #define AIR_PHY_PAGE_EXTENDED_4 0x0004
40
41 /* MII Registers Page 4*/
42 #define AIR_BPBUS_MODE 0x10
43 #define AIR_BPBUS_MODE_ADDR_FIXED 0x0000
44 #define AIR_BPBUS_MODE_ADDR_INCR BIT(15)
45 #define AIR_BPBUS_WR_ADDR_HIGH 0x11
46 #define AIR_BPBUS_WR_ADDR_LOW 0x12
47 #define AIR_BPBUS_WR_DATA_HIGH 0x13
48 #define AIR_BPBUS_WR_DATA_LOW 0x14
49 #define AIR_BPBUS_RD_ADDR_HIGH 0x15
50 #define AIR_BPBUS_RD_ADDR_LOW 0x16
51 #define AIR_BPBUS_RD_DATA_HIGH 0x17
52 #define AIR_BPBUS_RD_DATA_LOW 0x18
53
54 /* Registers on MDIO_MMD_VEND1 */
55 #define EN8811H_PHY_FW_STATUS 0x8009
56 #define EN8811H_PHY_READY 0x02
57
58 #define AIR_PHY_MCU_CMD_1 0x800c
59 #define AIR_PHY_MCU_CMD_1_MODE1 0x0
60 #define AIR_PHY_MCU_CMD_2 0x800d
61 #define AIR_PHY_MCU_CMD_2_MODE1 0x0
62 #define AIR_PHY_MCU_CMD_3 0x800e
63 #define AIR_PHY_MCU_CMD_3_MODE1 0x1101
64 #define AIR_PHY_MCU_CMD_3_DOCMD 0x1100
65 #define AIR_PHY_MCU_CMD_4 0x800f
66 #define AIR_PHY_MCU_CMD_4_MODE1 0x0002
67 #define AIR_PHY_MCU_CMD_4_INTCLR 0x00e4
68
69 /* Registers on MDIO_MMD_VEND2 */
70 #define AIR_PHY_LED_BCR 0x021
71 #define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0)
72 #define AIR_PHY_LED_BCR_TIME_TEST BIT(2)
73 #define AIR_PHY_LED_BCR_CLK_EN BIT(3)
74 #define AIR_PHY_LED_BCR_EXT_CTRL BIT(15)
75
76 #define AIR_PHY_LED_DUR_ON 0x022
77
78 #define AIR_PHY_LED_DUR_BLINK 0x023
79
80 #define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2))
81 #define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8))
82 #define AIR_PHY_LED_ON_LINK1000 BIT(0)
83 #define AIR_PHY_LED_ON_LINK100 BIT(1)
84 #define AIR_PHY_LED_ON_LINK10 BIT(2)
85 #define AIR_PHY_LED_ON_LINKDOWN BIT(3)
86 #define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */
87 #define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */
88 #define AIR_PHY_LED_ON_FORCE_ON BIT(6)
89 #define AIR_PHY_LED_ON_LINK2500 BIT(8)
90 #define AIR_PHY_LED_ON_POLARITY BIT(14)
91 #define AIR_PHY_LED_ON_ENABLE BIT(15)
92
93 #define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2))
94 #define AIR_PHY_LED_BLINK_1000TX BIT(0)
95 #define AIR_PHY_LED_BLINK_1000RX BIT(1)
96 #define AIR_PHY_LED_BLINK_100TX BIT(2)
97 #define AIR_PHY_LED_BLINK_100RX BIT(3)
98 #define AIR_PHY_LED_BLINK_10TX BIT(4)
99 #define AIR_PHY_LED_BLINK_10RX BIT(5)
100 #define AIR_PHY_LED_BLINK_COLLISION BIT(6)
101 #define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
102 #define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
103 #define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9)
104 #define AIR_PHY_LED_BLINK_2500TX BIT(10)
105 #define AIR_PHY_LED_BLINK_2500RX BIT(11)
106
107 /* Registers on BUCKPBUS */
108 #define EN8811H_2P5G_LPA 0x3b30
109 #define EN8811H_2P5G_LPA_2P5G BIT(0)
110
111 #define EN8811H_FW_VERSION 0x3b3c
112
113 #define EN8811H_POLARITY 0xca0f8
114 #define EN8811H_POLARITY_TX_NORMAL BIT(0)
115 #define EN8811H_POLARITY_RX_REVERSE BIT(1)
116
117 #define EN8811H_GPIO_OUTPUT 0xcf8b8
118 #define EN8811H_GPIO_OUTPUT_345 (BIT(3) | BIT(4) | BIT(5))
119
120 #define EN8811H_HWTRAP1 0xcf914
121 #define EN8811H_HWTRAP1_CKO BIT(12)
122 #define EN8811H_CLK_CGM 0xcf958
123 #define EN8811H_CLK_CGM_CKO BIT(26)
124
125 #define EN8811H_FW_CTRL_1 0x0f0018
126 #define EN8811H_FW_CTRL_1_START 0x0
127 #define EN8811H_FW_CTRL_1_FINISH 0x1
128 #define EN8811H_FW_CTRL_2 0x800000
129 #define EN8811H_FW_CTRL_2_LOADING BIT(11)
130
131 /* Led definitions */
132 #define EN8811H_LED_COUNT 3
133
134 /* Default LED setup:
135 * GPIO5 <-> LED0 On: Link detected, blink Rx/Tx
136 * GPIO4 <-> LED1 On: Link detected at 2500 or 1000 Mbps
137 * GPIO3 <-> LED2 On: Link detected at 2500 or 100 Mbps
138 */
139 #define AIR_DEFAULT_TRIGGER_LED0 (BIT(TRIGGER_NETDEV_LINK) | \
140 BIT(TRIGGER_NETDEV_RX) | \
141 BIT(TRIGGER_NETDEV_TX))
142 #define AIR_DEFAULT_TRIGGER_LED1 (BIT(TRIGGER_NETDEV_LINK_2500) | \
143 BIT(TRIGGER_NETDEV_LINK_1000))
144 #define AIR_DEFAULT_TRIGGER_LED2 (BIT(TRIGGER_NETDEV_LINK_2500) | \
145 BIT(TRIGGER_NETDEV_LINK_100))
146
147 struct led {
148 unsigned long rules;
149 unsigned long state;
150 };
151
152 #define clk_hw_to_en8811h_priv(_hw) \
153 container_of(_hw, struct en8811h_priv, hw)
154
155 struct en8811h_priv {
156 u32 firmware_version;
157 bool mcu_needs_restart;
158 struct led led[EN8811H_LED_COUNT];
159 struct clk_hw hw;
160 struct phy_device *phydev;
161 unsigned int cko_is_enabled;
162 };
163
164 enum {
165 AIR_PHY_LED_STATE_FORCE_ON,
166 AIR_PHY_LED_STATE_FORCE_BLINK,
167 };
168
169 enum {
170 AIR_PHY_LED_DUR_BLINK_32MS,
171 AIR_PHY_LED_DUR_BLINK_64MS,
172 AIR_PHY_LED_DUR_BLINK_128MS,
173 AIR_PHY_LED_DUR_BLINK_256MS,
174 AIR_PHY_LED_DUR_BLINK_512MS,
175 AIR_PHY_LED_DUR_BLINK_1024MS,
176 };
177
178 enum {
179 AIR_LED_DISABLE,
180 AIR_LED_ENABLE,
181 };
182
183 enum {
184 AIR_ACTIVE_LOW,
185 AIR_ACTIVE_HIGH,
186 };
187
188 enum {
189 AIR_LED_MODE_DISABLE,
190 AIR_LED_MODE_USER_DEFINE,
191 };
192
193 #define AIR_PHY_LED_DUR_UNIT 1024
194 #define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64MS)
195
196 static const unsigned long en8811h_led_trig = BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
197 BIT(TRIGGER_NETDEV_LINK) |
198 BIT(TRIGGER_NETDEV_LINK_10) |
199 BIT(TRIGGER_NETDEV_LINK_100) |
200 BIT(TRIGGER_NETDEV_LINK_1000) |
201 BIT(TRIGGER_NETDEV_LINK_2500) |
202 BIT(TRIGGER_NETDEV_RX) |
203 BIT(TRIGGER_NETDEV_TX);
204
air_phy_read_page(struct phy_device * phydev)205 static int air_phy_read_page(struct phy_device *phydev)
206 {
207 return __phy_read(phydev, AIR_EXT_PAGE_ACCESS);
208 }
209
air_phy_write_page(struct phy_device * phydev,int page)210 static int air_phy_write_page(struct phy_device *phydev, int page)
211 {
212 return __phy_write(phydev, AIR_EXT_PAGE_ACCESS, page);
213 }
214
__air_buckpbus_reg_write(struct phy_device * phydev,u32 pbus_address,u32 pbus_data)215 static int __air_buckpbus_reg_write(struct phy_device *phydev,
216 u32 pbus_address, u32 pbus_data)
217 {
218 int ret;
219
220 ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
221 if (ret < 0)
222 return ret;
223
224 ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH,
225 upper_16_bits(pbus_address));
226 if (ret < 0)
227 return ret;
228
229 ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW,
230 lower_16_bits(pbus_address));
231 if (ret < 0)
232 return ret;
233
234 ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH,
235 upper_16_bits(pbus_data));
236 if (ret < 0)
237 return ret;
238
239 ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW,
240 lower_16_bits(pbus_data));
241 if (ret < 0)
242 return ret;
243
244 return 0;
245 }
246
air_buckpbus_reg_write(struct phy_device * phydev,u32 pbus_address,u32 pbus_data)247 static int air_buckpbus_reg_write(struct phy_device *phydev,
248 u32 pbus_address, u32 pbus_data)
249 {
250 int saved_page;
251 int ret = 0;
252
253 saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
254
255 if (saved_page >= 0) {
256 ret = __air_buckpbus_reg_write(phydev, pbus_address,
257 pbus_data);
258 if (ret < 0)
259 phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
260 pbus_address, ret);
261 }
262
263 return phy_restore_page(phydev, saved_page, ret);
264 }
265
__air_buckpbus_reg_read(struct phy_device * phydev,u32 pbus_address,u32 * pbus_data)266 static int __air_buckpbus_reg_read(struct phy_device *phydev,
267 u32 pbus_address, u32 *pbus_data)
268 {
269 int pbus_data_low, pbus_data_high;
270 int ret;
271
272 ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
273 if (ret < 0)
274 return ret;
275
276 ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_HIGH,
277 upper_16_bits(pbus_address));
278 if (ret < 0)
279 return ret;
280
281 ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_LOW,
282 lower_16_bits(pbus_address));
283 if (ret < 0)
284 return ret;
285
286 pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
287 if (pbus_data_high < 0)
288 return pbus_data_high;
289
290 pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
291 if (pbus_data_low < 0)
292 return pbus_data_low;
293
294 *pbus_data = pbus_data_low | (pbus_data_high << 16);
295 return 0;
296 }
297
air_buckpbus_reg_read(struct phy_device * phydev,u32 pbus_address,u32 * pbus_data)298 static int air_buckpbus_reg_read(struct phy_device *phydev,
299 u32 pbus_address, u32 *pbus_data)
300 {
301 int saved_page;
302 int ret = 0;
303
304 saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
305
306 if (saved_page >= 0) {
307 ret = __air_buckpbus_reg_read(phydev, pbus_address, pbus_data);
308 if (ret < 0)
309 phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
310 pbus_address, ret);
311 }
312
313 return phy_restore_page(phydev, saved_page, ret);
314 }
315
__air_buckpbus_reg_modify(struct phy_device * phydev,u32 pbus_address,u32 mask,u32 set)316 static int __air_buckpbus_reg_modify(struct phy_device *phydev,
317 u32 pbus_address, u32 mask, u32 set)
318 {
319 int pbus_data_low, pbus_data_high;
320 u32 pbus_data_old, pbus_data_new;
321 int ret;
322
323 ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
324 if (ret < 0)
325 return ret;
326
327 ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_HIGH,
328 upper_16_bits(pbus_address));
329 if (ret < 0)
330 return ret;
331
332 ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_LOW,
333 lower_16_bits(pbus_address));
334 if (ret < 0)
335 return ret;
336
337 pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH);
338 if (pbus_data_high < 0)
339 return pbus_data_high;
340
341 pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW);
342 if (pbus_data_low < 0)
343 return pbus_data_low;
344
345 pbus_data_old = pbus_data_low | (pbus_data_high << 16);
346 pbus_data_new = (pbus_data_old & ~mask) | set;
347 if (pbus_data_new == pbus_data_old)
348 return 0;
349
350 ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH,
351 upper_16_bits(pbus_address));
352 if (ret < 0)
353 return ret;
354
355 ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW,
356 lower_16_bits(pbus_address));
357 if (ret < 0)
358 return ret;
359
360 ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH,
361 upper_16_bits(pbus_data_new));
362 if (ret < 0)
363 return ret;
364
365 ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW,
366 lower_16_bits(pbus_data_new));
367 if (ret < 0)
368 return ret;
369
370 return 0;
371 }
372
air_buckpbus_reg_modify(struct phy_device * phydev,u32 pbus_address,u32 mask,u32 set)373 static int air_buckpbus_reg_modify(struct phy_device *phydev,
374 u32 pbus_address, u32 mask, u32 set)
375 {
376 int saved_page;
377 int ret = 0;
378
379 saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
380
381 if (saved_page >= 0) {
382 ret = __air_buckpbus_reg_modify(phydev, pbus_address, mask,
383 set);
384 if (ret < 0)
385 phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
386 pbus_address, ret);
387 }
388
389 return phy_restore_page(phydev, saved_page, ret);
390 }
391
__air_write_buf(struct phy_device * phydev,u32 address,const struct firmware * fw)392 static int __air_write_buf(struct phy_device *phydev, u32 address,
393 const struct firmware *fw)
394 {
395 unsigned int offset;
396 int ret;
397 u16 val;
398
399 ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_INCR);
400 if (ret < 0)
401 return ret;
402
403 ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH,
404 upper_16_bits(address));
405 if (ret < 0)
406 return ret;
407
408 ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW,
409 lower_16_bits(address));
410 if (ret < 0)
411 return ret;
412
413 for (offset = 0; offset < fw->size; offset += 4) {
414 val = get_unaligned_le16(&fw->data[offset + 2]);
415 ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH, val);
416 if (ret < 0)
417 return ret;
418
419 val = get_unaligned_le16(&fw->data[offset]);
420 ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW, val);
421 if (ret < 0)
422 return ret;
423 }
424
425 return 0;
426 }
427
air_write_buf(struct phy_device * phydev,u32 address,const struct firmware * fw)428 static int air_write_buf(struct phy_device *phydev, u32 address,
429 const struct firmware *fw)
430 {
431 int saved_page;
432 int ret = 0;
433
434 saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
435
436 if (saved_page >= 0) {
437 ret = __air_write_buf(phydev, address, fw);
438 if (ret < 0)
439 phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__,
440 address, ret);
441 }
442
443 return phy_restore_page(phydev, saved_page, ret);
444 }
445
en8811h_wait_mcu_ready(struct phy_device * phydev)446 static int en8811h_wait_mcu_ready(struct phy_device *phydev)
447 {
448 int ret, reg_value;
449
450 /* Because of mdio-lock, may have to wait for multiple loads */
451 ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
452 EN8811H_PHY_FW_STATUS, reg_value,
453 reg_value == EN8811H_PHY_READY,
454 20000, 7500000, true);
455 if (ret) {
456 phydev_err(phydev, "MCU not ready: 0x%x\n", reg_value);
457 return -ENODEV;
458 }
459
460 return 0;
461 }
462
en8811h_load_firmware(struct phy_device * phydev)463 static int en8811h_load_firmware(struct phy_device *phydev)
464 {
465 struct en8811h_priv *priv = phydev->priv;
466 struct device *dev = &phydev->mdio.dev;
467 const struct firmware *fw1, *fw2;
468 int ret;
469
470 ret = request_firmware_direct(&fw1, EN8811H_MD32_DM, dev);
471 if (ret < 0)
472 return ret;
473
474 ret = request_firmware_direct(&fw2, EN8811H_MD32_DSP, dev);
475 if (ret < 0)
476 goto en8811h_load_firmware_rel1;
477
478 ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
479 EN8811H_FW_CTRL_1_START);
480 if (ret < 0)
481 goto en8811h_load_firmware_out;
482
483 ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
484 EN8811H_FW_CTRL_2_LOADING,
485 EN8811H_FW_CTRL_2_LOADING);
486 if (ret < 0)
487 goto en8811h_load_firmware_out;
488
489 ret = air_write_buf(phydev, AIR_FW_ADDR_DM, fw1);
490 if (ret < 0)
491 goto en8811h_load_firmware_out;
492
493 ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, fw2);
494 if (ret < 0)
495 goto en8811h_load_firmware_out;
496
497 ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
498 EN8811H_FW_CTRL_2_LOADING, 0);
499 if (ret < 0)
500 goto en8811h_load_firmware_out;
501
502 ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
503 EN8811H_FW_CTRL_1_FINISH);
504 if (ret < 0)
505 goto en8811h_load_firmware_out;
506
507 ret = en8811h_wait_mcu_ready(phydev);
508
509 air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,
510 &priv->firmware_version);
511 phydev_info(phydev, "MD32 firmware version: %08x\n",
512 priv->firmware_version);
513
514 en8811h_load_firmware_out:
515 release_firmware(fw2);
516
517 en8811h_load_firmware_rel1:
518 release_firmware(fw1);
519
520 if (ret < 0)
521 phydev_err(phydev, "Load firmware failed: %d\n", ret);
522
523 return ret;
524 }
525
en8811h_restart_mcu(struct phy_device * phydev)526 static int en8811h_restart_mcu(struct phy_device *phydev)
527 {
528 int ret;
529
530 ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
531 EN8811H_FW_CTRL_1_START);
532 if (ret < 0)
533 return ret;
534
535 ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
536 EN8811H_FW_CTRL_1_FINISH);
537 if (ret < 0)
538 return ret;
539
540 return en8811h_wait_mcu_ready(phydev);
541 }
542
air_hw_led_on_set(struct phy_device * phydev,u8 index,bool on)543 static int air_hw_led_on_set(struct phy_device *phydev, u8 index, bool on)
544 {
545 struct en8811h_priv *priv = phydev->priv;
546 bool changed;
547
548 if (index >= EN8811H_LED_COUNT)
549 return -EINVAL;
550
551 if (on)
552 changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_ON,
553 &priv->led[index].state);
554 else
555 changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_ON,
556 &priv->led[index].state);
557
558 changed |= (priv->led[index].rules != 0);
559
560 /* clear netdev trigger rules in case LED_OFF has been set */
561 if (!on)
562 priv->led[index].rules = 0;
563
564 if (changed)
565 return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
566 AIR_PHY_LED_ON(index),
567 AIR_PHY_LED_ON_MASK,
568 on ? AIR_PHY_LED_ON_FORCE_ON : 0);
569
570 return 0;
571 }
572
air_hw_led_blink_set(struct phy_device * phydev,u8 index,bool blinking)573 static int air_hw_led_blink_set(struct phy_device *phydev, u8 index,
574 bool blinking)
575 {
576 struct en8811h_priv *priv = phydev->priv;
577 bool changed;
578
579 if (index >= EN8811H_LED_COUNT)
580 return -EINVAL;
581
582 if (blinking)
583 changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
584 &priv->led[index].state);
585 else
586 changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
587 &priv->led[index].state);
588
589 changed |= (priv->led[index].rules != 0);
590
591 if (changed)
592 return phy_write_mmd(phydev, MDIO_MMD_VEND2,
593 AIR_PHY_LED_BLINK(index),
594 blinking ?
595 AIR_PHY_LED_BLINK_FORCE_BLINK : 0);
596 else
597 return 0;
598 }
599
air_led_blink_set(struct phy_device * phydev,u8 index,unsigned long * delay_on,unsigned long * delay_off)600 static int air_led_blink_set(struct phy_device *phydev, u8 index,
601 unsigned long *delay_on,
602 unsigned long *delay_off)
603 {
604 struct en8811h_priv *priv = phydev->priv;
605 bool blinking = false;
606 int err;
607
608 if (index >= EN8811H_LED_COUNT)
609 return -EINVAL;
610
611 if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
612 blinking = true;
613 *delay_on = 50;
614 *delay_off = 50;
615 }
616
617 err = air_hw_led_blink_set(phydev, index, blinking);
618 if (err)
619 return err;
620
621 /* led-blink set, so switch led-on off */
622 err = air_hw_led_on_set(phydev, index, false);
623 if (err)
624 return err;
625
626 /* hw-control is off*/
627 if (!!test_bit(AIR_PHY_LED_STATE_FORCE_BLINK, &priv->led[index].state))
628 priv->led[index].rules = 0;
629
630 return 0;
631 }
632
air_led_brightness_set(struct phy_device * phydev,u8 index,enum led_brightness value)633 static int air_led_brightness_set(struct phy_device *phydev, u8 index,
634 enum led_brightness value)
635 {
636 struct en8811h_priv *priv = phydev->priv;
637 int err;
638
639 if (index >= EN8811H_LED_COUNT)
640 return -EINVAL;
641
642 /* led-on set, so switch led-blink off */
643 err = air_hw_led_blink_set(phydev, index, false);
644 if (err)
645 return err;
646
647 err = air_hw_led_on_set(phydev, index, (value != LED_OFF));
648 if (err)
649 return err;
650
651 /* hw-control is off */
652 if (!!test_bit(AIR_PHY_LED_STATE_FORCE_ON, &priv->led[index].state))
653 priv->led[index].rules = 0;
654
655 return 0;
656 }
657
air_led_hw_control_get(struct phy_device * phydev,u8 index,unsigned long * rules)658 static int air_led_hw_control_get(struct phy_device *phydev, u8 index,
659 unsigned long *rules)
660 {
661 struct en8811h_priv *priv = phydev->priv;
662
663 if (index >= EN8811H_LED_COUNT)
664 return -EINVAL;
665
666 *rules = priv->led[index].rules;
667
668 return 0;
669 };
670
air_led_hw_control_set(struct phy_device * phydev,u8 index,unsigned long rules)671 static int air_led_hw_control_set(struct phy_device *phydev, u8 index,
672 unsigned long rules)
673 {
674 struct en8811h_priv *priv = phydev->priv;
675 u16 on = 0, blink = 0;
676 int ret;
677
678 if (index >= EN8811H_LED_COUNT)
679 return -EINVAL;
680
681 priv->led[index].rules = rules;
682
683 if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
684 on |= AIR_PHY_LED_ON_FDX;
685
686 if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
687 on |= AIR_PHY_LED_ON_LINK10;
688
689 if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
690 on |= AIR_PHY_LED_ON_LINK100;
691
692 if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
693 on |= AIR_PHY_LED_ON_LINK1000;
694
695 if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
696 on |= AIR_PHY_LED_ON_LINK2500;
697
698 if (rules & BIT(TRIGGER_NETDEV_RX)) {
699 blink |= AIR_PHY_LED_BLINK_10RX |
700 AIR_PHY_LED_BLINK_100RX |
701 AIR_PHY_LED_BLINK_1000RX |
702 AIR_PHY_LED_BLINK_2500RX;
703 }
704
705 if (rules & BIT(TRIGGER_NETDEV_TX)) {
706 blink |= AIR_PHY_LED_BLINK_10TX |
707 AIR_PHY_LED_BLINK_100TX |
708 AIR_PHY_LED_BLINK_1000TX |
709 AIR_PHY_LED_BLINK_2500TX;
710 }
711
712 if (blink || on) {
713 /* switch hw-control on, so led-on and led-blink are off */
714 clear_bit(AIR_PHY_LED_STATE_FORCE_ON,
715 &priv->led[index].state);
716 clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK,
717 &priv->led[index].state);
718 } else {
719 priv->led[index].rules = 0;
720 }
721
722 ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
723 AIR_PHY_LED_ON_MASK, on);
724
725 if (ret < 0)
726 return ret;
727
728 return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index),
729 blink);
730 };
731
air_led_init(struct phy_device * phydev,u8 index,u8 state,u8 pol)732 static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol)
733 {
734 int val = 0;
735 int err;
736
737 if (index >= EN8811H_LED_COUNT)
738 return -EINVAL;
739
740 if (state == AIR_LED_ENABLE)
741 val |= AIR_PHY_LED_ON_ENABLE;
742 else
743 val &= ~AIR_PHY_LED_ON_ENABLE;
744
745 if (pol == AIR_ACTIVE_HIGH)
746 val |= AIR_PHY_LED_ON_POLARITY;
747 else
748 val &= ~AIR_PHY_LED_ON_POLARITY;
749
750 err = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
751 AIR_PHY_LED_ON_ENABLE |
752 AIR_PHY_LED_ON_POLARITY, val);
753
754 if (err < 0)
755 return err;
756
757 return 0;
758 }
759
air_leds_init(struct phy_device * phydev,int num,int dur,int mode)760 static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode)
761 {
762 struct en8811h_priv *priv = phydev->priv;
763 int ret, i;
764
765 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK,
766 dur);
767 if (ret < 0)
768 return ret;
769
770 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON,
771 dur >> 1);
772 if (ret < 0)
773 return ret;
774
775 switch (mode) {
776 case AIR_LED_MODE_DISABLE:
777 ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
778 AIR_PHY_LED_BCR_EXT_CTRL |
779 AIR_PHY_LED_BCR_MODE_MASK, 0);
780 if (ret < 0)
781 return ret;
782 break;
783 case AIR_LED_MODE_USER_DEFINE:
784 ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
785 AIR_PHY_LED_BCR_EXT_CTRL |
786 AIR_PHY_LED_BCR_CLK_EN,
787 AIR_PHY_LED_BCR_EXT_CTRL |
788 AIR_PHY_LED_BCR_CLK_EN);
789 if (ret < 0)
790 return ret;
791 break;
792 default:
793 phydev_err(phydev, "LED mode %d is not supported\n", mode);
794 return -EINVAL;
795 }
796
797 for (i = 0; i < num; ++i) {
798 ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH);
799 if (ret < 0) {
800 phydev_err(phydev, "LED%d init failed: %d\n", i, ret);
801 return ret;
802 }
803 air_led_hw_control_set(phydev, i, priv->led[i].rules);
804 }
805
806 return 0;
807 }
808
en8811h_led_hw_is_supported(struct phy_device * phydev,u8 index,unsigned long rules)809 static int en8811h_led_hw_is_supported(struct phy_device *phydev, u8 index,
810 unsigned long rules)
811 {
812 if (index >= EN8811H_LED_COUNT)
813 return -EINVAL;
814
815 /* All combinations of the supported triggers are allowed */
816 if (rules & ~en8811h_led_trig)
817 return -EOPNOTSUPP;
818
819 return 0;
820 };
821
en8811h_clk_recalc_rate(struct clk_hw * hw,unsigned long parent)822 static unsigned long en8811h_clk_recalc_rate(struct clk_hw *hw,
823 unsigned long parent)
824 {
825 struct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);
826 struct phy_device *phydev = priv->phydev;
827 u32 pbus_value;
828 int ret;
829
830 ret = air_buckpbus_reg_read(phydev, EN8811H_HWTRAP1, &pbus_value);
831 if (ret < 0)
832 return ret;
833
834 return (pbus_value & EN8811H_HWTRAP1_CKO) ? 50000000 : 25000000;
835 }
836
en8811h_clk_enable(struct clk_hw * hw)837 static int en8811h_clk_enable(struct clk_hw *hw)
838 {
839 struct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);
840 struct phy_device *phydev = priv->phydev;
841
842 return air_buckpbus_reg_modify(phydev, EN8811H_CLK_CGM,
843 EN8811H_CLK_CGM_CKO,
844 EN8811H_CLK_CGM_CKO);
845 }
846
en8811h_clk_disable(struct clk_hw * hw)847 static void en8811h_clk_disable(struct clk_hw *hw)
848 {
849 struct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);
850 struct phy_device *phydev = priv->phydev;
851
852 air_buckpbus_reg_modify(phydev, EN8811H_CLK_CGM,
853 EN8811H_CLK_CGM_CKO, 0);
854 }
855
en8811h_clk_is_enabled(struct clk_hw * hw)856 static int en8811h_clk_is_enabled(struct clk_hw *hw)
857 {
858 struct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);
859 struct phy_device *phydev = priv->phydev;
860 u32 pbus_value;
861 int ret;
862
863 ret = air_buckpbus_reg_read(phydev, EN8811H_CLK_CGM, &pbus_value);
864 if (ret < 0)
865 return ret;
866
867 return (pbus_value & EN8811H_CLK_CGM_CKO);
868 }
869
en8811h_clk_save_context(struct clk_hw * hw)870 static int en8811h_clk_save_context(struct clk_hw *hw)
871 {
872 struct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);
873
874 priv->cko_is_enabled = en8811h_clk_is_enabled(hw);
875
876 return 0;
877 }
878
en8811h_clk_restore_context(struct clk_hw * hw)879 static void en8811h_clk_restore_context(struct clk_hw *hw)
880 {
881 struct en8811h_priv *priv = clk_hw_to_en8811h_priv(hw);
882
883 if (!priv->cko_is_enabled)
884 en8811h_clk_disable(hw);
885 }
886
887 static const struct clk_ops en8811h_clk_ops = {
888 .recalc_rate = en8811h_clk_recalc_rate,
889 .enable = en8811h_clk_enable,
890 .disable = en8811h_clk_disable,
891 .is_enabled = en8811h_clk_is_enabled,
892 .save_context = en8811h_clk_save_context,
893 .restore_context = en8811h_clk_restore_context,
894 };
895
en8811h_clk_provider_setup(struct device * dev,struct clk_hw * hw)896 static int en8811h_clk_provider_setup(struct device *dev, struct clk_hw *hw)
897 {
898 struct clk_init_data init;
899 int ret;
900
901 if (!IS_ENABLED(CONFIG_COMMON_CLK))
902 return 0;
903
904 init.name = devm_kasprintf(dev, GFP_KERNEL, "%s-cko",
905 fwnode_get_name(dev_fwnode(dev)));
906 if (!init.name)
907 return -ENOMEM;
908
909 init.ops = &en8811h_clk_ops;
910 init.flags = 0;
911 init.num_parents = 0;
912 hw->init = &init;
913
914 ret = devm_clk_hw_register(dev, hw);
915 if (ret)
916 return ret;
917
918 return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
919 }
920
en8811h_probe(struct phy_device * phydev)921 static int en8811h_probe(struct phy_device *phydev)
922 {
923 struct en8811h_priv *priv;
924 int ret;
925
926 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct en8811h_priv),
927 GFP_KERNEL);
928 if (!priv)
929 return -ENOMEM;
930 phydev->priv = priv;
931
932 ret = en8811h_load_firmware(phydev);
933 if (ret < 0)
934 return ret;
935
936 /* mcu has just restarted after firmware load */
937 priv->mcu_needs_restart = false;
938
939 priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0;
940 priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1;
941 priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2;
942
943 /* MDIO_DEVS1/2 empty, so set mmds_present bits here */
944 phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
945
946 ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR,
947 AIR_LED_MODE_DISABLE);
948 if (ret < 0) {
949 phydev_err(phydev, "Failed to disable leds: %d\n", ret);
950 return ret;
951 }
952
953 priv->phydev = phydev;
954 /* Co-Clock Output */
955 ret = en8811h_clk_provider_setup(&phydev->mdio.dev, &priv->hw);
956 if (ret)
957 return ret;
958
959 /* Configure led gpio pins as output */
960 ret = air_buckpbus_reg_modify(phydev, EN8811H_GPIO_OUTPUT,
961 EN8811H_GPIO_OUTPUT_345,
962 EN8811H_GPIO_OUTPUT_345);
963 if (ret < 0)
964 return ret;
965
966 return 0;
967 }
968
en8811h_config_init(struct phy_device * phydev)969 static int en8811h_config_init(struct phy_device *phydev)
970 {
971 struct en8811h_priv *priv = phydev->priv;
972 struct device *dev = &phydev->mdio.dev;
973 u32 pbus_value;
974 int ret;
975
976 /* If restart happened in .probe(), no need to restart now */
977 if (priv->mcu_needs_restart) {
978 ret = en8811h_restart_mcu(phydev);
979 if (ret < 0)
980 return ret;
981 } else {
982 /* Next calls to .config_init() mcu needs to restart */
983 priv->mcu_needs_restart = true;
984 }
985
986 /* Select mode 1, the only mode supported.
987 * Configures the SerDes for 2500Base-X with rate adaptation
988 */
989 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_1,
990 AIR_PHY_MCU_CMD_1_MODE1);
991 if (ret < 0)
992 return ret;
993 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_2,
994 AIR_PHY_MCU_CMD_2_MODE1);
995 if (ret < 0)
996 return ret;
997 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_3,
998 AIR_PHY_MCU_CMD_3_MODE1);
999 if (ret < 0)
1000 return ret;
1001 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_4,
1002 AIR_PHY_MCU_CMD_4_MODE1);
1003 if (ret < 0)
1004 return ret;
1005
1006 /* Serdes polarity */
1007 pbus_value = 0;
1008 if (device_property_read_bool(dev, "airoha,pnswap-rx"))
1009 pbus_value |= EN8811H_POLARITY_RX_REVERSE;
1010 else
1011 pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
1012 if (device_property_read_bool(dev, "airoha,pnswap-tx"))
1013 pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
1014 else
1015 pbus_value |= EN8811H_POLARITY_TX_NORMAL;
1016 ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
1017 EN8811H_POLARITY_RX_REVERSE |
1018 EN8811H_POLARITY_TX_NORMAL, pbus_value);
1019 if (ret < 0)
1020 return ret;
1021
1022 ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR,
1023 AIR_LED_MODE_USER_DEFINE);
1024 if (ret < 0) {
1025 phydev_err(phydev, "Failed to initialize leds: %d\n", ret);
1026 return ret;
1027 }
1028
1029 return 0;
1030 }
1031
en8811h_get_features(struct phy_device * phydev)1032 static int en8811h_get_features(struct phy_device *phydev)
1033 {
1034 linkmode_set_bit_array(phy_basic_ports_array,
1035 ARRAY_SIZE(phy_basic_ports_array),
1036 phydev->supported);
1037
1038 return genphy_c45_pma_read_abilities(phydev);
1039 }
1040
en8811h_get_rate_matching(struct phy_device * phydev,phy_interface_t iface)1041 static int en8811h_get_rate_matching(struct phy_device *phydev,
1042 phy_interface_t iface)
1043 {
1044 return RATE_MATCH_PAUSE;
1045 }
1046
en8811h_config_aneg(struct phy_device * phydev)1047 static int en8811h_config_aneg(struct phy_device *phydev)
1048 {
1049 bool changed = false;
1050 int ret;
1051 u32 adv;
1052
1053 if (phydev->autoneg == AUTONEG_DISABLE) {
1054 phydev_warn(phydev, "Disabling autoneg is not supported\n");
1055 return -EINVAL;
1056 }
1057
1058 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
1059
1060 ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
1061 MDIO_AN_10GBT_CTRL_ADV2_5G, adv);
1062 if (ret < 0)
1063 return ret;
1064 if (ret > 0)
1065 changed = true;
1066
1067 return __genphy_config_aneg(phydev, changed);
1068 }
1069
en8811h_read_status(struct phy_device * phydev)1070 static int en8811h_read_status(struct phy_device *phydev)
1071 {
1072 struct en8811h_priv *priv = phydev->priv;
1073 u32 pbus_value;
1074 int ret, val;
1075
1076 ret = genphy_update_link(phydev);
1077 if (ret)
1078 return ret;
1079
1080 phydev->master_slave_get = MASTER_SLAVE_CFG_UNSUPPORTED;
1081 phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
1082 phydev->speed = SPEED_UNKNOWN;
1083 phydev->duplex = DUPLEX_UNKNOWN;
1084 phydev->pause = 0;
1085 phydev->asym_pause = 0;
1086 phydev->rate_matching = RATE_MATCH_PAUSE;
1087
1088 ret = genphy_read_master_slave(phydev);
1089 if (ret < 0)
1090 return ret;
1091
1092 ret = genphy_read_lpa(phydev);
1093 if (ret < 0)
1094 return ret;
1095
1096 /* Get link partner 2.5GBASE-T ability from vendor register */
1097 ret = air_buckpbus_reg_read(phydev, EN8811H_2P5G_LPA, &pbus_value);
1098 if (ret < 0)
1099 return ret;
1100 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
1101 phydev->lp_advertising,
1102 pbus_value & EN8811H_2P5G_LPA_2P5G);
1103
1104 if (phydev->autoneg_complete)
1105 phy_resolve_aneg_pause(phydev);
1106
1107 if (!phydev->link)
1108 return 0;
1109
1110 /* Get real speed from vendor register */
1111 val = phy_read(phydev, AIR_AUX_CTRL_STATUS);
1112 if (val < 0)
1113 return val;
1114 switch (val & AIR_AUX_CTRL_STATUS_SPEED_MASK) {
1115 case AIR_AUX_CTRL_STATUS_SPEED_2500:
1116 phydev->speed = SPEED_2500;
1117 break;
1118 case AIR_AUX_CTRL_STATUS_SPEED_1000:
1119 phydev->speed = SPEED_1000;
1120 break;
1121 case AIR_AUX_CTRL_STATUS_SPEED_100:
1122 phydev->speed = SPEED_100;
1123 break;
1124 }
1125
1126 /* Firmware before version 24011202 has no vendor register 2P5G_LPA.
1127 * Assume link partner advertised it if connected at 2500Mbps.
1128 */
1129 if (priv->firmware_version < 0x24011202) {
1130 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
1131 phydev->lp_advertising,
1132 phydev->speed == SPEED_2500);
1133 }
1134
1135 /* Only supports full duplex */
1136 phydev->duplex = DUPLEX_FULL;
1137
1138 return 0;
1139 }
1140
en8811h_clear_intr(struct phy_device * phydev)1141 static int en8811h_clear_intr(struct phy_device *phydev)
1142 {
1143 int ret;
1144
1145 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_3,
1146 AIR_PHY_MCU_CMD_3_DOCMD);
1147 if (ret < 0)
1148 return ret;
1149
1150 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_4,
1151 AIR_PHY_MCU_CMD_4_INTCLR);
1152 if (ret < 0)
1153 return ret;
1154
1155 return 0;
1156 }
1157
en8811h_handle_interrupt(struct phy_device * phydev)1158 static irqreturn_t en8811h_handle_interrupt(struct phy_device *phydev)
1159 {
1160 int ret;
1161
1162 ret = en8811h_clear_intr(phydev);
1163 if (ret < 0) {
1164 phy_error(phydev);
1165 return IRQ_NONE;
1166 }
1167
1168 phy_trigger_machine(phydev);
1169
1170 return IRQ_HANDLED;
1171 }
1172
en8811h_resume(struct phy_device * phydev)1173 static int en8811h_resume(struct phy_device *phydev)
1174 {
1175 clk_restore_context();
1176
1177 return genphy_resume(phydev);
1178 }
1179
en8811h_suspend(struct phy_device * phydev)1180 static int en8811h_suspend(struct phy_device *phydev)
1181 {
1182 clk_save_context();
1183
1184 return genphy_suspend(phydev);
1185 }
1186
1187 static struct phy_driver en8811h_driver[] = {
1188 {
1189 PHY_ID_MATCH_MODEL(EN8811H_PHY_ID),
1190 .name = "Airoha EN8811H",
1191 .probe = en8811h_probe,
1192 .get_features = en8811h_get_features,
1193 .config_init = en8811h_config_init,
1194 .get_rate_matching = en8811h_get_rate_matching,
1195 .config_aneg = en8811h_config_aneg,
1196 .read_status = en8811h_read_status,
1197 .resume = en8811h_resume,
1198 .suspend = en8811h_suspend,
1199 .config_intr = en8811h_clear_intr,
1200 .handle_interrupt = en8811h_handle_interrupt,
1201 .led_hw_is_supported = en8811h_led_hw_is_supported,
1202 .read_page = air_phy_read_page,
1203 .write_page = air_phy_write_page,
1204 .led_blink_set = air_led_blink_set,
1205 .led_brightness_set = air_led_brightness_set,
1206 .led_hw_control_set = air_led_hw_control_set,
1207 .led_hw_control_get = air_led_hw_control_get,
1208 } };
1209
1210 module_phy_driver(en8811h_driver);
1211
1212 static const struct mdio_device_id __maybe_unused en8811h_tbl[] = {
1213 { PHY_ID_MATCH_MODEL(EN8811H_PHY_ID) },
1214 { }
1215 };
1216
1217 MODULE_DEVICE_TABLE(mdio, en8811h_tbl);
1218 MODULE_FIRMWARE(EN8811H_MD32_DM);
1219 MODULE_FIRMWARE(EN8811H_MD32_DSP);
1220
1221 MODULE_DESCRIPTION("Airoha EN8811H PHY drivers");
1222 MODULE_AUTHOR("Airoha");
1223 MODULE_AUTHOR("Eric Woudstra <ericwouds@gmail.com>");
1224 MODULE_LICENSE("GPL");
1225