See Quickstart guide for EMAC driver..
Driver for the EMAC (Ethernet Media Access Controller). This file contains basic functions for the EMAC, with support for all modes, settings and clock speeds.
This driver does not depend on other modules.
Modules | |
Related Project(s) | |
In this section you can find all the projects related to the Ethernet Media Access Controller. | |
Quick Start Guide(s) | |
In this section you can find a list of all Quick Start guides related to the Ethernet Media Access Controller. | |
Data Structures | |
struct | emac_dev_mem |
EMAC device memory management struct. More... | |
Macros | |
#define | CIRC_CLEAR(head, tail) (head = tail = 0) |
Clear circular buffer. More... | |
#define | CIRC_CNT(head, tail, size) (((head) - (tail)) % (size)) |
Return count in buffer. More... | |
#define | CIRC_EMPTY(head, tail) (head == tail) |
Circular buffer is empty ? More... | |
#define | CIRC_SPACE(head, tail, size) CIRC_CNT((tail),((head)+1),(size)) |
Typedefs | |
typedef struct emac_dev_mem | emac_dev_mem_t |
EMAC device memory management struct. More... | |
Functions | |
static void | circ_inc (uint16_t *headortail, uint32_t size) |
Increment head or tail. More... | |
uint32_t | emac_dev_get_tx_load (emac_device_t *p_emac_dev) |
Get current load of transmit. More... | |
void | emac_dev_init (Emac *p_emac, emac_device_t *p_emac_dev, emac_options_t *p_opt) |
Initialize the EMAC driver. More... | |
uint32_t | emac_dev_read (emac_device_t *p_emac_dev, uint8_t *p_frame, uint32_t ul_frame_size, uint32_t *p_rcv_size) |
Frames can be read from the EMAC in multiple sections. More... | |
void | emac_dev_reset (emac_device_t *p_emac_dev) |
Reset TX & RX queue & statistics. More... | |
void | emac_dev_set_rx_callback (emac_device_t *p_emac_dev, emac_dev_tx_cb_t func_rx_cb) |
Register/Clear RX callback. More... | |
uint8_t | emac_dev_set_tx_wakeup_callback (emac_device_t *p_emac_dev, emac_dev_wakeup_cb_t func_wakeup_cb, uint8_t uc_threshold) |
Register/Clear TX wakeup callback. More... | |
uint32_t | emac_dev_write (emac_device_t *p_emac_dev, void *p_buffer, uint32_t ul_size, emac_dev_tx_cb_t func_tx_cb) |
Send ulLength bytes from pcFrom. More... | |
void | emac_handler (emac_device_t *p_emac_dev) |
EMAC Interrupt handler. More... | |
static uint8_t | emac_init_mem (Emac *p_emac, emac_device_t *p_emac_dev, emac_dev_mem_t *p_dev_mm, emac_dev_tx_cb_t *p_tx_cb) |
Initialize the allocated buffer lists for EMAC driver to transfer data. More... | |
uint8_t | emac_phy_read (Emac *p_emac, uint8_t uc_phy_address, uint8_t uc_address, uint32_t *p_value) |
Read the PHY register. More... | |
uint8_t | emac_phy_write (Emac *p_emac, uint8_t uc_phy_address, uint8_t uc_address, uint32_t ul_value) |
Write the PHY register. More... | |
static void | emac_reset_rx_mem (emac_device_t *p_dev) |
Disable receiver, reset registers and descriptor list. More... | |
static void | emac_reset_tx_mem (emac_device_t *p_dev) |
Disable transfer, reset registers and descriptor lists. More... | |
static uint8_t | emac_wait_phy (Emac *p_emac, const uint32_t ul_retry) |
Wait PHY operation to be completed. More... | |
Variables | |
static emac_rx_descriptor_t | gs_rx_desc [EMAC_RX_BUFFERS] |
RX descriptors lists. More... | |
static emac_dev_tx_cb_t | gs_tx_callback [EMAC_TX_BUFFERS] |
TX callback lists. More... | |
static emac_tx_descriptor_t | gs_tx_desc [EMAC_TX_BUFFERS] |
TX descriptor lists. More... | |
static uint8_t | gs_uc_rx_buffer [EMAC_RX_BUFFERS *EMAC_RX_UNITSIZE] |
Receive Buffer. More... | |
static uint8_t | gs_uc_tx_buffer [EMAC_TX_BUFFERS *EMAC_TX_UNITSIZE] |
Send Buffer. More... | |
#define CIRC_CLEAR | ( | head, | |
tail | |||
) | (head = tail = 0) |
Clear circular buffer.
Referenced by emac_reset_tx_mem().
#define CIRC_CNT | ( | head, | |
tail, | |||
size | |||
) | (((head) - (tail)) % (size)) |
Return count in buffer.
Referenced by emac_dev_get_tx_load(), and emac_handler().
#define CIRC_EMPTY | ( | head, | |
tail | |||
) | (head == tail) |
Circular buffer is empty ?
Referenced by emac_handler().
#define CIRC_SPACE | ( | head, | |
tail, | |||
size | |||
) | CIRC_CNT((tail),((head)+1),(size)) |
Referenced by emac_dev_write(), and emac_handler().
typedef struct emac_dev_mem emac_dev_mem_t |
EMAC device memory management struct.
|
static |
Increment head or tail.
Referenced by emac_dev_read(), emac_dev_write(), and emac_handler().
uint32_t emac_dev_get_tx_load | ( | emac_device_t * | p_emac_dev | ) |
Get current load of transmit.
p_emac_dev | Pointer to the EMAC device instance. |
References CIRC_CNT, emac_device::us_tx_head, emac_device::us_tx_list_size, and emac_device::us_tx_tail.
void emac_dev_init | ( | Emac * | p_emac, |
emac_device_t * | p_emac_dev, | ||
emac_options_t * | p_opt | ||
) |
Initialize the EMAC driver.
p_emac | Pointer to the EMAC instance. |
p_emac_dev | Pointer to the EMAC device instance. |
p_opt | EMAC configure options. |
References emac_clear_rx_status(), emac_clear_statistics(), emac_clear_tx_status(), emac_disable_broadcast(), emac_disable_interrupt(), emac_enable_copy_all(), emac_get_configure(), emac_get_interrupt_status(), emac_init_mem(), emac_network_control(), emac_set_address(), emac_set_configure(), gs_rx_desc, gs_tx_callback, gs_tx_desc, gs_uc_rx_buffer, gs_uc_tx_buffer, emac_dev_mem::p_rx_buffer, emac_dev_mem::p_rx_dscr, emac_dev_mem::p_tx_buffer, emac_dev_mem::p_tx_dscr, emac_options::uc_copy_all_frame, emac_options::uc_mac_addr, emac_options::uc_no_boardcast, emac_dev_mem::us_rx_size, and emac_dev_mem::us_tx_size.
Referenced by low_level_init(), main(), and run_emac_link_test().
uint32_t emac_dev_read | ( | emac_device_t * | p_emac_dev, |
uint8_t * | p_frame, | ||
uint32_t | ul_frame_size, | ||
uint32_t * | p_rcv_size | ||
) |
Frames can be read from the EMAC in multiple sections.
Read ul_frame_size bytes from the EMAC receive buffers to pcTo. p_rcv_size is the size of the entire frame. Generally emac_read will be repeatedly called until the sum of all the ul_frame_size equals the value of p_rcv_size.
p_emac_dev | Pointer to the EMAC device instance. |
p_frame | Address of the frame buffer. |
ul_frame_size | Length of the frame. |
p_rcv_size | Received frame size. |
References emac_rx_descriptor::addr, circ_inc(), EMAC_OK, EMAC_PARAM, EMAC_RX_NULL, EMAC_RX_UNITSIZE, EMAC_RXD_ADDR_MASK, EMAC_RXD_EOF, EMAC_RXD_LEN_MASK, EMAC_RXD_OWNERSHIP, EMAC_RXD_SOF, EMAC_SIZE_TOO_SMALL, NULL, emac_device::p_rx_dscr, emac_rx_descriptor::status, emac_device::us_rx_idx, emac_device::us_rx_list_size, emac_rx_descriptor::emac_rx_addr::val, and emac_rx_descriptor::emac_rx_status::val.
Referenced by low_level_input(), main(), and run_emac_read_write_test().
void emac_dev_reset | ( | emac_device_t * | p_emac_dev | ) |
Reset TX & RX queue & statistics.
p_emac_dev | Pointer to EMAC device instance. |
References emac_network_control(), emac_reset_rx_mem(), emac_reset_tx_mem(), and emac_device::p_hw.
void emac_dev_set_rx_callback | ( | emac_device_t * | p_emac_dev, |
emac_dev_tx_cb_t | func_rx_cb | ||
) |
Register/Clear RX callback.
Callback will be invoked after the next received frame.
When emac_dev_read() returns EMAC_RX_NULL, the application task calls emac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state. The callback is in charge to resume the task once a new frame has been received. The next time emac_dev_read() is called, it will be successful.
This function is usually invoked from the RX callback itself with NULL callback, to unregister. Once the callback has resumed the application task, there is no need to invoke the callback again.
p_emac_dev | Pointer to the EMAC device instance. |
func_tx_cb | Receive callback function. |
References emac_disable_interrupt(), emac_enable_interrupt(), emac_device::func_rx_cb, NULL, and emac_device::p_hw.
uint8_t emac_dev_set_tx_wakeup_callback | ( | emac_device_t * | p_emac_dev, |
emac_dev_wakeup_cb_t | func_wakeup_cb, | ||
uint8_t | uc_threshold | ||
) |
Register/Clear TX wakeup callback.
When emac_dev_write() returns EMAC_TX_BUSY (all transmit descriptor busy), the application task calls emac_dev_set_tx_wakeup_callback() to register func_wakeup() callback and enters suspend state. The callback is in charge to resume the task once several transmit descriptors have been released. The next time emac_dev_write() will be called, it shall be successful.
This function is usually invoked with NULL callback from the TX wakeup callback itself, to unregister. Once the callback has resumed the application task, there is no need to invoke the callback again.
p_emac_dev | Pointer to EMAC device instance. |
func_wakeup | Pointer to wakeup callback function. |
uc_threshold | Number of free transmit descriptor before wakeup callback invoked. |
References EMAC_OK, EMAC_PARAM, emac_device::func_wakeup_cb, NULL, and emac_device::uc_wakeup_threshold.
uint32_t emac_dev_write | ( | emac_device_t * | p_emac_dev, |
void * | p_buffer, | ||
uint32_t | ul_size, | ||
emac_dev_tx_cb_t | func_tx_cb | ||
) |
Send ulLength bytes from pcFrom.
This copies the buffer to one of the EMAC Tx buffers, and then indicates to the EMAC that the buffer is ready. If lEndOfFrame is true then the data being copied is the end of the frame and the frame can be transmitted.
p_emac_dev | Pointer to the EMAC device instance. |
p_buffer | Pointer to the data buffer. |
ul_size | Length of the frame. |
func_tx_cb | Transmit callback function. |
References emac_tx_descriptor::addr, circ_inc(), CIRC_SPACE, EMAC_OK, EMAC_PARAM, emac_start_transmission(), EMAC_TX_BUSY, EMAC_TX_UNITSIZE, EMAC_TXD_LAST, EMAC_TXD_LEN_MASK, EMAC_TXD_WRAP, emac_device::func_tx_cb_list, emac_device::p_hw, emac_device::p_tx_dscr, emac_tx_descriptor::status, emac_device::us_tx_head, emac_device::us_tx_list_size, emac_device::us_tx_tail, and emac_tx_descriptor::emac_tx_status::val.
Referenced by emac_process_arp_packet(), emac_process_ip_packet(), low_level_output(), and run_emac_read_write_test().
void emac_handler | ( | emac_device_t * | p_emac_dev | ) |
EMAC Interrupt handler.
p_emac_dev | Pointer to EMAC device instance. |
References CIRC_CNT, CIRC_EMPTY, circ_inc(), CIRC_SPACE, emac_clear_rx_status(), emac_clear_tx_status(), emac_enable_transmit(), emac_get_interrupt_mask(), emac_get_interrupt_status(), emac_get_rx_status(), emac_get_tx_status(), emac_reset_tx_mem(), EMAC_TXD_USED, emac_device::func_rx_cb, emac_device::func_tx_cb_list, emac_device::func_wakeup_cb, emac_device::p_hw, emac_device::p_tx_dscr, emac_tx_descriptor::status, emac_device::uc_wakeup_threshold, emac_device::us_tx_head, emac_device::us_tx_list_size, emac_device::us_tx_tail, and emac_tx_descriptor::emac_tx_status::val.
Referenced by EMAC_Handler().
|
static |
Initialize the allocated buffer lists for EMAC driver to transfer data.
Must be invoked after emac_dev_init() but before RX/TX starts.
p_emac | Pointer to EMAC instance. |
p_emac_dev | Pointer to EMAC device instance. |
p_dev_mm | Pointer to the EMAC memory management control block. |
p_tx_cb | Pointer to allocated TX callback list. |
References emac_enable_interrupt(), emac_enable_receive(), emac_enable_statistics_write(), emac_enable_transmit(), EMAC_OK, EMAC_PARAM, emac_reset_rx_mem(), emac_reset_tx_mem(), emac_device::func_tx_cb_list, NULL, emac_dev_mem::p_rx_buffer, emac_device::p_rx_buffer, emac_dev_mem::p_rx_dscr, emac_device::p_rx_dscr, emac_dev_mem::p_tx_buffer, emac_device::p_tx_buffer, emac_dev_mem::p_tx_dscr, emac_device::p_tx_dscr, emac_device::us_rx_list_size, emac_dev_mem::us_rx_size, emac_device::us_tx_list_size, and emac_dev_mem::us_tx_size.
Referenced by emac_dev_init().
uint8_t emac_phy_read | ( | Emac * | p_emac, |
uint8_t | uc_phy_address, | ||
uint8_t | uc_address, | ||
uint32_t * | p_value | ||
) |
Read the PHY register.
p_emac | Pointer to the EMAC instance. |
uc_phy_address | PHY address. |
uc_address | Register address. |
p_value | Pointer to a 32-bit location to store read data. |
EMAC_OK if successfully, EMAC_TIMEOUT if timeout.
References emac_get_phy_data(), emac_maintain_phy(), EMAC_OK, EMAC_TIMEOUT, and emac_wait_phy().
Referenced by ethernet_phy_auto_negotiate(), ethernet_phy_find_valid(), ethernet_phy_reset(), and ethernet_phy_set_link().
uint8_t emac_phy_write | ( | Emac * | p_emac, |
uint8_t | uc_phy_address, | ||
uint8_t | uc_address, | ||
uint32_t | ul_value | ||
) |
Write the PHY register.
p_emac | Pointer to the EMAC instance. |
uc_phy_address | PHY Address. |
uc_address | Register Address. |
ul_value | Data to write, actually 16-bit data. |
EMAC_OK if successfully, EMAC_TIMEOUT if timeout.
References emac_maintain_phy(), EMAC_OK, EMAC_TIMEOUT, and emac_wait_phy().
Referenced by ethernet_phy_auto_negotiate(), and ethernet_phy_reset().
|
static |
Disable receiver, reset registers and descriptor list.
p_drv | Pointer to EMAC Driver instance. |
References emac_rx_descriptor::addr, emac_enable_receive(), EMAC_RX_UNITSIZE, EMAC_RXD_ADDR_MASK, EMAC_RXD_WRAP, emac_set_rx_queue(), emac_device::p_hw, emac_device::p_rx_buffer, emac_device::p_rx_dscr, emac_rx_descriptor::status, emac_device::us_rx_idx, emac_device::us_rx_list_size, emac_rx_descriptor::emac_rx_addr::val, and emac_rx_descriptor::emac_rx_status::val.
Referenced by emac_dev_reset(), and emac_init_mem().
|
static |
Disable transfer, reset registers and descriptor lists.
p_dev | Pointer to EMAC driver instance. |
References emac_tx_descriptor::addr, CIRC_CLEAR, emac_enable_transmit(), emac_set_tx_queue(), EMAC_TX_UNITSIZE, EMAC_TXD_USED, EMAC_TXD_WRAP, emac_device::p_hw, emac_device::p_tx_buffer, emac_device::p_tx_dscr, emac_tx_descriptor::status, emac_device::us_tx_head, emac_device::us_tx_list_size, emac_device::us_tx_tail, and emac_tx_descriptor::emac_tx_status::val.
Referenced by emac_dev_reset(), emac_handler(), and emac_init_mem().
|
static |
Wait PHY operation to be completed.
p_emac | HW controller address. |
ul_retry | The retry times, 0 to wait forever until completeness. |
Return EMAC_OK if the operation is completed successfully.
References emac_is_phy_idle(), EMAC_OK, and EMAC_TIMEOUT.
Referenced by emac_phy_read(), and emac_phy_write().
|
static |
RX descriptors lists.
Referenced by emac_dev_init().
|
static |
TX callback lists.
Referenced by emac_dev_init().
|
static |
TX descriptor lists.
Referenced by emac_dev_init().
|
static |
Receive Buffer.
Referenced by emac_dev_init().
|
static |
Send Buffer.
Section 3.6 of AMBA 2.0 spec states that burst should not cross the 1K Boundaries. Receive buffer manager write operations are burst of 2 words => 3 lsb bits of the address shall be set to 0.
Referenced by emac_dev_init().