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 frame length is FSIZE - FRAME HEADER - CRC32 */
561 	fsize_real = fsize - (ADIN2111_FRAME_HEADER_SIZE + sizeof(uint32_t));
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_real},
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 	pkt = net_pkt_rx_alloc_with_buffer(iface, fsize_real, AF_UNSPEC, 0,
594 					   K_MSEC(CONFIG_ETH_ADIN2111_TIMEOUT));
595 	if (!pkt) {
596 		eth_stats_update_errors_rx(iface);
597 		LOG_ERR("Port %u failed to alloc frame RX buffer, %u bytes",
598 			port_idx, fsize_real);
599 		return -ENOMEM;
600 	}
601 
602 	ret = net_pkt_write(pkt, ctx->buf, fsize_real);
603 	if (ret < 0) {
604 		eth_stats_update_errors_rx(iface);
605 		net_pkt_unref(pkt);
606 		LOG_ERR("Port %u failed to fill RX frame, %d", port_idx, ret);
607 		return ret;
608 	}
609 
610 	ret = net_recv_data(iface, pkt);
611 	if (ret < 0) {
612 		eth_stats_update_errors_rx(iface);
613 		net_pkt_unref(pkt);
614 		LOG_ERR("Port %u failed to enqueue frame to RX queue, %d",
615 			port_idx, ret);
616 		return ret;
617 	}
618 
619 	eth_stats_update_bytes_rx(iface, fsize_real);
620 	eth_stats_update_pkts_rx(iface);
621 
622 	return ret;
623 }
624 
adin2111_port_on_phyint(const struct device * dev)625 static inline void adin2111_port_on_phyint(const struct device *dev)
626 {
627 	const struct adin2111_port_config *cfg = dev->config;
628 	struct adin2111_port_data *data = dev->data;
629 	struct phy_link_state state;
630 
631 	if (phy_adin2111_handle_phy_irq(cfg->phy, &state) < 0) {
632 		/* no change or error */
633 		return;
634 	}
635 
636 	if (state.is_up) {
637 		net_eth_carrier_on(data->iface);
638 	} else {
639 		net_eth_carrier_off(data->iface);
640 	}
641 }
642 
adin2111_offload_thread(void * p1,void * p2,void * p3)643 static void adin2111_offload_thread(void *p1, void *p2, void *p3)
644 {
645 	ARG_UNUSED(p2);
646 	ARG_UNUSED(p3);
647 
648 	const struct device *dev = p1;
649 	struct adin2111_data *ctx = dev->data;
650 	const struct adin2111_config *adin_cfg = dev->config;
651 	bool is_adin2111 = (adin_cfg->id == ADIN2111_MAC);
652 	uint32_t status0;
653 	uint32_t status1;
654 	int ret;
655 
656 	for (;;) {
657 		/* await INT */
658 		k_sem_take(&ctx->offload_sem, K_FOREVER);
659 
660 		/* lock device */
661 		eth_adin2111_lock(dev, K_FOREVER);
662 
663 		/* disable interrupts */
664 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, UINT32_MAX);
665 		if (ret < 0) {
666 			goto continue_unlock;
667 		}
668 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, UINT32_MAX);
669 		if (ret < 0) {
670 			goto continue_unlock;
671 		}
672 
673 		/* read interrupts */
674 		ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS0, &status0);
675 		if (ret < 0) {
676 			goto continue_unlock;
677 		}
678 		ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS1, &status1);
679 		if (ret < 0) {
680 			goto continue_unlock;
681 		}
682 
683 		if (!ctx->oa) {
684 #if CONFIG_ETH_ADIN2111_SPI_CFG0
685 			if (status0 & ADIN2111_STATUS1_SPI_ERR) {
686 				LOG_WRN("Detected TX SPI CRC error");
687 			}
688 #endif
689 		}
690 
691 		/* handle port 1 phy interrupts */
692 		if (status0 & ADIN2111_STATUS0_PHYINT) {
693 			adin2111_port_on_phyint(ctx->port[0]);
694 		}
695 
696 		/* handle port 2 phy interrupts */
697 		if ((status1 & ADIN2111_STATUS1_PHYINT) && is_adin2111) {
698 			adin2111_port_on_phyint(ctx->port[1]);
699 		}
700 
701 		if (ctx->oa) {
702 			if (status1 & ADIN2111_STATUS1_P1_RX_RDY) {
703 				ret = eth_adin2111_oa_data_read(dev, 0);
704 				if (ret < 0) {
705 					break;
706 				}
707 			}
708 			if (status1 & ADIN2111_STATUS1_P2_RX_RDY) {
709 				ret = eth_adin2111_oa_data_read(dev, 1);
710 				if (ret < 0) {
711 					break;
712 				}
713 			}
714 			goto continue_unlock;
715 		}
716 
717 		/* handle port 1 rx */
718 		if (status1 & ADIN2111_STATUS1_P1_RX_RDY) {
719 			do {
720 				ret = adin2111_read_fifo(dev, 0U);
721 				if (ret < 0) {
722 					break;
723 				}
724 
725 				ret = eth_adin2111_reg_read(dev, ADIN2111_STATUS1, &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 ((status1 & ADIN2111_STATUS1_P2_RX_RDY) && is_adin2111) {
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, &status1);
741 				if (ret < 0) {
742 					goto continue_unlock;
743 				}
744 			} while (!!(status1 & ADIN2111_STATUS1_P2_RX_RDY));
745 		}
746 
747 continue_unlock:
748 		/* clear interrupts */
749 		ret = eth_adin2111_reg_write(dev, ADIN2111_STATUS0, ADIN2111_STATUS0_CLEAR);
750 		if (ret < 0) {
751 			LOG_ERR("Failed to clear STATUS0, %d", ret);
752 		}
753 		ret = eth_adin2111_reg_write(dev, ADIN2111_STATUS1, ADIN2111_STATUS1_CLEAR);
754 		if (ret < 0) {
755 			LOG_ERR("Failed to clear STATUS1, %d", ret);
756 		}
757 		/* enable interrupts */
758 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0);
759 		if (ret < 0) {
760 			LOG_ERR("Failed to write IMASK0, %d", ret);
761 		}
762 		ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, ctx->imask1);
763 		if (ret < 0) {
764 			LOG_ERR("Failed to write IMASK1, %d", ret);
765 		}
766 		eth_adin2111_unlock(dev);
767 	}
768 }
769 
adin2111_int_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)770 static void adin2111_int_callback(const struct device *dev,
771 				  struct gpio_callback *cb,
772 				  uint32_t pins)
773 {
774 	ARG_UNUSED(dev);
775 	ARG_UNUSED(pins);
776 
777 	struct adin2111_data *ctx = CONTAINER_OF(cb, struct adin2111_data, gpio_int_callback);
778 
779 	k_sem_give(&ctx->offload_sem);
780 }
781 
adin2111_read_tx_space(const struct device * dev,uint32_t * space)782 static int adin2111_read_tx_space(const struct device *dev, uint32_t *space)
783 {
784 	uint32_t val;
785 	int ret;
786 
787 	ret = eth_adin2111_reg_read(dev, ADIN2111_TX_SPACE, &val);
788 	if (ret < 0) {
789 		return ret;
790 	}
791 
792 	/* tx space is a number of halfwords (16-bits), multiply by 2 for bytes */
793 	*space = val * 2;
794 
795 	return ret;
796 }
797 
adin2111_port_send(const struct device * dev,struct net_pkt * pkt)798 static int adin2111_port_send(const struct device *dev, struct net_pkt *pkt)
799 {
800 	const struct adin2111_port_config *cfg = dev->config;
801 #if defined(CONFIG_NET_STATISTICS_ETHERNET)
802 	struct adin2111_port_data *data = dev->data;
803 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
804 	const struct device *adin = cfg->adin;
805 	struct adin2111_data *ctx = cfg->adin->data;
806 	size_t pkt_len = net_pkt_get_len(pkt);
807 	size_t header_size = ADIN2111_WRITE_HEADER_SIZE;
808 	size_t padded_size;
809 	size_t burst_size;
810 	uint32_t tx_space;
811 	int ret;
812 
813 	eth_adin2111_lock(adin, K_FOREVER);
814 
815 	if (ctx->oa) {
816 		uint32_t val, rca = 0;
817 		/*
818 		 * By high-traffic zperf test, noted that ADIN2111 does not like we send
819 		 * if there is something to be received. It stops to issue rx interrupts
820 		 * and zperf transfer hangs. Forcing a receive for this case.
821 		 */
822 		ret = eth_adin2111_reg_read(adin, ADIN2111_BUFSTS, &val);
823 		if (ret < 0) {
824 			return ret;
825 		}
826 		rca = val & ADIN2111_BUFSTS_RCA_MASK;
827 
828 		if (rca > 0) {
829 			eth_adin2111_unlock(adin);
830 			k_sem_give(&ctx->offload_sem);
831 			k_yield();
832 			eth_adin2111_lock(adin, K_FOREVER);
833 		}
834 
835 		ret = eth_adin2111_send_oa_frame(cfg->adin, pkt, htons(cfg->port_idx));
836 
837 		goto end_check;
838 	}
839 
840 	/* query remaining tx fifo space */
841 	ret = adin2111_read_tx_space(adin, &tx_space);
842 	if (ret < 0) {
843 		eth_stats_update_errors_tx(data->iface);
844 		LOG_ERR("Failed to read TX FIFO space, %d", ret);
845 		goto end_unlock;
846 	}
847 
848 	/**
849 	 * verify that there is space for the frame
850 	 * (frame + 2b header + 2b size field)
851 	 */
852 	if (tx_space <
853 	   (pkt_len + ADIN2111_FRAME_HEADER_SIZE + ADIN2111_INTERNAL_HEADER_SIZE)) {
854 		/* tx buffer is full */
855 		eth_stats_update_errors_tx(data->iface);
856 		ret = -EBUSY;
857 		goto end_unlock;
858 	}
859 
860 	/**
861 	 * pad to 64 bytes, otherwise MAC/PHY has to do it
862 	 * internally MAC adds 4 bytes for forward error correction
863 	 */
864 	if ((pkt_len + ADIN2111_TX_FIFO_BUFFER_MARGIN) < 64) {
865 		padded_size = pkt_len
866 			+ (64 - (pkt_len + ADIN2111_TX_FIFO_BUFFER_MARGIN))
867 			+ ADIN2111_FRAME_HEADER_SIZE;
868 	} else {
869 		padded_size = pkt_len + ADIN2111_FRAME_HEADER_SIZE;
870 	}
871 
872 	/* prepare burst write (write data must be in multiples of 4) */
873 	burst_size = ROUND_UP(padded_size, 4);
874 	if ((burst_size + ADIN2111_WRITE_HEADER_SIZE) > CONFIG_ETH_ADIN2111_BUFFER_SIZE) {
875 		ret = -ENOMEM;
876 		eth_stats_update_errors_tx(data->iface);
877 		goto end_unlock;
878 	}
879 
880 	/* prepare tx buffer */
881 	memset(ctx->buf, 0, burst_size + ADIN2111_WRITE_HEADER_SIZE);
882 
883 	/* spi header */
884 	*(uint16_t *)ctx->buf = htons(ADIN2111_TXN_CTRL_TX_REG);
885 #if CONFIG_ETH_ADIN2111_SPI_CFG0
886 	ctx->buf[2] = crc8_ccitt(0, ctx->buf, header_size);
887 	++header_size;
888 #endif /* CONFIG_ETH_ADIN2111_SPI_CFG0 */
889 
890 	/* frame header */
891 	*(uint16_t *)(ctx->buf + header_size) = htons(cfg->port_idx);
892 
893 	/* read pkt into tx buffer */
894 	ret = net_pkt_read(pkt,
895 			   (ctx->buf + header_size + ADIN2111_FRAME_HEADER_SIZE),
896 			   pkt_len);
897 	if (ret < 0) {
898 		eth_stats_update_errors_tx(data->iface);
899 		LOG_ERR("Port %u failed to read PKT into TX buffer, %d",
900 			cfg->port_idx, ret);
901 		goto end_unlock;
902 	}
903 
904 	/* write transmit size */
905 	ret = eth_adin2111_reg_write(adin, ADIN2111_TX_FSIZE, padded_size);
906 	if (ret < 0) {
907 		eth_stats_update_errors_tx(data->iface);
908 		LOG_ERR("Port %u write FSIZE failed, %d", cfg->port_idx, ret);
909 		goto end_unlock;
910 	}
911 
912 	/* write transaction */
913 	const struct spi_buf buf = {
914 		.buf = ctx->buf,
915 		.len = header_size + burst_size
916 	};
917 	const struct spi_buf_set tx = { .buffers = &buf, .count = 1U };
918 
919 	ret = spi_write_dt(&((const struct adin2111_config *) adin->config)->spi,
920 			   &tx);
921 end_check:
922 	if (ret < 0) {
923 		eth_stats_update_errors_tx(data->iface);
924 		LOG_ERR("Port %u frame SPI write failed, %d", cfg->port_idx, ret);
925 		goto end_unlock;
926 	}
927 
928 	eth_stats_update_bytes_tx(data->iface, pkt_len);
929 	eth_stats_update_pkts_tx(data->iface);
930 
931 end_unlock:
932 	eth_adin2111_unlock(adin);
933 	return ret;
934 }
935 
adin2111_config_sync(const struct device * dev)936 static int adin2111_config_sync(const struct device *dev)
937 {
938 	int ret;
939 	uint32_t val;
940 
941 	ret = eth_adin2111_reg_read(dev, ADIN2111_CONFIG0, &val);
942 	if (ret < 0) {
943 		return ret;
944 	}
945 
946 	val |= ADIN2111_CONFIG0_SYNC;
947 
948 	ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG0, val);
949 	if (ret < 0) {
950 		return ret;
951 	}
952 
953 	return 0;
954 }
955 
adin2111_write_filter_address(const struct device * dev,uint8_t * addr,uint8_t * mask,uint32_t rules,uint16_t slot)956 static int adin2111_write_filter_address(const struct device *dev,
957 					 uint8_t *addr, uint8_t *mask,
958 					 uint32_t rules, uint16_t slot)
959 {
960 	uint16_t offset = slot * 2U;
961 	int ret;
962 
963 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_FILT_UPR + offset,
964 				     rules | sys_get_be16(&addr[0]));
965 	if (ret < 0) {
966 		return ret;
967 	}
968 
969 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_FILT_LWR  + offset,
970 				     sys_get_be32(&addr[2]));
971 	if (ret < 0) {
972 		return ret;
973 	}
974 
975 	if (offset > 2U) {
976 		/* mask filter addresses are limited to 2 */
977 		return 0;
978 	}
979 
980 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_MSK_UPR + offset,
981 				     sys_get_be16(&mask[0]));
982 	if (ret < 0) {
983 		return ret;
984 	}
985 
986 	ret = eth_adin2111_reg_write(dev, ADIN2111_ADDR_MSK_LWR + offset,
987 				     sys_get_be32(&mask[2]));
988 	if (ret < 0) {
989 		return ret;
990 	}
991 
992 	return ret;
993 }
994 
adin2111_filter_multicast(const struct device * dev)995 static int adin2111_filter_multicast(const struct device *dev)
996 {
997 	const struct adin2111_config *cfg = dev->config;
998 	bool is_adin2111 = (cfg->id == ADIN2111_MAC);
999 	uint8_t mm[NET_ETH_ADDR_LEN] = {BIT(0), 0U, 0U, 0U, 0U, 0U};
1000 	uint8_t mmask[NET_ETH_ADDR_LEN] = {0xFFU, 0U, 0U, 0U, 0U, 0U};
1001 	uint32_t rules = ADIN2111_ADDR_APPLY2PORT1 |
1002 			 (is_adin2111 ? ADIN2111_ADDR_APPLY2PORT2 : 0) |
1003 			 ADIN2111_ADDR_TO_HOST |
1004 			 ADIN2111_ADDR_TO_OTHER_PORT;
1005 
1006 	return adin2111_write_filter_address(dev, mm, mmask, rules,
1007 					     ADIN2111_MULTICAST_ADDR_SLOT);
1008 }
1009 
adin2111_filter_broadcast(const struct device * dev)1010 static int adin2111_filter_broadcast(const struct device *dev)
1011 {
1012 	const struct adin2111_config *cfg = dev->config;
1013 	bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1014 	uint8_t mac[NET_ETH_ADDR_LEN] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
1015 	uint32_t rules = ADIN2111_ADDR_APPLY2PORT1 |
1016 			 (is_adin2111 ? ADIN2111_ADDR_APPLY2PORT2 : 0) |
1017 			 ADIN2111_ADDR_TO_HOST |
1018 			 ADIN2111_ADDR_TO_OTHER_PORT;
1019 
1020 	return adin2111_write_filter_address(dev, mac, mac, rules,
1021 					     ADIN2111_BROADCAST_ADDR_SLOT);
1022 }
1023 
adin2111_filter_unicast(const struct device * dev,uint8_t * addr,const uint16_t port_idx)1024 static int adin2111_filter_unicast(const struct device *dev, uint8_t *addr,
1025 				   const uint16_t port_idx)
1026 {
1027 	uint32_t rules = (port_idx == 0 ? ADIN2111_ADDR_APPLY2PORT1
1028 					: ADIN2111_ADDR_APPLY2PORT2)
1029 			 | ADIN2111_ADDR_TO_HOST;
1030 	uint16_t slot = (port_idx == 0 ? ADIN2111_UNICAST_P1_ADDR_SLOT
1031 				       : ADIN2111_UNICAST_P2_ADDR_SLOT);
1032 
1033 	return adin2111_write_filter_address(dev, addr, NULL, rules, slot);
1034 }
1035 
eth_adin2111_broadcast_filter(const struct device * dev,bool enable)1036 int eth_adin2111_broadcast_filter(const struct device *dev, bool enable)
1037 {
1038 	if (!enable) {
1039 		/* Clean up */
1040 		uint8_t mac[NET_ETH_ADDR_LEN] = {0};
1041 
1042 		return adin2111_write_filter_address(dev, mac, mac, 0,
1043 						     ADIN2111_BROADCAST_ADDR_SLOT);
1044 	}
1045 
1046 	return adin2111_filter_broadcast(dev);
1047 }
1048 
1049 /*
1050  * Check if a filter exists already.
1051  */
eth_adin2111_find_filter(const struct device * dev,uint8_t * mac,const uint16_t port_idx)1052 static int eth_adin2111_find_filter(const struct device *dev, uint8_t *mac, const uint16_t port_idx)
1053 {
1054 	int i, offset, reg, ret;
1055 
1056 	for (i = ADIN2111_FILTER_FIRST_SLOT; i < ADIN2111_FILTER_SLOTS; i++) {
1057 		offset = i << 1;
1058 		ret = eth_adin2111_reg_read(dev, ADIN2111_ADDR_FILT_UPR + offset, &reg);
1059 		if (ret < 0) {
1060 			return ret;
1061 		}
1062 		if ((reg & UINT16_MAX) == sys_get_be16(&mac[0])) {
1063 			if ((port_idx == 0 && !(reg & ADIN2111_ADDR_APPLY2PORT1)) ||
1064 			    (port_idx == 1 && !(reg & ADIN2111_ADDR_APPLY2PORT2)))
1065 				continue;
1066 
1067 			ret = eth_adin2111_reg_read(dev, ADIN2111_ADDR_FILT_LWR + offset, &reg);
1068 			if (ret < 0) {
1069 				return ret;
1070 			}
1071 			if (reg == sys_get_be32(&mac[2])) {
1072 				return i;
1073 			}
1074 		}
1075 	}
1076 
1077 	return -ENOENT;
1078 }
1079 
eth_adin2111_set_mac_filter(const struct device * dev,uint8_t * mac,const uint16_t port_idx)1080 static int eth_adin2111_set_mac_filter(const struct device *dev, uint8_t *mac,
1081 				       const uint16_t port_idx)
1082 {
1083 	int i, ret, offset;
1084 	uint32_t reg;
1085 
1086 	ret = eth_adin2111_find_filter(dev, mac, port_idx);
1087 	if (ret >= 0) {
1088 		LOG_WRN("MAC filter already set at pos %d, not setting it.", ret);
1089 		return ret;
1090 	}
1091 	if (ret != -ENOENT) {
1092 		return ret;
1093 	}
1094 
1095 	for (i = ADIN2111_FILTER_FIRST_SLOT; i < ADIN2111_FILTER_SLOTS; i++) {
1096 		offset = i << 1;
1097 		ret = eth_adin2111_reg_read(dev, ADIN2111_ADDR_FILT_UPR + offset, &reg);
1098 		if (ret < 0) {
1099 			return ret;
1100 		}
1101 		if (reg == 0) {
1102 			uint32_t rules = (port_idx == 0 ? ADIN2111_ADDR_APPLY2PORT1
1103 					: ADIN2111_ADDR_APPLY2PORT2)
1104 					| ADIN2111_ADDR_TO_HOST;
1105 
1106 			return adin2111_write_filter_address(dev, mac, NULL, rules, i);
1107 		}
1108 	}
1109 
1110 	return -ENOSPC;
1111 }
1112 
eth_adin2111_clear_mac_filter(const struct device * dev,uint8_t * mac,const uint16_t port_idx)1113 static int eth_adin2111_clear_mac_filter(const struct device *dev, uint8_t *mac,
1114 					 const uint16_t port_idx)
1115 {
1116 	int i;
1117 	uint8_t cmac[NET_ETH_ADDR_LEN] = {0};
1118 
1119 	i = eth_adin2111_find_filter(dev, mac, port_idx);
1120 	if (i < 0) {
1121 		return i;
1122 	}
1123 
1124 	return adin2111_write_filter_address(dev, cmac, cmac, 0, i);
1125 }
1126 
1127 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
eth_adin2111_set_promiscuous(const struct device * dev,const uint16_t port_idx,bool enable)1128 static int eth_adin2111_set_promiscuous(const struct device *dev, const uint16_t port_idx,
1129 					bool enable)
1130 {
1131 	const struct adin2111_config *cfg = dev->config;
1132 	bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1133 	uint32_t fwd_mask;
1134 
1135 	if ((!is_adin2111 && port_idx > 0) || (is_adin2111 && port_idx > 1)) {
1136 		return -EINVAL;
1137 	}
1138 
1139 	fwd_mask = port_idx ? ADIN2111_CONFIG2_P2_FWD_UNK2HOST : ADIN2111_CONFIG2_P1_FWD_UNK2HOST;
1140 
1141 	return eth_adin2111_reg_update(dev, ADIN2111_CONFIG2, fwd_mask, enable ? fwd_mask : 0);
1142 }
1143 #endif
1144 
adin2111_port_iface_init(struct net_if * iface)1145 static void adin2111_port_iface_init(struct net_if *iface)
1146 {
1147 	const struct device *dev = net_if_get_device(iface);
1148 	const struct adin2111_port_config *cfg = dev->config;
1149 	struct adin2111_port_data *data = dev->data;
1150 	const struct device *adin = cfg->adin;
1151 	struct adin2111_data *ctx = adin->data;
1152 	int ret;
1153 
1154 	if (!device_is_ready(adin)) {
1155 		LOG_ERR("ADIN %s is not ready, can't init port %u iface",
1156 			cfg->adin->name, cfg->port_idx);
1157 		return;
1158 	}
1159 
1160 	if (!device_is_ready(cfg->phy)) {
1161 		LOG_ERR("PHY %u is not ready, can't init port %u iface",
1162 			cfg->phy_addr, cfg->port_idx);
1163 		return;
1164 	}
1165 
1166 	ctx->port[cfg->port_idx] = dev;
1167 	data->iface = iface;
1168 
1169 	ret = adin2111_filter_unicast(adin, data->mac_addr, cfg->port_idx);
1170 	if (ret < 0) {
1171 		LOG_ERR("Port %u, failed to set unicast filter, %d",
1172 			cfg->port_idx, ret);
1173 		return;
1174 	}
1175 	net_if_set_link_addr(iface, data->mac_addr, sizeof(data->mac_addr),
1176 			     NET_LINK_ETHERNET);
1177 	ethernet_init(iface);
1178 	net_if_carrier_off(iface);
1179 
1180 	--ctx->ifaces_left_to_init;
1181 
1182 	/* if all ports are initialized */
1183 	if (ctx->ifaces_left_to_init == 0U) {
1184 		/* setup rx filters */
1185 		ret = adin2111_filter_multicast(adin);
1186 		if (ret < 0) {
1187 			LOG_ERR("Couldn't set multicast filter, %d", ret);
1188 			return;
1189 		}
1190 		ret = adin2111_filter_broadcast(adin);
1191 		if (ret < 0) {
1192 			LOG_ERR("Couldn't set broadcast filter, %d", ret);
1193 			return;
1194 		}
1195 
1196 		/* sync */
1197 		ret = adin2111_config_sync(adin);
1198 		if (ret < 0) {
1199 			LOG_ERR("Failed to write CONFIG0 SYNC, %d", ret);
1200 			return;
1201 		}
1202 
1203 		/* all ifaces are done, start INT processing */
1204 		k_thread_create(&ctx->rx_thread, ctx->rx_thread_stack,
1205 				K_KERNEL_STACK_SIZEOF(ctx->rx_thread_stack),
1206 				adin2111_offload_thread,
1207 				(void *)adin, NULL, NULL,
1208 				CONFIG_ETH_ADIN2111_IRQ_THREAD_PRIO,
1209 				K_ESSENTIAL, K_NO_WAIT);
1210 		k_thread_name_set(&ctx->rx_thread, "eth_adin2111_offload");
1211 	}
1212 }
1213 
adin2111_port_get_capabilities(const struct device * dev)1214 static enum ethernet_hw_caps adin2111_port_get_capabilities(const struct device *dev)
1215 {
1216 	ARG_UNUSED(dev);
1217 	return ETHERNET_LINK_10BASE_T |
1218 		ETHERNET_HW_FILTERING
1219 #if defined(CONFIG_NET_LLDP)
1220 		| ETHERNET_LLDP
1221 #endif
1222 		| ETHERNET_PROMISC_MODE;
1223 }
1224 
adin2111_port_set_config(const struct device * dev,enum ethernet_config_type type,const struct ethernet_config * config)1225 static int adin2111_port_set_config(const struct device *dev,
1226 				    enum ethernet_config_type type,
1227 				    const struct ethernet_config *config)
1228 {
1229 	const struct adin2111_port_config *cfg = dev->config;
1230 	struct adin2111_port_data *data = dev->data;
1231 	const struct device *adin = cfg->adin;
1232 	int ret = -ENOTSUP;
1233 
1234 	(void)eth_adin2111_lock(adin, K_FOREVER);
1235 
1236 	if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) {
1237 		ret = adin2111_filter_unicast(adin, (uint8_t *)&config->mac_address.addr[0],
1238 					      cfg->port_idx);
1239 		if (ret < 0) {
1240 			goto end_unlock;
1241 		}
1242 
1243 		(void)memcpy(data->mac_addr, config->mac_address.addr, sizeof(data->mac_addr));
1244 
1245 		(void)net_if_set_link_addr(data->iface, data->mac_addr, sizeof(data->mac_addr),
1246 					   NET_LINK_ETHERNET);
1247 	}
1248 
1249 	if (type == ETHERNET_CONFIG_TYPE_FILTER) {
1250 		/* Filtering for DA only */
1251 		if (config->filter.type & ETHERNET_FILTER_TYPE_DST_MAC_ADDRESS) {
1252 			uint8_t *mac = (uint8_t *)config->filter.mac_address.addr;
1253 
1254 			if (config->filter.set) {
1255 				ret = eth_adin2111_set_mac_filter(adin, mac, cfg->port_idx);
1256 			} else {
1257 				ret = eth_adin2111_clear_mac_filter(adin, mac, cfg->port_idx);
1258 			}
1259 		}
1260 	}
1261 
1262 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
1263 	if (type == ETHERNET_CONFIG_TYPE_PROMISC_MODE) {
1264 		ret = eth_adin2111_set_promiscuous(adin, cfg->port_idx, config->promisc_mode);
1265 	}
1266 #endif
1267 
1268 end_unlock:
1269 	(void)eth_adin2111_unlock(adin);
1270 	return ret;
1271 }
1272 
1273 #if defined(CONFIG_NET_STATISTICS_ETHERNET)
adin2111_port_get_stats(const struct device * dev)1274 static struct net_stats_eth *adin2111_port_get_stats(const struct device *dev)
1275 {
1276 	struct adin2111_port_data *data = dev->data;
1277 
1278 	return &data->stats;
1279 }
1280 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
1281 
adin2111_check_spi(const struct device * dev)1282 static int adin2111_check_spi(const struct device *dev)
1283 {
1284 	uint32_t count;
1285 	uint32_t val;
1286 	int ret;
1287 
1288 	/* check SPI communication by reading PHYID */
1289 	for (count = 0U; count < ADIN2111_DEV_AWAIT_RETRY_COUNT; ++count) {
1290 		ret = eth_adin2111_reg_read(dev, ADIN2111_PHYID, &val);
1291 		if (ret >= 0) {
1292 			if (val == ADIN2111_PHYID_RST_VAL || val == ADIN1110_PHYID_RST_VAL) {
1293 				break;
1294 			}
1295 			ret = -ETIMEDOUT;
1296 		}
1297 		k_sleep(K_USEC(ADIN2111_DEV_AWAIT_DELAY_POLL_US));
1298 	}
1299 
1300 	return ret;
1301 }
1302 
adin2111_await_device(const struct device * dev)1303 static int adin2111_await_device(const struct device *dev)
1304 {
1305 	uint32_t count;
1306 	uint32_t val;
1307 	int ret;
1308 
1309 	/* await reset complete (RESETC) and clear it */
1310 	for (count = 0U; count < ADIN2111_RESETC_AWAIT_RETRY_COUNT; ++count) {
1311 		ret = eth_adin2111_reg_read(dev, ADIN2111_PHYID, &val);
1312 		if (ret >= 0) {
1313 			/*
1314 			 * Even after getting RESETC, for some milliseconds registers are
1315 			 * still not properly readable (they reads 0),
1316 			 * so checking OUI read-only value instead.
1317 			 */
1318 			if ((val >> 10) == ADIN2111_PHYID_OUI) {
1319 				/* clear RESETC */
1320 				ret = eth_adin2111_reg_write(dev, ADIN2111_STATUS0,
1321 							 ADIN2111_STATUS0_RESETC);
1322 				if (ret >= 0) {
1323 					break;
1324 				}
1325 			}
1326 			ret = -ETIMEDOUT;
1327 		}
1328 		k_sleep(K_USEC(ADIN2111_RESETC_AWAIT_DELAY_POLL_US));
1329 	}
1330 
1331 	return ret;
1332 }
1333 
eth_adin2111_sw_reset(const struct device * dev,uint16_t delay)1334 int eth_adin2111_sw_reset(const struct device *dev, uint16_t delay)
1335 {
1336 	int ret;
1337 
1338 	ret = eth_adin2111_reg_write(dev, ADIN2111_RESET, ADIN2111_RESET_SWRESET);
1339 	if (ret < 0) {
1340 		return ret;
1341 	}
1342 
1343 	k_msleep(delay);
1344 
1345 	ret = adin2111_await_device(dev);
1346 	if (ret < 0) {
1347 		LOG_ERR("ADIN did't come out of the reset, %d", ret);
1348 		return ret;
1349 	}
1350 
1351 	return ret;
1352 }
1353 
adin2111_init(const struct device * dev)1354 static int adin2111_init(const struct device *dev)
1355 {
1356 	const struct adin2111_config *cfg = dev->config;
1357 	bool is_adin2111 = (cfg->id == ADIN2111_MAC);
1358 	struct adin2111_data *ctx = dev->data;
1359 	int ret;
1360 	uint32_t val;
1361 
1362 	__ASSERT(cfg->spi.config.frequency <= ADIN2111_SPI_MAX_FREQUENCY,
1363 		 "SPI frequency exceeds supported maximum\n");
1364 
1365 	if (!spi_is_ready_dt(&cfg->spi)) {
1366 		LOG_ERR("SPI bus %s not ready", cfg->spi.bus->name);
1367 		return -ENODEV;
1368 	}
1369 
1370 	if (!gpio_is_ready_dt(&cfg->interrupt)) {
1371 		LOG_ERR("Interrupt GPIO device %s is not ready",
1372 			cfg->interrupt.port->name);
1373 		return -ENODEV;
1374 	}
1375 
1376 	ret = gpio_pin_configure_dt(&cfg->interrupt, GPIO_INPUT);
1377 	if (ret < 0) {
1378 		LOG_ERR("Failed to configure interrupt GPIO, %d", ret);
1379 		return ret;
1380 	}
1381 
1382 	if (cfg->reset.port != NULL) {
1383 		if (!gpio_is_ready_dt(&cfg->reset)) {
1384 			LOG_ERR("Reset GPIO device %s is not ready",
1385 			cfg->reset.port->name);
1386 			return -ENODEV;
1387 		}
1388 
1389 		ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE);
1390 		if (ret < 0) {
1391 			LOG_ERR("Failed to configure reset GPIO, %d", ret);
1392 			return ret;
1393 		}
1394 
1395 		/* perform hard reset */
1396 		/* assert pin low for 16 µs (10 µs min) */
1397 		gpio_pin_set_dt(&cfg->reset, 1);
1398 		k_busy_wait(16U);
1399 		/* deassert and wait for 90 ms (max) for clocks stabilisation */
1400 		gpio_pin_set_dt(&cfg->reset, 0);
1401 		k_msleep(ADIN2111_HW_BOOT_DELAY_MS);
1402 	}
1403 
1404 	gpio_init_callback(&(ctx->gpio_int_callback),
1405 			   adin2111_int_callback,
1406 			   BIT(cfg->interrupt.pin));
1407 
1408 	ret = gpio_add_callback(cfg->interrupt.port, &ctx->gpio_int_callback);
1409 	if (ret < 0) {
1410 		LOG_ERR("Failed to add INT callback, %d", ret);
1411 		return ret;
1412 	}
1413 
1414 	k_msleep(ADIN2111_SPI_ACTIVE_DELAY_MS);
1415 
1416 	ret = adin2111_check_spi(dev);
1417 	if (ret < 0) {
1418 		LOG_ERR("Failed to communicate over SPI, %d", ret);
1419 		return ret;
1420 	}
1421 
1422 	/* perform MACPHY soft reset */
1423 	ret = eth_adin2111_sw_reset(dev, ADIN2111_SW_RESET_DELAY_MS);
1424 	if (ret < 0) {
1425 		LOG_ERR("MACPHY software reset failed, %d", ret);
1426 		return ret;
1427 	}
1428 
1429 	/* CONFIG 0 */
1430 	/* disable Frame Check Sequence validation on the host */
1431 	/* if that is enabled, then CONFIG_ETH_ADIN2111_SPI_CFG0 must be off */
1432 	ret = eth_adin2111_reg_read(dev, ADIN2111_CONFIG0, &val);
1433 	if (ret < 0) {
1434 		LOG_ERR("Failed to read CONFIG0, %d", ret);
1435 		return ret;
1436 	}
1437 
1438 	/* RXCTE must be disabled for Generic SPI */
1439 	val &= ~ADIN2111_CONFIG0_RXCTE;
1440 	val &= ~(ADIN2111_CONFIG0_TXCTE | ADIN2111_CONFIG0_TXFCSVE);
1441 
1442 	if (ctx->oa) {
1443 		val |= ADIN2111_CONFIG0_ZARFE;
1444 	}
1445 
1446 	ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG0, val);
1447 	if (ret < 0) {
1448 		LOG_ERR("Failed to write CONFIG0, %d", ret);
1449 		return ret;
1450 	}
1451 
1452 	/* CONFIG 2 */
1453 	ret = eth_adin2111_reg_read(dev, ADIN2111_CONFIG2, &val);
1454 	if (ret < 0) {
1455 		LOG_ERR("Failed to read CONFIG2, %d", ret);
1456 		return ret;
1457 	}
1458 
1459 	val |= ADIN2111_CONFIG2_CRC_APPEND;
1460 
1461 	/* configure forwarding of frames with unknown destination address */
1462 	/* to the other port. This forwarding is done in hardware.         */
1463 	/* The setting will take effect after the ports                    */
1464 	/* are out of software powerdown.                                  */
1465 	val |= (ADIN2111_CONFIG2_PORT_CUT_THRU_EN |
1466 		(is_adin2111 ? ADIN2111_CONFIG2_P1_FWD_UNK2P2 : 0) |
1467 		(is_adin2111 ? ADIN2111_CONFIG2_P2_FWD_UNK2P1 : 0));
1468 
1469 	ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG2, val);
1470 	if (ret < 0) {
1471 		LOG_ERR("Failed to write CONFIG2, %d", ret);
1472 		return ret;
1473 	}
1474 
1475 	/* configure interrupt masks */
1476 	ctx->imask0 = ~((uint32_t)ADIN2111_IMASK0_PHYINTM);
1477 	ctx->imask1 = ~(ADIN2111_IMASK1_TX_RDY_MASK |
1478 			ADIN2111_IMASK1_P1_RX_RDY_MASK |
1479 			ADIN2111_IMASK1_SPI_ERR_MASK |
1480 			(is_adin2111 ? ADIN2111_IMASK1_P2_RX_RDY_MASK : 0) |
1481 			(is_adin2111 ? ADIN2111_IMASK1_P2_PHYINT_MASK : 0));
1482 
1483 	/* enable interrupts */
1484 	ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0);
1485 	if (ret < 0) {
1486 		LOG_ERR("Failed to write IMASK0, %d", ret);
1487 		return ret;
1488 	}
1489 	ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK1, ctx->imask1);
1490 	if (ret < 0) {
1491 		LOG_ERR("Failed to write IMASK1, %d", ret);
1492 		return ret;
1493 	}
1494 
1495 	ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt,
1496 						GPIO_INT_EDGE_TO_ACTIVE);
1497 	if (ret < 0) {
1498 		LOG_ERR("Failed to enable INT, %d", ret);
1499 		return ret;
1500 	}
1501 
1502 	return ret;
1503 }
1504 
1505 static const struct ethernet_api adin2111_port_api = {
1506 	.iface_api.init = adin2111_port_iface_init,
1507 	.get_capabilities = adin2111_port_get_capabilities,
1508 	.set_config = adin2111_port_set_config,
1509 	.send = adin2111_port_send,
1510 #if defined(CONFIG_NET_STATISTICS_ETHERNET)
1511 	.get_stats = adin2111_port_get_stats,
1512 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
1513 };
1514 
1515 #define ADIN2111_STR(x)		#x
1516 #define ADIN2111_XSTR(x)	ADIN2111_STR(x)
1517 
1518 #define ADIN2111_DEF_BUF(name, size) static uint8_t __aligned(4) name[size]
1519 
1520 #define ADIN2111_MDIO_PHY_BY_ADDR(adin_n, phy_addr)						\
1521 	DEVICE_DT_GET(DT_CHILD(DT_INST_CHILD(adin_n, mdio), ethernet_phy_##phy_addr))
1522 
1523 #define ADIN2111_PORT_MAC(adin_n, port_n)							\
1524 	DT_PROP(DT_CHILD(DT_DRV_INST(adin_n), port##port_n), local_mac_address)
1525 
1526 #define ADIN2111_PORT_DEVICE_INIT_INSTANCE(parent_n, port_n, phy_n, name)			\
1527 	static struct adin2111_port_data name##_port_data_##port_n = {				\
1528 		.mac_addr = ADIN2111_PORT_MAC(parent_n, phy_n),					\
1529 	};											\
1530 	static const struct adin2111_port_config name##_port_config_##port_n = {		\
1531 		.adin = DEVICE_DT_INST_GET(parent_n),						\
1532 		.phy = ADIN2111_MDIO_PHY_BY_ADDR(parent_n, phy_n),				\
1533 		.port_idx = port_n,								\
1534 		.phy_addr = phy_n,								\
1535 	};											\
1536 	ETH_NET_DEVICE_INIT_INSTANCE(name##_port_##port_n, "port_" ADIN2111_XSTR(port_n),	\
1537 				     port_n, NULL, NULL, &name##_port_data_##port_n,		\
1538 				     &name##_port_config_##port_n, CONFIG_ETH_INIT_PRIORITY,	\
1539 				     &adin2111_port_api, NET_ETH_MTU);
1540 
1541 #define ADIN2111_SPI_OPERATION ((uint16_t)(SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8)))
1542 #define ADIN2111_MAC_INITIALIZE(inst, dev_id, ifaces, name)					\
1543 	ADIN2111_DEF_BUF(name##_buffer_##inst, CONFIG_ETH_ADIN2111_BUFFER_SIZE);		\
1544 	COND_CODE_1(DT_INST_PROP(inst, spi_oa),							\
1545 	(											\
1546 		ADIN2111_DEF_BUF(name##_oa_tx_buf_##inst, ADIN2111_OA_BUF_SZ);			\
1547 		ADIN2111_DEF_BUF(name##_oa_rx_buf_##inst, ADIN2111_OA_BUF_SZ);			\
1548 	), ())											\
1549 	static const struct adin2111_config name##_config_##inst = {				\
1550 		.id = dev_id,									\
1551 		.spi = SPI_DT_SPEC_INST_GET(inst, ADIN2111_SPI_OPERATION, 0),			\
1552 		.interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios),				\
1553 		.reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, { 0 }),			\
1554 	};											\
1555 	static struct adin2111_data name##_data_##inst = {					\
1556 		.ifaces_left_to_init = ifaces,							\
1557 		.port = {},									\
1558 		.offload_sem = Z_SEM_INITIALIZER(name##_data_##inst.offload_sem, 0, 1),		\
1559 		.lock = Z_MUTEX_INITIALIZER(name##_data_##inst.lock),				\
1560 		.buf = name##_buffer_##inst,							\
1561 		.oa = DT_INST_PROP(inst, spi_oa),						\
1562 		.oa_prot = DT_INST_PROP(inst, spi_oa_protection),				\
1563 		.oa_cps = 64,									\
1564 		.oa_tx_buf = COND_CODE_1(DT_INST_PROP(inst, spi_oa),				\
1565 					 (name##_oa_tx_buf_##inst), (NULL)),			\
1566 		.oa_rx_buf = COND_CODE_1(DT_INST_PROP(inst, spi_oa),				\
1567 					 (name##_oa_rx_buf_##inst), (NULL)),			\
1568 	};											\
1569 	/* adin */										\
1570 	DEVICE_DT_DEFINE(DT_DRV_INST(inst), adin2111_init, NULL,				\
1571 			 &name##_data_##inst, &name##_config_##inst,				\
1572 			 POST_KERNEL, CONFIG_ETH_INIT_PRIORITY,					\
1573 			 NULL);
1574 
1575 #define ADIN2111_MAC_INIT(inst)	ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2, adin2111)	\
1576 	/* ports */										\
1577 	ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin2111)				\
1578 	ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 1, 2, adin2111)
1579 
1580 #undef DT_DRV_COMPAT
1581 #define DT_DRV_COMPAT adi_adin2111
1582 DT_INST_FOREACH_STATUS_OKAY(ADIN2111_MAC_INIT)
1583 
1584 #define ADIN1110_MAC_INIT(inst)	ADIN2111_MAC_INITIALIZE(inst, ADIN1110_MAC, 1, adin1110)	\
1585 	/* ports */										\
1586 	ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1, adin1110)
1587 
1588 #undef DT_DRV_COMPAT
1589 #define DT_DRV_COMPAT adi_adin1110
1590 DT_INST_FOREACH_STATUS_OKAY(ADIN1110_MAC_INIT)
1591