1 /*
2  * Copyright 2023-2024 NXP
3  *
4  * Inspiration from phy_mii.c, which is:
5  * Copyright (c) 2021 IP-Logix Inc.
6  * Copyright 2022 NXP
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #define DT_DRV_COMPAT realtek_rtl8211f
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/net/phy.h>
15 #include <zephyr/net/mii.h>
16 #include <zephyr/drivers/mdio.h>
17 #include <string.h>
18 #include <zephyr/sys/util_macro.h>
19 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) || DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
20 #include <zephyr/drivers/gpio.h>
21 #endif
22 
23 #define LOG_MODULE_NAME phy_rt_rtl8211f
24 #define LOG_LEVEL CONFIG_PHY_LOG_LEVEL
25 #include <zephyr/logging/log.h>
26 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
27 
28 #define REALTEK_OUI_MSB (0x1CU)
29 
30 #define PHY_RT_RTL8211F_PHYSR_REG (0x1A)
31 
32 #define PHY_RT_RTL8211F_PHYSR_LINKSTATUS_MASK BIT(2)
33 #define PHY_RT_RTL8211F_PHYSR_LINKDUPLEX_MASK BIT(3)
34 #define PHY_RT_RTL8211F_PHYSR_LINKSPEED_MASK  (BIT(4) | BIT(5))
35 #define PHY_RT_RTL8211F_PHYSR_LINKSPEED_SHIFT (4U)
36 #define PHY_RT_RTL8211F_PHYSR_LINKSPEED_10M   (0U)
37 #define PHY_RT_RTL8211F_PHYSR_LINKSPEED_100M  (1U)
38 #define PHY_RT_RTL8211F_PHYSR_LINKSPEED_1000M (2U)
39 
40 #define PHY_RT_RTL8211F_PAGSR_REG (0x1F)
41 
42 #define PHY_RT_RTL8211F_PAGE_MIICR_ADDR   (0xD08)
43 #define PHY_RT_RTL8211F_MIICR1_REG        (0x11)
44 #define PHY_RT_RTL8211F_MIICR2_REG        (0x15)
45 #define PHY_RT_RTL8211F_MIICR1_TXDLY_MASK BIT(8)
46 #define PHY_RT_RTL8211F_MIICR2_RXDLY_MASK BIT(3)
47 
48 #define PHY_RT_RTL8211F_PAGE_INTR_PIN_ADDR (0xD40)
49 #define PHY_RT_RTL8211F_INTR_PIN_REG       (0x16)
50 #define PHY_RT_RTL8211F_INTR_PIN_MASK      BIT(5)
51 
52 #define PHY_RT_RTL8211F_PAGE_INTR_ADDR              (0xA42U)
53 #define PHY_RT_RTL8211F_INER_REG                    (0x12U)
54 #define PHY_RT_RTL8211F_INER_LINKSTATUS_CHANGE_MASK BIT(4)
55 #define PHY_RT_RTL8211F_INSR_REG                    (0x1DU)
56 
57 #define PHY_RT_RTL8211F_RESET_HOLD_TIME_MS 10
58 
59 struct rt_rtl8211f_config {
60 	uint8_t addr;
61 	const struct device *mdio_dev;
62 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
63 	const struct gpio_dt_spec reset_gpio;
64 #endif
65 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
66 	const struct gpio_dt_spec interrupt_gpio;
67 #endif
68 };
69 
70 struct rt_rtl8211f_data {
71 	const struct device *dev;
72 	struct phy_link_state state;
73 	phy_callback_t cb;
74 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
75 	struct gpio_callback gpio_callback;
76 #endif
77 	void *cb_data;
78 	struct k_mutex mutex;
79 	struct k_work_delayable phy_monitor_work;
80 };
81 
phy_rt_rtl8211f_read(const struct device * dev,uint16_t reg_addr,uint32_t * data)82 static int phy_rt_rtl8211f_read(const struct device *dev,
83 				uint16_t reg_addr, uint32_t *data)
84 {
85 	const struct rt_rtl8211f_config *config = dev->config;
86 	int ret;
87 
88 	/* Make sure excessive bits 16-31 are reset */
89 	*data = 0U;
90 
91 	/* Read the PHY register */
92 	ret = mdio_read(config->mdio_dev, config->addr, reg_addr, (uint16_t *)data);
93 	if (ret) {
94 		return ret;
95 	}
96 
97 	return 0;
98 }
99 
phy_rt_rtl8211f_write(const struct device * dev,uint16_t reg_addr,uint32_t data)100 static int phy_rt_rtl8211f_write(const struct device *dev,
101 				uint16_t reg_addr, uint32_t data)
102 {
103 	const struct rt_rtl8211f_config *config = dev->config;
104 	int ret;
105 
106 	ret = mdio_write(config->mdio_dev, config->addr, reg_addr, (uint16_t)data);
107 	if (ret) {
108 		return ret;
109 	}
110 
111 	return 0;
112 }
113 
phy_rt_rtl8211f_reset(const struct device * dev)114 static int phy_rt_rtl8211f_reset(const struct device *dev)
115 {
116 	const struct rt_rtl8211f_config *config = dev->config;
117 	uint32_t reg_val;
118 	int ret;
119 
120 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
121 	if (config->reset_gpio.port) {
122 		/* Start reset */
123 		ret = gpio_pin_set_dt(&config->reset_gpio, 0);
124 		if (ret) {
125 			return ret;
126 		}
127 
128 		/* Hold reset for the minimum time specified by datasheet */
129 		k_busy_wait(USEC_PER_MSEC * PHY_RT_RTL8211F_RESET_HOLD_TIME_MS);
130 
131 		/* Reset over */
132 		ret = gpio_pin_set_dt(&config->reset_gpio, 1);
133 		if (ret) {
134 			return ret;
135 		}
136 
137 		/* Wait another 30 ms (circuits settling time) before accessing registers */
138 		k_busy_wait(USEC_PER_MSEC * 30);
139 
140 		goto finalize_reset;
141 	}
142 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */
143 
144 	/* Reset PHY using register */
145 	ret = phy_rt_rtl8211f_write(dev, MII_BMCR, MII_BMCR_RESET);
146 	if (ret) {
147 		LOG_ERR("Error writing phy (%d) basic control register", config->addr);
148 		return ret;
149 	}
150 
151 	/* Wait for the minimum reset time specified by datasheet */
152 	k_busy_wait(USEC_PER_MSEC * PHY_RT_RTL8211F_RESET_HOLD_TIME_MS);
153 
154 	/* Wait for the reset to be cleared */
155 	do {
156 		ret = phy_rt_rtl8211f_read(dev, MII_BMCR, &reg_val);
157 		if (ret) {
158 			LOG_ERR("Error reading phy (%d) basic control register", config->addr);
159 			return ret;
160 		}
161 	} while (reg_val & MII_BMCR_RESET);
162 
163 	goto finalize_reset;
164 
165 finalize_reset:
166 	/* Wait until correct data can be read from registers */
167 	do {
168 		ret = phy_rt_rtl8211f_read(dev, MII_PHYID1R, &reg_val);
169 		if (ret) {
170 			LOG_ERR("Error reading phy (%d) identifier register 1", config->addr);
171 			return ret;
172 		}
173 	} while (reg_val != REALTEK_OUI_MSB);
174 
175 	return 0;
176 }
177 
phy_rt_rtl8211f_restart_autonegotiation(const struct device * dev)178 static int phy_rt_rtl8211f_restart_autonegotiation(const struct device *dev)
179 {
180 	const struct rt_rtl8211f_config *config = dev->config;
181 	uint32_t bmcr = 0;
182 	int ret;
183 
184 	/* Read control register to write back with autonegotiation bit */
185 	ret = phy_rt_rtl8211f_read(dev, MII_BMCR, &bmcr);
186 	if (ret) {
187 		LOG_ERR("Error reading phy (%d) basic control register", config->addr);
188 		return ret;
189 	}
190 
191 	/* (re)start autonegotiation */
192 	LOG_DBG("PHY (%d) is entering autonegotiation sequence", config->addr);
193 	bmcr |= MII_BMCR_AUTONEG_ENABLE | MII_BMCR_AUTONEG_RESTART;
194 
195 	ret = phy_rt_rtl8211f_write(dev, MII_BMCR, bmcr);
196 	if (ret) {
197 		LOG_ERR("Error writing phy (%d) basic control register", config->addr);
198 		return ret;
199 	}
200 
201 	return 0;
202 }
203 
phy_rt_rtl8211f_get_link(const struct device * dev,struct phy_link_state * state)204 static int phy_rt_rtl8211f_get_link(const struct device *dev,
205 					struct phy_link_state *state)
206 {
207 	const struct rt_rtl8211f_config *config = dev->config;
208 	struct rt_rtl8211f_data *data = dev->data;
209 	int ret;
210 	uint32_t physr = 0;
211 	uint32_t duplex = 0;
212 	struct phy_link_state old_state = data->state;
213 	struct phy_link_state new_state = {};
214 
215 	/* Lock mutex */
216 	ret = k_mutex_lock(&data->mutex, K_FOREVER);
217 	if (ret) {
218 		LOG_ERR("PHY mutex lock error");
219 		return ret;
220 	}
221 
222 	/* Read PHY specific status register */
223 	ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_PHYSR_REG, &physr);
224 	if (ret) {
225 		LOG_ERR("Error reading phy (%d) specific status register", config->addr);
226 		(void)k_mutex_unlock(&data->mutex);
227 		return ret;
228 	}
229 
230 	/* Unlock mutex */
231 	(void)k_mutex_unlock(&data->mutex);
232 
233 	new_state.is_up = physr & PHY_RT_RTL8211F_PHYSR_LINKSTATUS_MASK;
234 
235 	if (!new_state.is_up) {
236 		goto result;
237 	}
238 
239 	duplex = (physr & PHY_RT_RTL8211F_PHYSR_LINKDUPLEX_MASK);
240 	switch ((physr & PHY_RT_RTL8211F_PHYSR_LINKSPEED_MASK)
241 				>> PHY_RT_RTL8211F_PHYSR_LINKSPEED_SHIFT) {
242 		case PHY_RT_RTL8211F_PHYSR_LINKSPEED_100M:
243 			if (duplex) {
244 				new_state.speed = LINK_FULL_100BASE_T;
245 			} else {
246 				new_state.speed = LINK_HALF_100BASE_T;
247 			}
248 			break;
249 		case PHY_RT_RTL8211F_PHYSR_LINKSPEED_1000M:
250 			if (duplex) {
251 				new_state.speed = LINK_FULL_1000BASE_T;
252 			} else {
253 				new_state.speed = LINK_HALF_1000BASE_T;
254 			}
255 			break;
256 		case PHY_RT_RTL8211F_PHYSR_LINKSPEED_10M:
257 		default:
258 			if (duplex) {
259 				new_state.speed = LINK_FULL_10BASE_T;
260 			} else {
261 				new_state.speed = LINK_HALF_10BASE_T;
262 			}
263 			break;
264 	}
265 result:
266 	if (memcmp(&old_state, &new_state, sizeof(struct phy_link_state)) != 0) {
267 		LOG_INF("PHY %d is %s", config->addr, new_state.is_up ? "up" : "down");
268 		if (new_state.is_up) {
269 			LOG_INF("PHY (%d) Link speed %s Mb, %s duplex", config->addr,
270 				(PHY_LINK_IS_SPEED_1000M(new_state.speed) ? "1000" :
271 				(PHY_LINK_IS_SPEED_100M(new_state.speed) ? "100" : "10")),
272 				PHY_LINK_IS_FULL_DUPLEX(new_state.speed) ? "full" : "half");
273 		}
274 	}
275 
276 	memcpy(state, &new_state, sizeof(struct phy_link_state));
277 
278 	return ret;
279 }
280 
phy_rt_rtl8211f_cfg_link(const struct device * dev,enum phy_link_speed speeds)281 static int phy_rt_rtl8211f_cfg_link(const struct device *dev,
282 					enum phy_link_speed speeds)
283 {
284 	const struct rt_rtl8211f_config *config = dev->config;
285 	struct rt_rtl8211f_data *data = dev->data;
286 	uint32_t anar;
287 	uint32_t gbcr;
288 	int ret;
289 
290 	/* Lock mutex */
291 	ret = k_mutex_lock(&data->mutex, K_FOREVER);
292 	if (ret) {
293 		LOG_ERR("PHY mutex lock error");
294 		return ret;
295 	}
296 
297 	/* We are going to reconfigure the phy, don't need to monitor until done */
298 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
299 	if (!config->interrupt_gpio.port) {
300 		k_work_cancel_delayable(&data->phy_monitor_work);
301 	}
302 #else
303 	k_work_cancel_delayable(&data->phy_monitor_work);
304 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
305 
306 	/* Read ANAR register to write back */
307 	ret = phy_rt_rtl8211f_read(dev, MII_ANAR, &anar);
308 	if (ret) {
309 		LOG_ERR("Error reading phy (%d) advertising register", config->addr);
310 		goto done;
311 	}
312 
313 	/* Read GBCR register to write back */
314 	ret = phy_rt_rtl8211f_read(dev, MII_1KTCR, &gbcr);
315 	if (ret) {
316 		LOG_ERR("Error reading phy (%d) 1000Base-T control register", config->addr);
317 		goto done;
318 	}
319 
320 	/* Setup advertising register */
321 	if (speeds & LINK_FULL_100BASE_T) {
322 		anar |= MII_ADVERTISE_100_FULL;
323 	} else {
324 		anar &= ~MII_ADVERTISE_100_FULL;
325 	}
326 	if (speeds & LINK_HALF_100BASE_T) {
327 		anar |= MII_ADVERTISE_100_HALF;
328 	} else {
329 		anar &= ~MII_ADVERTISE_100_HALF;
330 	}
331 	if (speeds & LINK_FULL_10BASE_T) {
332 		anar |= MII_ADVERTISE_10_FULL;
333 	} else {
334 		anar &= ~MII_ADVERTISE_10_FULL;
335 	}
336 	if (speeds & LINK_HALF_10BASE_T) {
337 		anar |= MII_ADVERTISE_10_HALF;
338 	} else {
339 		anar &= ~MII_ADVERTISE_10_HALF;
340 	}
341 
342 	/* Setup 1000Base-T control register */
343 	if (speeds & LINK_FULL_1000BASE_T) {
344 		gbcr |= MII_ADVERTISE_1000_FULL;
345 	} else {
346 		gbcr &= ~MII_ADVERTISE_1000_FULL;
347 	}
348 
349 	/* Write capabilities to advertising register */
350 	ret = phy_rt_rtl8211f_write(dev, MII_ANAR, anar);
351 	if (ret) {
352 		LOG_ERR("Error writing phy (%d) advertising register", config->addr);
353 		goto done;
354 	}
355 
356 	/* Write capabilities to 1000Base-T control register */
357 	ret = phy_rt_rtl8211f_write(dev, MII_1KTCR, gbcr);
358 	if (ret) {
359 		LOG_ERR("Error writing phy (%d) 1000Base-T control register", config->addr);
360 		goto done;
361 	}
362 
363 	/* (Re)start autonegotiation */
364 	ret = phy_rt_rtl8211f_restart_autonegotiation(dev);
365 	if (ret) {
366 		LOG_ERR("Error restarting autonegotiation");
367 		goto done;
368 	}
369 done:
370 	/* Unlock mutex */
371 	(void)k_mutex_unlock(&data->mutex);
372 
373 	/* Start monitoring */
374 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
375 	if (!config->interrupt_gpio.port) {
376 		k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
377 	}
378 #else
379 	k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
380 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
381 
382 	return ret;
383 }
384 
phy_rt_rtl8211f_link_cb_set(const struct device * dev,phy_callback_t cb,void * user_data)385 static int phy_rt_rtl8211f_link_cb_set(const struct device *dev,
386 					phy_callback_t cb, void *user_data)
387 {
388 	struct rt_rtl8211f_data *data = dev->data;
389 
390 	data->cb = cb;
391 	data->cb_data = user_data;
392 
393 	phy_rt_rtl8211f_get_link(dev, &data->state);
394 
395 	data->cb(dev, &data->state, data->cb_data);
396 
397 	return 0;
398 }
399 
400 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
phy_rt_rtl8211f_clear_interrupt(struct rt_rtl8211f_data * data)401 static int phy_rt_rtl8211f_clear_interrupt(struct rt_rtl8211f_data *data)
402 {
403 	const struct device *dev = data->dev;
404 	const struct rt_rtl8211f_config *config = dev->config;
405 	uint32_t reg_val;
406 	int ret;
407 
408 	/* Lock mutex */
409 	ret = k_mutex_lock(&data->mutex, K_FOREVER);
410 	if (ret) {
411 		LOG_ERR("PHY mutex lock error");
412 		return ret;
413 	}
414 
415 	/* Read/clear PHY interrupt status register */
416 	ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_INSR_REG, &reg_val);
417 	if (ret) {
418 		LOG_ERR("Error reading phy (%d) interrupt status register", config->addr);
419 	}
420 
421 	/* Unlock mutex */
422 	(void)k_mutex_unlock(&data->mutex);
423 
424 	return ret;
425 }
426 
phy_rt_rtl8211f_interrupt_handler(const struct device * port,struct gpio_callback * cb,gpio_port_pins_t pins)427 static void phy_rt_rtl8211f_interrupt_handler(const struct device *port,
428 						struct gpio_callback *cb,
429 						gpio_port_pins_t pins)
430 {
431 	struct rt_rtl8211f_data *data = CONTAINER_OF(cb, struct rt_rtl8211f_data, gpio_callback);
432 	int ret;
433 
434 	ret = k_work_reschedule(&data->phy_monitor_work, K_NO_WAIT);
435 	if (ret < 0) {
436 		LOG_ERR("Failed to schedule phy_monitor_work from ISR");
437 	}
438 }
439 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
440 
phy_rt_rtl8211f_monitor_work_handler(struct k_work * work)441 static void phy_rt_rtl8211f_monitor_work_handler(struct k_work *work)
442 {
443 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
444 	struct rt_rtl8211f_data *data =
445 		CONTAINER_OF(dwork, struct rt_rtl8211f_data, phy_monitor_work);
446 	const struct device *dev = data->dev;
447 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
448 	const struct rt_rtl8211f_config *config = dev->config;
449 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
450 	struct phy_link_state state = {};
451 	int ret;
452 
453 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
454 	if (config->interrupt_gpio.port) {
455 		ret = phy_rt_rtl8211f_clear_interrupt(data);
456 		if (ret) {
457 			return;
458 		}
459 	}
460 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
461 
462 	ret = phy_rt_rtl8211f_get_link(dev, &state);
463 
464 	if (ret == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) {
465 		memcpy(&data->state, &state, sizeof(struct phy_link_state));
466 		if (data->cb) {
467 			data->cb(dev, &data->state, data->cb_data);
468 		}
469 	}
470 
471 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
472 	if (!config->interrupt_gpio.port) {
473 		k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
474 	}
475 #else
476 	k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
477 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
478 }
479 
phy_rt_rtl8211f_init(const struct device * dev)480 static int phy_rt_rtl8211f_init(const struct device *dev)
481 {
482 	const struct rt_rtl8211f_config *config = dev->config;
483 	struct rt_rtl8211f_data *data = dev->data;
484 	uint32_t reg_val;
485 	int ret;
486 
487 	data->dev = dev;
488 
489 	ret = k_mutex_init(&data->mutex);
490 	if (ret) {
491 		return ret;
492 	}
493 
494 	mdio_bus_enable(config->mdio_dev);
495 
496 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
497 	/* Configure reset pin */
498 	if (config->reset_gpio.port) {
499 		ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE);
500 		if (ret) {
501 			return ret;
502 		}
503 	}
504 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */
505 
506 	/* Reset PHY */
507 	ret = phy_rt_rtl8211f_reset(dev);
508 	if (ret) {
509 		LOG_ERR("Failed to reset phy (%d)", config->addr);
510 		return ret;
511 	}
512 
513 	/* Set RGMII Tx/Rx Delay. */
514 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG,
515 					PHY_RT_RTL8211F_PAGE_MIICR_ADDR);
516 	if (ret) {
517 		LOG_ERR("Error writing phy (%d) page select register", config->addr);
518 		return ret;
519 	}
520 
521 	ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_MIICR1_REG, &reg_val);
522 	if (ret) {
523 		LOG_ERR("Error reading phy (%d) mii control register1", config->addr);
524 		return ret;
525 	}
526 
527 	reg_val |= PHY_RT_RTL8211F_MIICR1_TXDLY_MASK;
528 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_MIICR1_REG, reg_val);
529 	if (ret) {
530 		LOG_ERR("Error writing phy (%d) mii control register1", config->addr);
531 		return ret;
532 	}
533 
534 	ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_MIICR2_REG, &reg_val);
535 	if (ret) {
536 		LOG_ERR("Error reading phy (%d) mii control register2", config->addr);
537 		return ret;
538 	}
539 
540 	reg_val |= PHY_RT_RTL8211F_MIICR2_RXDLY_MASK;
541 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_MIICR2_REG, reg_val);
542 	if (ret) {
543 		LOG_ERR("Error writing phy (%d) mii control register2", config->addr);
544 		return ret;
545 	}
546 
547 	/* Restore to default page 0 */
548 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, 0);
549 	if (ret) {
550 		LOG_ERR("Error writing phy (%d) page select register", config->addr);
551 		return ret;
552 	}
553 
554 	k_work_init_delayable(&data->phy_monitor_work, phy_rt_rtl8211f_monitor_work_handler);
555 
556 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
557 	if (!config->interrupt_gpio.port) {
558 		phy_rt_rtl8211f_monitor_work_handler(&data->phy_monitor_work.work);
559 		goto skip_int_gpio;
560 	}
561 
562 	/* Set INTB/PMEB pin to interrupt mode */
563 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG,
564 					PHY_RT_RTL8211F_PAGE_INTR_PIN_ADDR);
565 	if (ret) {
566 		LOG_ERR("Error writing phy (%d) page select register", config->addr);
567 		return ret;
568 	}
569 	ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_INTR_PIN_REG, &reg_val);
570 	if (!ret) {
571 		reg_val &= ~PHY_RT_RTL8211F_INTR_PIN_MASK;
572 		ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_INTR_PIN_REG, reg_val);
573 		if (ret) {
574 			LOG_ERR("Error writing phy (%d) interrupt pin setting register",
575 				config->addr);
576 			return ret;
577 		}
578 	} else {
579 		LOG_ERR("Error reading phy (%d) interrupt pin setting register", config->addr);
580 		return ret;
581 	}
582 	/* Restore to default page 0 */
583 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, 0);
584 	if (ret) {
585 		LOG_ERR("Error writing phy (%d) page select register", config->addr);
586 		return ret;
587 	}
588 
589 	/* Clear interrupt */
590 	ret = phy_rt_rtl8211f_clear_interrupt(data);
591 	if (ret) {
592 		return ret;
593 	}
594 
595 	/* Configure interrupt pin */
596 	ret = gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_INPUT);
597 	if (ret) {
598 		return ret;
599 	}
600 
601 	gpio_init_callback(&data->gpio_callback, phy_rt_rtl8211f_interrupt_handler,
602 				BIT(config->interrupt_gpio.pin));
603 	ret = gpio_add_callback_dt(&config->interrupt_gpio, &data->gpio_callback);
604 	if (ret) {
605 		return ret;
606 	}
607 
608 	ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_EDGE_TO_ACTIVE);
609 	if (ret) {
610 		return ret;
611 	}
612 
613 	/* Enable PHY interrupt. */
614 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG,
615 					PHY_RT_RTL8211F_PAGE_INTR_ADDR);
616 	if (ret) {
617 		LOG_ERR("Error writing phy (%d) page select register", config->addr);
618 		return ret;
619 	}
620 	ret = phy_rt_rtl8211f_read(dev, PHY_RT_RTL8211F_INER_REG, &reg_val);
621 	if (ret) {
622 		LOG_ERR("Error reading phy (%d) interrupt enable register", config->addr);
623 		return ret;
624 	}
625 	reg_val |= PHY_RT_RTL8211F_INER_LINKSTATUS_CHANGE_MASK;
626 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_INER_REG, reg_val);
627 	if (ret) {
628 		LOG_ERR("Error writing phy (%d) interrupt enable register", config->addr);
629 		return ret;
630 	}
631 	/* Restore to default page 0 */
632 	ret = phy_rt_rtl8211f_write(dev, PHY_RT_RTL8211F_PAGSR_REG, 0);
633 	if (ret) {
634 		LOG_ERR("Error writing phy (%d) page select register", config->addr);
635 		return ret;
636 	}
637 skip_int_gpio:
638 #else
639 	phy_rt_rtl8211f_monitor_work_handler(&data->phy_monitor_work.work);
640 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
641 
642 	return 0;
643 }
644 
645 static DEVICE_API(ethphy, rt_rtl8211f_phy_api) = {
646 	.get_link = phy_rt_rtl8211f_get_link,
647 	.cfg_link = phy_rt_rtl8211f_cfg_link,
648 	.link_cb_set = phy_rt_rtl8211f_link_cb_set,
649 	.read = phy_rt_rtl8211f_read,
650 	.write = phy_rt_rtl8211f_write,
651 };
652 
653 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
654 #define RESET_GPIO(n) \
655 		.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}),
656 #else
657 #define RESET_GPIO(n)
658 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */
659 
660 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
661 #define INTERRUPT_GPIO(n) \
662 		.interrupt_gpio = GPIO_DT_SPEC_INST_GET_OR(n, int_gpios, {0}),
663 #else
664 #define INTERRUPT_GPIO(n)
665 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
666 
667 #define REALTEK_RTL8211F_INIT(n)						\
668 	static const struct rt_rtl8211f_config rt_rtl8211f_##n##_config = {	\
669 		.addr = DT_INST_REG_ADDR(n),					\
670 		.mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)),			\
671 		RESET_GPIO(n)							\
672 		INTERRUPT_GPIO(n)						\
673 	};									\
674 										\
675 	static struct rt_rtl8211f_data rt_rtl8211f_##n##_data;			\
676 										\
677 	DEVICE_DT_INST_DEFINE(n, &phy_rt_rtl8211f_init, NULL,			\
678 			&rt_rtl8211f_##n##_data, &rt_rtl8211f_##n##_config,	\
679 			POST_KERNEL, CONFIG_PHY_INIT_PRIORITY,			\
680 			&rt_rtl8211f_phy_api);
681 
682 DT_INST_FOREACH_STATUS_OKAY(REALTEK_RTL8211F_INIT)
683