1 /*
2  * Copyright (c) 2023 PHOENIX CONTACT Electronics GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(eth_adin2111, CONFIG_ETHERNET_LOG_LEVEL);
9 
10 #include <zephyr/net/net_pkt.h>
11 #include <zephyr/net/ethernet.h>
12 #include <zephyr/net/phy.h>
13 
14 #if CONFIG_ETH_ADIN2111_SPI_CFG0
15 #include <zephyr/sys/crc.h>
16 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
17 #include <string.h>
18 #include <errno.h>
19 
20 #include <zephyr/net/net_if.h>
21 #include <zephyr/net/ethernet.h>
22 #include <zephyr/net/phy.h>
23 #include <zephyr/drivers/ethernet/eth_adin2111.h>
24 
25 #include "phy/phy_adin2111_priv.h"
26 #include "eth_adin2111_priv.h"
27 
28 #define DT_DRV_COMPAT adi_adin2111
29 
30 /* SPI Communication check retry delay */
31 #define ADIN2111_DEV_AWAIT_DELAY_POLL_US	100U
32 /* Number of retries SPI Communication check */
33 #define ADIN2111_DEV_AWAIT_RETRY_COUNT		200U
34 
35 /* ADIN RESETC check retry delay */
36 #define ADIN2111_RESETC_AWAIT_DELAY_POLL_US	100U
37 /* Number of retries for ADIN RESETC check */
38 #define ADIN2111_RESETC_AWAIT_RETRY_COUNT	200U
39 
40 /* Boot delay for clocks stabilisation (maximum 90ms) */
41 #define ADIN2111_HW_BOOT_DELAY_MS		100
42 
43 /* MAC Address Rule and DA Filter multicast slot/idx */
44 #define ADIN2111_MULTICAST_ADDR_SLOT		0U
45 /* MAC Address Rule and DA Filter broadcast slot/idx */
46 #define ADIN2111_BROADCAST_ADDR_SLOT		1U
47 /* MAC Address Rule and DA Filter Port 1 slot/idx */
48 #define ADIN2111_UNICAST_P1_ADDR_SLOT		2U
49 /* MAC Address Rule and DA Filter Port 2 slot/idx */
50 #define ADIN2111_UNICAST_P2_ADDR_SLOT		3U
51 /* Free slots for further filtering */
52 #define ADIN2111_FILTER_FIRST_SLOT		4U
53 #define ADIN2111_FILTER_SLOTS			16U
54 
55 /* As per RM rev. A table 3, t3 >= 50ms, delay for SPI interface to be ready */
56 #define ADIN2111_SPI_ACTIVE_DELAY_MS		50U
57 /* As per RM rev. A page 20: approximately 10 ms (maximum) for internal logic to be ready. */
58 #define ADIN2111_SW_RESET_DELAY_MS		10U
59 
eth_adin2111_mac_reset(const struct device * dev)60 int eth_adin2111_mac_reset(const struct device *dev)
61 {
62 	uint32_t val;
63 	int ret;
64 
65 	ret = eth_adin2111_reg_write(dev, ADIN2111_SOFT_RST_REG, ADIN2111_SWRESET_KEY1);
66 	if (ret < 0) {
67 		return ret;
68 	}
69 	ret = eth_adin2111_reg_write(dev, ADIN2111_SOFT_RST_REG, ADIN2111_SWRESET_KEY2);
70 	if (ret < 0) {
71 		return ret;
72 	}
73 	ret = eth_adin2111_reg_write(dev, ADIN2111_SOFT_RST_REG, ADIN2111_SWRELEASE_KEY1);
74 	if (ret < 0) {
75 		return ret;
76 	}
77 	ret = eth_adin2111_reg_write(dev, ADIN2111_SOFT_RST_REG, ADIN2111_SWRELEASE_KEY2);
78 	if (ret < 0) {
79 		return ret;
80 	}
81 	ret = eth_adin2111_reg_read(dev, ADIN1110_MAC_RST_STATUS_REG, &val);
82 	if (ret < 0) {
83 		return ret;
84 	}
85 	if (val == 0) {
86 		return -EBUSY;
87 	}
88 
89 	return 0;
90 }
91 
eth_adin2111_reg_update(const struct device * dev,const uint16_t reg,uint32_t mask,uint32_t data)92 int eth_adin2111_reg_update(const struct device *dev, const uint16_t reg,
93 			    uint32_t mask,  uint32_t data)
94 {
95 	uint32_t val;
96 	int ret;
97 
98 	ret = eth_adin2111_reg_read(dev, reg, &val);
99 	if (ret < 0) {
100 		return ret;
101 	}
102 
103 	val &= ~mask;
104 	val |= mask & data;
105 
106 	return eth_adin2111_reg_write(dev, reg, val);
107 }
108 
eth_adin2111_get_iface(const struct device * dev,const uint16_t port_idx)109 struct net_if *eth_adin2111_get_iface(const struct device *dev, const uint16_t port_idx)
110 {
111 	struct adin2111_data *ctx = dev->data;
112 
113 	return ((struct adin2111_port_data *)ctx->port[port_idx]->data)->iface;
114 }
115 
eth_adin2111_lock(const struct device * dev,k_timeout_t timeout)116 int eth_adin2111_lock(const struct device *dev, k_timeout_t timeout)
117 {
118 	struct adin2111_data *ctx = dev->data;
119 
120 	return k_mutex_lock(&ctx->lock, timeout);
121 }
122 
eth_adin2111_unlock(const struct device * dev)123 int eth_adin2111_unlock(const struct device *dev)
124 {
125 	struct adin2111_data *ctx = dev->data;
126 
127 	return k_mutex_unlock(&ctx->lock);
128 }
129 
eth_adin2111_oa_get_parity(const uint32_t x)130 static inline bool eth_adin2111_oa_get_parity(const uint32_t x)
131 {
132 	uint32_t y;
133 
134 	y = x ^ (x >> 1);
135 	y = y ^ (y >> 2);
136 	y = y ^ (y >> 4);
137 	y = y ^ (y >> 8);
138 	y = y ^ (y >> 16);
139 
140 	return !(y & 1);
141 }
142 
eth_adin2111_oa_spi_xfer(const struct device * dev,uint8_t * buf_rx,uint8_t * buf_tx,int len)143 int eth_adin2111_oa_spi_xfer(const struct device *dev, uint8_t *buf_rx, uint8_t *buf_tx, int len)
144 {
145 	const struct adin2111_config *cfg = dev->config;
146 
147 	struct spi_buf tx_buf[1];
148 	struct spi_buf rx_buf[1];
149 	struct spi_buf_set tx;
150 	struct spi_buf_set rx;
151 	int ret;
152 
153 	tx_buf[0].buf = buf_tx;
154 	tx_buf[0].len = len;
155 	rx_buf[0].buf = buf_rx;
156 	rx_buf[0].len = len;
157 
158 	rx.buffers = rx_buf;
159 	rx.count = 1;
160 	tx.buffers = tx_buf;
161 	tx.count = 1;
162 
163 	ret = spi_transceive_dt(&cfg->spi, &tx, &rx);
164 	if (ret < 0) {
165 		LOG_ERR("ERRR dma!\n");
166 		return ret;
167 	}
168 
169 	return 0;
170 }
171 
eth_adin2111_reg_read_oa(const struct device * dev,const uint16_t reg,uint32_t * val)172 static int eth_adin2111_reg_read_oa(const struct device *dev, const uint16_t reg,
173 				    uint32_t *val)
174 {
175 	struct adin2111_data *ctx = dev->data;
176 	uint32_t pval;
177 	uint32_t *hdr = (uint32_t *)ctx->oa_tx_buf;
178 	int len;
179 	int ret;
180 
181 	*hdr = reg << 8;
182 	if (reg >= 0x30) {
183 		*hdr |= ADIN2111_OA_CTL_MMS;
184 	}
185 
186 	*hdr |= eth_adin2111_oa_get_parity(*hdr);
187 	*hdr = sys_cpu_to_be32(*hdr);
188 
189 	len = (ctx->oa_prot) ? ADIN2111_OA_CTL_LEN_PROT : ADIN2111_OA_CTL_LEN;
190 
191 	ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, len);
192 	if (ret < 0) {
193 		return ret;
194 	}
195 
196 	*val = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[8]);
197 
198 	/* In protected mode read data is followed by its compliment value */
199 	if (ctx->oa_prot) {
200 		pval = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[12]);
201 		if (*val != ~pval) {
202 			LOG_ERR("OA protected mode rx error !");
203 			return -1;
204 		}
205 	}
206 
207 	return 0;
208 }
209 
eth_adin2111_reg_write_oa(const struct device * dev,const uint16_t reg,uint32_t val)210 static int eth_adin2111_reg_write_oa(const struct device *dev, const uint16_t reg,
211 				     uint32_t val)
212 {
213 	struct adin2111_data *ctx = dev->data;
214 	uint32_t pval;
215 	uint32_t *hdr = (uint32_t *)ctx->oa_tx_buf;
216 	int len;
217 	int ret;
218 
219 	*hdr = reg << 8 | ADIN2111_OA_CTL_WNR;
220 	if (reg >= 0x30) {
221 		*hdr |= ADIN2111_OA_CTL_MMS;
222 	}
223 
224 	*hdr |= eth_adin2111_oa_get_parity(*hdr);
225 	*hdr = sys_cpu_to_be32(*hdr);
226 
227 	len = (ctx->oa_prot) ? ADIN2111_OA_CTL_LEN_PROT : ADIN2111_OA_CTL_LEN;
228 
229 	*(uint32_t *)&ctx->oa_tx_buf[4] = sys_cpu_to_be32(val);
230 	if (ctx->oa_prot) {
231 		*(uint32_t *)&ctx->oa_tx_buf[8] = sys_cpu_to_be32(~val);
232 	}
233 
234 	ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, len);
235 	if (ret < 0) {
236 		return ret;
237 	}
238 
239 	if (ctx->oa_prot) {
240 		pval = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[12]);
241 		if (val != ~pval) {
242 			LOG_ERR("OA protected mode tx error !");
243 			return -1;
244 		}
245 	}
246 
247 	return 0;
248 }
249 
eth_adin2111_oa_data_read(const struct device * dev,const uint16_t port_idx)250 int eth_adin2111_oa_data_read(const struct device *dev, const uint16_t port_idx)
251 {
252 	struct adin2111_data *ctx = dev->data;
253 	struct net_if *iface = ((struct adin2111_port_data *)ctx->port[port_idx]->data)->iface;
254 	struct net_pkt *pkt;
255 	uint32_t hdr, ftr;
256 	int i, len, rx_pos, ret, rca, swo;
257 
258 	ret = eth_adin2111_reg_read(dev, ADIN2111_BUFSTS, &rca);
259 	if (ret < 0) {
260 		LOG_ERR("can't read BUFSTS");
261 		return -EIO;
262 	}
263 
264 	rca &= ADIN2111_BUFSTS_RCA_MASK;
265 
266 	/* Preare all tx headers */
267 	for (i = 0, len = 0; i < rca; ++i) {
268 		hdr = ADIN2111_OA_DATA_HDR_DNC;
269 		hdr |= eth_adin2111_oa_get_parity(hdr);
270 
271 		*(uint32_t *)&ctx->oa_tx_buf[len] = sys_cpu_to_be32(hdr);
272 
273 		len += sizeof(uint32_t) + ctx->oa_cps;
274 	}
275 
276 	ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, len);
277 	if (ret < 0) {
278 		LOG_ERR("SPI xfer failed");
279 		return ret;
280 	}
281 
282 	for (i = 0, rx_pos = 0; i < rca; ++i) {
283 
284 		ftr = sys_be32_to_cpu(*(uint32_t *)&ctx->oa_rx_buf[rx_pos + ctx->oa_cps]);
285 
286 		if (eth_adin2111_oa_get_parity(ftr)) {
287 			LOG_ERR("OA RX: Footer parity error !");
288 			return -EIO;
289 		}
290 		if (!(ftr & ADIN2111_OA_DATA_FTR_SYNC)) {
291 			LOG_ERR("OA RX: Configuration not in sync !");
292 			return -EIO;
293 		}
294 		if (!(ftr & ADIN2111_OA_DATA_FTR_DV)) {
295 			LOG_DBG("OA RX: Data chunk not valid, skip !");
296 			goto update_pos;
297 		}
298 		if (ftr & ADIN2111_OA_DATA_FTR_SV) {
299 			swo = (ftr & ADIN2111_OA_DATA_FTR_SWO_MSK) >> ADIN2111_OA_DATA_FTR_SWO;
300 			if (swo != 0) {
301 				LOG_ERR("OA RX: Misalignbed start of frame !");
302 				return -EIO;
303 			}
304 			/* Reset store cursor */
305 			ctx->scur = 0;
306 		}
307 
308 		len = (ftr & ADIN2111_OA_DATA_FTR_EV) ?
309 		       ((ftr & ADIN2111_OA_DATA_FTR_EBO_MSK) >> ADIN2111_OA_DATA_FTR_EBO) + 1 :
310 		       ctx->oa_cps;
311 		memcpy(&ctx->buf[ctx->scur], &ctx->oa_rx_buf[rx_pos], len);
312 		ctx->scur += len;
313 
314 		if (ftr & ADIN2111_OA_DATA_FTR_EV) {
315 			pkt = net_pkt_rx_alloc_with_buffer(iface, CONFIG_ETH_ADIN2111_BUFFER_SIZE,
316 							   AF_UNSPEC, 0,
317 							   K_MSEC(CONFIG_ETH_ADIN2111_TIMEOUT));
318 			if (!pkt) {
319 				LOG_ERR("OA RX: cannot allcate packet space, skipping.");
320 				return -EIO;
321 			}
322 			/* Skipping CRC32 */
323 			ret = net_pkt_write(pkt, ctx->buf, ctx->scur - sizeof(uint32_t));
324 			if (ret < 0) {
325 				net_pkt_unref(pkt);
326 				LOG_ERR("Failed to write pkt, scur %d, err %d", ctx->scur, ret);
327 				return ret;
328 			}
329 			ret = net_recv_data(iface, pkt);
330 			if (ret < 0) {
331 				net_pkt_unref(pkt);
332 				LOG_ERR("Port %u failed to enqueue frame to RX queue, %d",
333 					port_idx, ret);
334 				return ret;
335 			}
336 		}
337 update_pos:
338 		rx_pos += ctx->oa_cps + sizeof(uint32_t);
339 	}
340 
341 	return ret;
342 }
343 
344 /*
345  * Setting up for a single dma transfer.
346  */
eth_adin2111_send_oa_frame(const struct device * dev,struct net_pkt * pkt,const uint16_t port_idx)347 static int eth_adin2111_send_oa_frame(const struct device *dev, struct net_pkt *pkt,
348 				      const uint16_t port_idx)
349 {
350 	struct adin2111_data *ctx = dev->data;
351 	uint16_t clen, len = net_pkt_get_len(pkt);
352 	uint32_t hdr;
353 	uint8_t chunks, i;
354 	int ret, txc, cur;
355 
356 	chunks = len / ctx->oa_cps;
357 
358 	if (len % ctx->oa_cps) {
359 		chunks++;
360 	}
361 
362 	ret = eth_adin2111_reg_read(dev, ADIN2111_BUFSTS, &txc);
363 	if (ret < 0) {
364 		LOG_ERR("Cannot read txc");
365 		return -EIO;
366 	}
367 
368 	txc = (txc & ADIN2111_BUFSTS_TXC_MASK) >> ADIN2111_BUFSTS_TXC;
369 	if (txc < chunks) {
370 		return -EIO;
371 	}
372 
373 	/* Prepare for single dma transfer */
374 	for (i = 1, cur = 0; i <= chunks; i++) {
375 		hdr = ADIN2111_OA_DATA_HDR_DNC | ADIN2111_OA_DATA_HDR_DV |
376 			ADIN2111_OA_DATA_HDR_NORX;
377 		hdr |= (!!port_idx << ADIN2111_OA_DATA_HDR_VS);
378 		if (i == 1) {
379 			hdr |= ADIN2111_OA_DATA_HDR_SV;
380 		}
381 		if (i == chunks) {
382 			hdr |= ADIN2111_OA_DATA_HDR_EV;
383 			hdr |= (ctx->oa_cps - 1) << ADIN2111_OA_DATA_HDR_EBO;
384 		}
385 
386 		hdr |= eth_adin2111_oa_get_parity(hdr);
387 
388 		*(uint32_t *)&ctx->oa_tx_buf[cur] = sys_cpu_to_be32(hdr);
389 		cur += sizeof(uint32_t);
390 
391 		clen = len > ctx->oa_cps ? ctx->oa_cps : len;
392 		ret = net_pkt_read(pkt, &ctx->oa_tx_buf[cur], clen);
393 		if (ret < 0) {
394 			LOG_ERR("Cannot read from tx packet");
395 			return ret;
396 		}
397 		cur += ctx->oa_cps;
398 		len -= clen;
399 	}
400 
401 	ret = eth_adin2111_oa_spi_xfer(dev, ctx->oa_rx_buf, ctx->oa_tx_buf, cur);
402 	if (ret < 0) {
403 		LOG_ERR("Error on SPI xfer");
404 		return ret;
405 	}
406 
407 	return 0;
408 }
409 
eth_adin2111_reg_read_generic(const struct device * dev,const uint16_t reg,uint32_t * val)410 static int eth_adin2111_reg_read_generic(const struct device *dev,
411 					 const uint16_t reg,
412 					 uint32_t *val)
413 {
414 	const struct adin2111_config *cfg = dev->config;
415 	size_t header_len = ADIN2111_READ_HEADER_SIZE;
416 	size_t read_len = sizeof(uint32_t);
417 	int ret;
418 #if CONFIG_ETH_ADIN2111_SPI_CFG0
419 	uint8_t rcv_crc;
420 	uint8_t comp_crc;
421 	uint8_t buf[ADIN2111_REG_READ_BUF_SIZE_CRC] = { 0 };
422 #else
423 	uint8_t buf[ADIN2111_REG_READ_BUF_SIZE] = { 0 };
424 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
425 
426 	/* spi header */
427 	*(uint16_t *)buf = htons((ADIN2111_READ_TXN_CTRL | reg));
428 #if CONFIG_ETH_ADIN2111_SPI_CFG0
429 	buf[2] = crc8_ccitt(0, buf, ADIN2111_SPI_HEADER_SIZE);
430 	/* TA */
431 	buf[3] = 0U;
432 	++header_len;
433 	++read_len;
434 #else
435 	/* TA */
436 	buf[2] = 0U;
437 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
438 
439 	const struct spi_buf tx_buf = { .buf = buf, .len = header_len + read_len };
440 	const struct spi_buf rx_buf = { .buf = buf, .len = header_len + read_len };
441 	const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1U };
442 	const struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1U };
443 
444 	ret = spi_transceive_dt(&cfg->spi, &tx, &rx);
445 	if (ret < 0) {
446 		return ret;
447 	}
448 
449 #if CONFIG_ETH_ADIN2111_SPI_CFG0
450 	comp_crc = crc8_ccitt(0, &buf[header_len], sizeof(uint32_t));
451 	rcv_crc = buf[header_len + sizeof(uint32_t)];
452 
453 	if (rcv_crc != comp_crc) {
454 		/* invalid crc */
455 		return -EIO;
456 	}
457 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
458 
459 	*val = ntohl((*(uint32_t *)(&buf[header_len])));
460 
461 	return ret;
462 }
463 
eth_adin2111_reg_write_generic(const struct device * dev,const uint16_t reg,const uint32_t val)464 static int eth_adin2111_reg_write_generic(const struct device *dev,
465 					  const uint16_t reg,
466 					  const uint32_t val)
467 {
468 	const struct adin2111_config *cfg = dev->config;
469 	size_t header_size = ADIN2111_WRITE_HEADER_SIZE;
470 	size_t data_size = sizeof(uint32_t);
471 #if CONFIG_ETH_ADIN2111_SPI_CFG0
472 	uint8_t buf[ADIN2111_REG_WRITE_BUF_SIZE_CRC] = { 0 };
473 #else
474 	uint8_t buf[ADIN2111_REG_WRITE_BUF_SIZE] = { 0 };
475 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
476 
477 	/* spi header */
478 	*(uint16_t *)buf = htons((ADIN2111_WRITE_TXN_CTRL | reg));
479 	#if CONFIG_ETH_ADIN2111_SPI_CFG0
480 	buf[2] = crc8_ccitt(0, buf, header_size);
481 	++header_size;
482 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
483 
484 	/* reg */
485 	*(uint32_t *)(buf + header_size) = htonl(val);
486 #if CONFIG_ETH_ADIN2111_SPI_CFG0
487 	buf[header_size + data_size] = crc8_ccitt(0, &buf[header_size], data_size);
488 	++data_size;
489 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
490 
491 	const struct spi_buf spi_tx_buf = {
492 		.buf = buf,
493 		.len = header_size + data_size
494 	};
495 	const struct spi_buf_set tx = { .buffers = &spi_tx_buf, .count = 1U };
496 
497 	return spi_write_dt(&cfg->spi, &tx);
498 }
499 
eth_adin2111_reg_read(const struct device * dev,const uint16_t reg,uint32_t * val)500 int eth_adin2111_reg_read(const struct device *dev, const uint16_t reg,
501 			  uint32_t *val)
502 {
503 	struct adin2111_data *ctx = dev->data;
504 	int rval;
505 
506 	if (ctx->oa) {
507 		rval = eth_adin2111_reg_read_oa(dev, reg, val);
508 	} else {
509 		rval = eth_adin2111_reg_read_generic(dev, reg, val);
510 	}
511 
512 	return rval;
513 }
514 
eth_adin2111_reg_write(const struct device * dev,const uint16_t reg,const uint32_t val)515 int eth_adin2111_reg_write(const struct device *dev, const uint16_t reg,
516 			   const uint32_t val)
517 {
518 	struct adin2111_data *ctx = dev->data;
519 	int rval;
520 
521 	if (ctx->oa) {
522 		rval = eth_adin2111_reg_write_oa(dev, reg, val);
523 	} else {
524 		rval = eth_adin2111_reg_write_generic(dev, reg, val);
525 	}
526 
527 	return rval;
528 }
529 
adin2111_read_fifo(const struct device * dev,const uint16_t port_idx)530 static int adin2111_read_fifo(const struct device *dev, const uint16_t port_idx)
531 {
532 	const struct adin2111_config *cfg = dev->config;
533 	struct adin2111_data *ctx = dev->data;
534 	struct net_if *iface;
535 	struct net_pkt *pkt;
536 	uint16_t fsize_reg = ((port_idx == 0U) ? ADIN2111_P1_RX_FSIZE : ADIN2111_P2_RX_FSIZE);
537 	uint16_t rx_reg = ((port_idx == 0U) ? ADIN2111_P1_RX : ADIN2111_P2_RX);
538 	uint32_t fsize;
539 	uint32_t fsize_real;
540 	uint32_t padding_len;
541 #if CONFIG_ETH_ADIN2111_SPI_CFG0
542 	uint8_t cmd_buf[ADIN2111_FIFO_READ_CMD_BUF_SIZE_CRC] = { 0 };
543 #else
544 	uint8_t cmd_buf[ADIN2111_FIFO_READ_CMD_BUF_SIZE] = { 0 };
545 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
546 	int ret;
547 
548 	iface = ((struct adin2111_port_data *)ctx->port[port_idx]->data)->iface;
549 
550 	/* get received frame size in bytes */
551 	ret = eth_adin2111_reg_read(dev, fsize_reg, &fsize);
552 	if (ret < 0) {
553 		eth_stats_update_errors_rx(iface);
554 		LOG_ERR("Port %u failed to read RX FSIZE, %d", port_idx, ret);
555 		return ret;
556 	}
557 
558 	/* burst read must be in multiples of 4 */
559 	padding_len = ((fsize % 4) == 0) ? 0U : (ROUND_UP(fsize, 4U) - fsize);
560 	/* actual available frame length is FSIZE - FRAME HEADER */
561 	fsize -= ADIN2111_FRAME_HEADER_SIZE;
562 
563 	/* spi header */
564 	*(uint16_t *)cmd_buf = htons((ADIN2111_READ_TXN_CTRL | rx_reg));
565 #if CONFIG_ETH_ADIN2111_SPI_CFG0
566 	cmd_buf[2] = crc8_ccitt(0, cmd_buf, ADIN2111_SPI_HEADER_SIZE);
567 	/* TA */
568 	cmd_buf[3] = 0U;
569 #else
570 	/* TA */
571 	cmd_buf[2] = 0U;
572 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
573 
574 	const struct spi_buf tx_buf = { .buf = cmd_buf, .len = sizeof(cmd_buf) };
575 	const struct spi_buf rx_buf[3] = {
576 		{.buf = NULL, .len = sizeof(cmd_buf) + ADIN2111_FRAME_HEADER_SIZE},
577 		{.buf = ctx->buf, .len = fsize},
578 		{.buf = NULL, .len = padding_len }
579 	};
580 	const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1U };
581 	const struct spi_buf_set rx = {
582 		.buffers = rx_buf,
583 		.count = ((padding_len == 0U) ? 2U : 3U)
584 	};
585 
586 	ret = spi_transceive_dt(&cfg->spi, &tx, &rx);
587 	if (ret < 0) {
588 		eth_stats_update_errors_rx(iface);
589 		LOG_ERR("Port %u failed to read RX FIFO, %d", port_idx, ret);
590 		return ret;
591 	}
592 
593 	/* remove CRC32 and pass to the stack */
594 	fsize_real = fsize - sizeof(uint32_t);
595 
596 	pkt = net_pkt_rx_alloc_with_buffer(iface, fsize_real, AF_UNSPEC, 0,
597 					   K_MSEC(CONFIG_ETH_ADIN2111_TIMEOUT));
598 	if (!pkt) {
599 		eth_stats_update_errors_rx(iface);
600 		LOG_ERR("Port %u failed to alloc frame RX buffer, %u bytes",
601 			port_idx, fsize_real);
602 		return -ENOMEM;
603 	}
604 
605 	ret = net_pkt_write(pkt, ctx->buf, fsize_real);
606 	if (ret < 0) {
607 		eth_stats_update_errors_rx(iface);
608 		net_pkt_unref(pkt);
609 		LOG_ERR("Port %u failed to fill RX frame, %d", port_idx, ret);
610 		return ret;
611 	}
612 
613 	ret = net_recv_data(iface, pkt);
614 	if (ret < 0) {
615 		eth_stats_update_errors_rx(iface);
616 		net_pkt_unref(pkt);
617 		LOG_ERR("Port %u failed to enqueue frame to RX queue, %d",
618 			port_idx, ret);
619 		return ret;
620 	}
621 
622 	eth_stats_update_bytes_rx(iface, fsize_real);
623 	eth_stats_update_pkts_rx(iface);
624 
625 	return ret;
626 }
627 
adin2111_port_on_phyint(const struct device * dev)628 static inline void adin2111_port_on_phyint(const struct device *dev)
629 {
630 	const struct adin2111_port_config *cfg = dev->config;
631 	struct adin2111_port_data *data = dev->data;
632 	struct phy_link_state state;
633 
634 	if (phy_adin2111_handle_phy_irq(cfg->phy, &state) < 0) {
635 		/* no change or error */
636 		return;
637 	}
638 
639 	if (state.is_up) {
640 		net_eth_carrier_on(data->iface);
641 	} else {
642 		net_eth_carrier_off(data->iface);
643 	}
644 }
645 
adin2111_offload_thread(void * p1,void * p2,void * p3)646 static void adin2111_offload_thread(void *p1, void *p2, void *p3)
647 {
648 	ARG_UNUSED(p2);
649 	ARG_UNUSED(p3);
650 
651 	const struct device *dev = p1;
652 	struct adin2111_data *ctx = dev->data;
653 	const struct adin2111_config *adin_cfg = dev->config;
654 	const bool is_adin2111 = (adin_cfg->id == ADIN2111_MAC);
655 	uint32_t status0;
656 	uint32_t status1;
657 	int ret;
658 
659 	for (;;) {
660 		/* await INT */
661 		k_sem_take(&ctx->offload_sem, K_FOREVER);
662 
663 		/* lock device */
664 		eth_adin2111_lock(dev, K_FOREVER);
665 
666 		/* disable interrupts */
667 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, UINT32_MAX);
668 		if (ret < 0) {
669 			goto continue_unlock;
670 		}
671 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, UINT32_MAX);
672 		if (ret < 0) {
673 			goto continue_unlock;
674 		}
675 
676 		/* read interrupts */
677 		ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS0, &status0);
678 		if (ret < 0) {
679 			goto continue_unlock;
680 		}
681 		ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS1, &status1);
682 		if (ret < 0) {
683 			goto continue_unlock;
684 		}
685 
686 		/* handle port 1 phy interrupts */
687 		if (status0 & ADIN2111_STATUS0_PHYINT) {
688 			adin2111_port_on_phyint(ctx->port[0]);
689 		}
690 
691 		/* handle port 2 phy interrupts */
692 		if (is_adin2111 && (status1 & ADIN2111_STATUS1_PHYINT)) {
693 			adin2111_port_on_phyint(ctx->port[1]);
694 		}
695 
696 		if (ctx->oa) {
697 			if (status1 & ADIN2111_STATUS1_P1_RX_RDY) {
698 				ret = eth_adin2111_oa_data_read(dev, 0);
699 				if (ret < 0) {
700 					goto continue_unlock;
701 				}
702 			}
703 			if (is_adin2111 && (status1 & ADIN2111_STATUS1_P2_RX_RDY)) {
704 				ret = eth_adin2111_oa_data_read(dev, 1);
705 				if (ret < 0) {
706 					goto continue_unlock;
707 				}
708 			}
709 		} else {
710 #if CONFIG_ETH_ADIN2111_SPI_CFG0
711 			if (status0 & ADIN2111_STATUS1_SPI_ERR) {
712 				LOG_WRN("Detected TX SPI CRC error");
713 			}
714 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
715 
716 			/* handle port 1 rx */
717 			if (status1 & ADIN2111_STATUS1_P1_RX_RDY) {
718 				do {
719 					ret = adin2111_read_fifo(dev, 0U);
720 					if (ret < 0) {
721 						break;
722 					}
723 
724 					ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS1,
725 								    &status1);
726 					if (ret < 0) {
727 						goto continue_unlock;
728 					}
729 				} while (!!(status1 & ADIN2111_STATUS1_P1_RX_RDY));
730 			}
731 
732 			/* handle port 2 rx */
733 			if (is_adin2111 && (status1 & ADIN2111_STATUS1_P2_RX_RDY)) {
734 				do {
735 					ret = adin2111_read_fifo(dev, 1U);
736 					if (ret < 0) {
737 						break;
738 					}
739 
740 					ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS1,
741 								    &status1);
742 					if (ret < 0) {
743 						goto continue_unlock;
744 					}
745 				} while (!!(status1 & ADIN2111_STATUS1_P2_RX_RDY));
746 			}
747 		}
748 
749 continue_unlock:
750 		/* clear interrupts */
751 		ret = eth_adin2111_reg_write(dev, ADIN2111_STATUS0, ADIN2111_STATUS0_CLEAR);
752 		if (ret < 0) {
753 			LOG_ERR("Failed to clear STATUS0, %d", ret);
754 		}
755 		ret = eth_adin2111_reg_write(dev, ADIN2111_STATUS1, ADIN2111_STATUS1_CLEAR);
756 		if (ret < 0) {
757 			LOG_ERR("Failed to clear STATUS1, %d", ret);
758 		}
759 		/* enable interrupts */
760 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0);
761 		if (ret < 0) {
762 			LOG_ERR("Failed to write IMASK0, %d", ret);
763 		}
764 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, ctx->imask1);
765 		if (ret < 0) {
766 			LOG_ERR("Failed to write IMASK1, %d", ret);
767 		}
768 		eth_adin2111_unlock(dev);
769 	}
770 }
771 
adin2111_int_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)772 static void adin2111_int_callback(const struct device *dev,
773 				  struct gpio_callback *cb,
774 				  uint32_t pins)
775 {
776 	ARG_UNUSED(dev);
777 	ARG_UNUSED(pins);
778 
779 	struct adin2111_data *ctx = CONTAINER_OF(cb, struct adin2111_data, gpio_int_callback);
780 
781 	k_sem_give(&ctx->offload_sem);
782 }
783 
adin2111_read_tx_space(const struct device * dev,uint32_t * space)784 static int adin2111_read_tx_space(const struct device *dev, uint32_t *space)
785 {
786 	uint32_t val;
787 	int ret;
788 
789 	ret = eth_adin2111_reg_read(dev, ADIN2111_TX_SPACE, &val);
790 	if (ret < 0) {
791 		return ret;
792 	}
793 
794 	/* tx space is a number of halfwords (16-bits), multiply by 2 for bytes */
795 	*space = val * 2;
796 
797 	return ret;
798 }
799 
adin2111_port_send(const struct device * dev,struct net_pkt * pkt)800 static int adin2111_port_send(const struct device *dev, struct net_pkt *pkt)
801 {
802 	const struct adin2111_port_config *cfg = dev->config;
803 #if defined(CONFIG_NET_STATISTICS_ETHERNET)
804 	struct adin2111_port_data *data = dev->data;
805 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
806 	const struct device *adin = cfg->adin;
807 	struct adin2111_data *ctx = cfg->adin->data;
808 	size_t pkt_len = net_pkt_get_len(pkt);
809 	size_t header_size = ADIN2111_WRITE_HEADER_SIZE;
810 	size_t padded_size;
811 	size_t burst_size;
812 	uint32_t tx_space;
813 	int ret;
814 
815 	eth_adin2111_lock(adin, K_FOREVER);
816 
817 	if (ctx->oa) {
818 		uint32_t val, rca = 0;
819 		/*
820 		 * By high-traffic zperf test, noted that ADIN2111 does not like we send
821 		 * if there is something to be received. It stops to issue rx interrupts
822 		 * and zperf transfer hangs. Forcing a receive for this case.
823 		 */
824 		ret = eth_adin2111_reg_read(adin, ADIN2111_BUFSTS, &val);
825 		if (ret < 0) {
826 			return ret;
827 		}
828 		rca = val & ADIN2111_BUFSTS_RCA_MASK;
829 
830 		if (rca > 0) {
831 			eth_adin2111_unlock(adin);
832 			k_sem_give(&ctx->offload_sem);
833 			k_yield();
834 			eth_adin2111_lock(adin, K_FOREVER);
835 		}
836 
837 		ret = eth_adin2111_send_oa_frame(cfg->adin, pkt, htons(cfg->port_idx));
838 
839 		goto end_check;
840 	}
841 
842 	/* query remaining tx fifo space */
843 	ret = adin2111_read_tx_space(adin, &tx_space);
844 	if (ret < 0) {
845 		eth_stats_update_errors_tx(data->iface);
846 		LOG_ERR("Failed to read TX FIFO space, %d", ret);
847 		goto end_unlock;
848 	}
849 
850 	/**
851 	 * verify that there is space for the frame
852 	 * (frame + 2b header + 2b size field)
853 	 */
854 	if (tx_space <
855 	   (pkt_len + ADIN2111_FRAME_HEADER_SIZE + ADIN2111_INTERNAL_HEADER_SIZE)) {
856 		/* tx buffer is full */
857 		eth_stats_update_errors_tx(data->iface);
858 		ret = -EBUSY;
859 		goto end_unlock;
860 	}
861 
862 	/**
863 	 * pad to 64 bytes, otherwise MAC/PHY has to do it
864 	 * internally MAC adds 4 bytes for forward error correction
865 	 */
866 	if ((pkt_len + ADIN2111_TX_FIFO_BUFFER_MARGIN) < 64) {
867 		padded_size = pkt_len
868 			+ (64 - (pkt_len + ADIN2111_TX_FIFO_BUFFER_MARGIN))
869 			+ ADIN2111_FRAME_HEADER_SIZE;
870 	} else {
871 		padded_size = pkt_len + ADIN2111_FRAME_HEADER_SIZE;
872 	}
873 
874 	/* prepare burst write (write data must be in multiples of 4) */
875 	burst_size = ROUND_UP(padded_size, 4);
876 	if ((burst_size + ADIN2111_WRITE_HEADER_SIZE) > CONFIG_ETH_ADIN2111_BUFFER_SIZE) {
877 		ret = -ENOMEM;
878 		eth_stats_update_errors_tx(data->iface);
879 		goto end_unlock;
880 	}
881 
882 	/* prepare tx buffer */
883 	memset(ctx->buf, 0, burst_size + ADIN2111_WRITE_HEADER_SIZE);
884 
885 	/* spi header */
886 	*(uint16_t *)ctx->buf = htons(ADIN2111_TXN_CTRL_TX_REG);
887 #if CONFIG_ETH_ADIN2111_SPI_CFG0
888 	ctx->buf[2] = crc8_ccitt(0, ctx->buf, header_size);
889 	++header_size;
890 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
891 
892 	/* frame header */
893 	*(uint16_t *)(ctx->buf + header_size) = htons(cfg->port_idx);
894 
895 	/* read pkt into tx buffer */
896 	ret = net_pkt_read(pkt,
897 			   (ctx->buf + header_size + ADIN2111_FRAME_HEADER_SIZE),
898 			   pkt_len);
899 	if (ret < 0) {
900 		eth_stats_update_errors_tx(data->iface);
901 		LOG_ERR("Port %u failed to read PKT into TX buffer, %d",
902 			cfg->port_idx, ret);
903 		goto end_unlock;
904 	}
905 
906 	/* write transmit size */
907 	ret = eth_adin2111_reg_write(adin, ADIN2111_TX_FSIZE, padded_size);
908 	if (ret < 0) {
909 		eth_stats_update_errors_tx(data->iface);
910 		LOG_ERR("Port %u write FSIZE failed, %d", cfg->port_idx, ret);
911 		goto end_unlock;
912 	}
913 
914 	/* write transaction */
915 	const struct spi_buf buf = {
916 		.buf = ctx->buf,
917 		.len = header_size + burst_size
918 	};
919 	const struct spi_buf_set tx = { .buffers = &buf, .count = 1U };
920 
921 	ret = spi_write_dt(&((const struct adin2111_config *) adin->config)->spi,
922 			   &tx);
923 end_check:
924 	if (ret < 0) {
925 		eth_stats_update_errors_tx(data->iface);
926 		LOG_ERR("Port %u frame SPI write failed, %d", cfg->port_idx, ret);
927 		goto end_unlock;
928 	}
929 
930 	eth_stats_update_bytes_tx(data->iface, pkt_len);
931 	eth_stats_update_pkts_tx(data->iface);
932 
933 end_unlock:
934 	eth_adin2111_unlock(adin);
935 	return ret;
936 }
937 
adin2111_config_sync(const struct device * dev)938 static int adin2111_config_sync(const struct device *dev)
939 {
940 	int ret;
941 	uint32_t val;
942 
943 	ret = eth_adin2111_reg_read(dev, ADIN2111_CONFIG0, &val);
944 	if (ret < 0) {
945 		return ret;
946 	}
947 
948 	val |= ADIN2111_CONFIG0_SYNC;
949 
950 	ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG0, val);
951 	if (ret < 0) {
952 		return ret;
953 	}
954 
955 	return 0;
956 }
957 
adin2111_write_filter_address(const struct device * dev,uint8_t * addr,uint8_t * mask,uint32_t rules,uint16_t slot)958 static int adin2111_write_filter_address(const struct device *dev,
959 					 uint8_t *addr, uint8_t *mask,
960 					 uint32_t rules, uint16_t slot)
961 {
962 	uint16_t offset = slot * 2U;
963 	int ret;
964 
965 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_FILT_UPR + offset,
966 				     rules | sys_get_be16(&addr[0]));
967 	if (ret < 0) {
968 		return ret;
969 	}
970 
971 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_FILT_LWR  + offset,
972 				     sys_get_be32(&addr[2]));
973 	if (ret < 0) {
974 		return ret;
975 	}
976 
977 	if (offset > 2U) {
978 		/* mask filter addresses are limited to 2 */
979 		return 0;
980 	}
981 
982 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_MSK_UPR + offset,
983 				     sys_get_be16(&mask[0]));
984 	if (ret < 0) {
985 		return ret;
986 	}
987 
988 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_MSK_LWR + offset,
989 				     sys_get_be32(&mask[2]));
990 	if (ret < 0) {
991 		return ret;
992 	}
993 
994 	return ret;
995 }
996 
adin2111_filter_multicast(const struct device * dev)997 static int adin2111_filter_multicast(const struct device *dev)
998 {
999 	const struct adin2111_config *cfg = dev->config;
1000 	const bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1001 	uint8_t mm[NET_ETH_ADDR_LEN] = {BIT(0), 0U, 0U, 0U, 0U, 0U};
1002 	uint8_t mmask[NET_ETH_ADDR_LEN] = {0xFFU, 0U, 0U, 0U, 0U, 0U};
1003 	uint32_t rules = ADIN2111_ADDR_APPLY2PORT1 |
1004 			 (is_adin2111 ? ADIN2111_ADDR_APPLY2PORT2 : 0) |
1005 			 ADIN2111_ADDR_TO_HOST |
1006 			 ADIN2111_ADDR_TO_OTHER_PORT;
1007 
1008 	return adin2111_write_filter_address(dev, mm, mmask, rules,
1009 					     ADIN2111_MULTICAST_ADDR_SLOT);
1010 }
1011 
adin2111_filter_broadcast(const struct device * dev)1012 static int adin2111_filter_broadcast(const struct device *dev)
1013 {
1014 	const struct adin2111_config *cfg = dev->config;
1015 	const bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1016 	uint8_t mac[NET_ETH_ADDR_LEN] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
1017 	uint32_t rules = ADIN2111_ADDR_APPLY2PORT1 |
1018 			 (is_adin2111 ? ADIN2111_ADDR_APPLY2PORT2 : 0) |
1019 			 ADIN2111_ADDR_TO_HOST |
1020 			 ADIN2111_ADDR_TO_OTHER_PORT;
1021 
1022 	return adin2111_write_filter_address(dev, mac, mac, rules,
1023 					     ADIN2111_BROADCAST_ADDR_SLOT);
1024 }
1025 
adin2111_filter_unicast(const struct device * dev,uint8_t * addr,const uint16_t port_idx)1026 static int adin2111_filter_unicast(const struct device *dev, uint8_t *addr,
1027 				   const uint16_t port_idx)
1028 {
1029 	uint32_t rules = (port_idx == 0 ? ADIN2111_ADDR_APPLY2PORT1
1030 					: ADIN2111_ADDR_APPLY2PORT2)
1031 			 | ADIN2111_ADDR_TO_HOST;
1032 	uint16_t slot = (port_idx == 0 ? ADIN2111_UNICAST_P1_ADDR_SLOT
1033 				       : ADIN2111_UNICAST_P2_ADDR_SLOT);
1034 
1035 	return adin2111_write_filter_address(dev, addr, NULL, rules, slot);
1036 }
1037 
eth_adin2111_broadcast_filter(const struct device * dev,bool enable)1038 int eth_adin2111_broadcast_filter(const struct device *dev, bool enable)
1039 {
1040 	if (!enable) {
1041 		/* Clean up */
1042 		uint8_t mac[NET_ETH_ADDR_LEN] = {0};
1043 
1044 		return adin2111_write_filter_address(dev, mac, mac, 0,
1045 						     ADIN2111_BROADCAST_ADDR_SLOT);
1046 	}
1047 
1048 	return adin2111_filter_broadcast(dev);
1049 }
1050 
1051 /*
1052  * Check if a filter exists already.
1053  */
eth_adin2111_find_filter(const struct device * dev,uint8_t * mac,const uint16_t port_idx)1054 static int eth_adin2111_find_filter(const struct device *dev, uint8_t *mac, const uint16_t port_idx)
1055 {
1056 	int i, offset, reg, ret;
1057 
1058 	for (i = ADIN2111_FILTER_FIRST_SLOT; i < ADIN2111_FILTER_SLOTS; i++) {
1059 		offset = i << 1;
1060 		ret = eth_adin2111_reg_read(dev, ADIN2111_ADDR_FILT_UPR + offset, &reg);
1061 		if (ret < 0) {
1062 			return ret;
1063 		}
1064 		if ((reg & UINT16_MAX) == sys_get_be16(&mac[0])) {
1065 			if ((port_idx == 0 && !(reg & ADIN2111_ADDR_APPLY2PORT1)) ||
1066 			    (port_idx == 1 && !(reg & ADIN2111_ADDR_APPLY2PORT2))) {
1067 				continue;
1068 			}
1069 
1070 			ret = eth_adin2111_reg_read(dev, ADIN2111_ADDR_FILT_LWR + offset, &reg);
1071 			if (ret < 0) {
1072 				return ret;
1073 			}
1074 			if (reg == sys_get_be32(&mac[2])) {
1075 				return i;
1076 			}
1077 		}
1078 	}
1079 
1080 	return -ENOENT;
1081 }
1082 
eth_adin2111_set_mac_filter(const struct device * dev,uint8_t * mac,const uint16_t port_idx)1083 static int eth_adin2111_set_mac_filter(const struct device *dev, uint8_t *mac,
1084 				       const uint16_t port_idx)
1085 {
1086 	int i, ret, offset;
1087 	uint32_t reg;
1088 
1089 	ret = eth_adin2111_find_filter(dev, mac, port_idx);
1090 	if (ret >= 0) {
1091 		LOG_WRN("MAC filter already set at pos %d, not setting it.", ret);
1092 		return ret;
1093 	}
1094 	if (ret != -ENOENT) {
1095 		return ret;
1096 	}
1097 
1098 	for (i = ADIN2111_FILTER_FIRST_SLOT; i < ADIN2111_FILTER_SLOTS; i++) {
1099 		offset = i << 1;
1100 		ret = eth_adin2111_reg_read(dev, ADIN2111_ADDR_FILT_UPR + offset, &reg);
1101 		if (ret < 0) {
1102 			return ret;
1103 		}
1104 		if (reg == 0) {
1105 			uint32_t rules = (port_idx == 0 ? ADIN2111_ADDR_APPLY2PORT1
1106 					: ADIN2111_ADDR_APPLY2PORT2)
1107 					| ADIN2111_ADDR_TO_HOST;
1108 
1109 			return adin2111_write_filter_address(dev, mac, NULL, rules, i);
1110 		}
1111 	}
1112 
1113 	return -ENOSPC;
1114 }
1115 
eth_adin2111_clear_mac_filter(const struct device * dev,uint8_t * mac,const uint16_t port_idx)1116 static int eth_adin2111_clear_mac_filter(const struct device *dev, uint8_t *mac,
1117 					 const uint16_t port_idx)
1118 {
1119 	int i;
1120 	uint8_t cmac[NET_ETH_ADDR_LEN] = {0};
1121 
1122 	i = eth_adin2111_find_filter(dev, mac, port_idx);
1123 	if (i < 0) {
1124 		return i;
1125 	}
1126 
1127 	return adin2111_write_filter_address(dev, cmac, cmac, 0, i);
1128 }
1129 
1130 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
eth_adin2111_set_promiscuous(const struct device * dev,const uint16_t port_idx,bool enable)1131 static int eth_adin2111_set_promiscuous(const struct device *dev, const uint16_t port_idx,
1132 					bool enable)
1133 {
1134 	const struct adin2111_config *cfg = dev->config;
1135 	const bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1136 	uint32_t fwd_mask;
1137 
1138 	if ((!is_adin2111 && port_idx > 0) || (is_adin2111 && port_idx > 1)) {
1139 		return -EINVAL;
1140 	}
1141 
1142 	fwd_mask = port_idx ? ADIN2111_CONFIG2_P2_FWD_UNK2HOST : ADIN2111_CONFIG2_P1_FWD_UNK2HOST;
1143 
1144 	return eth_adin2111_reg_update(dev, ADIN2111_CONFIG2, fwd_mask, enable ? fwd_mask : 0);
1145 }
1146 #endif
1147 
adin2111_port_iface_init(struct net_if * iface)1148 static void adin2111_port_iface_init(struct net_if *iface)
1149 {
1150 	const struct device *dev = net_if_get_device(iface);
1151 	const struct adin2111_port_config *cfg = dev->config;
1152 	struct adin2111_port_data *data = dev->data;
1153 	const struct device *adin = cfg->adin;
1154 	struct adin2111_data *ctx = adin->data;
1155 	int ret;
1156 
1157 	if (!device_is_ready(adin)) {
1158 		LOG_ERR("ADIN %s is not ready, can't init port %u iface",
1159 			cfg->adin->name, cfg->port_idx);
1160 		return;
1161 	}
1162 
1163 	if (!device_is_ready(cfg->phy)) {
1164 		LOG_ERR("PHY %u is not ready, can't init port %u iface",
1165 			cfg->phy_addr, cfg->port_idx);
1166 		return;
1167 	}
1168 
1169 	ctx->port[cfg->port_idx] = dev;
1170 	data->iface = iface;
1171 
1172 	ret = adin2111_filter_unicast(adin, data->mac_addr, cfg->port_idx);
1173 	if (ret < 0) {
1174 		LOG_ERR("Port %u, failed to set unicast filter, %d",
1175 			cfg->port_idx, ret);
1176 		return;
1177 	}
1178 	net_if_set_link_addr(iface, data->mac_addr, sizeof(data->mac_addr),
1179 			     NET_LINK_ETHERNET);
1180 	ethernet_init(iface);
1181 	net_if_carrier_off(iface);
1182 
1183 	--ctx->ifaces_left_to_init;
1184 
1185 	/* if all ports are initialized */
1186 	if (ctx->ifaces_left_to_init == 0U) {
1187 		/* setup rx filters */
1188 		ret = adin2111_filter_multicast(adin);
1189 		if (ret < 0) {
1190 			LOG_ERR("Couldn't set multicast filter, %d", ret);
1191 			return;
1192 		}
1193 		ret = adin2111_filter_broadcast(adin);
1194 		if (ret < 0) {
1195 			LOG_ERR("Couldn't set broadcast filter, %d", ret);
1196 			return;
1197 		}
1198 
1199 		/* sync */
1200 		ret = adin2111_config_sync(adin);
1201 		if (ret < 0) {
1202 			LOG_ERR("Failed to write CONFIG0 SYNC, %d", ret);
1203 			return;
1204 		}
1205 
1206 		/* all ifaces are done, start INT processing */
1207 		k_thread_create(&ctx->rx_thread, ctx->rx_thread_stack,
1208 				K_KERNEL_STACK_SIZEOF(ctx->rx_thread_stack),
1209 				adin2111_offload_thread,
1210 				(void *)adin, NULL, NULL,
1211 				CONFIG_ETH_ADIN2111_IRQ_THREAD_PRIO,
1212 				K_ESSENTIAL, K_NO_WAIT);
1213 		k_thread_name_set(&ctx->rx_thread, "eth_adin2111_offload");
1214 	}
1215 }
1216 
adin2111_port_get_capabilities(const struct device * dev)1217 static enum ethernet_hw_caps adin2111_port_get_capabilities(const struct device *dev)
1218 {
1219 	ARG_UNUSED(dev);
1220 	return ETHERNET_LINK_10BASE_T |
1221 		ETHERNET_HW_FILTERING
1222 #if defined(CONFIG_NET_LLDP)
1223 		| ETHERNET_LLDP
1224 #endif
1225 		| ETHERNET_PROMISC_MODE;
1226 }
1227 
adin2111_port_set_config(const struct device * dev,enum ethernet_config_type type,const struct ethernet_config * config)1228 static int adin2111_port_set_config(const struct device *dev,
1229 				    enum ethernet_config_type type,
1230 				    const struct ethernet_config *config)
1231 {
1232 	const struct adin2111_port_config *cfg = dev->config;
1233 	struct adin2111_port_data *data = dev->data;
1234 	const struct device *adin = cfg->adin;
1235 	int ret = -ENOTSUP;
1236 
1237 	(void)eth_adin2111_lock(adin, K_FOREVER);
1238 
1239 	if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) {
1240 		ret = adin2111_filter_unicast(adin, (uint8_t *)&config->mac_address.addr[0],
1241 					      cfg->port_idx);
1242 		if (ret < 0) {
1243 			goto end_unlock;
1244 		}
1245 
1246 		(void)memcpy(data->mac_addr, config->mac_address.addr, sizeof(data->mac_addr));
1247 
1248 		(void)net_if_set_link_addr(data->iface, data->mac_addr, sizeof(data->mac_addr),
1249 					   NET_LINK_ETHERNET);
1250 	}
1251 
1252 	if (type == ETHERNET_CONFIG_TYPE_FILTER) {
1253 		/* Filtering for DA only */
1254 		if (config->filter.type & ETHERNET_FILTER_TYPE_DST_MAC_ADDRESS) {
1255 			uint8_t *mac = (uint8_t *)config->filter.mac_address.addr;
1256 
1257 			if (config->filter.set) {
1258 				ret = eth_adin2111_set_mac_filter(adin, mac, cfg->port_idx);
1259 			} else {
1260 				ret = eth_adin2111_clear_mac_filter(adin, mac, cfg->port_idx);
1261 			}
1262 		}
1263 	}
1264 
1265 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
1266 	if (type == ETHERNET_CONFIG_TYPE_PROMISC_MODE) {
1267 		ret = eth_adin2111_set_promiscuous(adin, cfg->port_idx, config->promisc_mode);
1268 	}
1269 #endif
1270 
1271 end_unlock:
1272 	(void)eth_adin2111_unlock(adin);
1273 	return ret;
1274 }
1275 
1276 #if defined(CONFIG_NET_STATISTICS_ETHERNET)
adin2111_port_get_stats(const struct device * dev)1277 static struct net_stats_eth *adin2111_port_get_stats(const struct device *dev)
1278 {
1279 	struct adin2111_port_data *data = dev->data;
1280 
1281 	return &data->stats;
1282 }
1283 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
1284 
adin2111_check_spi(const struct device * dev)1285 static int adin2111_check_spi(const struct device *dev)
1286 {
1287 	uint32_t count;
1288 	uint32_t val;
1289 	int ret;
1290 
1291 	/* check SPI communication by reading PHYID */
1292 	for (count = 0U; count < ADIN2111_DEV_AWAIT_RETRY_COUNT; ++count) {
1293 		ret = eth_adin2111_reg_read(dev, ADIN2111_PHYID, &val);
1294 		if (ret >= 0) {
1295 			if (val == ADIN2111_PHYID_RST_VAL || val == ADIN1110_PHYID_RST_VAL) {
1296 				break;
1297 			}
1298 			ret = -ETIMEDOUT;
1299 		}
1300 		k_sleep(K_USEC(ADIN2111_DEV_AWAIT_DELAY_POLL_US));
1301 	}
1302 
1303 	return ret;
1304 }
1305 
adin2111_await_device(const struct device * dev)1306 static int adin2111_await_device(const struct device *dev)
1307 {
1308 	uint32_t count;
1309 	uint32_t val;
1310 	int ret;
1311 
1312 	/* await reset complete (RESETC) and clear it */
1313 	for (count = 0U; count < ADIN2111_RESETC_AWAIT_RETRY_COUNT; ++count) {
1314 		ret = eth_adin2111_reg_read(dev, ADIN2111_PHYID, &val);
1315 		if (ret >= 0) {
1316 			/*
1317 			 * Even after getting RESETC, for some milliseconds registers are
1318 			 * still not properly readable (they reads 0),
1319 			 * so checking OUI read-only value instead.
1320 			 */
1321 			if ((val >> 10) == ADIN2111_PHYID_OUI) {
1322 				/* clear RESETC */
1323 				ret = eth_adin2111_reg_write(dev, ADIN2111_STATUS0,
1324 							 ADIN2111_STATUS0_RESETC);
1325 				if (ret >= 0) {
1326 					break;
1327 				}
1328 			}
1329 			ret = -ETIMEDOUT;
1330 		}
1331 		k_sleep(K_USEC(ADIN2111_RESETC_AWAIT_DELAY_POLL_US));
1332 	}
1333 
1334 	return ret;
1335 }
1336 
eth_adin2111_sw_reset(const struct device * dev,uint16_t delay)1337 int eth_adin2111_sw_reset(const struct device *dev, uint16_t delay)
1338 {
1339 	int ret;
1340 
1341 	ret = eth_adin2111_reg_write(dev, ADIN2111_RESET, ADIN2111_RESET_SWRESET);
1342 	if (ret < 0) {
1343 		return ret;
1344 	}
1345 
1346 	k_msleep(delay);
1347 
1348 	ret = adin2111_await_device(dev);
1349 	if (ret < 0) {
1350 		LOG_ERR("ADIN did't come out of the reset, %d", ret);
1351 		return ret;
1352 	}
1353 
1354 	return ret;
1355 }
1356 
adin2111_init(const struct device * dev)1357 static int adin2111_init(const struct device *dev)
1358 {
1359 	const struct adin2111_config *cfg = dev->config;
1360 	const bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1361 	struct adin2111_data *ctx = dev->data;
1362 	int ret;
1363 	uint32_t val;
1364 
1365 	__ASSERT(cfg->spi.config.frequency <= ADIN2111_SPI_MAX_FREQUENCY,
1366 		 "SPI frequency exceeds supported maximum\n");
1367 
1368 	if (!spi_is_ready_dt(&cfg->spi)) {
1369 		LOG_ERR("SPI bus %s not ready", cfg->spi.bus->name);
1370 		return -ENODEV;
1371 	}
1372 
1373 	if (!gpio_is_ready_dt(&cfg->interrupt)) {
1374 		LOG_ERR("Interrupt GPIO device %s is not ready",
1375 			cfg->interrupt.port->name);
1376 		return -ENODEV;
1377 	}
1378 
1379 	ret = gpio_pin_configure_dt(&cfg->interrupt, GPIO_INPUT);
1380 	if (ret < 0) {
1381 		LOG_ERR("Failed to configure interrupt GPIO, %d", ret);
1382 		return ret;
1383 	}
1384 
1385 	if (cfg->reset.port != NULL) {
1386 		if (!gpio_is_ready_dt(&cfg->reset)) {
1387 			LOG_ERR("Reset GPIO device %s is not ready",
1388 			cfg->reset.port->name);
1389 			return -ENODEV;
1390 		}
1391 
1392 		ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE);
1393 		if (ret < 0) {
1394 			LOG_ERR("Failed to configure reset GPIO, %d", ret);
1395 			return ret;
1396 		}
1397 
1398 		/* perform hard reset */
1399 		/* assert pin low for 16 µs (10 µs min) */
1400 		gpio_pin_set_dt(&cfg->reset, 1);
1401 		k_busy_wait(16U);
1402 		/* deassert and wait for 90 ms (max) for clocks stabilisation */
1403 		gpio_pin_set_dt(&cfg->reset, 0);
1404 		k_msleep(ADIN2111_HW_BOOT_DELAY_MS);
1405 	}
1406 
1407 	gpio_init_callback(&(ctx->gpio_int_callback),
1408 			   adin2111_int_callback,
1409 			   BIT(cfg->interrupt.pin));
1410 
1411 	ret = gpio_add_callback(cfg->interrupt.port, &ctx->gpio_int_callback);
1412 	if (ret < 0) {
1413 		LOG_ERR("Failed to add INT callback, %d", ret);
1414 		return ret;
1415 	}
1416 
1417 	k_msleep(ADIN2111_SPI_ACTIVE_DELAY_MS);
1418 
1419 	ret = adin2111_check_spi(dev);
1420 	if (ret < 0) {
1421 		LOG_ERR("Failed to communicate over SPI, %d", ret);
1422 		return ret;
1423 	}
1424 
1425 	/* perform MACPHY soft reset */
1426 	ret = eth_adin2111_sw_reset(dev, ADIN2111_SW_RESET_DELAY_MS);
1427 	if (ret < 0) {
1428 		LOG_ERR("MACPHY software reset failed, %d", ret);
1429 		return ret;
1430 	}
1431 
1432 	/* CONFIG 0 */
1433 	/* disable Frame Check Sequence validation on the host */
1434 	/* if that is enabled, then CONFIG_ETH_ADIN2111_SPI_CFG0 must be off */
1435 	ret = eth_adin2111_reg_read(dev, ADIN2111_CONFIG0, &val);
1436 	if (ret < 0) {
1437 		LOG_ERR("Failed to read CONFIG0, %d", ret);
1438 		return ret;
1439 	}
1440 
1441 	/* RXCTE must be disabled for Generic SPI */
1442 	val &= ~ADIN2111_CONFIG0_RXCTE;
1443 	val &= ~(ADIN2111_CONFIG0_TXCTE | ADIN2111_CONFIG0_TXFCSVE);
1444 
1445 	if (ctx->oa) {
1446 		val |= ADIN2111_CONFIG0_ZARFE;
1447 	}
1448 
1449 	ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG0, val);
1450 	if (ret < 0) {
1451 		LOG_ERR("Failed to write CONFIG0, %d", ret);
1452 		return ret;
1453 	}
1454 
1455 	/* CONFIG 2 */
1456 	ret = eth_adin2111_reg_read(dev, ADIN2111_CONFIG2, &val);
1457 	if (ret < 0) {
1458 		LOG_ERR("Failed to read CONFIG2, %d", ret);
1459 		return ret;
1460 	}
1461 
1462 	val |= ADIN2111_CONFIG2_CRC_APPEND;
1463 
1464 	/* configure forwarding of frames with unknown destination address */
1465 	/* to the other port. This forwarding is done in hardware.         */
1466 	/* The setting will take effect after the ports                    */
1467 	/* are out of software powerdown.                                  */
1468 	val |= (ADIN2111_CONFIG2_PORT_CUT_THRU_EN |
1469 		(is_adin2111 ? ADIN2111_CONFIG2_P1_FWD_UNK2P2 : 0) |
1470 		(is_adin2111 ? ADIN2111_CONFIG2_P2_FWD_UNK2P1 : 0));
1471 
1472 	ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG2, val);
1473 	if (ret < 0) {
1474 		LOG_ERR("Failed to write CONFIG2, %d", ret);
1475 		return ret;
1476 	}
1477 
1478 	/* configure interrupt masks */
1479 	ctx->imask0 = ~((uint32_t)ADIN2111_IMASK0_PHYINTM);
1480 	ctx->imask1 = ~(ADIN2111_IMASK1_TX_RDY_MASK |
1481 			ADIN2111_IMASK1_P1_RX_RDY_MASK |
1482 			ADIN2111_IMASK1_SPI_ERR_MASK |
1483 			(is_adin2111 ? ADIN2111_IMASK1_P2_RX_RDY_MASK : 0) |
1484 			(is_adin2111 ? ADIN2111_IMASK1_P2_PHYINT_MASK : 0));
1485 
1486 	/* enable interrupts */
1487 	ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0);
1488 	if (ret < 0) {
1489 		LOG_ERR("Failed to write IMASK0, %d", ret);
1490 		return ret;
1491 	}
1492 	ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, ctx->imask1);
1493 	if (ret < 0) {
1494 		LOG_ERR("Failed to write IMASK1, %d", ret);
1495 		return ret;
1496 	}
1497 
1498 	ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt,
1499 						GPIO_INT_EDGE_TO_ACTIVE);
1500 	if (ret < 0) {
1501 		LOG_ERR("Failed to enable INT, %d", ret);
1502 		return ret;
1503 	}
1504 
1505 	return ret;
1506 }
1507 
1508 static const struct ethernet_api adin2111_port_api = {
1509 	.iface_api.init = adin2111_port_iface_init,
1510 	.get_capabilities = adin2111_port_get_capabilities,
1511 	.set_config = adin2111_port_set_config,
1512 	.send = adin2111_port_send,
1513 #if defined(CONFIG_NET_STATISTICS_ETHERNET)
1514 	.get_stats = adin2111_port_get_stats,
1515 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
1516 };
1517 
1518 #define ADIN2111_STR(x)		#x
1519 #define ADIN2111_XSTR(x)	ADIN2111_STR(x)
1520 
1521 #define ADIN2111_DEF_BUF(name, size) static uint8_t __aligned(4) name[size]
1522 
1523 #define ADIN2111_MDIO_PHY_BY_ADDR(adin_n, phy_addr)						\
1524 	DEVICE_DT_GET(DT_CHILD(DT_INST_CHILD(adin_n, mdio), ethernet_phy_##phy_addr))
1525 
1526 #define ADIN2111_PORT_MAC(adin_n, port_n)							\
1527 	DT_PROP(DT_CHILD(DT_DRV_INST(adin_n), port##port_n), local_mac_address)
1528 
1529 #define ADIN2111_PORT_DEVICE_INIT_INSTANCE(parent_n, port_n, phy_n, name)			\
1530 	static struct adin2111_port_data name##_port_data_##port_n = {				\
1531 		.mac_addr = ADIN2111_PORT_MAC(parent_n, phy_n),					\
1532 	};											\
1533 	static const struct adin2111_port_config name##_port_config_##port_n = {		\
1534 		.adin = DEVICE_DT_INST_GET(parent_n),						\
1535 		.phy = ADIN2111_MDIO_PHY_BY_ADDR(parent_n, phy_n),				\
1536 		.port_idx = port_n,								\
1537 		.phy_addr = phy_n,								\
1538 	};											\
1539 	ETH_NET_DEVICE_INIT_INSTANCE(name##_port_##port_n, "port_" ADIN2111_XSTR(port_n),	\
1540 				     port_n, NULL, NULL, &name##_port_data_##port_n,		\
1541 				     &name##_port_config_##port_n, CONFIG_ETH_INIT_PRIORITY,	\
1542 				     &adin2111_port_api, NET_ETH_MTU);
1543 
1544 #define ADIN2111_SPI_OPERATION ((uint16_t)(SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8)))
1545 #define ADIN2111_MAC_INITIALIZE(inst, dev_id, ifaces, name)					\
1546 	ADIN2111_DEF_BUF(name##_buffer_##inst, CONFIG_ETH_ADIN2111_BUFFER_SIZE);		\
1547 	COND_CODE_1(DT_INST_PROP(inst, spi_oa),							\
1548 	(											\
1549 		ADIN2111_DEF_BUF(name##_oa_tx_buf_##inst, ADIN2111_OA_BUF_SZ);			\
1550 		ADIN2111_DEF_BUF(name##_oa_rx_buf_##inst, ADIN2111_OA_BUF_SZ);			\
1551 	), ())											\
1552 	static const struct adin2111_config name##_config_##inst = {				\
1553 		.id = dev_id,									\
1554 		.spi = SPI_DT_SPEC_INST_GET(inst, ADIN2111_SPI_OPERATION, 0),			\
1555 		.interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios),				\
1556 		.reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, { 0 }),			\
1557 	};											\
1558 	static struct adin2111_data name##_data_##inst = {					\
1559 		.ifaces_left_to_init = ifaces,							\
1560 		.port = {},									\
1561 		.offload_sem = Z_SEM_INITIALIZER(name##_data_##inst.offload_sem, 0, 1),		\
1562 		.lock = Z_MUTEX_INITIALIZER(name##_data_##inst.lock),				\
1563 		.buf = name##_buffer_##inst,							\
1564 		.oa = DT_INST_PROP(inst, spi_oa),						\
1565 		.oa_prot = DT_INST_PROP(inst, spi_oa_protection),				\
1566 		.oa_cps = 64,									\
1567 		.oa_tx_buf = COND_CODE_1(DT_INST_PROP(inst, spi_oa),				\
1568 					 (name##_oa_tx_buf_##inst), (NULL)),			\
1569 		.oa_rx_buf = COND_CODE_1(DT_INST_PROP(inst, spi_oa),				\
1570 					 (name##_oa_rx_buf_##inst), (NULL)),			\
1571 	};											\
1572 	/* adin */										\
1573 	DEVICE_DT_DEFINE(DT_DRV_INST(inst), adin2111_init, NULL,				\
1574 			 &name##_data_##inst, &name##_config_##inst,				\
1575 			 POST_KERNEL, CONFIG_ETH_INIT_PRIORITY,					\
1576 			 NULL);
1577 
1578 #define ADIN2111_MAC_INIT(inst)	ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2, adin2111)	\
1579 	/* ports */										\
1580 	ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin2111)				\
1581 	ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 1, 2, adin2111)
1582 
1583 #undef DT_DRV_COMPAT
1584 #define DT_DRV_COMPAT adi_adin2111
1585 DT_INST_FOREACH_STATUS_OKAY(ADIN2111_MAC_INIT)
1586 
1587 #define ADIN1110_MAC_INIT(inst)	ADIN2111_MAC_INITIALIZE(inst, ADIN1110_MAC, 1, adin1110)	\
1588 	/* ports */										\
1589 	ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin1110)
1590 
1591 #undef DT_DRV_COMPAT
1592 #define DT_DRV_COMPAT adi_adin1110
1593 DT_INST_FOREACH_STATUS_OKAY(ADIN1110_MAC_INIT)
1594