1 /* LAN9250 Stand-alone Ethernet Controller with SPI
2  *
3  * Copyright (c) 2024 Mario Paja
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 #define DT_DRV_COMPAT microchip_lan9250
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/device.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/drivers/spi.h>
15 #include <zephyr/net/net_pkt.h>
16 #include <zephyr/net/net_if.h>
17 #include <zephyr/net/ethernet.h>
18 #include <ethernet/eth_stats.h>
19 
20 #include "eth_lan9250_priv.h"
21 
22 LOG_MODULE_REGISTER(eth_lan9250, CONFIG_ETHERNET_LOG_LEVEL);
23 
lan9250_write_sys_reg(const struct device * dev,uint16_t address,uint32_t data)24 static int lan9250_write_sys_reg(const struct device *dev, uint16_t address, uint32_t data)
25 {
26 	const struct lan9250_config *config = dev->config;
27 	uint8_t cmd[1] = {LAN9250_SPI_INSTR_WRITE};
28 	uint8_t addr[2];
29 	uint8_t instr[4];
30 	struct spi_buf tx_buf[3];
31 	const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3};
32 
33 	sys_put_be16(address, addr);
34 	sys_put_le32(data, instr);
35 
36 	tx_buf[0].buf = &cmd;
37 	tx_buf[0].len = ARRAY_SIZE(cmd);
38 	tx_buf[1].buf = addr;
39 	tx_buf[1].len = ARRAY_SIZE(addr);
40 	tx_buf[2].buf = instr;
41 	tx_buf[2].len = ARRAY_SIZE(instr);
42 
43 	return spi_write_dt(&config->spi, &tx);
44 }
45 
lan9250_read_sys_reg(const struct device * dev,uint16_t address,uint32_t * value)46 static int lan9250_read_sys_reg(const struct device *dev, uint16_t address, uint32_t *value)
47 {
48 	const struct lan9250_config *config = dev->config;
49 	uint8_t cmd[1] = {LAN9250_SPI_INSTR_READ};
50 	uint8_t addr[2];
51 	struct spi_buf tx_buf[3];
52 	struct spi_buf rx_buf[3];
53 	const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3};
54 	const struct spi_buf_set rx = {.buffers = rx_buf, .count = 3};
55 
56 	sys_put_be16(address, addr);
57 
58 	tx_buf[0].buf = &cmd;
59 	tx_buf[0].len = ARRAY_SIZE(cmd);
60 	tx_buf[1].buf = addr;
61 	tx_buf[1].len = ARRAY_SIZE(addr);
62 	tx_buf[2].buf = NULL;
63 	tx_buf[2].len = sizeof(uint32_t);
64 
65 	rx_buf[0].buf = NULL;
66 	rx_buf[0].len = 1;
67 	rx_buf[1].buf = NULL;
68 	rx_buf[1].len = 2;
69 	rx_buf[2].buf = value;
70 	rx_buf[2].len = sizeof(uint32_t);
71 
72 	return spi_transceive_dt(&config->spi, &tx, &rx);
73 }
74 
lan9250_wait_ready(const struct device * dev,uint16_t address,uint32_t mask,uint32_t expected,uint32_t m_second)75 static int lan9250_wait_ready(const struct device *dev, uint16_t address, uint32_t mask,
76 			      uint32_t expected, uint32_t m_second)
77 {
78 	uint32_t tmp;
79 	int wait_time = 0;
80 
81 	while (true) {
82 		lan9250_read_sys_reg(dev, address, &tmp);
83 		wait_time++;
84 		k_busy_wait(USEC_PER_MSEC * 1U);
85 		if ((tmp & mask) == expected) {
86 			return 0;
87 		} else if (wait_time == m_second) {
88 			LOG_ERR("NOT READY");
89 			return -EIO;
90 		}
91 	}
92 }
93 
lan9250_read_mac_reg(const struct device * dev,uint8_t address,uint32_t * value)94 static int lan9250_read_mac_reg(const struct device *dev, uint8_t address, uint32_t *value)
95 {
96 	uint32_t tmp;
97 
98 	/* Wait for MAC to be ready and send writing register command and data */
99 	lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0,
100 			   LAN9250_MAC_TIMEOUT);
101 	lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD,
102 			      address | LAN9250_MAC_CSR_CMD_BUSY | LAN9250_MAC_CSR_CMD_READ);
103 
104 	/* Wait for MAC to be ready and send writing register command and data */
105 	lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0,
106 			   LAN9250_MAC_TIMEOUT);
107 	lan9250_read_sys_reg(dev, LAN9250_MAC_CSR_DATA, &tmp);
108 
109 	*value = tmp;
110 	return 0;
111 }
112 
lan9250_write_mac_reg(const struct device * dev,uint8_t address,uint32_t data)113 static int lan9250_write_mac_reg(const struct device *dev, uint8_t address, uint32_t data)
114 {
115 	/* Wait for MAC to be ready and send writing register command and data */
116 	lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0,
117 			   LAN9250_MAC_TIMEOUT);
118 	lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_DATA, data);
119 	lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, address | LAN9250_MAC_CSR_CMD_BUSY);
120 
121 	/* Wait until writing MAC is done */
122 	lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0,
123 			   LAN9250_MAC_TIMEOUT);
124 
125 	return 0;
126 }
127 
lan9250_wait_mac_ready(const struct device * dev,uint8_t address,uint32_t mask,uint32_t expected,uint32_t m_second)128 static int lan9250_wait_mac_ready(const struct device *dev, uint8_t address, uint32_t mask,
129 				  uint32_t expected, uint32_t m_second)
130 {
131 	uint32_t tmp;
132 	int wait_time = 0;
133 
134 	while (true) {
135 		lan9250_read_mac_reg(dev, address, &tmp);
136 		wait_time++;
137 		k_msleep(1);
138 		if ((tmp & mask) == expected) {
139 			return 0;
140 		} else if (wait_time == m_second) {
141 			return -EIO;
142 		}
143 	}
144 }
145 
lan9250_read_phy_reg(const struct device * dev,uint8_t address,uint16_t * value)146 static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint16_t *value)
147 {
148 	uint32_t tmp;
149 
150 	/* Wait PHY to be ready and send reading register command */
151 	lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0,
152 			       LAN9250_PHY_TIMEOUT);
153 
154 	/* Reference: Microchip Ethernet LAN9250
155 	 * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/
156 	 *
157 	 * Datasheet:
158 	 * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001913A.pdf
159 	 *
160 	 * 12.2.18 PHY REGISTERS
161 	 * The PHY registers are indirectly accessed through the Host MAC MII Access Register
162 	 * (HMAC_MII_ACC) and Host MAC MII Data Register (HMAC_MII_DATA).
163 	 *
164 	 * Write 32bit value to the indirect MAC registers
165 	 * Where phy_add = 0b00001 & index = address
166 	 * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F) << 6)
167 	 */
168 	lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, (1 << 11) | ((address & 0x1F) << 6));
169 
170 	/* Wait PHY to be ready and send reading register command */
171 	lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0,
172 			       LAN9250_PHY_TIMEOUT);
173 
174 	/* Read 32bit value from the indirect MAC registers */
175 	lan9250_read_mac_reg(dev, LAN9250_HMAC_MII_DATA, &tmp);
176 	*value = tmp;
177 
178 	return 0;
179 }
180 
lan9250_write_phy_reg(const struct device * dev,uint8_t address,uint16_t data)181 static int lan9250_write_phy_reg(const struct device *dev, uint8_t address, uint16_t data)
182 {
183 	/* Wait PHY to be ready and send reading register command */
184 	lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0,
185 			       LAN9250_PHY_TIMEOUT);
186 	lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_DATA, data);
187 
188 	/* Reference: Microchip Ethernet LAN9250
189 	 * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/
190 	 *
191 	 * Datasheet:
192 	 * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001913A.pdf
193 	 *
194 	 * 12.2.18 PHY REGISTERS
195 	 * The PHY registers are indirectly accessed through the Host MAC MII Access Register
196 	 * (HMAC_MII_ACC) and Host MAC MII Data Register (HMAC_MII_DATA).
197 	 *
198 	 * Write 32bit value to the indirect MAC registers
199 	 * Where phy_add = 0b00001 & index = address
200 	 * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F)<< 6) | MIIWnR
201 	 */
202 	lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC,
203 			      (1 << 11) | ((address & 0x1F) << 6) | LAN9250_HMAC_MII_ACC_MIIW_R);
204 
205 	/* Wait PHY to be ready and send reading register command */
206 	lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0,
207 			       LAN9250_PHY_TIMEOUT);
208 
209 	return 0;
210 }
211 
lan9250_set_macaddr(const struct device * dev)212 static int lan9250_set_macaddr(const struct device *dev)
213 {
214 	struct lan9250_runtime *ctx = dev->data;
215 
216 	lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRL,
217 			      ctx->mac_address[0] | (ctx->mac_address[1] << 8) |
218 			      (ctx->mac_address[2] << 16) | (ctx->mac_address[3] << 24));
219 	lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRH,
220 			      ctx->mac_address[4] | (ctx->mac_address[5] << 8));
221 
222 	return 0;
223 }
224 
lan9250_hw_cfg_check(const struct device * dev)225 static int lan9250_hw_cfg_check(const struct device *dev)
226 {
227 	uint32_t tmp;
228 
229 	do {
230 		lan9250_read_sys_reg(dev, LAN9250_HW_CFG, &tmp);
231 		k_busy_wait(USEC_PER_MSEC * 1U);
232 	} while ((tmp & LAN9250_HW_CFG_DEVICE_READY) == 0);
233 
234 	return 0;
235 }
236 
lan9250_sw_reset(const struct device * dev)237 static int lan9250_sw_reset(const struct device *dev)
238 {
239 	lan9250_write_sys_reg(dev, LAN9250_RESET_CTL,
240 			      LAN9250_RESET_CTL_HMAC_RST | LAN9250_RESET_CTL_PHY_RST |
241 			      LAN9250_RESET_CTL_DIGITAL_RST);
242 
243 	/* Wait until LAN9250 SPI bus is ready */
244 	lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, LAN9250_BYTE_TEST_DEFAULT,
245 			   LAN9250_RESET_TIMEOUT);
246 
247 	return 0;
248 }
249 
lan9250_configure(const struct device * dev)250 static int lan9250_configure(const struct device *dev)
251 {
252 	uint32_t tmp;
253 
254 	lan9250_hw_cfg_check(dev);
255 
256 	/* Read LAN9250 hardware ID */
257 	lan9250_read_sys_reg(dev, LAN9250_ID_REV, &tmp);
258 	if ((tmp & LAN9250_ID_REV_CHIP_ID) != LAN9250_ID_REV_CHIP_ID_DEFAULT) {
259 		LOG_ERR("ERROR: Bad Rev ID: %08x\n", tmp);
260 		return -ENODEV;
261 	}
262 
263 	/* Configure TX FIFO size mode to be 8:
264 	 *
265 	 *   - TX data FIFO size:   7680
266 	 *   - RX data FIFO size:   7680
267 	 *   - TX status FIFO size: 512
268 	 *   - RX status FIFO size: 512
269 	 */
270 	lan9250_write_sys_reg(dev, LAN9250_HW_CFG,
271 			      LAN9250_HW_CFG_MBO | LAN9250_HW_CFG_TX_FIF_SZ_8KB);
272 
273 	/* Configure MAC automatic flow control:
274 	 *
275 	 *  Reference: Microchip Ethernet LAN9250
276 	 *  https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/
277 	 *  LAN_Regwrite32(AFC_CFG, 0x006E3741);
278 	 *
279 	 */
280 	lan9250_write_sys_reg(dev, LAN9250_AFC_CFG, 0x006e3741);
281 
282 	/* Configure interrupt:
283 	 *
284 	 *   - Interrupt De-assertion interval: 100
285 	 *   - Interrupt output to pin
286 	 *   - Interrupt pin active output low
287 	 *   - Interrupt pin push-pull driver
288 	 */
289 	lan9250_write_sys_reg(dev, LAN9250_IRQ_CFG,
290 			      LAN9250_IRQ_CFG_INT_DEAS_100US | LAN9250_IRQ_CFG_IRQ_EN |
291 			      LAN9250_IRQ_CFG_IRQ_TYPE_PP);
292 
293 	/* Configure interrupt trigger source, please refer to macro
294 	 * LAN9250_INT_SOURCE.
295 	 */
296 	lan9250_write_sys_reg(dev, LAN9250_INT_EN,
297 			      LAN9250_INT_EN_PHY_INT_EN | LAN9250_INT_EN_RSFL_EN);
298 
299 	/* Disable TX data FIFO available interrupt */
300 	lan9250_write_sys_reg(dev, LAN9250_FIFO_INT,
301 			      LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL |
302 			      LAN9250_FIFO_INT_TX_STATUS_LEVEL);
303 
304 	/* Configure RX:
305 	 *
306 	 *   - RX DMA counter: Ethernet maximum packet size
307 	 *   - RX data offset: 4, so that need read dummy before reading data
308 	 */
309 	lan9250_write_sys_reg(dev, LAN9250_RX_CFG, 0x06000000 | 0x00000400);
310 
311 	/* Configure remote power management:
312 	 *
313 	 *   - Auto wakeup
314 	 *   - Disable 1588 clock
315 	 *   - Disable 1588 timestamp unit clock
316 	 *   - Energy-detect
317 	 *   - Wake on
318 	 *   - Clear wakeon
319 	 */
320 	lan9250_write_sys_reg(dev, LAN9250_PMT_CTRL,
321 			      LAN9250_PMT_CTRL_PM_WAKE | LAN9250_PMT_CTRL_1588_DIS |
322 			      LAN9250_PMT_CTRL_1588_TSU_DIS | LAN9250_PMT_CTRL_WOL_EN |
323 			      LAN9250_PMT_CTRL_WOL_STS);
324 
325 	/* Configure PHY basic control:
326 	 *
327 	 *   - Auto-Negotiation for 10/100 Mbits and Half/Full Duplex
328 	 */
329 	lan9250_write_phy_reg(dev, LAN9250_PHY_BASIC_CONTROL,
330 			      LAN9250_PHY_BASIC_CONTROL_PHY_AN |
331 			      LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB |
332 			      LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX);
333 
334 	/* Configure PHY auto-negotiation advertisement capability:
335 	 *
336 	 *   - Asymmetric pause
337 	 *   - Symmetric pause
338 	 *   - 100Base-X half/full duplex
339 	 *   - 10Base-X half/full duplex
340 	 *   - Select IEEE802.3
341 	 */
342 	lan9250_write_phy_reg(dev, LAN9250_PHY_AN_ADV,
343 			      LAN9250_PHY_AN_ADV_ASYM_PAUSE | LAN9250_PHY_AN_ADV_SYM_PAUSE |
344 			      LAN9250_PHY_AN_ADV_100BTX_HD | LAN9250_PHY_AN_ADV_100BTX_FD |
345 			      LAN9250_PHY_AN_ADV_10BT_HD | LAN9250_PHY_AN_ADV_10BT_FD |
346 			      LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT);
347 
348 	/* Configure PHY special mode:
349 	 *
350 	 *   - PHY mode = 111b, enable all capable and auto-nagotiation
351 	 *   - PHY address = 1, default value is fixed to 1 by manufacturer
352 	 */
353 	lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_MODES, 0x00E0 | 1);
354 
355 	/* Configure PHY special control or status indication:
356 	 *
357 	 *   - Port auto-MDIX determined by bits 14 and 13
358 	 *   - Auto-MDIX
359 	 *   - Disable SQE tests
360 	 */
361 	lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STAT_IND,
362 			      LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL |
363 			      LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN |
364 			      LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF);
365 
366 	/* Configure PHY interrupt source:
367 	 *
368 	 *   - Link up
369 	 *   - Link down
370 	 */
371 	lan9250_write_phy_reg(dev, LAN9250_PHY_INTERRUPT_MASK,
372 			      LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP |
373 			      LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN);
374 
375 	/* Configure special control or status:
376 	 *
377 	 *   - Fixed to write 0000010b to reserved filed
378 	 */
379 	lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STATUS,
380 			      LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT);
381 
382 	/* Clear interrupt status */
383 	lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF);
384 
385 	/* Configure HMAC control:
386 	 *
387 	 *   - Automatically strip the pad field on incoming packets
388 	 *   - TX enable
389 	 *   - RX enable
390 	 *   - Full duplex
391 	 *   - Promiscuous disabled
392 	 */
393 	lan9250_write_mac_reg(dev, LAN9250_HMAC_CR,
394 			      LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_TXEN | LAN9250_HMAC_CR_RXEN |
395 			      LAN9250_HMAC_CR_FDPX);
396 
397 	/* Configure TX:
398 	 *
399 	 *   - TX enable
400 	 */
401 	lan9250_write_sys_reg(dev, LAN9250_TX_CFG, LAN9250_TX_CFG_TX_ON);
402 
403 	return 0;
404 }
405 
lan9250_write_buf(const struct device * dev,uint8_t * data_buffer,uint16_t buf_len)406 static int lan9250_write_buf(const struct device *dev, uint8_t *data_buffer, uint16_t buf_len)
407 {
408 	const struct lan9250_config *config = dev->config;
409 	uint8_t cmd[1] = {LAN9250_SPI_INSTR_WRITE};
410 	uint8_t instr[2] = {(LAN9250_TX_DATA_FIFO >> 8) & 0xFF, (LAN9250_TX_DATA_FIFO & 0xFF)};
411 	struct spi_buf tx_buf[3];
412 	const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3};
413 
414 	tx_buf[0].buf = &cmd;
415 	tx_buf[0].len = ARRAY_SIZE(cmd);
416 	tx_buf[1].buf = &instr;
417 	tx_buf[1].len = ARRAY_SIZE(instr);
418 	tx_buf[2].buf = data_buffer;
419 	tx_buf[2].len = buf_len;
420 
421 	return spi_transceive_dt(&config->spi, &tx, NULL);
422 }
423 
lan9250_read_buf(const struct device * dev,uint8_t * data_buffer,uint16_t buf_len)424 static int lan9250_read_buf(const struct device *dev, uint8_t *data_buffer, uint16_t buf_len)
425 {
426 	const struct lan9250_config *config = dev->config;
427 	uint8_t cmd[1] = {LAN9250_SPI_INSTR_READ};
428 	uint8_t instr[2] = {(LAN9250_RX_DATA_FIFO >> 8) & 0xFF, (LAN9250_RX_DATA_FIFO & 0xFF)};
429 	struct spi_buf tx_buf[3];
430 	struct spi_buf rx_buf[3];
431 	const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3};
432 	const struct spi_buf_set rx = {.buffers = rx_buf, .count = 3};
433 
434 	tx_buf[0].buf = &cmd;
435 	tx_buf[0].len = ARRAY_SIZE(cmd);
436 	tx_buf[1].buf = &instr;
437 	tx_buf[1].len = ARRAY_SIZE(instr);
438 	tx_buf[2].buf = NULL;
439 	tx_buf[2].len = buf_len;
440 
441 	rx_buf[0].buf = NULL;
442 	rx_buf[0].len = 1;
443 	rx_buf[1].buf = NULL;
444 	rx_buf[1].len = 2;
445 	rx_buf[2].buf = data_buffer;
446 	rx_buf[2].len = buf_len;
447 
448 	return spi_transceive_dt(&config->spi, &tx, &rx);
449 }
450 
lan9250_rx(const struct device * dev)451 static int lan9250_rx(const struct device *dev)
452 {
453 	const struct lan9250_config *config = dev->config;
454 	struct lan9250_runtime *ctx = dev->data;
455 	const uint16_t buf_rx_size = CONFIG_NET_BUF_DATA_SIZE;
456 	struct net_pkt *pkt;
457 	struct net_buf *pkt_buf;
458 	uint16_t pkt_len;
459 	uint8_t pktcnt;
460 	uint32_t tmp;
461 
462 	/* Check valid packet count */
463 	lan9250_read_sys_reg(dev, LAN9250_RX_FIFO_INF, &tmp);
464 	pktcnt = (tmp & 0x00ff0000) >> 16;
465 
466 	/* Check packet length */
467 	lan9250_read_sys_reg(dev, LAN9250_RX_STATUS_FIFO, &tmp);
468 	pkt_len = (tmp & LAN9250_RX_STS_PACKET_LEN) >> 16;
469 
470 	if (pktcnt == 0 || pkt_len == 0) {
471 		return 0;
472 	}
473 
474 	/* Read dummy  data */
475 	lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp);
476 	pkt_len -= 4;
477 
478 	if (pkt_len > NET_ETH_MAX_FRAME_SIZE) {
479 		LOG_ERR("Maximum frame length exceeded, it should be: %d", NET_ETH_MAX_FRAME_SIZE);
480 		eth_stats_update_errors_rx(ctx->iface);
481 	}
482 
483 	/* Get the frame from the buffer */
484 	pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_len, AF_UNSPEC, 0,
485 					   K_MSEC(config->timeout));
486 	if (!pkt) {
487 		LOG_ERR("%s: Could not allocate rx buffer", dev->name);
488 		eth_stats_update_errors_rx(ctx->iface);
489 		return 0;
490 	}
491 
492 	pkt_buf = pkt->buffer;
493 
494 	do {
495 		uint8_t *data_ptr = pkt_buf->data;
496 		uint16_t data_len;
497 
498 		if (pkt_len > buf_rx_size) {
499 			data_len = buf_rx_size;
500 		} else {
501 			data_len = pkt_len;
502 		}
503 		pkt_len -= data_len;
504 
505 		lan9250_read_buf(dev, data_ptr, data_len);
506 		net_buf_add(pkt_buf, data_len);
507 		pkt_buf = pkt_buf->frags;
508 	} while (pkt_len > 0);
509 
510 	lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp);
511 	net_pkt_set_iface(pkt, ctx->iface);
512 
513 	/* Feed buffer frame to IP stack */
514 	if (net_recv_data(net_pkt_iface(pkt), pkt) < 0) {
515 		net_pkt_unref(pkt);
516 	}
517 
518 	k_sem_give(&ctx->tx_rx_sem);
519 
520 	return 0;
521 }
522 
lan9250_tx(const struct device * dev,struct net_pkt * pkt)523 static int lan9250_tx(const struct device *dev, struct net_pkt *pkt)
524 {
525 	struct lan9250_runtime *ctx = dev->data;
526 	size_t len = net_pkt_get_len(pkt);
527 	uint32_t regval;
528 	uint16_t free_size;
529 	uint8_t status_size;
530 	uint32_t tmp;
531 
532 	lan9250_read_sys_reg(dev, LAN9250_TX_FIFO_INF, &regval);
533 	status_size = (regval & LAN9250_TX_FIFO_INF_TXSUSED) >> 16;
534 	free_size = regval & LAN9250_TX_FIFO_INF_TXFREE;
535 
536 	k_sem_take(&ctx->tx_rx_sem, K_FOREVER);
537 
538 	/* TX command 'A' */
539 	lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO,
540 			      LAN9250_TX_CMD_A_INT_ON_COMP | LAN9250_TX_CMD_A_BUFFER_ALIGN_4B |
541 			      LAN9250_TX_CMD_A_START_OFFSET_0B |
542 			      LAN9250_TX_CMD_A_FIRST_SEG | LAN9250_TX_CMD_A_LAST_SEG | len);
543 
544 	/* TX command 'B' */
545 	lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, LAN9250_TX_CMD_B_PACKET_TAG | len);
546 
547 	if (net_pkt_read(pkt, ctx->buf, len)) {
548 		return -EIO;
549 	}
550 
551 	lan9250_write_buf(dev, ctx->buf, LAN9250_ALIGN(len));
552 
553 	for (int i = 0; i < status_size; i++) {
554 		lan9250_read_sys_reg(dev, LAN9250_TX_STATUS_FIFO, &tmp);
555 	}
556 
557 	k_sem_give(&ctx->tx_rx_sem);
558 
559 	return 0;
560 }
561 
lan9250_gpio_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)562 static void lan9250_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
563 {
564 	struct lan9250_runtime *context = CONTAINER_OF(cb, struct lan9250_runtime, gpio_cb);
565 
566 	k_sem_give(&context->int_sem);
567 }
568 
lan9250_thread(void * p1,void * p2,void * p3)569 static void lan9250_thread(void *p1, void *p2, void *p3)
570 {
571 	ARG_UNUSED(p2);
572 	ARG_UNUSED(p3);
573 
574 	struct lan9250_runtime *context = p1;
575 	uint32_t int_sts;
576 	uint16_t tmp;
577 	uint32_t ier;
578 
579 	while (true) {
580 		k_sem_take(&context->int_sem, K_FOREVER);
581 
582 		/* Save interrupt enable register value */
583 		lan9250_read_sys_reg(context->dev, LAN9250_INT_EN, &ier);
584 
585 		/* Disable interrupts to release the interrupt line */
586 		lan9250_write_sys_reg(context->dev, LAN9250_INT_EN, 0);
587 
588 		/* Read interrupt status register */
589 		lan9250_read_sys_reg(context->dev, LAN9250_INT_STS, &int_sts);
590 
591 		if ((int_sts & LAN9250_INT_STS_PHY_INT) != 0) {
592 
593 			/* Read PHY interrupt source register */
594 			lan9250_read_phy_reg(context->dev, LAN9250_PHY_INTERRUPT_SOURCE, &tmp);
595 			if (tmp & LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP) {
596 				LOG_DBG("LINK UP");
597 				net_eth_carrier_on(context->iface);
598 			} else if (tmp & LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN) {
599 				LOG_DBG("LINK DOWN");
600 				net_eth_carrier_off(context->iface);
601 			}
602 		}
603 
604 		if ((int_sts & LAN9250_INT_STS_RSFL) != 0) {
605 			lan9250_write_sys_reg(context->dev, LAN9250_INT_STS, LAN9250_INT_STS_RSFL);
606 			lan9250_rx(context->dev);
607 		}
608 
609 		/* Re-enable interrupts */
610 		lan9250_write_sys_reg(context->dev, LAN9250_INT_EN, ier);
611 	}
612 }
613 
lan9250_get_capabilities(const struct device * dev)614 static enum ethernet_hw_caps lan9250_get_capabilities(const struct device *dev)
615 {
616 	ARG_UNUSED(dev);
617 
618 	return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T;
619 }
620 
lan9250_iface_init(struct net_if * iface)621 static void lan9250_iface_init(struct net_if *iface)
622 {
623 	const struct device *dev = net_if_get_device(iface);
624 	struct lan9250_runtime *context = dev->data;
625 
626 	net_if_set_link_addr(iface, context->mac_address, sizeof(context->mac_address),
627 			     NET_LINK_ETHERNET);
628 	context->iface = iface;
629 	ethernet_init(iface);
630 
631 	net_if_carrier_off(iface);
632 }
633 
lan9250_set_config(const struct device * dev,enum ethernet_config_type type,const struct ethernet_config * config)634 static int lan9250_set_config(const struct device *dev, enum ethernet_config_type type,
635 			      const struct ethernet_config *config)
636 {
637 	struct lan9250_runtime *ctx = dev->data;
638 
639 	if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) {
640 		memcpy(ctx->mac_address, config->mac_address.addr, sizeof(ctx->mac_address));
641 		lan9250_set_macaddr(dev);
642 		return net_if_set_link_addr(ctx->iface, ctx->mac_address, sizeof(ctx->mac_address),
643 					    NET_LINK_ETHERNET);
644 	}
645 
646 	return -ENOTSUP;
647 }
648 
649 static const struct ethernet_api api_funcs = {
650 	.iface_api.init = lan9250_iface_init,
651 	.get_capabilities = lan9250_get_capabilities,
652 	.set_config = lan9250_set_config,
653 	.send = lan9250_tx,
654 };
655 
lan9250_init(const struct device * dev)656 static int lan9250_init(const struct device *dev)
657 {
658 	const struct lan9250_config *config = dev->config;
659 	struct lan9250_runtime *context = dev->data;
660 
661 	context->dev = dev;
662 
663 	/* SPI config */
664 	if (!spi_is_ready_dt(&config->spi)) {
665 		LOG_ERR("SPI master port %s not ready", config->spi.bus->name);
666 		return -EINVAL;
667 	}
668 
669 	/* Initialize GPIO */
670 	if (!gpio_is_ready_dt(&config->interrupt)) {
671 		LOG_ERR("GPIO port %s not ready", config->interrupt.port->name);
672 		return -EINVAL;
673 	}
674 
675 	if (gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT)) {
676 		LOG_ERR("Unable to configure GPIO pin %u", config->interrupt.pin);
677 		return -EINVAL;
678 	}
679 
680 	gpio_init_callback(&(context->gpio_cb), lan9250_gpio_callback, BIT(config->interrupt.pin));
681 	if (gpio_add_callback(config->interrupt.port, &(context->gpio_cb))) {
682 		return -EINVAL;
683 	}
684 
685 	gpio_pin_interrupt_configure_dt(&config->interrupt, GPIO_INT_EDGE_TO_ACTIVE);
686 
687 	/* Wait until LAN9250 SPI bus is ready */
688 	lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, LAN9250_BYTE_TEST_DEFAULT,
689 			   LAN9250_RESET_TIMEOUT);
690 	lan9250_sw_reset(dev);
691 	lan9250_configure(dev);
692 	lan9250_set_macaddr(dev);
693 
694 	k_thread_create(&context->thread, context->thread_stack,
695 			CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE, lan9250_thread, context, NULL,
696 			NULL, K_PRIO_COOP(CONFIG_ETH_LAN9250_RX_THREAD_PRIO), 0, K_NO_WAIT);
697 
698 	LOG_INF("LAN9250 Initialized");
699 
700 	return 0;
701 }
702 
703 #define LAN9250_DEFINE(inst)                                                                       \
704 	static struct lan9250_runtime lan9250_##inst##_runtime = {                                 \
705 		.mac_address = DT_INST_PROP(inst, local_mac_address),                              \
706 		.tx_rx_sem = Z_SEM_INITIALIZER(lan9250_##inst##_runtime.tx_rx_sem, 1, UINT_MAX),   \
707 		.int_sem = Z_SEM_INITIALIZER(lan9250_##inst##_runtime.int_sem, 0, UINT_MAX),       \
708 	};                                                                                         \
709                                                                                                    \
710 	static const struct lan9250_config lan9250_##inst##_config = {                             \
711 		.spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0),                             \
712 		.interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios),                               \
713 		.timeout = CONFIG_ETH_LAN9250_BUF_ALLOC_TIMEOUT,                                   \
714 	};                                                                                         \
715                                                                                                    \
716 	ETH_NET_DEVICE_DT_INST_DEFINE(inst, lan9250_init, NULL, &lan9250_##inst##_runtime,         \
717 				      &lan9250_##inst##_config, CONFIG_ETH_INIT_PRIORITY,          \
718 				      &api_funcs, NET_ETH_MTU);
719 DT_INST_FOREACH_STATUS_OKAY(LAN9250_DEFINE);
720