1 /*
2 * Copyright (c) 2016-2019 Arm Limited
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "lan9118_eth_drv.h"
19 #include "los_debug.h"
20
21 #if LWIP_IPV6
22 #include "lwip/ethip6.h"
23 #endif
24
25 #define DSB __DSB()
26
27 #define LAN9118_NETIF_NAME "lan9118"
28 #define LAN9118_NETIF_NICK "eth0"
29 #define LAN9118_NETIF_TEST_IP "10.0.2.15"
30 #define LAN9118_NETIF_TEST_GW "10.0.2.2"
31 #define LAN9118_NETIF_TEST_MASK "255.255.255.0"
32
33 #define LAN9118_ETH_MAX_FRAME_SIZE 1522U
34 #define LAN9118_BUFF_ALIGNMENT 4U
35 #define UINT32_MAX ((uint32_t)-1)
36 #define SLEEP_TIME_MS 60
37 #define NETIF_SETUP_OVERTIME 100
38
39 static struct netif g_NetIf;
40 static const struct lan9118_eth_dev_cfg_t LAN9118_ETH_DEV_CFG = {.base = LAN9118_BASE};
41 static struct lan9118_eth_dev_data_t LAN9118_ETH_DEV_DATA = {.state = 0};
42 struct lan9118_eth_dev_t LAN9118_ETH_DEV = {&(LAN9118_ETH_DEV_CFG), &(LAN9118_ETH_DEV_DATA)};
43 struct lan9118_eth_dev_t* g_dev = &LAN9118_ETH_DEV;
44
45 extern void tcpip_init(tcpip_init_done_fn initfunc, void* arg);
46
47 /** Setter bit manipulation macro */
48 #define SET_BIT(WORD, BIT_INDEX) \
49 ({ \
50 DSB; \
51 ((WORD)) |= ((1U) << (BIT_INDEX)); \
52 })
53
54 /** Clearing bit manipulation macro */
55 #define CLR_BIT(WORD, BIT_INDEX) \
56 ({ \
57 DSB; \
58 (WORD) &= ~((1U) << (BIT_INDEX)); \
59 })
60
61 /** Getter bit manipulation macro */
62 #define GET_BIT(WORD, BIT_INDEX) \
63 ({ \
64 UINT32 r = (bool)(((WORD) & ((1U) << (BIT_INDEX)))); \
65 DSB; \
66 r; \
67 })
68
69 /** Setter bit-field manipulation macro */
70 #define SET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET, VALUE) \
71 ({ \
72 DSB; \
73 ((WORD) |= (((VALUE) & (BIT_MASK)) << (BIT_OFFSET))); \
74 })
75
76 /** Clearing bit-field manipulation macro */
77 #define CLR_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET, VALUE) \
78 ({ \
79 DSB; \
80 ((WORD) &= ~(((VALUE) & (BIT_MASK)) << (BIT_OFFSET))); \
81 })
82
83 /** Getter bit-field manipulation macro */
84 #define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) \
85 ({ \
86 UINT32 r = (WORD); \
87 DSB; \
88 r = (((r) >> (BIT_OFFSET)) & (BIT_MASK)); \
89 r; \
90 })
91
92 /** Millisec timeout macros */
93 #define RESET_TIME_OUT_MS 10U
94 #define REG_WRITE_TIME_OUT_MS 50U
95 #define PHY_RESET_TIME_OUT_MS 100U
96 #define INIT_FINISH_DELAY 2000U
97
98 struct lan9118_eth_reg_map_t {
99 uint32_t rx_data_port; /**< Receive FIFO Ports (offset 0x0) */
100 uint32_t reserved1[0x7];
101 uint32_t tx_data_port; /**< Transmit FIFO Ports (offset 0x20) */
102 uint32_t reserved2[0x7];
103
104 uint32_t rx_status_port; /**< Receive FIFO status port (offset 0x40) */
105 uint32_t rx_status_peek; /**< Receive FIFO status peek (offset 0x44) */
106 uint32_t tx_status_port; /**< Transmit FIFO status port (offset 0x48) */
107 uint32_t tx_status_peek; /**< Transmit FIFO status peek (offset 0x4C) */
108
109 uint32_t id_revision; /**< Chip ID and Revision (offset 0x50) */
110 uint32_t irq_cfg; /**< Main Interrupt Config (offset 0x54) */
111 uint32_t irq_status; /**< Interrupt Status (offset 0x58) */
112 uint32_t irq_enable; /**< Interrupt Enable Register (offset 0x5C) */
113 uint32_t reserved3; /**< Reserved for future use (offset 0x60) */
114 uint32_t byte_test; /**< Byte order test 87654321h (offset 0x64) */
115 uint32_t fifo_level_irq; /**< FIFO Level Interrupts (offset 0x68) */
116 uint32_t rx_cfg; /**< Receive Configuration (offset 0x6C) */
117 uint32_t tx_cfg; /**< Transmit Configuration (offset 0x70) */
118 uint32_t hw_cfg; /**< Hardware Configuration (offset 0x74) */
119 uint32_t rx_datapath_ctrl; /**< RX Datapath Control (offset 0x78) */
120 uint32_t rx_fifo_inf; /**< Receive FIFO Information (offset 0x7C) */
121 uint32_t tx_fifo_inf; /**< Transmit FIFO Information (offset 0x80) */
122 uint32_t pmt_ctrl; /**< Power Management Control (offset 0x84) */
123 uint32_t gpio_cfg; /**< GPIO Configuration (offset 0x88) */
124 uint32_t gptimer_cfg; /**< GP Timer Configuration (offset 0x8C) */
125 uint32_t gptimer_count; /**< GP Timer Count (offset 0x90) */
126 uint32_t reserved4; /**< Reserved for future use (offset 0x94) */
127 uint32_t word_swap; /**< WORD SWAP Register (offset 0x98) */
128 uint32_t free_run_counter; /**< Free Run Counter (offset 0x9C) */
129 uint32_t rx_dropped_frames; /**< RX Dropped Frames Counter (offset 0xA0) */
130 uint32_t mac_csr_cmd; /**< MAC CSR Synchronizer Cmd (offset 0xA4) */
131 uint32_t mac_csr_data; /**< MAC CSR Synchronizer Data (offset 0xA8) */
132 uint32_t afc_cfg; /**< AutomaticFlow Ctrl Config (offset 0xAC) */
133 uint32_t eeprom_cmd; /**< EEPROM Command (offset 0xB0) */
134 uint32_t eeprom_data; /**< EEPROM Data (offset 0xB4) */
135 };
136
137 /**
138 * \brief FIFO Info definitions
139 *
140 */
141 #define FIFO_USED_SPACE_MASK 0xFFFFU
142 #define DATA_FIFO_USED_SPACE_POS 0U
143
144 /**
145 * \brief MAC CSR Synchronizer Command bit definitions
146 *
147 */
148 enum mac_csr_cmd_bits_t {
149 MAC_CSR_CMD_RW_INDEX = 30U,
150 MAC_CSR_CMD_BUSY_INDEX = 31U,
151 };
152
153 #define MAC_CSR_CMD_ADDRESS_MASK 0x0FU
154
155 /**
156 * \brief MAC Control register bit definitions
157 *
158 */
159 enum mac_reg_cr_bits_t { MAC_REG_CR_RXEN_INDEX = 2U, MAC_REG_CR_TXEN_INDEX = 3U };
160
161 /**
162 * \brief MII Access register bit definitions
163 *
164 */
165 enum mac_reg_mii_acc_bits_t {
166 MAC_REG_MII_ACC_BUSY_INDEX = 0U,
167 MAC_REG_MII_ACC_WRITE_INDEX = 1U,
168 MAC_REG_MII_ACC_PHYADDR_INDEX = 11U
169 };
170 #define MAC_REG_MII_ACC_MII_REG_MASK 0x1FU
171 #define MAC_REG_MII_ACC_MII_REG_OFFSET 6U
172
173 /**
174 * \brief Hardware config register bit definitions
175 *
176 */
177 enum hw_cfg_reg_bits_t {
178 HW_CFG_REG_SRST_INDEX = 0U,
179 HW_CFG_REG_SRST_TIMEOUT_INDEX = 1U,
180 HW_CFG_REG_MUST_BE_ONE_INDEX = 20U,
181 };
182 #define HW_CFG_REG_TX_FIFO_SIZE_POS 16U
183 #define HW_CFG_REG_TX_FIFO_SIZE_MIN 2U /*< Min Tx fifo size in KB */
184 #define HW_CFG_REG_TX_FIFO_SIZE_MAX 14U /*< Max Tx fifo size in KB */
185 #define HW_CFG_REG_TX_FIFO_SIZE 5U /*< Tx fifo size in KB */
186
187 /**
188 * \brief EEPROM command register bit definitions
189 *
190 */
191 enum eeprom_cmd_reg_bits_t {
192 EEPROM_CMD_REG_BUSY_INDEX = 31U,
193 };
194
195 /**
196 * \brief PHY Basic Control register bit definitions
197 *
198 */
199 enum phy_reg_bctrl_reg_bits_t {
200 PHY_REG_BCTRL_RST_AUTO_NEG_INDEX = 9U,
201 PHY_REG_BCTRL_AUTO_NEG_EN_INDEX = 12U,
202 PHY_REG_BCTRL_RESET_INDEX = 15U
203 };
204
205 /**
206 * \brief TX Command A bit definitions
207 *
208 */
209 #define TX_CMD_DATA_START_OFFSET_BYTES_POS 16U
210 #define TX_CMD_DATA_START_OFFSET_BYTES_MASK 0x1FU
211
212 enum tx_command_a_bits_t { TX_COMMAND_A_LAST_SEGMENT_INDEX = 12U, TX_COMMAND_A_FIRST_SEGMENT_INDEX = 13U };
213
214 #define TX_CMD_PKT_LEN_BYTES_MASK 0x7FFU
215 #define TX_CMD_PKT_TAG_MASK 0xFFFFU
216 #define TX_CMD_PKT_TAG_POS 16U
217
218 #define RX_FIFO_STATUS_PKT_LENGTH_POS 16U
219 #define RX_FIFO_STATUS_PKT_LENGTH_MASK 0x3FFFU
220
221 /**
222 * \brief Interrupt Configuration register bit definitions
223 *
224 */
225 enum irq_cfg_bits_t { IRQ_CFG_IRQ_EN_INDEX = 8U };
226
227 #define AFC_BACK_DUR_MASK 0x0FU
228 #define AFC_BACK_DUR_POS 4U
229 #define AFC_BACK_DUR 4U /**< equal to 50us */
230
231 #define AFC_LOW_LEVEL_MASK 0xFFU
232 #define AFC_LOW_LEVEL_POS 8U
233 #define AFC_LOW_LEVEL 55U /**< specifies in multiple of 64 bytes */
234
235 #define AFC_HIGH_LEVEL_MASK 0xFFU
236 #define AFC_HIGH_LEVEL_POS 16U
237 #define AFC_HIGH_LEVEL 110U /**< specifies in multiple of 64 bytes */
238
239 #define BYTE_LEN 4
240 /**
241 * \brief Auto-Negotiation Advertisement register bit definitions
242 *
243 */
244 enum aneg_bits_t {
245 ANEG_10_BASE_T_INDEX = 5U, /**< 10Mbps able */
246 ANEG_10_BASE_T_FULL_DUPL_INDEX = 6U, /**< 10Mbps with full duplex */
247 ANEG_100_BASE_TX_INDEX = 7U, /**< 100Mbps Tx able */
248 ANEG_100_BASE_TX_FULL_DUPL_INDEX = 8U, /**< 100Mbps with full duplex */
249 ANEG_SYMM_PAUSE_INDEX = 10U, /**< Symmetric Pause */
250 ANEG_ASYMM_PAUSE_INDEX = 11U /**< Asymmetric Pause */
251 };
252
253 /**
254 * \brief Transmit Configuration register bit definitions
255 *
256 */
257 enum tx_cfg_bits_t {
258 TX_CFG_STOP_INDEX = 0U, /*< stop */
259 TX_CFG_ON_INDEX = 1U, /*< on */
260 TX_CFG_AO_INDEX = 2U, /*< allow overrun */
261 TX_CFG_TXD_DUMP_INDEX = 14U, /*< Data FIFO dump */
262 TX_CFG_TXS_DUMP_INDEX = 15U /*< Status FIFO dump */
263 };
264
265 /**
266 * \brief Chip ID definitions
267 *
268 */
269 #define CHIP_ID 0x1180001
270
271 /**
272 * Helper struct to hold private data used to operate your ethernet interface.
273 * Keeping the ethernet address of the MAC in this struct is not necessary
274 * as it is already kept in the struct netif.
275 */
276 struct EtherNetif {
277 struct eth_addr* ethaddr;
278 };
279
DelayMs(uint32_t ms)280 static void DelayMs(uint32_t ms)
281 {
282 uint32_t delayMs = 1000;
283 delayMs = delayMs * ms;
284 usleep(delayMs);
285 }
286
GetPayloadAddr(const struct pbuf * buf)287 static void* GetPayloadAddr(const struct pbuf* buf)
288 {
289 return buf->payload;
290 }
291
SetTotalLen(struct pbuf * pbuf)292 static void SetTotalLen(struct pbuf* pbuf)
293 {
294 if (!pbuf->next) {
295 pbuf->tot_len = pbuf->len;
296 return;
297 }
298
299 uint32_t total_len;
300 struct pbuf* pbuf_tailing;
301
302 while (pbuf) {
303 total_len = pbuf->len;
304
305 pbuf_tailing = pbuf->next;
306 while (pbuf_tailing) {
307 total_len += pbuf_tailing->len;
308 pbuf_tailing = pbuf_tailing->next;
309 }
310
311 pbuf->tot_len = total_len;
312 pbuf = pbuf->next;
313 }
314 }
315
AlignMemory(struct pbuf * pbuf,uint32_t const align)316 static void AlignMemory(struct pbuf* pbuf, uint32_t const align)
317 {
318 if (!align) {
319 return;
320 }
321
322 struct pbuf* pbuf_start = pbuf;
323
324 while (pbuf) {
325 uint32_t remainder = ((uint32_t)pbuf->payload) % align;
326 if (remainder) {
327 uint32_t offset = align - remainder;
328 if (offset >= align) {
329 offset = align;
330 }
331 pbuf->payload = ((char*)pbuf->payload) + offset;
332 }
333 pbuf->len -= align;
334 pbuf = pbuf->next;
335 }
336
337 // Correct total lengths
338 SetTotalLen(pbuf_start);
339 }
340
AllocHeap(const uint32_t size,uint32_t const align)341 static struct pbuf* AllocHeap(const uint32_t size, uint32_t const align)
342 {
343 struct pbuf* pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
344 if (pbuf == NULL) {
345 return NULL;
346 }
347
348 AlignMemory(pbuf, align);
349
350 return pbuf;
351 }
352
SetLen(const struct pbuf * buf,const uint32_t len)353 static void SetLen(const struct pbuf* buf, const uint32_t len)
354 {
355 struct pbuf* pbuf = buf;
356 pbuf->len = len;
357 SetTotalLen(pbuf);
358 }
359
GetLen(const struct pbuf * buf)360 static uint32_t GetLen(const struct pbuf* buf)
361 {
362 return buf->len;
363 }
364
GetTotalLen(const struct pbuf * buf)365 static uint32_t GetTotalLen(const struct pbuf* buf)
366 {
367 return buf->tot_len;
368 }
369
fill_tx_fifo(const struct lan9118_eth_dev_t * dev,uint8_t * data,uint32_t size_bytes)370 static void fill_tx_fifo(const struct lan9118_eth_dev_t* dev, uint8_t* data, uint32_t size_bytes)
371 {
372 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
373
374 uint32_t tx_data_port_tmp = 0;
375 uint8_t* tx_data_port_tmp_ptr = (uint8_t*)&tx_data_port_tmp;
376
377 #ifdef ETH_PAD_SIZE
378 data += ETH_PAD_SIZE;
379 #endif
380
381 uint32_t remainder_bytes = (size_bytes % 4);
382
383 if (remainder_bytes > 0) {
384 uint32_t filler_bytes = (4 - remainder_bytes);
385
386 for (uint32_t i = 0; i < 4; i++) {
387 if (i < filler_bytes) {
388 tx_data_port_tmp_ptr[i] = 0;
389 } else {
390 tx_data_port_tmp_ptr[i] = data[i - filler_bytes];
391 }
392 }
393
394 SET_BIT_FIELD(register_map->tx_data_port, 0xFFFFFFFF, 0, tx_data_port_tmp);
395
396 size_bytes -= remainder_bytes;
397 data += remainder_bytes;
398 }
399
400 while (size_bytes > 0) {
401 /* Keep the same endianness in data as in the temp variable */
402 tx_data_port_tmp_ptr[0] = data[0];
403 tx_data_port_tmp_ptr[1] = data[1];
404 tx_data_port_tmp_ptr[2] = data[2];
405 tx_data_port_tmp_ptr[3] = data[3];
406
407 SET_BIT_FIELD(register_map->tx_data_port, 0xFFFFFFFF, 0, tx_data_port_tmp);
408
409 data += BYTE_LEN;
410 size_bytes -= BYTE_LEN;
411 }
412 }
413
empty_rx_fifo(const struct lan9118_eth_dev_t * dev,uint8_t * data,uint32_t size_bytes)414 static void empty_rx_fifo(const struct lan9118_eth_dev_t* dev, uint8_t* data, uint32_t size_bytes)
415 {
416 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
417
418 uint32_t rx_data_port_tmp = 0;
419 uint8_t* rx_data_port_tmp_ptr = (uint8_t*)&rx_data_port_tmp;
420
421 #ifdef ETH_PAD_SIZE
422 data += ETH_PAD_SIZE;
423 #endif
424
425 uint32_t remainder_bytes = (size_bytes % 4);
426 size_bytes -= remainder_bytes;
427
428 while (size_bytes > 0) {
429 /* Keep the same endianness in data as in the temp variable */
430 rx_data_port_tmp = GET_BIT_FIELD(register_map->rx_data_port, 0xFFFFFFFF, 0);
431
432 data[0] = rx_data_port_tmp_ptr[0];
433 data[1] = rx_data_port_tmp_ptr[1];
434 data[2] = rx_data_port_tmp_ptr[2];
435 data[3] = rx_data_port_tmp_ptr[3];
436
437 data += BYTE_LEN;
438 size_bytes -= BYTE_LEN;
439 }
440
441 if (remainder_bytes > 0) {
442 rx_data_port_tmp = GET_BIT_FIELD(register_map->rx_data_port, 0xFFFFFFFF, 0);
443
444 for (uint32_t i = 0; i < remainder_bytes; i++) {
445 data[i] = rx_data_port_tmp_ptr[i];
446 }
447 }
448 }
449
lan9118_mac_regread(const struct lan9118_eth_dev_t * dev,enum lan9118_mac_reg_offsets_t regoffset,uint32_t * data)450 enum lan9118_error_t lan9118_mac_regread(const struct lan9118_eth_dev_t* dev, enum lan9118_mac_reg_offsets_t regoffset,
451 uint32_t* data)
452 {
453 volatile uint32_t val;
454 uint32_t maccmd = GET_BIT_FIELD(regoffset, MAC_CSR_CMD_ADDRESS_MASK, 0);
455 uint32_t time_out = REG_WRITE_TIME_OUT_MS;
456
457 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
458
459 /* Make sure there's no pending operation */
460 if (!(GET_BIT(register_map->mac_csr_cmd, MAC_CSR_CMD_BUSY_INDEX))) {
461 SET_BIT(maccmd, MAC_CSR_CMD_RW_INDEX);
462 SET_BIT(maccmd, MAC_CSR_CMD_BUSY_INDEX);
463 register_map->mac_csr_cmd = maccmd; /* Start operation */
464
465 do {
466 val = register_map->byte_test; /* A no-op read. */
467 (void)val;
468 if (dev->data->wait_ms) {
469 dev->data->wait_ms(1);
470 }
471 time_out--;
472 } while (time_out && GET_BIT(register_map->mac_csr_cmd, MAC_CSR_CMD_BUSY_INDEX));
473
474 if (!time_out) {
475 return LAN9118_ERROR_TIMEOUT;
476 } else {
477 *data = register_map->mac_csr_data;
478 }
479 } else {
480 return LAN9118_ERROR_BUSY;
481 }
482 return LAN9118_ERROR_NONE;
483 }
484
lan9118_mac_regwrite(const struct lan9118_eth_dev_t * dev,enum lan9118_mac_reg_offsets_t regoffset,uint32_t data)485 enum lan9118_error_t lan9118_mac_regwrite(const struct lan9118_eth_dev_t* dev, enum lan9118_mac_reg_offsets_t regoffset,
486 uint32_t data)
487 {
488 volatile uint32_t read = 0;
489 uint32_t maccmd = GET_BIT_FIELD(regoffset, MAC_CSR_CMD_ADDRESS_MASK, 0);
490 uint32_t time_out = REG_WRITE_TIME_OUT_MS;
491
492 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
493
494 /* Make sure there's no pending operation */
495 if (!GET_BIT(register_map->mac_csr_cmd, MAC_CSR_CMD_BUSY_INDEX)) {
496 register_map->mac_csr_data = data; /* Store data. */
497
498 CLR_BIT(maccmd, MAC_CSR_CMD_RW_INDEX);
499 SET_BIT(maccmd, MAC_CSR_CMD_BUSY_INDEX);
500
501 register_map->mac_csr_cmd = maccmd;
502
503 do {
504 read = register_map->byte_test; /* A no-op read. */
505 (void)read;
506 if (dev->data->wait_ms) {
507 dev->data->wait_ms(1);
508 }
509 time_out--;
510 } while (time_out && (register_map->mac_csr_cmd & GET_BIT(register_map->mac_csr_cmd, MAC_CSR_CMD_BUSY_INDEX)));
511 if (!time_out) {
512 return LAN9118_ERROR_TIMEOUT;
513 }
514 } else {
515 return LAN9118_ERROR_BUSY;
516 }
517 return LAN9118_ERROR_NONE;
518 }
519
lan9118_phy_regread(const struct lan9118_eth_dev_t * dev,enum phy_reg_offsets_t regoffset,uint32_t * data)520 enum lan9118_error_t lan9118_phy_regread(const struct lan9118_eth_dev_t* dev, enum phy_reg_offsets_t regoffset,
521 uint32_t* data)
522 {
523 uint32_t val = 0;
524 uint32_t phycmd = 0;
525 uint32_t time_out = REG_WRITE_TIME_OUT_MS;
526
527 if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_MII_ACC, &val)) {
528 return LAN9118_ERROR_INTERNAL;
529 }
530
531 if (!GET_BIT(val, MAC_REG_MII_ACC_BUSY_INDEX)) {
532 phycmd = 0;
533 SET_BIT(phycmd, MAC_REG_MII_ACC_PHYADDR_INDEX);
534 SET_BIT_FIELD(phycmd, MAC_REG_MII_ACC_MII_REG_MASK, MAC_REG_MII_ACC_MII_REG_OFFSET, regoffset);
535 CLR_BIT(phycmd, MAC_REG_MII_ACC_WRITE_INDEX);
536 SET_BIT(phycmd, MAC_REG_MII_ACC_BUSY_INDEX);
537
538 if (lan9118_mac_regwrite(dev, LAN9118_MAC_REG_OFFSET_MII_ACC, phycmd)) {
539 return LAN9118_ERROR_INTERNAL;
540 }
541
542 val = 0;
543 do {
544 if (dev->data->wait_ms) {
545 dev->data->wait_ms(1);
546 }
547 time_out--;
548 if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_MII_ACC, &val)) {
549 return LAN9118_ERROR_INTERNAL;
550 }
551 } while (time_out && (GET_BIT(val, MAC_REG_MII_ACC_BUSY_INDEX)));
552
553 if (!time_out) {
554 return LAN9118_ERROR_TIMEOUT;
555 } else if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_MII_DATA, data)) {
556 return LAN9118_ERROR_INTERNAL;
557 }
558 } else {
559 return LAN9118_ERROR_BUSY;
560 }
561 return LAN9118_ERROR_NONE;
562 }
563
lan9118_phy_regwrite(const struct lan9118_eth_dev_t * dev,enum phy_reg_offsets_t regoffset,uint32_t data)564 enum lan9118_error_t lan9118_phy_regwrite(const struct lan9118_eth_dev_t* dev, enum phy_reg_offsets_t regoffset,
565 uint32_t data)
566 {
567 uint32_t val = 0;
568 uint32_t phycmd = 0;
569 uint32_t time_out = REG_WRITE_TIME_OUT_MS;
570
571 if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_MII_ACC, &val)) {
572 return LAN9118_ERROR_INTERNAL;
573 }
574
575 if (!GET_BIT(val, MAC_REG_MII_ACC_BUSY_INDEX)) {
576 /* Load the data */
577 if (lan9118_mac_regwrite(dev, LAN9118_MAC_REG_OFFSET_MII_DATA, (data & 0xFFFF))) {
578 return LAN9118_ERROR_INTERNAL;
579 }
580 phycmd = 0;
581 SET_BIT(phycmd, MAC_REG_MII_ACC_PHYADDR_INDEX);
582 SET_BIT_FIELD(phycmd, MAC_REG_MII_ACC_MII_REG_MASK, MAC_REG_MII_ACC_MII_REG_OFFSET, regoffset);
583 SET_BIT(phycmd, MAC_REG_MII_ACC_WRITE_INDEX);
584 SET_BIT(phycmd, MAC_REG_MII_ACC_BUSY_INDEX);
585 /* Start operation */
586 if (lan9118_mac_regwrite(dev, LAN9118_MAC_REG_OFFSET_MII_ACC, phycmd)) {
587 return LAN9118_ERROR_INTERNAL;
588 }
589
590 phycmd = 0;
591
592 do {
593 if (dev->data->wait_ms) {
594 dev->data->wait_ms(1);
595 }
596 time_out--;
597 if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_MII_ACC, &phycmd)) {
598 return LAN9118_ERROR_INTERNAL;
599 }
600 } while (time_out && GET_BIT(phycmd, 0));
601
602 if (!time_out) {
603 return LAN9118_ERROR_TIMEOUT;
604 }
605
606 } else {
607 return LAN9118_ERROR_BUSY;
608 }
609 return LAN9118_ERROR_NONE;
610 }
611
lan9118_read_id(const struct lan9118_eth_dev_t * dev)612 uint32_t lan9118_read_id(const struct lan9118_eth_dev_t* dev)
613 {
614 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
615
616 uint32_t lan9118Id = 0;
617
618 lan9118Id = register_map->id_revision;
619
620 return lan9118Id;
621 }
622
lan9118_soft_reset(const struct lan9118_eth_dev_t * dev)623 enum lan9118_error_t lan9118_soft_reset(const struct lan9118_eth_dev_t* dev)
624 {
625 uint32_t time_out = RESET_TIME_OUT_MS;
626
627 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
628
629 /* Soft reset */
630 SET_BIT(register_map->hw_cfg, HW_CFG_REG_SRST_INDEX);
631
632 do {
633 if (dev->data->wait_ms) {
634 dev->data->wait_ms(1);
635 }
636 time_out--;
637 } while (time_out && GET_BIT(register_map->hw_cfg, HW_CFG_REG_SRST_TIMEOUT_INDEX));
638
639 if (!time_out) {
640 return LAN9118_ERROR_TIMEOUT;
641 }
642
643 return LAN9118_ERROR_NONE;
644 }
645
lan9118_set_txfifo(const struct lan9118_eth_dev_t * dev,uint32_t val)646 void lan9118_set_txfifo(const struct lan9118_eth_dev_t* dev, uint32_t val)
647 {
648 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
649
650 if (val >= HW_CFG_REG_TX_FIFO_SIZE_MIN && val <= HW_CFG_REG_TX_FIFO_SIZE_MAX) {
651 register_map->hw_cfg = val << HW_CFG_REG_TX_FIFO_SIZE_POS;
652 }
653 }
654
lan9118_set_fifo_level_irq(const struct lan9118_eth_dev_t * dev,enum lan9118_fifo_level_irq_pos_t irq_level_pos,uint32_t level)655 enum lan9118_error_t lan9118_set_fifo_level_irq(const struct lan9118_eth_dev_t* dev,
656 enum lan9118_fifo_level_irq_pos_t irq_level_pos, uint32_t level)
657 {
658 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
659
660 if (level < LAN9118_FIFO_LEVEL_IRQ_LEVEL_MIN || level > LAN9118_FIFO_LEVEL_IRQ_LEVEL_MAX) {
661 return LAN9118_ERROR_PARAM;
662 }
663
664 CLR_BIT_FIELD(register_map->fifo_level_irq, LAN9118_FIFO_LEVEL_IRQ_MASK, irq_level_pos,
665 LAN9118_FIFO_LEVEL_IRQ_MASK);
666 SET_BIT_FIELD(register_map->fifo_level_irq, LAN9118_FIFO_LEVEL_IRQ_MASK, irq_level_pos, level);
667 return LAN9118_ERROR_NONE;
668 }
669
lan9118_wait_eeprom(const struct lan9118_eth_dev_t * dev)670 enum lan9118_error_t lan9118_wait_eeprom(const struct lan9118_eth_dev_t* dev)
671 {
672 uint32_t time_out = REG_WRITE_TIME_OUT_MS;
673
674 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
675
676 do {
677 if (dev->data->wait_ms) {
678 dev->data->wait_ms(1);
679 }
680 time_out--;
681 } while (time_out && GET_BIT(register_map->eeprom_cmd, EEPROM_CMD_REG_BUSY_INDEX));
682
683 if (!time_out) {
684 return LAN9118_ERROR_TIMEOUT;
685 }
686
687 return LAN9118_ERROR_NONE;
688 }
689
lan9118_init_irqs(const struct lan9118_eth_dev_t * dev)690 void lan9118_init_irqs(const struct lan9118_eth_dev_t* dev)
691 {
692 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
693
694 lan9118_disable_all_interrupts(dev);
695 lan9118_clear_all_interrupts(dev);
696
697 /* Set IRQ deassertion interval */
698 SET_BIT_FIELD(register_map->irq_cfg, 0xFFFFFFFF, 0, 0x11);
699
700 /* enable interrupts */
701 SET_BIT(register_map->irq_cfg, IRQ_CFG_IRQ_EN_INDEX);
702 }
703
lan9118_check_phy(const struct lan9118_eth_dev_t * dev)704 enum lan9118_error_t lan9118_check_phy(const struct lan9118_eth_dev_t* dev)
705 {
706 uint32_t phyid1 = 0;
707 uint32_t phyid2 = 0;
708
709 if (lan9118_phy_regread(dev, LAN9118_PHY_REG_OFFSET_ID1, &phyid1)) {
710 return LAN9118_ERROR_INTERNAL;
711 }
712 if (lan9118_phy_regread(dev, LAN9118_PHY_REG_OFFSET_ID2, &phyid2)) {
713 return LAN9118_ERROR_INTERNAL;
714 }
715 if ((phyid1 == 0xFFFF && phyid2 == 0xFFFF) || (phyid1 == 0x0 && phyid2 == 0x0)) {
716 return LAN9118_ERROR_INTERNAL;
717 }
718 return LAN9118_ERROR_NONE;
719 }
720
lan9118_reset_phy(const struct lan9118_eth_dev_t * dev)721 enum lan9118_error_t lan9118_reset_phy(const struct lan9118_eth_dev_t* dev)
722 {
723 uint32_t read = 0;
724
725 if (lan9118_phy_regread(dev, LAN9118_PHY_REG_OFFSET_BCTRL, &read)) {
726 return LAN9118_ERROR_INTERNAL;
727 }
728
729 SET_BIT(read, PHY_REG_BCTRL_RESET_INDEX);
730 if (lan9118_phy_regwrite(dev, LAN9118_PHY_REG_OFFSET_BCTRL, read)) {
731 return LAN9118_ERROR_INTERNAL;
732 }
733
734 return LAN9118_ERROR_NONE;
735 }
736
lan9118_advertise_cap(const struct lan9118_eth_dev_t * dev)737 void lan9118_advertise_cap(const struct lan9118_eth_dev_t* dev)
738 {
739 uint32_t aneg_adv = 0;
740 lan9118_phy_regread(dev, LAN9118_PHY_REG_OFFSET_ANEG_ADV, &aneg_adv);
741
742 SET_BIT(aneg_adv, ANEG_10_BASE_T_INDEX);
743 SET_BIT(aneg_adv, ANEG_10_BASE_T_FULL_DUPL_INDEX);
744 SET_BIT(aneg_adv, ANEG_100_BASE_TX_INDEX);
745 SET_BIT(aneg_adv, ANEG_100_BASE_TX_FULL_DUPL_INDEX);
746 SET_BIT(aneg_adv, ANEG_SYMM_PAUSE_INDEX);
747 SET_BIT(aneg_adv, ANEG_ASYMM_PAUSE_INDEX);
748
749 lan9118_phy_regwrite(dev, LAN9118_PHY_REG_OFFSET_ANEG_ADV, aneg_adv);
750 }
751
lan9118_enable_xmit(const struct lan9118_eth_dev_t * dev)752 void lan9118_enable_xmit(const struct lan9118_eth_dev_t* dev)
753 {
754 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
755
756 SET_BIT(register_map->tx_cfg, TX_CFG_ON_INDEX);
757 }
758
lan9118_enable_mac_xmit(const struct lan9118_eth_dev_t * dev)759 void lan9118_enable_mac_xmit(const struct lan9118_eth_dev_t* dev)
760 {
761 uint32_t mac_cr = 0;
762 lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_CR, &mac_cr);
763
764 SET_BIT(mac_cr, MAC_REG_CR_TXEN_INDEX);
765
766 lan9118_mac_regwrite(dev, LAN9118_MAC_REG_OFFSET_CR, mac_cr);
767 }
768
lan9118_enable_mac_recv(const struct lan9118_eth_dev_t * dev)769 void lan9118_enable_mac_recv(const struct lan9118_eth_dev_t* dev)
770 {
771 uint32_t mac_cr = 0;
772 lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_CR, &mac_cr);
773
774 SET_BIT(mac_cr, MAC_REG_CR_RXEN_INDEX);
775
776 lan9118_mac_regwrite(dev, LAN9118_MAC_REG_OFFSET_CR, mac_cr);
777 }
778
lan9118_check_id(const struct lan9118_eth_dev_t * dev)779 int lan9118_check_id(const struct lan9118_eth_dev_t* dev)
780 {
781 uint32_t id = lan9118_read_id(dev);
782
783 return ((id == CHIP_ID) ? 0 : 1);
784 }
785
lan9118_enable_interrupt(const struct lan9118_eth_dev_t * dev,enum lan9118_interrupt_source source)786 void lan9118_enable_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source)
787 {
788 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
789
790 SET_BIT(register_map->irq_enable, source);
791 }
792
lan9118_disable_interrupt(const struct lan9118_eth_dev_t * dev,enum lan9118_interrupt_source source)793 void lan9118_disable_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source)
794 {
795 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
796
797 CLR_BIT(register_map->irq_enable, source);
798 }
799
lan9118_disable_all_interrupts(const struct lan9118_eth_dev_t * dev)800 void lan9118_disable_all_interrupts(const struct lan9118_eth_dev_t* dev)
801 {
802 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
803
804 register_map->irq_enable = 0;
805 }
806
lan9118_clear_interrupt(const struct lan9118_eth_dev_t * dev,enum lan9118_interrupt_source source)807 void lan9118_clear_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source)
808 {
809 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
810
811 SET_BIT(register_map->irq_status, source);
812 }
813
lan9118_clear_all_interrupts(const struct lan9118_eth_dev_t * dev)814 void lan9118_clear_all_interrupts(const struct lan9118_eth_dev_t* dev)
815 {
816 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
817
818 register_map->irq_status = UINT32_MAX;
819 }
820
lan9118_get_interrupt(const struct lan9118_eth_dev_t * dev,enum lan9118_interrupt_source source)821 int lan9118_get_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source)
822 {
823 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
824
825 return GET_BIT(register_map->irq_status, source);
826 }
827
lan9118_establish_link(const struct lan9118_eth_dev_t * dev)828 void lan9118_establish_link(const struct lan9118_eth_dev_t* dev)
829 {
830 uint32_t bcr = 0;
831 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
832
833 lan9118_phy_regread(dev, LAN9118_PHY_REG_OFFSET_BCTRL, &bcr);
834 SET_BIT(bcr, PHY_REG_BCTRL_AUTO_NEG_EN_INDEX);
835 SET_BIT(bcr, PHY_REG_BCTRL_RST_AUTO_NEG_INDEX);
836 lan9118_phy_regwrite(dev, LAN9118_PHY_REG_OFFSET_BCTRL, bcr);
837
838 SET_BIT(register_map->hw_cfg, HW_CFG_REG_MUST_BE_ONE_INDEX);
839 }
840
lan9118_read_mac_address(const struct lan9118_eth_dev_t * dev,char * mac)841 enum lan9118_error_t lan9118_read_mac_address(const struct lan9118_eth_dev_t* dev, char* mac)
842 {
843 uint32_t mac_low = 0;
844 uint32_t mac_high = 0;
845
846 if (!mac) {
847 return LAN9118_ERROR_PARAM;
848 }
849
850 if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_ADDRH, &mac_high)) {
851 return LAN9118_ERROR_INTERNAL;
852 }
853 if (lan9118_mac_regread(dev, LAN9118_MAC_REG_OFFSET_ADDRL, &mac_low)) {
854 return LAN9118_ERROR_INTERNAL;
855 }
856 mac[0] = mac_low & 0xFF;
857 mac[1] = (mac_low >> 8) & 0xFF;
858 mac[2] = (mac_low >> 16) & 0xFF;
859 mac[3] = (mac_low >> 24) & 0xFF;
860 mac[4] = mac_high & 0xFF;
861 mac[5] = (mac_high >> 8) & 0xFF;
862
863 return LAN9118_ERROR_NONE;
864 }
865
lan9118_init(const struct lan9118_eth_dev_t * dev,void (* wait_ms_function)(uint32_t))866 enum lan9118_error_t lan9118_init(const struct lan9118_eth_dev_t* dev, void (*wait_ms_function)(uint32_t))
867 {
868 uint32_t phyreset = 0;
869 enum lan9118_error_t error = LAN9118_ERROR_NONE;
870 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
871
872 if (!wait_ms_function) {
873 return LAN9118_ERROR_PARAM;
874 }
875 dev->data->wait_ms = wait_ms_function;
876
877 error = lan9118_check_id(dev);
878 if (error != LAN9118_ERROR_NONE) {
879 return error;
880 }
881
882 error = lan9118_soft_reset(dev);
883 if (error != LAN9118_ERROR_NONE) {
884 return error;
885 }
886
887 lan9118_set_txfifo(dev, HW_CFG_REG_TX_FIFO_SIZE);
888
889 SET_BIT_FIELD(register_map->afc_cfg, AFC_BACK_DUR_MASK, AFC_BACK_DUR_POS, AFC_BACK_DUR);
890 SET_BIT_FIELD(register_map->afc_cfg, AFC_LOW_LEVEL_MASK, AFC_LOW_LEVEL_POS, AFC_LOW_LEVEL);
891 SET_BIT_FIELD(register_map->afc_cfg, AFC_HIGH_LEVEL_MASK, AFC_HIGH_LEVEL_POS, AFC_HIGH_LEVEL);
892
893 error = lan9118_wait_eeprom(dev);
894 if (error != LAN9118_ERROR_NONE) {
895 return error;
896 }
897
898 lan9118_init_irqs(dev);
899
900 /* Configure MAC addresses here if needed. */
901 error = lan9118_check_phy(dev);
902 if (error != LAN9118_ERROR_NONE) {
903 return error;
904 }
905
906 error = lan9118_reset_phy(dev);
907 if (error != LAN9118_ERROR_NONE) {
908 return error;
909 }
910
911 if (dev->data->wait_ms) {
912 dev->data->wait_ms(PHY_RESET_TIME_OUT_MS);
913 }
914 /* Checking whether phy reset completed successfully.*/
915 error = lan9118_phy_regread(dev, LAN9118_PHY_REG_OFFSET_BCTRL, &phyreset);
916 if (error != LAN9118_ERROR_NONE) {
917 return error;
918 }
919
920 if (GET_BIT(phyreset, PHY_REG_BCTRL_RESET_INDEX)) {
921 return LAN9118_ERROR_INTERNAL;
922 }
923
924 lan9118_advertise_cap(dev);
925 lan9118_establish_link(dev);
926 lan9118_enable_mac_xmit(dev);
927 lan9118_enable_xmit(dev);
928 lan9118_enable_mac_recv(dev);
929
930 /* This sleep is compulsory otherwise txmit/receive will fail. */
931 if (dev->data->wait_ms) {
932 dev->data->wait_ms(INIT_FINISH_DELAY);
933 }
934 dev->data->state = 1;
935
936 return LAN9118_ERROR_NONE;
937 }
938
lan9118_send_by_chunks(const struct lan9118_eth_dev_t * dev,uint32_t total_payload_length,bool is_new_packet,const char * data,uint32_t current_size)939 enum lan9118_error_t lan9118_send_by_chunks(const struct lan9118_eth_dev_t* dev, uint32_t total_payload_length,
940 bool is_new_packet, const char* data, uint32_t current_size)
941 {
942 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
943 bool is_first_segment = false;
944 bool is_last_segment = false;
945 uint32_t txcmd_a, txcmd_b = 0;
946 uint32_t tx_buffer_free_space = 0;
947 volatile uint32_t xmit_stat = 0;
948
949 if (!data) {
950 return LAN9118_ERROR_PARAM;
951 }
952
953 if (is_new_packet) {
954 is_first_segment = true;
955 dev->data->ongoing_packet_length = total_payload_length;
956 dev->data->ongoing_packet_length_sent = 0;
957 } else if (dev->data->ongoing_packet_length != total_payload_length ||
958 dev->data->ongoing_packet_length_sent >= total_payload_length) {
959 return LAN9118_ERROR_PARAM;
960 }
961
962 /* Would next chunk fit into buffer? */
963 tx_buffer_free_space = GET_BIT_FIELD(register_map->tx_fifo_inf, FIFO_USED_SPACE_MASK, DATA_FIFO_USED_SPACE_POS);
964
965 if (current_size > tx_buffer_free_space) {
966 return LAN9118_ERROR_INTERNAL; /* Not enough space in FIFO */
967 }
968 if ((dev->data->ongoing_packet_length_sent + current_size) == total_payload_length) {
969 is_last_segment = true;
970 }
971
972 txcmd_a = 0;
973 txcmd_b = 0;
974
975 if (is_last_segment) {
976 SET_BIT(txcmd_a, TX_COMMAND_A_LAST_SEGMENT_INDEX);
977 }
978 if (is_first_segment) {
979 SET_BIT(txcmd_a, TX_COMMAND_A_FIRST_SEGMENT_INDEX);
980 }
981
982 uint32_t data_start_offset_bytes = (4 - (current_size % 4));
983
984 SET_BIT_FIELD(txcmd_a, TX_CMD_PKT_LEN_BYTES_MASK, 0, current_size);
985 SET_BIT_FIELD(txcmd_a, TX_CMD_DATA_START_OFFSET_BYTES_MASK, TX_CMD_DATA_START_OFFSET_BYTES_POS,
986 data_start_offset_bytes);
987
988 SET_BIT_FIELD(txcmd_b, TX_CMD_PKT_LEN_BYTES_MASK, 0, current_size);
989 SET_BIT_FIELD(txcmd_b, TX_CMD_PKT_TAG_MASK, TX_CMD_PKT_TAG_POS, current_size);
990
991 SET_BIT_FIELD(register_map->tx_data_port, 0xFFFFFFFF, 0, txcmd_a);
992 SET_BIT_FIELD(register_map->tx_data_port, 0xFFFFFFFF, 0, txcmd_b);
993
994 fill_tx_fifo(dev, (uint8_t*)data, current_size);
995
996 if (is_last_segment) {
997 /* Pop status port for error check */
998 xmit_stat = register_map->tx_status_port;
999 (void)xmit_stat;
1000 }
1001 dev->data->ongoing_packet_length_sent += current_size;
1002 return LAN9118_ERROR_NONE;
1003 }
1004
lan9118_get_rxfifo_data_used_space(const struct lan9118_eth_dev_t * dev)1005 uint32_t lan9118_get_rxfifo_data_used_space(const struct lan9118_eth_dev_t* dev)
1006 {
1007 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
1008
1009 return GET_BIT_FIELD(register_map->rx_fifo_inf, FIFO_USED_SPACE_MASK, DATA_FIFO_USED_SPACE_POS);
1010 }
1011
lan9118_receive_by_chunks(const struct lan9118_eth_dev_t * dev,char * data,uint32_t dlen)1012 uint32_t lan9118_receive_by_chunks(const struct lan9118_eth_dev_t* dev, char* data, uint32_t dlen)
1013 {
1014 uint32_t rxfifo_inf = 0;
1015 uint32_t rxfifo_stat = 0;
1016 uint32_t packet_length_byte = 0;
1017 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
1018
1019 if (!data) {
1020 return 0; /* Invalid input parameter, cannot read */
1021 }
1022
1023 rxfifo_inf = GET_BIT_FIELD(register_map->rx_fifo_inf, 0xFFFFFFFF, 0);
1024
1025 if (rxfifo_inf & 0xFFFF) { /* If there's data */
1026 rxfifo_stat = GET_BIT_FIELD(register_map->rx_status_port, 0xFFFFFFFF, 0);
1027 if (rxfifo_stat != 0) { /* Fetch status of this packet */
1028 /* Ethernet controller is padding to 32bit aligned data */
1029 packet_length_byte =
1030 GET_BIT_FIELD(rxfifo_stat, RX_FIFO_STATUS_PKT_LENGTH_MASK, RX_FIFO_STATUS_PKT_LENGTH_POS);
1031
1032 dev->data->current_rx_size_words = packet_length_byte;
1033 }
1034 }
1035
1036 empty_rx_fifo(dev, (uint8_t*)data, packet_length_byte);
1037 dev->data->current_rx_size_words = 0;
1038
1039 return packet_length_byte;
1040 }
1041
lan9118_peek_next_packet_size(const struct lan9118_eth_dev_t * dev)1042 uint32_t lan9118_peek_next_packet_size(const struct lan9118_eth_dev_t* dev)
1043 {
1044 uint32_t packet_size = 0;
1045 struct lan9118_eth_reg_map_t* register_map = (struct lan9118_eth_reg_map_t*)dev->cfg->base;
1046
1047 if (lan9118_get_rxfifo_data_used_space(dev)) {
1048 packet_size =
1049 GET_BIT_FIELD(register_map->rx_status_peek, RX_FIFO_STATUS_PKT_LENGTH_MASK, RX_FIFO_STATUS_PKT_LENGTH_POS);
1050 }
1051 return packet_size;
1052 }
1053
LowLevelInput(void)1054 struct pbuf* LowLevelInput(void)
1055 {
1056 struct pbuf* p = NULL;
1057 uint32_t messageLength = 0;
1058 uint32_t receivedBytes = 0;
1059
1060 messageLength = lan9118_peek_next_packet_size(g_dev);
1061 if (messageLength == 0) {
1062 return p;
1063 }
1064
1065 p = AllocHeap(LAN9118_ETH_MAX_FRAME_SIZE, LAN9118_BUFF_ALIGNMENT);
1066 if (p != NULL) {
1067 LOS_TaskLock();
1068
1069 receivedBytes = lan9118_receive_by_chunks(g_dev, (char*)GetPayloadAddr(p), GetLen(p));
1070 if (receivedBytes == 0) {
1071 pbuf_free(p);
1072 p = NULL;
1073 } else {
1074 receivedBytes += 2;
1075 SetLen(p, receivedBytes);
1076 }
1077
1078 LOS_TaskUnlock();
1079 }
1080
1081 return p;
1082 }
1083
Lan9118LinkOut(struct netif * netif,struct pbuf * buf)1084 err_t Lan9118LinkOut(struct netif* netif, struct pbuf* buf)
1085 {
1086 uint32_t bufferLength = 0;
1087
1088 if (buf == NULL) {
1089 return ERR_BUF;
1090 } else {
1091 bufferLength = GetTotalLen(buf) - ETH_PAD_SIZE;
1092
1093 LOS_TaskLock();
1094
1095 lan9118_send_by_chunks(g_dev, bufferLength, true, (const char*)GetPayloadAddr(buf), bufferLength);
1096
1097 LOS_TaskUnlock();
1098
1099 return ERR_OK;
1100 }
1101 }
1102
Lan9118PacketRx(void)1103 void Lan9118PacketRx(void)
1104 {
1105 struct pbuf* buf;
1106
1107 buf = LowLevelInput();
1108
1109 if (buf != NULL) {
1110
1111 LOS_TaskLock();
1112 if (g_NetIf.input(buf, &g_NetIf) != ERR_OK) {
1113 PRINT_ERR("Emac LWIP: IP input error\n");
1114 pbuf_free(buf);
1115 }
1116 LOS_TaskUnlock();
1117 }
1118 }
1119
EthernetReceiveHandler(void)1120 void EthernetReceiveHandler(void)
1121 {
1122 if (lan9118_get_interrupt(g_dev, LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL)) {
1123 lan9118_clear_interrupt(g_dev, LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL);
1124
1125 lan9118_disable_interrupt(g_dev, LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL);
1126
1127 Lan9118PacketRx();
1128
1129 lan9118_enable_interrupt(g_dev, LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL);
1130 }
1131
1132 return;
1133 }
1134
LowLevelInit(struct netif * netif)1135 void LowLevelInit(struct netif* netif)
1136 {
1137 enum lan9118_error_t ret = LAN9118_ERROR_NONE;
1138
1139 /* set MAC hardware address length */
1140 netif->hwaddr_len = ETHARP_HWADDR_LEN;
1141
1142 /* maximum transfer unit */
1143 netif->mtu = LAN9118_ETH_MTU_SIZE;
1144
1145 /* set MAC hardware address */
1146 ret = lan9118_read_mac_address(g_dev, (char*)netif->hwaddr);
1147 if (ret != LAN9118_ERROR_NONE) {
1148 PRINT_ERR("get mac addr error\n");
1149 return;
1150 }
1151
1152 /* Interface capabilities */
1153 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_LINK_UP;
1154
1155 #if LWIP_IPV6 && LWIP_IPV6_MLD
1156 /*
1157 * For hardware/netifs that implement MAC filtering.
1158 * All-nodes link-local is handled by default, so we must let the hardware
1159 * know to allow multicast packets in. Should set mld_mac_filter previously.
1160 */
1161 if (netif->mld_mac_filter != NULL) {
1162 ip6_addr_t ip6_allnodes_ll;
1163 ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
1164 netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
1165 }
1166 #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
1167 }
1168
EthernetifInit(struct netif * netif)1169 err_t EthernetifInit(struct netif* netif)
1170 {
1171 struct EtherNetif* ethernetif;
1172
1173 LWIP_ASSERT("netif != NULL", (netif != NULL));
1174
1175 ethernetif = mem_malloc(sizeof(struct EtherNetif));
1176 if (ethernetif == NULL) {
1177 PRINT_ERR("EthernetifInit: out of memory\n");
1178 return ERR_MEM;
1179 }
1180
1181 netif->state = ethernetif;
1182 netif->link_layer_type = ETHERNET_DRIVER_IF;
1183
1184 #if LWIP_NETIF_HOSTNAME
1185 netif->hostname = LAN9118_NETIF_NAME;
1186 #endif
1187
1188 memcpy(netif->name, LAN9118_NETIF_NICK, (sizeof(netif->name) < sizeof(LAN9118_NETIF_NICK)) ? sizeof(netif->name) : sizeof(LAN9118_NETIF_NICK));
1189 memcpy(netif->full_name, LAN9118_NETIF_NICK, (IFNAMSIZ < sizeof(LAN9118_NETIF_NICK)) ? IFNAMSIZ : sizeof(LAN9118_NETIF_NICK));
1190
1191 /* Initialize the hardware */
1192 enum lan9118_error_t init_successful = lan9118_init(g_dev, &DelayMs);
1193 if (init_successful != LAN9118_ERROR_NONE) {
1194 return false;
1195 }
1196
1197 /* Init FIFO level interrupts: use Rx status level irq to trigger
1198 * interrupts for any non-processed packets, while Tx is not irq driven */
1199 lan9118_set_fifo_level_irq(g_dev, LAN9118_FIFO_LEVEL_IRQ_RX_STATUS_POS, LAN9118_FIFO_LEVEL_IRQ_LEVEL_MIN);
1200 lan9118_set_fifo_level_irq(g_dev, LAN9118_FIFO_LEVEL_IRQ_TX_STATUS_POS, LAN9118_FIFO_LEVEL_IRQ_LEVEL_MIN);
1201 lan9118_set_fifo_level_irq(g_dev, LAN9118_FIFO_LEVEL_IRQ_TX_DATA_POS, LAN9118_FIFO_LEVEL_IRQ_LEVEL_MAX);
1202
1203 /* Enable Ethernet interrupts */
1204 lan9118_enable_interrupt(g_dev, LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL);
1205 (void)LOS_HwiCreate(ETHERNET_IRQn, 0, 0, (HWI_PROC_FUNC)EthernetReceiveHandler, 0);
1206
1207 #if LWIP_IPV4
1208 netif->output = etharp_output;
1209 #endif /* LWIP_IPV4 */
1210
1211 #if LWIP_IPV6
1212 netif->output_ip6 = ethip6_output;
1213 #endif /* LWIP_IPV6 */
1214
1215 netif->linkoutput = Lan9118LinkOut;
1216
1217 /* initialize mac */
1218 LowLevelInit(netif);
1219
1220 return ERR_OK;
1221 }
1222
Lan9118NetInit(void)1223 void Lan9118NetInit(void)
1224 {
1225 ip4_addr_t ip;
1226 ip4_addr_t mask;
1227 ip4_addr_t gw;
1228 static uint32_t overtime = 0;
1229 struct netif* NetifInitRet;
1230
1231 ip.addr = ipaddr_addr(LAN9118_NETIF_TEST_IP);
1232 mask.addr = ipaddr_addr(LAN9118_NETIF_TEST_MASK);
1233 gw.addr = ipaddr_addr(LAN9118_NETIF_TEST_GW);
1234
1235 NetifInitRet = netif_add(&g_NetIf, &ip, &mask, &gw, g_NetIf.state, EthernetifInit, tcpip_input);
1236 if (NetifInitRet == NULL) {
1237 PRINT_ERR("NetifInit error!\n");
1238 return;
1239 }
1240
1241 netif_set_default(&g_NetIf);
1242 netifapi_netif_set_up(&g_NetIf);
1243 do {
1244 DelayMs(SLEEP_TIME_MS);
1245 overtime++;
1246 if (overtime > NETIF_SETUP_OVERTIME) {
1247 PRINT_ERR("netif_is_link_up overtime!\n");
1248 break;
1249 }
1250 } while (netif_is_link_up(&g_NetIf) == 0);
1251 if (overtime <= NETIF_SETUP_OVERTIME) {
1252 printf("netif init succeed!\n");
1253 }
1254 }
1255
NetInit(void)1256 void NetInit(void)
1257 {
1258
1259 printf("tcpip_init start\n");
1260
1261 tcpip_init(NULL, NULL);
1262
1263 printf("tcpip_init end\n");
1264
1265 Lan9118NetInit();
1266 }
1267