NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
StarterWare Ethernet Design
The StarterWare Ethernet software deliverable consists of four main layers:
- Device Abstraction Layer - EMAC/CPSW DAL, MDIO DAL, PHY DAL
- LWIP Network Interface Layer - StarterWare NetIF port for LWIP
- LWIP Application Layer - An IP stack based application based on LWIP. Examples provided with StarterWare include an HTTP server, a UDP based client, an echo server, etc. The packets start and end at this layer.
- System Application Layer - The application layer that is used for system initialization and can be used for any other algorithm of the system
Device Abstraction Layer
This layer implements the lowest level hardware abstraction APIs that can be used for control and configuration of the EMAC device. There are three files that form this layer and are located at StarterWare_xx_yy_mm_pp/drivers:
- emac.c OR cpsw.c
- mdio.c - MDIO interface between the PHY and MAC
- lan8710a.c - PHY device
The device abstraction layer is implemented as a very light layer just for hardware/device access and conforms to the generic framework of StarterWare. It does not maintain any state variables.
lwIP Interface Layer
To interface with the rest of the network, the device abstraction layer needs to be glued with a network stack that can form and interpret network packets. StarterWare uses lwIP for this purpose because it has no OS dependency and supports many standard network protocols. The device abstraction hooks into the interface layer of lwIP. This is also referred to as the device-specific "port" or the StarterWare-interface for lwIP. This lwIP interface layer forms a major part of the StarterWare network driver. It defines standard interface entry points and state variables. A network device is represented by struct netif, generically referred to as netif. The netif contains all the information about the interface, including the IP/MAC address(s), TCP/IP options, protocol handlers, link information, and (most importantly) the network device driver entry point callbacks. Every network interface must implement the linkoutput and init callbacks, and all state information is maintained in this structure. The interface layer also implements the core interrupt handling and DMA handling. All the required function calls for initializing the lwIP stack and registering the StarterWare network interface are performed in lwiplib.c. Refer to the lwIP documentation for more information about the lwIP stack implementation. Further sections below explain the network interface initialization and registration. This is located at third_party/lwip-1.x.x/ports/<port_name>/
StarterWare Network Interface Layer
The main tasks of the StarterWare network interface layer are:
- Network device initialization
The first step towards bringing up the interface is done as part of the <device>if_init. This function is called when the network device is registered with the lwIP stack using netif_add. As part of the initialization, the netif output callbacks are registered and hardware initialization, including PHY and DMA initialization, is performed. DMA buffer descriptor (BD) pools are maintained in the CPPI RAM for both TX and RX channels. The descriptor chains are maintained by the "free_head", which points to the next unused/free descriptor in the BD pool, and "active_tail", which points to the last BD in the active queue that has been en-queued to the hardware. The packet buffers (pbuf) are pre-allocated for maximum length and queued in the receive buffer descriptors before the reception begins. Please refer to the lwIP documentation for details on pbuf handling by lwIP.
- Packet data transmission
Packet data transmission takes place inside the linkoutput callback registered with the lwIP stack. This callback is invoked whenever the lwIP stack receives a packet for transmission from the application layer. The pbuf can contain a chain of packet buffers and hence the DMA descriptors are properly updated (chained if necessary), with SOP, EOP and length fields. The first DMA descriptor is marked with the EOP and OWNER flags, while only the last is set with the EOP flag. After filling the BD's with the pbuf information, the BD, which corresponds to the SOP is written to the HEAD descriptor pointer register to start the transmission. Once a packet is transmitted, the EMAC Control Core generates a transmit interrupt. This interrupt is cleared only if the completion pointer is written with the last BD processed. In the interrupt handler, the next BD to process is taken and traversed to reach the BD that corresponds to the end of the packet. This BD, which corresponds to the end of the packet, is written to the completion pointer. After this, the pbuf that corresponds to this packet is freed. Thus it is made sure that the freeing of pbuf is done only after the packet transmission is complete.
- Packet data reception
Packet reception takes place in the context of the interrupt handler for receive. As described earlier, the receive buffer descriptors are en-queued to the DMA before the reception can actually begin. The pbuf allocated for maximum length, may actually contain a chain of packet buffers. The descriptors are updated for OWNER flag only. The EOP, SOP and EOQ are updated by the DMA upon completion of the reception. One important point to note is that, the actual data received may be less/more than the max length allocated. Hence the pbuf chain needs to be adjusted as detailed here. First, the active_head (which is the first BD en-queued), is checked for OWNER bit having been cleared by the DMA. Then the BD list is traversed, starting at the active_head, to find the EOP BD, which is the last BD of the current packet. While doing so if the EOP is not found on the current BD, then the pbuf of the current BD is chained to the pbuf of the next BD, since the current packet has spilled over to the next BD. Once, the EOP is found the last pbuf is updated as the terminator (pbuf->next = NULL). Thus, the entire packet is collected and passed to the upper layer for processing. Since, the current BD has been done with, it is put back at the free_head, by allocating a new pbuf.
lwIP Application Layer
This layer contains the ethernet application (HTTP server, echo server, etc.). This is located at StarterWare_xx_yy_mm_pp/third_party/lwip-1.x.x/apps/<application>. This is the layer at which all the imcoming packets terminate and all outgoing packets originate.
System Application Layer
This layer implements system level initialization and provides options for lwIP stack. This layer can contain any other algorithms, decoding, etc. The main IP stack based application is part of the lwip directory as mentioned above.