• 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 /**
19  * \file lan9118_drv.h
20  * \brief Generic driver for LAN9118 Ethernet controller
21  */
22 
23 #ifndef __LAN9118_ETH_H__
24 #define __LAN9118_ETH_H__
25 
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include "los_config.h"
29 #include "los_event.h"
30 #include "los_interrupt.h"
31 #include "los_reg.h"
32 #include "stdio.h"
33 #include "los_reg.h"
34 #include "los_arch_context.h"
35 #include "netinet/if_ether.h"
36 #include "lwip/opt.h"
37 #include <lwip/netif.h>
38 #include "lwip/etharp.h"
39 #include "lwip/tcpip.h"
40 #include "lwip/mem.h"
41 #include <lwip/pbuf.h>
42 #include <lwip/netifapi.h>
43 
44 #define LAN9118_BASE         0x40200000UL /* Ethernet LAN9118 BASE Address */
45 #define ETHERNET_IRQn        13           /* Ethernet Interrupt */
46 #define LAN9118_ETH_MTU_SIZE 1500U        /* Ethernet MTU */
47 
48 /** LAN9118 device configuration structure */
49 struct lan9118_eth_dev_cfg_t {
50     const uint32_t base; /*!< LAN9118 base address */
51 };
52 
53 /** LAN9118 device data structure */
54 struct lan9118_eth_dev_data_t {
55     uint32_t state;                      /*!< Indicates if the LAN9118 driver
56                                               is initialized and enabled */
57     void (*wait_ms)(uint32_t);           /*!< function pointer to system's millisec delay
58                                          function, will be used for delays */
59     uint32_t ongoing_packet_length;      /*!< size in bytes of the packet
60                                                   is being sent */
61     uint32_t ongoing_packet_length_sent; /*!< size in bytes of the packet
62                                                   has been sent */
63     uint32_t current_rx_size_words;      /*!< Data length in words,
64                                                   currently is being read */
65 };
66 
67 /** LAN9118 device structure */
68 struct lan9118_eth_dev_t {
69     const struct lan9118_eth_dev_cfg_t* const cfg; /*!< configuration */
70     struct lan9118_eth_dev_data_t* const data;     /*!< data */
71 };
72 
73 /**
74  * \brief Error code definitions
75  *
76  */
77 enum lan9118_error_t {
78     LAN9118_ERROR_NONE = 0U,    /*!< no error */
79     LAN9118_ERROR_TIMEOUT = 1U, /*!< timeout */
80     LAN9118_ERROR_BUSY = 2U,    /*!< no error */
81     LAN9118_ERROR_PARAM = 3U,   /*!< invalid parameter */
82     LAN9118_ERROR_INTERNAL = 4U /*!< internal error */
83 };
84 
85 /**
86  * \brief Interrupt source definitions
87  *
88  */
89 enum lan9118_interrupt_source {
90     LAN9118_INTERRUPT_GPIO0 = 0U,
91     LAN9118_INTERRUPT_GPIO1 = 1U,
92     LAN9118_INTERRUPT_GPIO2 = 2U,
93     LAN9118_INTERRUPT_RX_STATUS_FIFO_LEVEL = 3U,
94     LAN9118_INTERRUPT_RX_STATUS_FIFO_FULL = 4U,
95     /* 5 Reserved according to Datasheet */
96     LAN9118_INTERRUPT_RX_DROPPED_FRAME = 6U,
97     LAN9118_INTERRUPT_TX_STATUS_FIFO_LEVEL = 7U,
98     LAN9118_INTERRUPT_TX_STATUS_FIFO_FULL = 8U,
99     LAN9118_INTERRUPT_TX_DATA_FIFO_AVAILABLE = 9U,
100     LAN9118_INTERRUPT_TX_DATA_FIFO_OVERRUN = 10U,
101     /* 11, 12 Reserved according to Datasheet */
102     LAN9118_INTERRUPT_TX_ERROR = 13U,
103     LAN9118_INTERRUPT_RX_ERROR = 14U,
104     LAN9118_INTERRUPT_RX_WATCHDOG_TIMEOUT = 15U,
105     LAN9118_INTERRUPT_TX_STATUS_OVERFLOW = 16U,
106     LAN9118_INTERRUPT_TX_POWER_MANAGEMENT = 17U,
107     LAN9118_INTERRUPT_PHY = 18U,
108     LAN9118_INTERRUPT_GP_TIMER = 19U,
109     LAN9118_INTERRUPT_RX_DMA = 20U,
110     LAN9118_INTERRUPT_TX_IOC = 21U,
111     /* 22 Reserved according to Datasheet*/
112     LAN9118_INTERRUPT_RX_DROPPED_FRAME_HALF = 23U,
113     LAN9118_INTERRUPT_RX_STOPPED = 24U,
114     LAN9118_INTERRUPT_TX_STOPPED = 25U,
115     /* 26 - 30 Reserved according to Datasheet*/
116     LAN9118_INTERRUPT_SW = 31U
117 };
118 
119 /**
120  * \brief MAC register offset definitions
121  *
122  */
123 enum lan9118_mac_reg_offsets_t {
124     LAN9118_MAC_REG_OFFSET_CR = 0x1U,
125     LAN9118_MAC_REG_OFFSET_ADDRH = 0x2U,
126     LAN9118_MAC_REG_OFFSET_ADDRL = 0x3U,
127     LAN9118_MAC_REG_OFFSET_HASHH = 0x4U,
128     LAN9118_MAC_REG_OFFSET_HASHL = 0x5U,
129     LAN9118_MAC_REG_OFFSET_MII_ACC = 0x6U,
130     LAN9118_MAC_REG_OFFSET_MII_DATA = 0x7U,
131     LAN9118_MAC_REG_OFFSET_FLOW = 0x8U,
132     LAN9118_MAC_REG_OFFSET_VLAN1 = 0x9U,
133     LAN9118_MAC_REG_OFFSET_VLAN2 = 0xAU,
134     LAN9118_MAC_REG_OFFSET_WUFF = 0xBU,
135     LAN9118_MAC_REG_OFFSET_WUCSR = 0xCU,
136 };
137 
138 /**
139  * \brief PHY register offset definitions
140  *
141  */
142 enum phy_reg_offsets_t {
143     LAN9118_PHY_REG_OFFSET_BCTRL = 0U,
144     LAN9118_PHY_REG_OFFSET_BSTATUS = 1U,
145     LAN9118_PHY_REG_OFFSET_ID1 = 2U,
146     LAN9118_PHY_REG_OFFSET_ID2 = 3U,
147     LAN9118_PHY_REG_OFFSET_ANEG_ADV = 4U,
148     LAN9118_PHY_REG_OFFSET_ANEG_LPA = 5U,
149     LAN9118_PHY_REG_OFFSET_ANEG_EXP = 6U,
150     LAN9118_PHY_REG_OFFSET_MCONTROL = 17U,
151     LAN9118_PHY_REG_OFFSET_MSTATUS = 18U,
152     LAN9118_PHY_REG_OFFSET_CSINDICATE = 27U,
153     LAN9118_PHY_REG_OFFSET_INTSRC = 29U,
154     LAN9118_PHY_REG_OFFSET_INTMASK = 30U,
155     LAN9118_PHY_REG_OFFSET_CS = 31U
156 };
157 
158 /**
159  * \brief FIFO Level Interrupt bit definitions
160  *
161  */
162 enum lan9118_fifo_level_irq_pos_t {
163     LAN9118_FIFO_LEVEL_IRQ_RX_STATUS_POS = 0U,
164     LAN9118_FIFO_LEVEL_IRQ_TX_STATUS_POS = 16U,
165     LAN9118_FIFO_LEVEL_IRQ_TX_DATA_POS = 24U
166 };
167 
168 /**
169  * \brief FIFO Level Interrupt limits
170  *
171  */
172 #define LAN9118_FIFO_LEVEL_IRQ_MASK      0xFFU
173 #define LAN9118_FIFO_LEVEL_IRQ_LEVEL_MIN 0U
174 #define LAN9118_FIFO_LEVEL_IRQ_LEVEL_MAX LAN9118_FIFO_LEVEL_IRQ_MASK
175 
176 /**
177  * \brief Initializes LAN9118 Ethernet controller to a known default state:
178  *          - device ID is checked
179  *          - global interrupt is enabled, but all irq sources are disabled
180  *          - all capabilities are advertised
181  *              - 10Mbps able
182  *              - 10Mbps with full duplex
183  *              - 100Mbps Tx able
184  *              - 100Mbps with full duplex
185  *              - Symmetric Pause
186  *              - Asymmetric Pause
187  *          - Establish link enabled
188  *          - Rx enabled
189  *          - Tx enabled
190  *        Init should be called prior to any other process and
191  *        it's the caller's responsibility to follow proper call order.
192  *
193  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
194  * \param[in] wait_ms_function function pointer to a millisec delay function
195  *                             for proper timing of some processes
196  *
197  * \return error code /ref lan9118_error_t
198  */
199 enum lan9118_error_t lan9118_init(const struct lan9118_eth_dev_t* dev, void (*wait_ms_function)(uint32_t));
200 
201 /**
202  * \brief Reads the MAC register.
203  *
204  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
205  * \param[in] regoffset Register offset
206  * \param[in, out] data Pointer to register will be read
207  *
208  * \return error code /ref lan9118_error_t
209  */
210 enum lan9118_error_t lan9118_mac_regread(const struct lan9118_eth_dev_t* dev, enum lan9118_mac_reg_offsets_t regoffset,
211                                          uint32_t* data);
212 
213 /**
214  * \brief Writes the MAC register.
215  *
216  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
217  * \param[in] regoffset Register offset
218  * \param[in] data Register value to write
219  *
220  * \return error code /ref lan9118_error_t
221  */
222 enum lan9118_error_t lan9118_mac_regwrite(const struct lan9118_eth_dev_t* dev, enum lan9118_mac_reg_offsets_t regoffset,
223                                           uint32_t data);
224 
225 /**
226  * \brief Reads the PHY register.
227  *
228  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
229  * \param[in] regoffset Register offset
230  * \param[out] data Register value is read
231  *
232  * \return error code /ref lan9118_error_t
233  */
234 enum lan9118_error_t lan9118_phy_regread(const struct lan9118_eth_dev_t* dev, enum phy_reg_offsets_t regoffset, \
235                                          uint32_t* data);
236 
237 /**
238  * \brief Writes the PHY register.
239  *
240  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
241  * \param[in] regoffset Register offset
242  * \param[in] data Register value to write
243  *
244  * \return error code /ref lan9118_error_t
245  */
246 enum lan9118_error_t lan9118_phy_regwrite(const struct lan9118_eth_dev_t* dev, enum phy_reg_offsets_t regoffset, \
247                                           uint32_t data);
248 
249 /**
250  * \brief Reads the Ethernet Controller's ID.
251  *
252  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
253  *
254  * \return ID number
255  */
256 uint32_t lan9118_read_id(const struct lan9118_eth_dev_t* dev);
257 
258 /**
259  * \brief Initiates a soft reset, returns failure or success.
260  *
261  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
262  *
263  * \return error code /ref lan9118_error_t
264  */
265 enum lan9118_error_t lan9118_soft_reset(const struct lan9118_eth_dev_t* dev);
266 
267 /**
268  * \brief Sets the Maximum Transmission Unit by Tx fifo size.
269  *        Note: The MTU will be smaller than 512 bytes,
270  *        which is used by the status.
271  *
272  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
273  * \param[in] val Size of the fifo in kbytes
274  *                \ref HW_CFG_REG_TX_FIFO_SIZE_MIN
275  *                \ref HW_CFG_REG_TX_FIFO_SIZE_MAX
276  */
277 void lan9118_set_txfifo(const struct lan9118_eth_dev_t* dev, uint32_t val);
278 
279 /**
280  * \brief Sets the FIFO level interrupt for a given source.
281  *
282  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
283  * \param[in] irq_level_pos Bit position of the FIFO to set
284  *            \ref lan9118_fifo_level_irq_pos_t
285  * \param[in] level Level of the FIFO, when the FIFO used space is greater
286  *             than this value, corresponding interrupt will be generated.
287  *
288  * \return error code /ref lan9118_error_t
289  */
290 enum lan9118_error_t lan9118_set_fifo_level_irq(const struct lan9118_eth_dev_t* dev,
291                                                 enum lan9118_fifo_level_irq_pos_t irq_level_pos, uint32_t level);
292 
293 /**
294  * \brief Waits for EEPROM to be ready to use.
295  *
296  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
297  *
298  * \return error code /ref lan9118_error_t
299  */
300 enum lan9118_error_t lan9118_wait_eeprom(const struct lan9118_eth_dev_t* dev);
301 
302 /**
303  * \brief Initializes irqs by clearing and disabling all interrupt sources
304  *        and enable interrupts. Since all interrupt sources are disabled,
305  *        interrupt won't be triggered, until interrupt sources won't be
306  *        enabled by \ref lan9118_enable_interrupt
307  *
308  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
309  */
310 void lan9118_init_irqs(const struct lan9118_eth_dev_t* dev);
311 
312 /**
313  * \brief Checks PHY ID registers.
314  *
315  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
316  *
317  * \return error code /ref lan9118_error_t
318  */
319 enum lan9118_error_t lan9118_check_phy(const struct lan9118_eth_dev_t* dev);
320 
321 /**
322  * \brief Resets PHY.
323  *
324  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
325  *
326  * \return error code /ref lan9118_error_t
327  */
328 enum lan9118_error_t lan9118_reset_phy(const struct lan9118_eth_dev_t* dev);
329 
330 /**
331  * \brief Advertises all speeds and pauses capabilities.
332  *
333  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
334  */
335 void lan9118_advertise_cap(const struct lan9118_eth_dev_t* dev);
336 
337 /**
338  * \brief Enables transmission.
339  *
340  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
341  */
342 void lan9118_enable_xmit(const struct lan9118_eth_dev_t* dev);
343 
344 /**
345  * \brief Enables MAC Transmitter.
346  *
347  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
348  */
349 void lan9118_enable_mac_xmit(const struct lan9118_eth_dev_t* dev);
350 
351 /**
352  * \brief Enables receiving.
353  *
354  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
355  */
356 void lan9118_enable_mac_recv(const struct lan9118_eth_dev_t* dev);
357 
358 /**
359  * \brief Enables the given interrupt source.
360  *
361  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
362  * \param[in] source Enum of the interrupt source.
363  */
364 void lan9118_enable_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source);
365 
366 /**
367  * \brief Disables the given interrupt source.
368  *
369  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
370  * \param[in] source Enum of the interrupt source.
371  */
372 void lan9118_disable_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source);
373 
374 /**
375  * \brief Disables all interrupt sources.
376  *
377  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
378  */
379 void lan9118_disable_all_interrupts(const struct lan9118_eth_dev_t* dev);
380 
381 /**
382  * \brief Clears the given interrupt source.
383  *
384  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
385  * \param[in] source Enum of the interrupt source.
386  */
387 void lan9118_clear_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source);
388 
389 /**
390  * \brief Clears all interrupt sources.
391  *
392  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
393  */
394 void lan9118_clear_all_interrupts(const struct lan9118_eth_dev_t* dev);
395 
396 /**
397  * \brief Gets the status of the given interrupt source.
398  *
399  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
400  * \param[in] source Enum of the interrupt source.
401  *
402  * \return non-zero if the given interrupt source is triggered, zero otherwise
403  */
404 int lan9118_get_interrupt(const struct lan9118_eth_dev_t* dev, enum lan9118_interrupt_source source);
405 
406 /**
407  * \brief Establishes link
408  *
409  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
410  */
411 void lan9118_establish_link(const struct lan9118_eth_dev_t* dev);
412 
413 /**
414  * \brief Reads the Ethernet Controller's MAC address from its EEPROM.
415  *
416  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
417  * \param[in,out] mac array will include the read MAC address in
418  *                6 bytes hexadecimal format.
419  *                It should be allocated by the caller to 6 bytes.
420  *
421  * \return error code /ref lan9118_error_t
422  */
423 enum lan9118_error_t lan9118_read_mac_address(const struct lan9118_eth_dev_t* dev, char* mac);
424 
425 /**
426  * \brief Check device ID.
427  *
428  * \return error code /ref lan9118_error_t
429  */
430 int lan9118_check_id(const struct lan9118_eth_dev_t* dev);
431 
432 /**
433  * \brief Sends data from the given buffer as an Ethernet packet.
434  *        The full packet length must be specified at the beginning
435  *        of a new packet transmission.
436  *
437  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
438  * \param[in] total_payload_length Length of the ethernet payload.
439  *            Should be equal to the sum of passed buffers within a packet.
440  * \param[in] is_new_packet Should be set to true if the input buffer has to
441  *            be sent as the start of a new packet or as a full packet.
442  * \param[in] data Pointer to the data buffer to be sent.
443  * \param[in] current_size Size of the data in bytes.
444  *
445  * \return error code /ref lan9118_error_t
446  */
447 enum lan9118_error_t lan9118_send_by_chunks(const struct lan9118_eth_dev_t* dev, uint32_t total_payload_length,
448                                             bool is_new_packet, const char* data, uint32_t current_size);
449 
450 /**
451  * \brief Reads an incoming Ethernet packet into the given buffer.
452  *        Stops reading at packet border.
453  *
454  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
455  * \param[in,out] data Pointer to a pre-allocated input buffer.
456  *                     Allocating sufficient memory space is the caller's
457  *                     responsibility, which is typically done by calling
458  *                     \ref lan9118_peek_next_packet_size.
459  * \param[in] dlen Length of the allocated data in bytes.
460  *
461  * \return Number of bytes read from the Rx FIFO into the given buffer.
462  */
463 uint32_t lan9118_receive_by_chunks(const struct lan9118_eth_dev_t* dev, char* data, uint32_t dlen);
464 
465 /**
466  * \brief Get the used space of Rx fifo in bytes.
467  *
468  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
469  *
470  * \return Data received and waiting for read in bytes
471  */
472 uint32_t lan9118_get_rxfifo_data_used_space(const struct lan9118_eth_dev_t* dev);
473 
474 /**
475  * \brief Gets the size of next unread packet in Rx buffer, using the peak
476  *        register, which is not destructive so can be read asynchronously.
477  *        Warning: In case of heavy receiving loads, this register may not
478  *        be in perfect sync.
479  *
480  * \param[in] dev Ethernet device structure \ref lan9118_eth_dev_t
481  *
482  * \return Size of the next packet in bytes, read from the Rx Peek register.
483  */
484 uint32_t lan9118_peek_next_packet_size(const struct lan9118_eth_dev_t* dev);
485 
486 /** \brief  Allocates a buf and returns the data from the incoming
487  * packet.
488  *
489  *  \return a buf filled with the received packet
490  * (including MAC header)
491  */
492 struct pbuf* LowLevelInput(void);
493 
494 /**
495  * \brief Sends the packet over the link
496  *
497  * That can not be called from an interrupt context.
498  *
499  * @param netif a pre-allocated netif structure
500  * @param buf  Packet to be send
501  * @return     True if the packet was send successfully, False otherwise
502  */
503 err_t Lan9118LinkOut(struct netif* netif, struct pbuf* buf);
504 
505 /** \brief  Packet reception task
506  *
507  * This task is called when a packet is received. It will
508  * pass the packet to the Network Stack.
509  */
510 void Lan9118PacketRx(void);
511 
512 /** \brief  interrupt called
513  *
514  * This task is handle rx data.
515  */
516 void EthernetReceiveHandler(void);
517 
518 /**
519  * \brief In this function, the hardware should be initialized.
520  * Called from EthernetifInit().
521  *
522  * @param netif the already initialized lwip network interface structure
523  *        for this ethernetif
524  */
525 void LowLevelInit(struct netif* netif);
526 
527 /**
528  * \brief Init net config
529  *
530  * This task is called when netif_add()
531  */
532 err_t EthernetifInit(struct netif* netif);
533 
534 /**
535  * \brief Init Lan9118 net
536  *
537  */
538 void Lan9118NetInit(void);
539 
540 /**
541  * \brief Init net
542  *
543  */
544 void NetInit(void);
545 
546 #endif /* __LAN9118_ETH_H__ */
547