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 microchip_ksz8081
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 #include <zephyr/drivers/gpio.h>
20 
21 #define LOG_MODULE_NAME phy_mc_ksz8081
22 #define LOG_LEVEL CONFIG_PHY_LOG_LEVEL
23 #include <zephyr/logging/log.h>
24 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
25 
26 #define PHY_MC_KSZ8081_OMSO_REG			0x16
27 #define PHY_MC_KSZ8081_OMSO_FACTORY_MODE_MASK	BIT(15)
28 #define PHY_MC_KSZ8081_OMSO_NAND_TREE_MASK	BIT(5)
29 #define PHY_MC_KSZ8081_OMSO_RMII_OVERRIDE_MASK	BIT(1)
30 #define PHY_MC_KSZ8081_OMSO_MII_OVERRIDE_MASK	BIT(0)
31 
32 #define PHY_MC_KSZ8081_CTRL2_REG		0x1F
33 #define PHY_MC_KSZ8081_CTRL2_REF_CLK_SEL	BIT(7)
34 
35 enum ksz8081_interface {
36 	KSZ8081_MII,
37 	KSZ8081_RMII,
38 	KSZ8081_RMII_25MHZ,
39 };
40 
41 struct mc_ksz8081_config {
42 	uint8_t addr;
43 	const struct device *mdio_dev;
44 	enum ksz8081_interface phy_iface;
45 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
46 	const struct gpio_dt_spec reset_gpio;
47 #endif
48 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
49 	const struct gpio_dt_spec interrupt_gpio;
50 #endif
51 };
52 
53 struct mc_ksz8081_data {
54 	const struct device *dev;
55 	struct phy_link_state state;
56 	phy_callback_t cb;
57 	void *cb_data;
58 	struct k_mutex mutex;
59 	struct k_work_delayable phy_monitor_work;
60 };
61 
phy_mc_ksz8081_read(const struct device * dev,uint16_t reg_addr,uint32_t * data)62 static int phy_mc_ksz8081_read(const struct device *dev,
63 				uint16_t reg_addr, uint32_t *data)
64 {
65 	const struct mc_ksz8081_config *config = dev->config;
66 	int ret;
67 
68 	/* Make sure excessive bits 16-31 are reset */
69 	*data = 0U;
70 
71 	ret = mdio_read(config->mdio_dev, config->addr, reg_addr, (uint16_t *)data);
72 	if (ret) {
73 		return ret;
74 	}
75 
76 	return 0;
77 }
78 
phy_mc_ksz8081_write(const struct device * dev,uint16_t reg_addr,uint32_t data)79 static int phy_mc_ksz8081_write(const struct device *dev,
80 				uint16_t reg_addr, uint32_t data)
81 {
82 	const struct mc_ksz8081_config *config = dev->config;
83 	int ret;
84 
85 	ret = mdio_write(config->mdio_dev, config->addr, reg_addr, (uint16_t)data);
86 	if (ret) {
87 		return ret;
88 	}
89 
90 	return 0;
91 }
92 
phy_mc_ksz8081_autonegotiate(const struct device * dev)93 static int phy_mc_ksz8081_autonegotiate(const struct device *dev)
94 {
95 	const struct mc_ksz8081_config *config = dev->config;
96 	int ret;
97 	uint32_t bmcr = 0;
98 	uint32_t bmsr = 0;
99 	uint16_t timeout = CONFIG_PHY_AUTONEG_TIMEOUT_MS / 100;
100 
101 	/* Read control register to write back with autonegotiation bit */
102 	ret = phy_mc_ksz8081_read(dev, MII_BMCR, &bmcr);
103 	if (ret) {
104 		LOG_ERR("Error reading phy (%d) basic control register", config->addr);
105 		return ret;
106 	}
107 
108 	/* (re)start autonegotiation */
109 	LOG_DBG("PHY (%d) is entering autonegotiation sequence", config->addr);
110 	bmcr |= MII_BMCR_AUTONEG_ENABLE | MII_BMCR_AUTONEG_RESTART;
111 	bmcr &= ~MII_BMCR_ISOLATE;
112 
113 	ret = phy_mc_ksz8081_write(dev, MII_BMCR, bmcr);
114 	if (ret) {
115 		LOG_ERR("Error writing phy (%d) basic control register", config->addr);
116 		return ret;
117 	}
118 
119 	/* TODO change this to GPIO interrupt driven */
120 	do {
121 		if (timeout-- == 0) {
122 			LOG_DBG("PHY (%d) autonegotiation timed out", config->addr);
123 			/* The value -ETIMEDOUT can be returned by PHY read/write functions, so
124 			 * return -ENETDOWN instead to distinguish link timeout from PHY timeout.
125 			 */
126 			return -ENETDOWN;
127 		}
128 		k_msleep(100);
129 
130 		ret = phy_mc_ksz8081_read(dev, MII_BMSR, &bmsr);
131 		if (ret) {
132 			LOG_ERR("Error reading phy (%d) basic status register", config->addr);
133 			return ret;
134 		}
135 	} while (!(bmsr & MII_BMSR_AUTONEG_COMPLETE));
136 
137 	LOG_DBG("PHY (%d) autonegotiation completed", config->addr);
138 
139 	return 0;
140 }
141 
phy_mc_ksz8081_get_link(const struct device * dev,struct phy_link_state * state)142 static int phy_mc_ksz8081_get_link(const struct device *dev,
143 					struct phy_link_state *state)
144 {
145 	const struct mc_ksz8081_config *config = dev->config;
146 	struct mc_ksz8081_data *data = dev->data;
147 	int ret;
148 	uint32_t bmsr = 0;
149 	uint32_t anar = 0;
150 	uint32_t anlpar = 0;
151 	struct phy_link_state old_state = data->state;
152 
153 	/* Lock mutex */
154 	ret = k_mutex_lock(&data->mutex, K_FOREVER);
155 	if (ret) {
156 		LOG_ERR("PHY mutex lock error");
157 		return ret;
158 	}
159 
160 	/* Read link state */
161 	ret = phy_mc_ksz8081_read(dev, MII_BMSR, &bmsr);
162 	if (ret) {
163 		LOG_ERR("Error reading phy (%d) basic status register", config->addr);
164 		goto done;
165 	}
166 	state->is_up = bmsr & MII_BMSR_LINK_STATUS;
167 
168 	if (!state->is_up) {
169 		goto result;
170 	}
171 
172 	/* Read currently configured advertising options */
173 	ret = phy_mc_ksz8081_read(dev, MII_ANAR, &anar);
174 	if (ret) {
175 		LOG_ERR("Error reading phy (%d) advertising register", config->addr);
176 		goto done;
177 	}
178 
179 	/* Read link partner capability */
180 	ret = phy_mc_ksz8081_read(dev, MII_ANLPAR, &anlpar);
181 	if (ret) {
182 		LOG_ERR("Error reading phy (%d) link partner register", config->addr);
183 		goto done;
184 	}
185 
186 	uint32_t mutual_capabilities = anar & anlpar;
187 
188 	if (mutual_capabilities & MII_ADVERTISE_100_FULL) {
189 		state->speed = LINK_FULL_100BASE_T;
190 	} else if (mutual_capabilities & MII_ADVERTISE_100_HALF) {
191 		state->speed = LINK_HALF_100BASE_T;
192 	} else if (mutual_capabilities & MII_ADVERTISE_10_FULL) {
193 		state->speed = LINK_FULL_10BASE_T;
194 	} else if (mutual_capabilities & MII_ADVERTISE_10_HALF) {
195 		state->speed = LINK_HALF_10BASE_T;
196 	} else {
197 		ret = -EIO;
198 	}
199 
200 result:
201 	if (memcmp(&old_state, state, sizeof(struct phy_link_state)) != 0) {
202 		LOG_DBG("PHY %d is %s", config->addr, state->is_up ? "up" : "down");
203 		if (state->is_up) {
204 			LOG_DBG("PHY (%d) Link speed %s Mb, %s duplex\n", config->addr,
205 				(PHY_LINK_IS_SPEED_100M(state->speed) ? "100" : "10"),
206 				PHY_LINK_IS_FULL_DUPLEX(state->speed) ? "full" : "half");
207 		}
208 	}
209 
210 done:
211 	k_mutex_unlock(&data->mutex);
212 
213 	return ret;
214 }
215 
216 /*
217  * Configuration set statically (DT) that should never change
218  * This function is needed in case the PHY is reset then the next call
219  * to configure the phy will ensure this configuration will be redone
220  */
phy_mc_ksz8081_static_cfg(const struct device * dev)221 static int phy_mc_ksz8081_static_cfg(const struct device *dev)
222 {
223 	const struct mc_ksz8081_config *config = dev->config;
224 	uint32_t omso = 0;
225 	uint32_t ctrl2 = 0;
226 	int ret = 0;
227 
228 	/* Force normal operation in the case of factory mode */
229 	ret = phy_mc_ksz8081_read(dev, PHY_MC_KSZ8081_OMSO_REG, (uint32_t *)&omso);
230 	if (ret) {
231 		return ret;
232 	}
233 
234 	omso &= ~PHY_MC_KSZ8081_OMSO_FACTORY_MODE_MASK &
235 		~PHY_MC_KSZ8081_OMSO_NAND_TREE_MASK;
236 	if (config->phy_iface == KSZ8081_RMII) {
237 		omso &= ~PHY_MC_KSZ8081_OMSO_MII_OVERRIDE_MASK;
238 		omso |= PHY_MC_KSZ8081_OMSO_RMII_OVERRIDE_MASK;
239 	}
240 
241 	ret = phy_mc_ksz8081_write(dev, PHY_MC_KSZ8081_OMSO_REG, (uint32_t)omso);
242 	if (ret) {
243 		return ret;
244 	}
245 
246 	/* Select correct reference clock mode depending on interface setup */
247 	ret = phy_mc_ksz8081_read(dev, PHY_MC_KSZ8081_CTRL2_REG, (uint32_t *)&ctrl2);
248 	if (ret) {
249 		return ret;
250 	}
251 
252 	if (config->phy_iface == KSZ8081_RMII) {
253 		ctrl2 |= PHY_MC_KSZ8081_CTRL2_REF_CLK_SEL;
254 	} else {
255 		ctrl2 &= ~PHY_MC_KSZ8081_CTRL2_REF_CLK_SEL;
256 	}
257 
258 	ret = phy_mc_ksz8081_write(dev, PHY_MC_KSZ8081_CTRL2_REG, (uint32_t)ctrl2);
259 	if (ret) {
260 		return ret;
261 	}
262 
263 	return 0;
264 }
265 
266 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
phy_ksz8081_reset_gpio(const struct mc_ksz8081_config * config)267 static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config)
268 {
269 	int ret;
270 
271 	if (!config->reset_gpio.port) {
272 		return -ENODEV;
273 	}
274 
275 	/* Start reset */
276 	ret = gpio_pin_set_dt(&config->reset_gpio, 0);
277 	if (ret) {
278 		return ret;
279 	}
280 
281 	/* Wait for at least 500 us as specified by datasheet */
282 	k_busy_wait(1000);
283 
284 	/* Reset over */
285 	ret = gpio_pin_set_dt(&config->reset_gpio, 1);
286 
287 	/* After deasserting reset, must wait at least 100 us to use programming interface */
288 	k_busy_wait(200);
289 
290 	return ret;
291 }
292 #else
phy_ksz8081_reset_gpio(const struct mc_ksz8081_config * config)293 static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config)
294 {
295 	ARG_UNUSED(config);
296 
297 	return -ENODEV;
298 }
299 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */
300 
phy_mc_ksz8081_reset(const struct device * dev)301 static int phy_mc_ksz8081_reset(const struct device *dev)
302 {
303 	const struct mc_ksz8081_config *config = dev->config;
304 	struct mc_ksz8081_data *data = dev->data;
305 	int ret;
306 
307 	/* Lock mutex */
308 	ret = k_mutex_lock(&data->mutex, K_FOREVER);
309 	if (ret) {
310 		LOG_ERR("PHY mutex lock error");
311 		return ret;
312 	}
313 
314 	ret = phy_ksz8081_reset_gpio(config);
315 	if (ret != -ENODEV) { /* On -ENODEV, attempt command-based reset */
316 		goto done;
317 	}
318 
319 	ret = phy_mc_ksz8081_write(dev, MII_BMCR, MII_BMCR_RESET);
320 	if (ret) {
321 		goto done;
322 	}
323 
324 	/* According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1,
325 	 * a PHY reset may take up to 0.5 s.
326 	 */
327 	k_busy_wait(500 * USEC_PER_MSEC);
328 
329 done:
330 	/* Unlock mutex */
331 	k_mutex_unlock(&data->mutex);
332 	return ret;
333 }
334 
phy_mc_ksz8081_cfg_link(const struct device * dev,enum phy_link_speed speeds)335 static int phy_mc_ksz8081_cfg_link(const struct device *dev,
336 					enum phy_link_speed speeds)
337 {
338 	const struct mc_ksz8081_config *config = dev->config;
339 	struct mc_ksz8081_data *data = dev->data;
340 	struct phy_link_state state = {};
341 	int ret;
342 	uint32_t anar;
343 
344 	/* Lock mutex */
345 	ret = k_mutex_lock(&data->mutex, K_FOREVER);
346 	if (ret) {
347 		LOG_ERR("PHY mutex lock error");
348 		goto done;
349 	}
350 
351 	/* We are going to reconfigure the phy, don't need to monitor until done */
352 	k_work_cancel_delayable(&data->phy_monitor_work);
353 
354 	/* DT configurations */
355 	ret = phy_mc_ksz8081_static_cfg(dev);
356 	if (ret) {
357 		goto done;
358 	}
359 
360 	/* Read ANAR register to write back */
361 	ret = phy_mc_ksz8081_read(dev, MII_ANAR, &anar);
362 	if (ret) {
363 		LOG_ERR("Error reading phy (%d) advertising register", config->addr);
364 		goto done;
365 	}
366 
367 	/* Setup advertising register */
368 	if (speeds & LINK_FULL_100BASE_T) {
369 		anar |= MII_ADVERTISE_100_FULL;
370 	} else {
371 		anar &= ~MII_ADVERTISE_100_FULL;
372 	}
373 	if (speeds & LINK_HALF_100BASE_T) {
374 		anar |= MII_ADVERTISE_100_HALF;
375 	} else {
376 		anar &= ~MII_ADVERTISE_100_HALF;
377 	}
378 	if (speeds & LINK_FULL_10BASE_T) {
379 		anar |= MII_ADVERTISE_10_FULL;
380 	} else {
381 		anar &= ~MII_ADVERTISE_10_FULL;
382 	}
383 	if (speeds & LINK_HALF_10BASE_T) {
384 		anar |= MII_ADVERTISE_10_HALF;
385 	} else {
386 		anar &= ~MII_ADVERTISE_10_HALF;
387 	}
388 
389 	/* Write capabilities to advertising register */
390 	ret = phy_mc_ksz8081_write(dev, MII_ANAR, anar);
391 	if (ret) {
392 		LOG_ERR("Error writing phy (%d) advertising register", config->addr);
393 		goto done;
394 	}
395 
396 	/* (re)do autonegotiation */
397 	ret = phy_mc_ksz8081_autonegotiate(dev);
398 	if (ret && (ret != -ENETDOWN)) {
399 		LOG_ERR("Error in autonegotiation");
400 		goto done;
401 	}
402 
403 	/* Get link status */
404 	ret = phy_mc_ksz8081_get_link(dev, &state);
405 
406 	if (ret == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) {
407 		memcpy(&data->state, &state, sizeof(struct phy_link_state));
408 		if (data->cb) {
409 			data->cb(dev, &data->state, data->cb_data);
410 		}
411 	}
412 
413 	/* Log the results of the configuration */
414 	LOG_INF("PHY %d is %s", config->addr, data->state.is_up ? "up" : "down");
415 	if (data->state.is_up) {
416 		LOG_INF("PHY (%d) Link speed %s Mb, %s duplex\n", config->addr,
417 			(PHY_LINK_IS_SPEED_100M(data->state.speed) ? "100" : "10"),
418 			PHY_LINK_IS_FULL_DUPLEX(data->state.speed) ? "full" : "half");
419 	}
420 
421 done:
422 	/* Unlock mutex */
423 	k_mutex_unlock(&data->mutex);
424 
425 	/* Start monitoring */
426 	k_work_reschedule(&data->phy_monitor_work,
427 				K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
428 
429 	return ret;
430 }
431 
phy_mc_ksz8081_link_cb_set(const struct device * dev,phy_callback_t cb,void * user_data)432 static int phy_mc_ksz8081_link_cb_set(const struct device *dev,
433 					phy_callback_t cb, void *user_data)
434 {
435 	struct mc_ksz8081_data *data = dev->data;
436 
437 	data->cb = cb;
438 	data->cb_data = user_data;
439 
440 	phy_mc_ksz8081_get_link(dev, &data->state);
441 
442 	data->cb(dev, &data->state, data->cb_data);
443 
444 	return 0;
445 }
446 
phy_mc_ksz8081_monitor_work_handler(struct k_work * work)447 static void phy_mc_ksz8081_monitor_work_handler(struct k_work *work)
448 {
449 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
450 	struct mc_ksz8081_data *data =
451 		CONTAINER_OF(dwork, struct mc_ksz8081_data, phy_monitor_work);
452 	const struct device *dev = data->dev;
453 	struct phy_link_state state = {};
454 	int rc;
455 
456 	rc = phy_mc_ksz8081_get_link(dev, &state);
457 
458 	if (rc == 0 && memcmp(&state, &data->state, sizeof(struct phy_link_state)) != 0) {
459 		memcpy(&data->state, &state, sizeof(struct phy_link_state));
460 		if (data->cb) {
461 			data->cb(dev, &data->state, data->cb_data);
462 		}
463 	}
464 
465 	/* TODO change this to GPIO interrupt driven */
466 	k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD));
467 }
468 
phy_mc_ksz8081_init(const struct device * dev)469 static int phy_mc_ksz8081_init(const struct device *dev)
470 {
471 	const struct mc_ksz8081_config *config = dev->config;
472 	struct mc_ksz8081_data *data = dev->data;
473 	int ret;
474 
475 	data->dev = dev;
476 
477 	ret = k_mutex_init(&data->mutex);
478 	if (ret) {
479 		return ret;
480 	}
481 
482 	mdio_bus_enable(config->mdio_dev);
483 
484 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
485 	if (!config->interrupt_gpio.port) {
486 		goto skip_int_gpio;
487 	}
488 
489 	/* Prevent NAND TREE mode */
490 	ret = gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_OUTPUT_ACTIVE);
491 	if (ret) {
492 		return ret;
493 	}
494 
495 skip_int_gpio:
496 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) */
497 
498 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
499 	if (config->reset_gpio.port) {
500 		ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE);
501 		if (ret) {
502 			return ret;
503 		}
504 	}
505 #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */
506 
507 	/* Reset PHY */
508 	ret = phy_mc_ksz8081_reset(dev);
509 	if (ret) {
510 		return ret;
511 	}
512 
513 	k_work_init_delayable(&data->phy_monitor_work,
514 				phy_mc_ksz8081_monitor_work_handler);
515 
516 	return 0;
517 }
518 
519 static DEVICE_API(ethphy, mc_ksz8081_phy_api) = {
520 	.get_link = phy_mc_ksz8081_get_link,
521 	.cfg_link = phy_mc_ksz8081_cfg_link,
522 	.link_cb_set = phy_mc_ksz8081_link_cb_set,
523 	.read = phy_mc_ksz8081_read,
524 	.write = phy_mc_ksz8081_write,
525 };
526 
527 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
528 #define RESET_GPIO(n) \
529 		.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}),
530 #else
531 #define RESET_GPIO(n)
532 #endif /* reset gpio */
533 
534 #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
535 #define INTERRUPT_GPIO(n) \
536 		.interrupt_gpio = GPIO_DT_SPEC_INST_GET_OR(n, int_gpios, {0}),
537 #else
538 #define INTERRUPT_GPIO(n)
539 #endif /* interrupt gpio */
540 
541 #define MICROCHIP_KSZ8081_INIT(n)						\
542 	static const struct mc_ksz8081_config mc_ksz8081_##n##_config = {	\
543 		.addr = DT_INST_REG_ADDR(n),					\
544 		.mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)),			\
545 		.phy_iface = DT_INST_ENUM_IDX(n, microchip_interface_type),	\
546 		RESET_GPIO(n)							\
547 		INTERRUPT_GPIO(n)						\
548 	};									\
549 										\
550 	static struct mc_ksz8081_data mc_ksz8081_##n##_data;			\
551 										\
552 	DEVICE_DT_INST_DEFINE(n, &phy_mc_ksz8081_init, NULL,			\
553 			&mc_ksz8081_##n##_data, &mc_ksz8081_##n##_config,	\
554 			POST_KERNEL, CONFIG_PHY_INIT_PRIORITY,			\
555 			&mc_ksz8081_phy_api);
556 
557 DT_INST_FOREACH_STATUS_OKAY(MICROCHIP_KSZ8081_INIT)
558