1 /* ENC424J600 Stand-alone Ethernet Controller with SPI
2  *
3  * Copyright (c) 2016 Intel Corporation
4  * Copyright (c) 2019 PHYTEC Messtechnik GmbH
5  * Copyright (c) 2021 Laird Connectivity
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #define DT_DRV_COMPAT microchip_enc424j600
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/device.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <zephyr/drivers/gpio.h>
17 #include <zephyr/drivers/spi.h>
18 #include <zephyr/net/net_pkt.h>
19 #include <zephyr/net/net_if.h>
20 #include <zephyr/net/ethernet.h>
21 #include <ethernet/eth_stats.h>
22 
23 #include "eth_enc424j600_priv.h"
24 
25 LOG_MODULE_REGISTER(ethdrv, CONFIG_ETHERNET_LOG_LEVEL);
26 
enc424j600_write_sbc(const struct device * dev,uint8_t cmd)27 static void enc424j600_write_sbc(const struct device *dev, uint8_t cmd)
28 {
29 	const struct enc424j600_config *config = dev->config;
30 	uint8_t buf[2] = { cmd, 0xFF };
31 	const struct spi_buf tx_buf = {
32 		.buf = buf,
33 		.len = 1,
34 	};
35 	const struct spi_buf_set tx = {
36 		.buffers = &tx_buf,
37 		.count = 1
38 	};
39 
40 	spi_write_dt(&config->spi, &tx);
41 }
42 
enc424j600_write_sfru(const struct device * dev,uint8_t addr,uint16_t value)43 static void enc424j600_write_sfru(const struct device *dev, uint8_t addr,
44 				  uint16_t value)
45 {
46 	const struct enc424j600_config *config = dev->config;
47 	uint8_t buf[4];
48 	const struct spi_buf tx_buf = {
49 		.buf = buf,
50 		.len = sizeof(buf)
51 	};
52 	const struct spi_buf_set tx = {
53 		.buffers = &tx_buf,
54 		.count = 1
55 	};
56 
57 	buf[0] = ENC424J600_NBC_WCRU;
58 	buf[1] = addr;
59 	buf[2] = value;
60 	buf[3] = value >> 8;
61 
62 	spi_write_dt(&config->spi, &tx);
63 }
64 
enc424j600_read_sfru(const struct device * dev,uint8_t addr,uint16_t * value)65 static void enc424j600_read_sfru(const struct device *dev, uint8_t addr,
66 				 uint16_t *value)
67 {
68 	const struct enc424j600_config *config = dev->config;
69 	uint8_t buf[4];
70 	const struct spi_buf tx_buf = {
71 		.buf = buf,
72 		.len = 2
73 	};
74 	const struct spi_buf_set tx = {
75 		.buffers = &tx_buf,
76 		.count = 1
77 	};
78 	struct spi_buf rx_buf = {
79 		.buf = buf,
80 		.len = sizeof(buf),
81 	};
82 	const struct spi_buf_set rx = {
83 		.buffers = &rx_buf,
84 		.count = 1
85 	};
86 
87 	buf[0] = ENC424J600_NBC_RCRU;
88 	buf[1] = addr;
89 
90 	if (!spi_transceive_dt(&config->spi, &tx, &rx)) {
91 		*value = ((uint16_t)buf[3] << 8 | buf[2]);
92 	} else {
93 		LOG_DBG("Failure while reading register 0x%02x", addr);
94 		*value = 0U;
95 	}
96 }
97 
enc424j600_modify_sfru(const struct device * dev,uint8_t opcode,uint16_t addr,uint16_t value)98 static void enc424j600_modify_sfru(const struct device *dev, uint8_t opcode,
99 				   uint16_t addr, uint16_t value)
100 {
101 	const struct enc424j600_config *config = dev->config;
102 	uint8_t buf[4];
103 	const struct spi_buf tx_buf = {
104 		.buf = buf,
105 		.len = sizeof(buf)
106 	};
107 	const struct spi_buf_set tx = {
108 		.buffers = &tx_buf,
109 		.count = 1
110 	};
111 
112 	buf[0] = opcode;
113 	buf[1] = addr;
114 	buf[2] = value;
115 	buf[3] = value >> 8;
116 
117 	spi_write_dt(&config->spi, &tx);
118 }
119 
120 #define enc424j600_set_sfru(dev, addr, value) \
121 	enc424j600_modify_sfru(dev, ENC424J600_NBC_BFSU, addr, value)
122 
123 #define enc424j600_clear_sfru(dev, addr, value)	\
124 	enc424j600_modify_sfru(dev, ENC424J600_NBC_BFCU, addr, value)
125 
126 
enc424j600_write_phy(const struct device * dev,uint16_t addr,uint16_t data)127 static void enc424j600_write_phy(const struct device *dev, uint16_t addr,
128 				 uint16_t data)
129 {
130 	uint16_t mistat;
131 
132 	enc424j600_write_sfru(dev, ENC424J600_SFR2_MIREGADRL, addr);
133 	enc424j600_write_sfru(dev, ENC424J600_SFR3_MIWRL, data);
134 
135 	do {
136 		k_busy_wait(ENC424J600_PHY_ACCESS_DELAY);
137 		enc424j600_read_sfru(dev, ENC424J600_SFR3_MISTATL, &mistat);
138 	} while ((mistat & ENC424J600_MISTAT_BUSY));
139 }
140 
enc424j600_read_phy(const struct device * dev,uint16_t addr,uint16_t * data)141 static void enc424j600_read_phy(const struct device *dev, uint16_t addr,
142 				uint16_t *data)
143 {
144 	uint16_t mistat;
145 
146 	enc424j600_write_sfru(dev, ENC424J600_SFR2_MIREGADRL, addr);
147 	enc424j600_write_sfru(dev, ENC424J600_SFR2_MICMDL,
148 			      ENC424J600_MICMD_MIIRD);
149 
150 	do {
151 		k_busy_wait(ENC424J600_PHY_ACCESS_DELAY);
152 		enc424j600_read_sfru(dev, ENC424J600_SFR3_MISTATL, &mistat);
153 	} while ((mistat & ENC424J600_MISTAT_BUSY));
154 
155 	enc424j600_write_sfru(dev, ENC424J600_SFR2_MICMDL, 0);
156 	enc424j600_read_sfru(dev, ENC424J600_SFR3_MIRDL, data);
157 }
158 
enc424j600_write_mem(const struct device * dev,uint8_t opcode,uint8_t * data_buffer,uint16_t buf_len)159 static void enc424j600_write_mem(const struct device *dev, uint8_t opcode,
160 				 uint8_t *data_buffer, uint16_t buf_len)
161 {
162 	const struct enc424j600_config *config = dev->config;
163 	uint8_t buf[1] = { opcode };
164 	const struct spi_buf tx_buf[2] = {
165 		{
166 			.buf = buf,
167 			.len = 1
168 		},
169 		{
170 			.buf = data_buffer,
171 			.len = buf_len
172 		},
173 	};
174 	const struct spi_buf_set tx = {
175 		.buffers = tx_buf,
176 		.count = 2
177 	};
178 
179 	if (spi_write_dt(&config->spi, &tx)) {
180 		LOG_ERR("Failed to write SRAM buffer");
181 		return;
182 	}
183 }
184 
enc424j600_read_mem(const struct device * dev,uint8_t opcode,uint8_t * data_buffer,uint16_t buf_len)185 static void enc424j600_read_mem(const struct device *dev, uint8_t opcode,
186 				uint8_t *data_buffer, uint16_t buf_len)
187 {
188 	const struct enc424j600_config *config = dev->config;
189 	uint8_t buf[1] = { opcode };
190 	const struct spi_buf tx_buf = {
191 		.buf = buf,
192 		.len = 1
193 	};
194 	const struct spi_buf_set tx = {
195 		.buffers = &tx_buf,
196 		.count = 1
197 	};
198 	struct spi_buf rx_buf[2] = {
199 		{
200 			.buf = NULL,
201 			.len = 1
202 		},
203 		{
204 			.buf = data_buffer,
205 			.len = buf_len
206 		},
207 	};
208 	const struct spi_buf_set rx = {
209 		.buffers = rx_buf,
210 		.count = 2
211 	};
212 
213 	if (spi_transceive_dt(&config->spi, &tx, &rx)) {
214 		LOG_ERR("Failed to read SRAM buffer");
215 		return;
216 	}
217 }
218 
enc424j600_gpio_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)219 static void enc424j600_gpio_callback(const struct device *dev,
220 				       struct gpio_callback *cb,
221 				       uint32_t pins)
222 {
223 	struct enc424j600_runtime *context =
224 		CONTAINER_OF(cb, struct enc424j600_runtime, gpio_cb);
225 
226 	k_sem_give(&context->int_sem);
227 }
228 
enc424j600_init_filters(const struct device * dev)229 static void enc424j600_init_filters(const struct device *dev)
230 {
231 	uint16_t tmp;
232 
233 	enc424j600_write_sfru(dev, ENC424J600_SFR1_ERXFCONL,
234 			      ENC424J600_ERXFCON_CRCEN |
235 			      ENC424J600_ERXFCON_RUNTEN |
236 			      ENC424J600_ERXFCON_UCEN |
237 			      ENC424J600_ERXFCON_MCEN |
238 			      ENC424J600_ERXFCON_BCEN);
239 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
240 		enc424j600_read_sfru(dev, ENC424J600_SFR1_ERXFCONL, &tmp);
241 		LOG_DBG("ERXFCON: 0x%04x", tmp);
242 	}
243 }
244 
enc424j600_init_phy(const struct device * dev)245 static void enc424j600_init_phy(const struct device *dev)
246 {
247 	uint16_t tmp;
248 
249 	enc424j600_write_phy(dev, ENC424J600_PSFR_PHANA,
250 			     ENC424J600_PHANA_ADPAUS_SYMMETRIC_ONLY |
251 			     ENC424J600_PHANA_AD100FD |
252 			     ENC424J600_PHANA_AD100 |
253 			     ENC424J600_PHANA_AD10FD |
254 			     ENC424J600_PHANA_AD10 |
255 			     ENC424J600_PHANA_ADIEEE_DEFAULT);
256 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
257 		enc424j600_read_phy(dev, ENC424J600_PSFR_PHANA, &tmp);
258 		LOG_DBG("PHANA: 0x%04x", tmp);
259 	}
260 
261 	enc424j600_read_phy(dev, ENC424J600_PSFR_PHCON1, &tmp);
262 	tmp |= ENC424J600_PHCON1_RENEG;
263 	LOG_DBG("PHCON1: 0x%04x", tmp);
264 	enc424j600_write_phy(dev, ENC424J600_PSFR_PHCON1, tmp);
265 }
266 
enc424j600_setup_mac(const struct device * dev)267 static void enc424j600_setup_mac(const struct device *dev)
268 {
269 	uint16_t tmp;
270 	uint16_t macon2;
271 
272 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
273 		enc424j600_read_phy(dev, ENC424J600_PSFR_PHANLPA, &tmp);
274 		LOG_DBG("PHANLPA: 0x%04x", tmp);
275 	}
276 
277 	enc424j600_read_phy(dev, ENC424J600_PSFR_PHSTAT3, &tmp);
278 
279 	if (tmp & ENC424J600_PHSTAT3_SPDDPX_100) {
280 		LOG_INF("100Mbps");
281 	} else if (tmp & ENC424J600_PHSTAT3_SPDDPX_10) {
282 		LOG_INF("10Mbps");
283 	} else {
284 		LOG_ERR("Unknown speed configuration");
285 	}
286 
287 	if (tmp & ENC424J600_PHSTAT3_SPDDPX_FD) {
288 		LOG_INF("full duplex");
289 		enc424j600_read_sfru(dev, ENC424J600_SFR2_MACON2L, &macon2);
290 		macon2 |= ENC424J600_MACON2_FULDPX;
291 		enc424j600_write_sfru(dev, ENC424J600_SFR2_MACON2L, macon2);
292 		enc424j600_write_sfru(dev, ENC424J600_SFR2_MABBIPGL,
293 				      ENC424J600_MABBIPG_DEFAULT);
294 
295 	} else {
296 		LOG_INF("half duplex");
297 	}
298 
299 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
300 		enc424j600_read_sfru(dev, ENC424J600_SFR2_MACON2L, &tmp);
301 		LOG_DBG("MACON2: 0x%04x", tmp);
302 
303 		enc424j600_read_sfru(dev, ENC424J600_SFR2_MAMXFLL, &tmp);
304 		LOG_DBG("MAMXFL (maximum frame length): %u", tmp);
305 	}
306 }
307 
enc424j600_tx(const struct device * dev,struct net_pkt * pkt)308 static int enc424j600_tx(const struct device *dev, struct net_pkt *pkt)
309 {
310 	struct enc424j600_runtime *context = dev->data;
311 	uint16_t len = net_pkt_get_len(pkt);
312 	struct net_buf *frag;
313 	uint16_t tmp;
314 
315 	LOG_DBG("pkt %p (len %u)", pkt, len);
316 
317 	k_sem_take(&context->tx_rx_sem, K_FOREVER);
318 
319 	enc424j600_write_sfru(dev, ENC424J600_SFR4_EGPWRPTL,
320 			      ENC424J600_TXSTART);
321 
322 	for (frag = pkt->frags; frag; frag = frag->frags) {
323 		enc424j600_write_mem(dev, ENC424J600_NBC_WGPDATA, frag->data,
324 				     frag->len);
325 	}
326 
327 	enc424j600_write_sfru(dev, ENC424J600_SFR0_ETXSTL,
328 			      ENC424J600_TXSTART);
329 	enc424j600_write_sfru(dev, ENC424J600_SFR0_ETXLENL, len);
330 	enc424j600_write_sbc(dev, ENC424J600_1BC_SETTXRTS);
331 
332 	do {
333 		k_sleep(K_MSEC(1));
334 		enc424j600_read_sfru(dev, ENC424J600_SFRX_ECON1L, &tmp);
335 	} while (tmp & ENC424J600_ECON1_TXRTS);
336 
337 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
338 		enc424j600_read_sfru(dev, ENC424J600_SFR0_ETXSTATL, &tmp);
339 		LOG_DBG("ETXSTAT: 0x%04x", tmp);
340 	}
341 
342 	k_sem_give(&context->tx_rx_sem);
343 
344 	return 0;
345 }
346 
enc424j600_rx(const struct device * dev)347 static int enc424j600_rx(const struct device *dev)
348 {
349 	struct enc424j600_runtime *context = dev->data;
350 	const struct enc424j600_config *config = dev->config;
351 	uint8_t info[ENC424J600_RSV_SIZE + ENC424J600_PTR_NXP_PKT_SIZE];
352 	struct net_buf *pkt_buf = NULL;
353 	struct net_pkt *pkt;
354 	uint16_t frm_len = 0U;
355 	uint32_t status;
356 	uint16_t tmp;
357 
358 	k_sem_take(&context->tx_rx_sem, K_FOREVER);
359 
360 	enc424j600_write_sfru(dev, ENC424J600_SFR4_ERXRDPTL,
361 			      context->next_pkt_ptr);
362 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
363 		enc424j600_read_sfru(dev, ENC424J600_SFR4_ERXRDPTL, &tmp);
364 		LOG_DBG("set ERXRDPT to 0x%04x", tmp);
365 	}
366 
367 	enc424j600_read_mem(dev, ENC424J600_NBC_RRXDATA, info,
368 			    sizeof(info));
369 
370 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
371 		enc424j600_read_sfru(dev, ENC424J600_SFR4_ERXRDPTL, &tmp);
372 		LOG_DBG("ERXRDPT is 0x%04x now", tmp);
373 	}
374 
375 	context->next_pkt_ptr = sys_get_le16(&info[0]);
376 	frm_len = sys_get_le16(&info[2]);
377 	status = sys_get_le32(&info[4]);
378 	LOG_DBG("npp 0x%04x, length %u, status 0x%08x",
379 		context->next_pkt_ptr, frm_len, status);
380 	/* frame length without FCS */
381 	frm_len -= 4;
382 	if (frm_len > NET_ETH_MAX_FRAME_SIZE) {
383 		LOG_ERR("Maximum frame length exceeded");
384 		eth_stats_update_errors_rx(context->iface);
385 		goto done;
386 	}
387 
388 	/* Get the frame from the buffer */
389 	pkt = net_pkt_rx_alloc_with_buffer(context->iface, frm_len,
390 					   AF_UNSPEC, 0,
391 					   K_MSEC(config->timeout));
392 	if (!pkt) {
393 		LOG_ERR("Could not allocate rx buffer");
394 		eth_stats_update_errors_rx(context->iface);
395 		goto done;
396 	}
397 
398 	pkt_buf = pkt->buffer;
399 
400 	do {
401 		size_t frag_len;
402 		uint8_t *data_ptr;
403 		size_t spi_frame_len;
404 
405 		data_ptr = pkt_buf->data;
406 
407 		/* Review the space available for the new frag */
408 		frag_len = net_buf_tailroom(pkt_buf);
409 
410 		if (frm_len > frag_len) {
411 			spi_frame_len = frag_len;
412 		} else {
413 			spi_frame_len = frm_len;
414 		}
415 
416 		enc424j600_read_mem(dev, ENC424J600_NBC_RRXDATA, data_ptr,
417 				    spi_frame_len);
418 
419 		net_buf_add(pkt_buf, spi_frame_len);
420 
421 		/* One fragment has been written via SPI */
422 		frm_len -= spi_frame_len;
423 		pkt_buf = pkt_buf->frags;
424 	} while (frm_len > 0);
425 
426 	if (net_recv_data(context->iface, pkt) < 0) {
427 		net_pkt_unref(pkt);
428 	}
429 
430 done:
431 	if (context->next_pkt_ptr == ENC424J600_RXSTART) {
432 		tmp = ENC424J600_RXEND - 1;
433 		LOG_DBG("wrap back");
434 	} else {
435 		tmp = context->next_pkt_ptr - 2;
436 	}
437 
438 	enc424j600_write_sfru(dev, ENC424J600_SFR0_ERXTAILL, tmp);
439 	enc424j600_write_sbc(dev, ENC424J600_1BC_SETPKTDEC);
440 	k_sem_give(&context->tx_rx_sem);
441 
442 	return 0;
443 }
444 
enc424j600_rx_thread(void * p1,void * p2,void * p3)445 static void enc424j600_rx_thread(void *p1, void *p2, void *p3)
446 {
447 	ARG_UNUSED(p2);
448 	ARG_UNUSED(p3);
449 
450 	struct enc424j600_runtime *context = p1;
451 	uint16_t eir;
452 	uint16_t estat;
453 	uint8_t counter;
454 
455 	while (true) {
456 		k_sem_take(&context->int_sem, K_FOREVER);
457 
458 		enc424j600_write_sbc(context->dev, ENC424J600_1BC_CLREIE);
459 		enc424j600_read_sfru(context->dev, ENC424J600_SFRX_EIRL, &eir);
460 		enc424j600_read_sfru(context->dev,
461 				     ENC424J600_SFRX_ESTATL, &estat);
462 		LOG_DBG("ESTAT: 0x%04x", estat);
463 
464 		if (eir & ENC424J600_EIR_PKTIF) {
465 			counter = (uint8_t)estat;
466 			while (counter) {
467 				enc424j600_rx(context->dev);
468 				enc424j600_read_sfru(context->dev,
469 						     ENC424J600_SFRX_ESTATL,
470 						     &estat);
471 				counter = (uint8_t)estat;
472 				LOG_DBG("ESTAT: 0x%04x", estat);
473 			}
474 		} else if (eir & ENC424J600_EIR_LINKIF) {
475 			enc424j600_clear_sfru(context->dev,
476 					      ENC424J600_SFRX_EIRL,
477 					      ENC424J600_EIR_LINKIF);
478 			if (estat & ENC424J600_ESTAT_PHYLNK) {
479 				LOG_INF("Link up");
480 				enc424j600_setup_mac(context->dev);
481 				net_eth_carrier_on(context->iface);
482 			} else {
483 				LOG_INF("Link down");
484 
485 				if (context->iface_initialized) {
486 					net_eth_carrier_off(context->iface);
487 				}
488 			}
489 		} else {
490 			LOG_ERR("Unknown Interrupt, EIR: 0x%04x", eir);
491 			/*
492 			 * Terminate interrupt handling thread
493 			 * only when debugging.
494 			 */
495 			if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
496 				k_oops();
497 			}
498 		}
499 
500 		enc424j600_write_sbc(context->dev, ENC424J600_1BC_SETEIE);
501 	}
502 }
503 
enc424j600_get_config(const struct device * dev,enum ethernet_config_type type,struct ethernet_config * config)504 static int enc424j600_get_config(const struct device *dev,
505 				 enum ethernet_config_type type,
506 				 struct ethernet_config *config)
507 {
508 	uint16_t tmp;
509 	int rc = 0;
510 	struct enc424j600_runtime *context = dev->data;
511 
512 	if (type != ETHERNET_CONFIG_TYPE_LINK &&
513 	    type != ETHERNET_CONFIG_TYPE_DUPLEX) {
514 		/* Unsupported configuration query */
515 		return -ENOTSUP;
516 	}
517 
518 	k_sem_take(&context->tx_rx_sem, K_FOREVER);
519 
520 	if (type == ETHERNET_CONFIG_TYPE_LINK) {
521 		/* Query active link speed */
522 		enc424j600_read_phy(dev, ENC424J600_PSFR_PHSTAT3, &tmp);
523 
524 		if (tmp & ENC424J600_PHSTAT3_SPDDPX_100) {
525 			/* 100Mbps link speed */
526 			config->l.link_100bt = true;
527 		} else if (tmp & ENC424J600_PHSTAT3_SPDDPX_10) {
528 			/* 10Mbps link speed */
529 			config->l.link_10bt = true;
530 		} else {
531 			/* Unknown link speed */
532 			rc = -EINVAL;
533 		}
534 	} else if (type == ETHERNET_CONFIG_TYPE_DUPLEX) {
535 		/* Query if half or full duplex */
536 		enc424j600_read_phy(dev, ENC424J600_PSFR_PHSTAT3, &tmp);
537 
538 		/* Assume operating in half duplex mode */
539 		config->full_duplex = false;
540 
541 		if (tmp & ENC424J600_PHSTAT3_SPDDPX_FD) {
542 			/* Operating in full duplex mode */
543 			config->full_duplex = true;
544 		}
545 	}
546 
547 	k_sem_give(&context->tx_rx_sem);
548 
549 	return rc;
550 }
551 
enc424j600_get_capabilities(const struct device * dev)552 static enum ethernet_hw_caps enc424j600_get_capabilities(const struct device *dev)
553 {
554 	ARG_UNUSED(dev);
555 
556 	return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T;
557 }
558 
enc424j600_iface_init(struct net_if * iface)559 static void enc424j600_iface_init(struct net_if *iface)
560 {
561 	const struct device *dev = net_if_get_device(iface);
562 	struct enc424j600_runtime *context = dev->data;
563 
564 	net_if_set_link_addr(iface, context->mac_address,
565 			     sizeof(context->mac_address),
566 			     NET_LINK_ETHERNET);
567 	context->iface = iface;
568 	ethernet_init(iface);
569 
570 	net_if_carrier_off(iface);
571 	context->iface_initialized = true;
572 }
573 
enc424j600_start_device(const struct device * dev)574 static int enc424j600_start_device(const struct device *dev)
575 {
576 	struct enc424j600_runtime *context = dev->data;
577 	uint16_t tmp;
578 
579 	if (!context->suspended) {
580 		LOG_INF("Not suspended");
581 		return 0;
582 	}
583 
584 	k_sem_take(&context->tx_rx_sem, K_FOREVER);
585 
586 	enc424j600_set_sfru(dev, ENC424J600_SFR3_ECON2L,
587 			    ENC424J600_ECON2_ETHEN |
588 			    ENC424J600_ECON2_STRCH);
589 
590 	enc424j600_read_phy(dev, ENC424J600_PSFR_PHCON1, &tmp);
591 	tmp &= ~ENC424J600_PHCON1_PSLEEP;
592 	enc424j600_write_phy(dev, ENC424J600_PSFR_PHCON1, tmp);
593 
594 	enc424j600_set_sfru(dev, ENC424J600_SFRX_ECON1L,
595 			      ENC424J600_ECON1_RXEN);
596 
597 	context->suspended = false;
598 	k_sem_give(&context->tx_rx_sem);
599 	LOG_INF("started");
600 
601 	return 0;
602 }
603 
enc424j600_stop_device(const struct device * dev)604 static int enc424j600_stop_device(const struct device *dev)
605 {
606 	struct enc424j600_runtime *context = dev->data;
607 	uint16_t tmp;
608 
609 	if (context->suspended) {
610 		LOG_WRN("Already suspended");
611 		return 0;
612 	}
613 
614 	k_sem_take(&context->tx_rx_sem, K_FOREVER);
615 
616 	enc424j600_clear_sfru(dev, ENC424J600_SFRX_ECON1L,
617 			      ENC424J600_ECON1_RXEN);
618 
619 	do {
620 		k_sleep(K_MSEC(10U));
621 		enc424j600_read_sfru(dev, ENC424J600_SFRX_ESTATL, &tmp);
622 	} while (tmp & ENC424J600_ESTAT_RXBUSY);
623 
624 	do {
625 		k_sleep(K_MSEC(10U));
626 		enc424j600_read_sfru(dev, ENC424J600_SFRX_ECON1L, &tmp);
627 	} while (tmp & ENC424J600_ECON1_TXRTS);
628 
629 	enc424j600_read_phy(dev, ENC424J600_PSFR_PHCON1, &tmp);
630 	tmp |= ENC424J600_PHCON1_PSLEEP;
631 	enc424j600_write_phy(dev, ENC424J600_PSFR_PHCON1, tmp);
632 
633 	enc424j600_clear_sfru(dev, ENC424J600_SFR3_ECON2L,
634 			      ENC424J600_ECON2_ETHEN |
635 			      ENC424J600_ECON2_STRCH);
636 
637 	context->suspended = true;
638 	k_sem_give(&context->tx_rx_sem);
639 	LOG_INF("stopped");
640 
641 	return 0;
642 }
643 
644 static const struct ethernet_api api_funcs = {
645 	.iface_api.init		= enc424j600_iface_init,
646 	.get_config		= enc424j600_get_config,
647 	.get_capabilities	= enc424j600_get_capabilities,
648 	.send			= enc424j600_tx,
649 	.start			= enc424j600_start_device,
650 	.stop			= enc424j600_stop_device,
651 };
652 
enc424j600_init(const struct device * dev)653 static int enc424j600_init(const struct device *dev)
654 {
655 	const struct enc424j600_config *config = dev->config;
656 	struct enc424j600_runtime *context = dev->data;
657 	uint8_t retries = ENC424J600_DEFAULT_NUMOF_RETRIES;
658 	uint16_t tmp;
659 
660 	context->dev = dev;
661 
662 	/* SPI config */
663 	if (!spi_is_ready_dt(&config->spi)) {
664 		LOG_ERR("SPI master port %s not ready", config->spi.bus->name);
665 		return -EINVAL;
666 	}
667 
668 	/* Initialize GPIO */
669 	if (!gpio_is_ready_dt(&config->interrupt)) {
670 		LOG_ERR("GPIO port %s not ready", config->interrupt.port->name);
671 		return -EINVAL;
672 	}
673 
674 	if (gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT)) {
675 		LOG_ERR("Unable to configure GPIO pin %u",
676 			config->interrupt.pin);
677 		return -EINVAL;
678 	}
679 
680 	gpio_init_callback(&(context->gpio_cb), enc424j600_gpio_callback,
681 			   BIT(config->interrupt.pin));
682 
683 	if (gpio_add_callback(config->interrupt.port, &(context->gpio_cb))) {
684 		return -EINVAL;
685 	}
686 
687 	gpio_pin_interrupt_configure_dt(&config->interrupt,
688 					GPIO_INT_EDGE_TO_ACTIVE);
689 
690 	/* Check SPI connection */
691 	do {
692 		k_busy_wait(USEC_PER_MSEC * 1U);
693 		enc424j600_write_sfru(dev, ENC424J600_SFRX_EUDASTL, 0x4AFE);
694 		enc424j600_read_sfru(dev, ENC424J600_SFRX_EUDASTL, &tmp);
695 		retries--;
696 	} while (tmp != 0x4AFE && retries);
697 
698 	if (tmp != 0x4AFE) {
699 		LOG_ERR("Timeout, failed to establish SPI connection");
700 		return -EIO;
701 	}
702 
703 	retries = ENC424J600_DEFAULT_NUMOF_RETRIES;
704 	do {
705 		k_busy_wait(USEC_PER_MSEC * 1U);
706 		enc424j600_read_sfru(dev, ENC424J600_SFRX_ESTATL, &tmp);
707 		retries--;
708 	} while (!(tmp & ENC424J600_ESTAT_CLKRDY)  && retries);
709 
710 	if (!(tmp & ENC424J600_ESTAT_CLKRDY)) {
711 		LOG_ERR("CLKRDY not set");
712 		return -EIO;
713 	}
714 
715 	enc424j600_write_sbc(dev, ENC424J600_1BC_SETETHRST);
716 
717 	k_busy_wait(ENC424J600_PHY_READY_DELAY);
718 	enc424j600_read_sfru(dev, ENC424J600_SFRX_EUDASTL, &tmp);
719 	if (tmp) {
720 		LOG_ERR("Failed to initialize ENC424J600");
721 		return -EIO;
722 	}
723 
724 	/* Disable INTIE and setup interrupt logic */
725 	enc424j600_write_sfru(dev, ENC424J600_SFR3_EIEL,
726 			      ENC424J600_EIE_PKTIE | ENC424J600_EIE_LINKIE);
727 
728 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
729 		enc424j600_read_sfru(dev, ENC424J600_SFR3_EIEL, &tmp);
730 		LOG_DBG("EIE: 0x%04x", tmp);
731 	}
732 
733 	/* Configure TX and RX buffer */
734 	enc424j600_write_sfru(dev, ENC424J600_SFR0_ETXSTL,
735 			      ENC424J600_TXSTART);
736 	enc424j600_write_sfru(dev, ENC424J600_SFR0_ERXSTL,
737 			      ENC424J600_RXSTART);
738 	enc424j600_write_sfru(dev, ENC424J600_SFR0_ERXTAILL,
739 			      (ENC424J600_RXEND - 1));
740 	context->next_pkt_ptr = ENC424J600_RXSTART;
741 
742 	/* Disable user-defined buffer */
743 	enc424j600_write_sfru(dev, ENC424J600_SFRX_EUDASTL,
744 			      (ENC424J600_RXEND - 1));
745 	enc424j600_write_sfru(dev, ENC424J600_SFRX_EUDANDL,
746 			      (ENC424J600_RXEND - 1));
747 
748 	/* read MAC address byte 2 and 1 */
749 	enc424j600_read_sfru(dev, ENC424J600_SFR3_MAADR1L, &tmp);
750 	context->mac_address[0] = tmp;
751 	context->mac_address[1] = tmp >> 8;
752 	/* read MAC address byte 4 and 3 */
753 	enc424j600_read_sfru(dev, ENC424J600_SFR3_MAADR2L, &tmp);
754 	context->mac_address[2] = tmp;
755 	context->mac_address[3] = tmp >> 8;
756 	/* read MAC address byte 6 and 5 */
757 	enc424j600_read_sfru(dev, ENC424J600_SFR3_MAADR3L, &tmp);
758 	context->mac_address[4] = tmp;
759 	context->mac_address[5] = tmp >> 8;
760 
761 	enc424j600_init_filters(dev);
762 	enc424j600_init_phy(dev);
763 
764 	/* Enable Reception */
765 	enc424j600_set_sfru(dev, ENC424J600_SFRX_ECON1L, ENC424J600_ECON1_RXEN);
766 	if (CONFIG_ETHERNET_LOG_LEVEL == LOG_LEVEL_DBG) {
767 		enc424j600_read_sfru(dev, ENC424J600_SFRX_ECON1L, &tmp);
768 		LOG_DBG("ECON1: 0x%04x", tmp);
769 	}
770 
771 	/* Start interruption-poll thread */
772 	k_thread_create(&context->thread, context->thread_stack,
773 			CONFIG_ETH_ENC424J600_RX_THREAD_STACK_SIZE,
774 			enc424j600_rx_thread,
775 			context, NULL, NULL,
776 			K_PRIO_COOP(CONFIG_ETH_ENC424J600_RX_THREAD_PRIO),
777 			0, K_NO_WAIT);
778 
779 	enc424j600_write_sbc(dev, ENC424J600_1BC_SETEIE);
780 
781 	context->suspended = false;
782 	LOG_INF("ENC424J600 Initialized");
783 
784 	return 0;
785 }
786 
787 static struct enc424j600_runtime enc424j600_0_runtime = {
788 	.tx_rx_sem = Z_SEM_INITIALIZER(enc424j600_0_runtime.tx_rx_sem,
789 				       1,  UINT_MAX),
790 	.int_sem  = Z_SEM_INITIALIZER(enc424j600_0_runtime.int_sem,
791 				      0, UINT_MAX),
792 };
793 
794 static const struct enc424j600_config enc424j600_0_config = {
795 	.spi = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8), 0),
796 	.interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios),
797 	.timeout = CONFIG_ETH_ENC424J600_TIMEOUT,
798 };
799 
800 ETH_NET_DEVICE_DT_INST_DEFINE(0,
801 		    enc424j600_init, NULL,
802 		    &enc424j600_0_runtime, &enc424j600_0_config,
803 		    CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU);
804