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, ®val);
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