• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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