Updated K64F ethernet driver to use memory manager

pull/6847/head
Mika Leppänen 2017-12-21 11:13:22 +02:00 committed by Kevin Bracey
parent bc5d4d1c0d
commit 668e0821a1
2 changed files with 37 additions and 33 deletions

View File

@ -38,7 +38,6 @@
#include "cmsis_os.h" #include "cmsis_os.h"
#include "mbed_interface.h" #include "mbed_interface.h"
#include "emac_stack_mem.h"
#include "mbed_assert.h" #include "mbed_assert.h"
#include "netsocket/nsapi_types.h" #include "netsocket/nsapi_types.h"
#include "mbed_shared_queues.h" #include "mbed_shared_queues.h"
@ -56,9 +55,9 @@ uint8_t *tx_desc_start_addr;
// RX Buffer descriptors // RX Buffer descriptors
uint8_t *rx_desc_start_addr; uint8_t *rx_desc_start_addr;
// RX packet buffer pointers // RX packet buffer pointers
emac_stack_mem_t *rx_buff[ENET_RX_RING_LEN]; emac_mem_buf_t *rx_buff[ENET_RX_RING_LEN];
// TX packet buffer pointers // TX packet buffer pointers
emac_stack_mem_t *tx_buff[ENET_RX_RING_LEN]; emac_mem_buf_t *tx_buff[ENET_RX_RING_LEN];
// RX packet payload pointers // RX packet payload pointers
uint32_t *rx_ptr[ENET_RX_RING_LEN]; uint32_t *rx_ptr[ENET_RX_RING_LEN];
@ -138,7 +137,7 @@ void K64F_EMAC::tx_reclaim()
// Traverse all descriptors, looking for the ones modified by the uDMA // Traverse all descriptors, looking for the ones modified by the uDMA
while((tx_consume_index != tx_produce_index) && while((tx_consume_index != tx_produce_index) &&
(!(g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))) { (!(g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))) {
emac_stack_mem_free(tx_buff[tx_consume_index % ENET_TX_RING_LEN]); memory_manager->free(tx_buff[tx_consume_index % ENET_TX_RING_LEN]);
if (g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK) if (g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
g_handle.txBdDirty = g_handle.txBdBase; g_handle.txBdDirty = g_handle.txBdBase;
else else
@ -212,11 +211,11 @@ bool K64F_EMAC::low_level_init_successful()
/* Create buffers for each receive BD */ /* Create buffers for each receive BD */
for (i = 0; i < ENET_RX_RING_LEN; i++) { for (i = 0; i < ENET_RX_RING_LEN; i++) {
rx_buff[i] = emac_stack_mem_alloc(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT); rx_buff[i] = memory_manager->alloc_heap(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT);
if (NULL == rx_buff[i]) if (NULL == rx_buff[i])
return false; return false;
rx_ptr[i] = (uint32_t*)emac_stack_mem_ptr(rx_buff[i]); rx_ptr[i] = (uint32_t*)memory_manager->get_ptr(rx_buff[i]);
} }
tx_consume_index = tx_produce_index = 0; tx_consume_index = tx_produce_index = 0;
@ -277,16 +276,16 @@ bool K64F_EMAC::low_level_init_successful()
} }
/** \brief Allocates a emac_stack_mem_t and returns the data from the incoming packet. /** \brief Allocates a emac_mem_buf_t and returns the data from the incoming packet.
* *
* \param[in] idx index of packet to be read * \param[in] idx index of packet to be read
* \return a emac_stack_mem_t filled with the received packet (including MAC header) * \return a emac_mem_buf_t filled with the received packet (including MAC header)
*/ */
emac_stack_mem_t *K64F_EMAC::low_level_input(int idx) emac_mem_buf_t *K64F_EMAC::low_level_input(int idx)
{ {
volatile enet_rx_bd_struct_t *bdPtr = g_handle.rxBdCurrent; volatile enet_rx_bd_struct_t *bdPtr = g_handle.rxBdCurrent;
emac_stack_mem_t *p = NULL; emac_mem_buf_t *p = NULL;
emac_stack_mem_t *temp_rxbuf = NULL; emac_mem_buf_t *temp_rxbuf = NULL;
uint32_t length = 0; uint32_t length = 0;
const uint16_t err_mask = ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK | ENET_BUFFDESCRIPTOR_RX_CRC_MASK | const uint16_t err_mask = ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK | ENET_BUFFDESCRIPTOR_RX_CRC_MASK |
ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK | ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK; ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK | ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK;
@ -306,10 +305,10 @@ emac_stack_mem_t *K64F_EMAC::low_level_input(int idx)
/* Zero-copy */ /* Zero-copy */
p = rx_buff[idx]; p = rx_buff[idx];
emac_stack_mem_set_len(p, length); memory_manager->set_len(p, length);
/* Attempt to queue new buffer */ /* Attempt to queue new buffer */
temp_rxbuf = emac_stack_mem_alloc(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT); temp_rxbuf = memory_manager->alloc_heap(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT);
if (NULL == temp_rxbuf) { if (NULL == temp_rxbuf) {
/* Re-queue the same buffer */ /* Re-queue the same buffer */
update_read_buffer(NULL); update_read_buffer(NULL);
@ -322,12 +321,9 @@ emac_stack_mem_t *K64F_EMAC::low_level_input(int idx)
} }
rx_buff[idx] = temp_rxbuf; rx_buff[idx] = temp_rxbuf;
rx_ptr[idx] = (uint32_t*)emac_stack_mem_ptr(rx_buff[idx]); rx_ptr[idx] = (uint32_t*)memory_manager->get_ptr(rx_buff[idx]);
update_read_buffer((uint8_t*)rx_ptr[idx]); update_read_buffer((uint8_t*)rx_ptr[idx]);
/* Save size */
emac_stack_mem_set_chain_len(p, length);
} }
#ifdef LOCK_RX_THREAD #ifdef LOCK_RX_THREAD
@ -343,7 +339,7 @@ emac_stack_mem_t *K64F_EMAC::low_level_input(int idx)
*/ */
void K64F_EMAC::input(int idx) void K64F_EMAC::input(int idx)
{ {
emac_stack_mem_t *p; emac_mem_buf_t *p;
/* move received packet into a new buf */ /* move received packet into a new buf */
p = low_level_input(idx); p = low_level_input(idx);
@ -412,21 +408,17 @@ void K64F_EMAC::packet_tx()
* \param[in] buf the MAC packet to send (e.g. IP packet including MAC addresses and type) * \param[in] buf the MAC packet to send (e.g. IP packet including MAC addresses and type)
* \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent * \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
*/ */
bool K64F_EMAC::link_out(emac_stack_mem_chain_t *chain) bool K64F_EMAC::link_out(emac_mem_buf_t *buf)
{ {
emac_stack_mem_t *q; emac_mem_buf_t *temp_pbuf;
emac_stack_mem_t *temp_pbuf;
uint8_t *psend = NULL, *dst;
temp_pbuf = emac_stack_mem_alloc(emac_stack_mem_chain_len(chain), ENET_BUFF_ALIGNMENT); temp_pbuf = memory_manager->alloc_heap(memory_manager->get_total_len(buf), ENET_BUFF_ALIGNMENT);
if (NULL == temp_pbuf) if (NULL == temp_pbuf)
return false; return false;
psend = (uint8_t*)emac_stack_mem_ptr(temp_pbuf); // Copy to new buffer and free original
for (q = emac_stack_mem_chain_dequeue(&chain), dst = psend; q != NULL; q = emac_stack_mem_chain_dequeue(&chain)) { memory_manager->copy(temp_pbuf, buf);
memcpy(dst, emac_stack_mem_ptr(q), emac_stack_mem_len(q)); memory_manager->free(buf);
dst += emac_stack_mem_len(q);
}
/* Check if a descriptor is available for the transfer. */ /* Check if a descriptor is available for the transfer. */
if (xTXDCountSem.wait(0) == 0) if (xTXDCountSem.wait(0) == 0)
@ -440,8 +432,8 @@ bool K64F_EMAC::link_out(emac_stack_mem_chain_t *chain)
tx_produce_index += 1; tx_produce_index += 1;
/* Setup transfers */ /* Setup transfers */
g_handle.txBdCurrent->buffer = psend; g_handle.txBdCurrent->buffer = static_cast<uint8_t *>(memory_manager->get_ptr(temp_pbuf));
g_handle.txBdCurrent->length = emac_stack_mem_len(temp_pbuf); g_handle.txBdCurrent->length = memory_manager->get_len(temp_pbuf);
g_handle.txBdCurrent->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); g_handle.txBdCurrent->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
/* Increase the buffer descriptor address. */ /* Increase the buffer descriptor address. */
@ -545,7 +537,7 @@ uint8_t K64F_EMAC::get_hwaddr_size() const
bool K64F_EMAC::get_hwaddr(uint8_t *addr) const bool K64F_EMAC::get_hwaddr(uint8_t *addr) const
{ {
return false; return false;
} }
void K64F_EMAC::set_hwaddr(const uint8_t *addr) void K64F_EMAC::set_hwaddr(const uint8_t *addr)
@ -574,6 +566,11 @@ void K64F_EMAC::power_down()
/* No-op at this stage */ /* No-op at this stage */
} }
void K64F_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr)
{
memory_manager = &mem_mngr;
}
K64F_EMAC &K64F_EMAC::get_instance() { K64F_EMAC &K64F_EMAC::get_instance() {
static K64F_EMAC emac; static K64F_EMAC emac;

View File

@ -72,7 +72,7 @@ public:
* @param buf Packet to be send * @param buf Packet to be send
* @return True if the packet was send successfully, False otherwise * @return True if the packet was send successfully, False otherwise
*/ */
virtual bool link_out(emac_stack_mem_chain_t *buf); virtual bool link_out(emac_mem_buf_t *buf);
/** /**
* Initializes the HW * Initializes the HW
@ -107,6 +107,12 @@ public:
*/ */
virtual void add_multicast_group(uint8_t *address); virtual void add_multicast_group(uint8_t *address);
/** Sets memory manager that is used to handle memory buffers
*
* @param mem_mngr Pointer to memory manager
*/
virtual void set_memory_manager(EMACMemoryManager &mem_mngr);
private: private:
bool low_level_init_successful(); bool low_level_init_successful();
void rx_isr(); void rx_isr();
@ -115,7 +121,7 @@ private:
void packet_tx(); void packet_tx();
void tx_reclaim(); void tx_reclaim();
void input(int idx); void input(int idx);
emac_stack_mem_t *low_level_input(int idx); emac_mem_buf_t *low_level_input(int idx);
static void thread_function(void* pvParameters); static void thread_function(void* pvParameters);
void phy_task(); void phy_task();
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param); static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param);
@ -127,6 +133,7 @@ private:
uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */ uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */
emac_link_input_cb_t emac_link_input_cb; /**< Callback for incoming data */ emac_link_input_cb_t emac_link_input_cb; /**< Callback for incoming data */
emac_link_state_change_cb_t emac_link_state_cb; /**< Link state change callback */ emac_link_state_change_cb_t emac_link_state_cb; /**< Link state change callback */
EMACMemoryManager *memory_manager; /**< Memory manager */
int phy_task_handle; /**< Handle for phy task event */ int phy_task_handle; /**< Handle for phy task event */
struct PHY_STATE { struct PHY_STATE {
int connected; int connected;