The LPC LWIP port uses zero-copy buffers. Zero-copy buffers can improve system performance over copied buffers when transferring large amounts of ethernet data. Zero-copy buffers also use less memory for data storage, as bounce buffers are not needed between the LWIP pbufs and the ethernet DMA buffers. This section gives a brief overview of how buffers are managed in the driver and the LWIP applications.
For zero-copy buffers, the initial pbufs needed to receive packets are pre-allocated and assigned to the ethernet controller at the maximum expected packet size. It should be noted that the payload for the packet in a pbuf must always be non-chained (contiguous) for receive. The driver will allocate packets with maximum packet size without any chaining. When a packet is received, the hardware places the received data directly into the pbuf's data (payload) area. The pbuf is then passed to the network layer without an extra copy where it is used by the application or LWIP and then de-allocated once it finishes with the packet.
Once the pbuf leaves the driver's functions, it no longer tracks it or it's buffer, but the original descriptor that was associated with the pbuf is now available for a new pbuf. The driver will attetmpt to allocate and requeue a new pbuf for the descriptor before returning the received packet. If memory is not available for the new pbuf, the descriptor remains free and an attenpt will be made to allocate a new pbuf on the next received packet. (Calling lpc_rx_queue() anytime will also attempt to reload any idle RX descriptors).
Note: For the LPC17xx, the descriptors and buffers must be located only in peripheral RAM or external memory. For the LPC18xx/43xx, descriptors and buffers can be located anywhere.
For zero-copy buffers, the initial pbuf's payload addresses are used directly with the EMAC TX descriptors. The driver will chain buffers in the descriptor if needed (if a chained pbuf is used) and keep a reference of the pbufs that are used for the transfer. The buffers/pbufs must remain in memory until the EMAC has transferred the data related to the pbuf(s). Once the EMAC transfers the buffers, the pbuf(s) will be de-allocated by the driver.
Note: For the LPC17xx, the descriptors and buffers must be located only in peripheral RAM or external memory. For the LPC18xx/43xx, descriptors and buffers can be located anywhere.
In some cases, buffers may be passed to the driver that are located in FLASH memory, IRAM, or slow memory. The EMAC driver and peripheral can't send this data directly via DMA (due to architecture or speed restrictions), so the data needs to be relocated to an area of memory that it can be sent from. If the driver detects that a buffer address used for a zero-copy transfer is not usable by the EMAC, it will copy the buffer to a temporary bounce buffer and send it from that buffer instead. This occurs automatically inside the driver if the bounce buffer support is enabled. If the bounce buffer support is not enabled and a non-usable buffer is detected, the driver will raise an exception.
For the LPC17xx, this support is enabled by setting LPC_TX_PBUF_BOUNCE_EN to 1.
For the LCP18xx/43xx, this support is enabled by setting LPC_CHECK_SLOWMEM to 1. If LPC_CHECK_SLOWMEM is set to 1, the memory ranges for the check must be setup with the LPC_SLOWMEM_ARRAY define.