mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Updated K64F ethernet driver to use memory manager
							parent
							
								
									bc5d4d1c0d
								
							
						
					
					
						commit
						668e0821a1
					
				| 
						 | 
				
			
			@ -38,7 +38,6 @@
 | 
			
		|||
#include "cmsis_os.h"
 | 
			
		||||
 | 
			
		||||
#include "mbed_interface.h"
 | 
			
		||||
#include "emac_stack_mem.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -56,9 +55,9 @@ uint8_t *tx_desc_start_addr;
 | 
			
		|||
// RX Buffer descriptors
 | 
			
		||||
uint8_t *rx_desc_start_addr;
 | 
			
		||||
// 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
 | 
			
		||||
emac_stack_mem_t *tx_buff[ENET_RX_RING_LEN];
 | 
			
		||||
emac_mem_buf_t *tx_buff[ENET_RX_RING_LEN];
 | 
			
		||||
// RX packet payload pointers
 | 
			
		||||
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
 | 
			
		||||
  while((tx_consume_index != tx_produce_index) &&
 | 
			
		||||
        (!(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)
 | 
			
		||||
        g_handle.txBdDirty = g_handle.txBdBase;
 | 
			
		||||
      else
 | 
			
		||||
| 
						 | 
				
			
			@ -212,11 +211,11 @@ bool K64F_EMAC::low_level_init_successful()
 | 
			
		|||
 | 
			
		||||
  /* Create buffers for each receive BD */
 | 
			
		||||
  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])
 | 
			
		||||
      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;
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *  \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;
 | 
			
		||||
  emac_stack_mem_t *p = NULL;
 | 
			
		||||
  emac_stack_mem_t *temp_rxbuf = NULL;
 | 
			
		||||
  emac_mem_buf_t *p = NULL;
 | 
			
		||||
  emac_mem_buf_t *temp_rxbuf = NULL;
 | 
			
		||||
  uint32_t length = 0;
 | 
			
		||||
  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;
 | 
			
		||||
| 
						 | 
				
			
			@ -306,10 +305,10 @@ emac_stack_mem_t *K64F_EMAC::low_level_input(int idx)
 | 
			
		|||
 | 
			
		||||
    /* Zero-copy */
 | 
			
		||||
    p = rx_buff[idx];
 | 
			
		||||
    emac_stack_mem_set_len(p, length);
 | 
			
		||||
    memory_manager->set_len(p, length);
 | 
			
		||||
 | 
			
		||||
    /* 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) {
 | 
			
		||||
      /* Re-queue the same buffer */
 | 
			
		||||
      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_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]);
 | 
			
		||||
 | 
			
		||||
    /* Save size */
 | 
			
		||||
    emac_stack_mem_set_chain_len(p, length);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
{
 | 
			
		||||
  emac_stack_mem_t *p;
 | 
			
		||||
  emac_mem_buf_t *p;
 | 
			
		||||
 | 
			
		||||
  /* move received packet into a new buf */
 | 
			
		||||
  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)
 | 
			
		||||
 *  \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_stack_mem_t *temp_pbuf;
 | 
			
		||||
  uint8_t *psend = NULL, *dst;
 | 
			
		||||
  emac_mem_buf_t *temp_pbuf;
 | 
			
		||||
 | 
			
		||||
  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)
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  psend = (uint8_t*)emac_stack_mem_ptr(temp_pbuf);
 | 
			
		||||
  for (q = emac_stack_mem_chain_dequeue(&chain), dst = psend; q != NULL; q = emac_stack_mem_chain_dequeue(&chain)) {
 | 
			
		||||
    memcpy(dst, emac_stack_mem_ptr(q), emac_stack_mem_len(q));
 | 
			
		||||
    dst += emac_stack_mem_len(q);
 | 
			
		||||
  }
 | 
			
		||||
  // Copy to new buffer and free original
 | 
			
		||||
  memory_manager->copy(temp_pbuf, buf);
 | 
			
		||||
  memory_manager->free(buf);
 | 
			
		||||
 | 
			
		||||
  /* Check if a descriptor is available for the transfer. */
 | 
			
		||||
  if (xTXDCountSem.wait(0) == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -440,8 +432,8 @@ bool K64F_EMAC::link_out(emac_stack_mem_chain_t *chain)
 | 
			
		|||
  tx_produce_index += 1;
 | 
			
		||||
 | 
			
		||||
  /* Setup transfers */
 | 
			
		||||
  g_handle.txBdCurrent->buffer = psend;
 | 
			
		||||
  g_handle.txBdCurrent->length = emac_stack_mem_len(temp_pbuf);
 | 
			
		||||
  g_handle.txBdCurrent->buffer = static_cast<uint8_t *>(memory_manager->get_ptr(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);
 | 
			
		||||
 | 
			
		||||
  /* 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
 | 
			
		||||
{
 | 
			
		||||
  return false;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void K64F_EMAC::set_hwaddr(const uint8_t *addr)
 | 
			
		||||
| 
						 | 
				
			
			@ -574,6 +566,11 @@ void K64F_EMAC::power_down()
 | 
			
		|||
  /* No-op at this stage */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void K64F_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr)
 | 
			
		||||
{
 | 
			
		||||
    memory_manager = &mem_mngr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
K64F_EMAC &K64F_EMAC::get_instance() {
 | 
			
		||||
    static K64F_EMAC emac;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ public:
 | 
			
		|||
     * @param buf  Packet to be send
 | 
			
		||||
     * @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
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ public:
 | 
			
		|||
     */
 | 
			
		||||
    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:
 | 
			
		||||
    bool low_level_init_successful();
 | 
			
		||||
    void rx_isr();
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +121,7 @@ private:
 | 
			
		|||
    void packet_tx();
 | 
			
		||||
    void tx_reclaim();
 | 
			
		||||
    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);
 | 
			
		||||
    void phy_task();
 | 
			
		||||
    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 */
 | 
			
		||||
    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 */
 | 
			
		||||
    EMACMemoryManager *memory_manager; /**< Memory manager */
 | 
			
		||||
    int phy_task_handle; /**< Handle for phy task event */
 | 
			
		||||
    struct PHY_STATE {
 | 
			
		||||
        int connected;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue