Added preferred alignment to emac and copy to/from to memory manager

pull/6847/head
Mika Leppänen 2018-01-11 16:07:41 +02:00 committed by Kevin Bracey
parent 4950a993fd
commit 5da3cd9cce
9 changed files with 176 additions and 6 deletions

View File

@ -63,6 +63,16 @@ void LWIPMemoryManager::copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_
pbuf_copy(static_cast<struct pbuf *>(to_buf), static_cast<const struct pbuf *>(from_buf));
}
void LWIPMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
{
pbuf_take(static_cast<struct pbuf *>(to_buf), ptr, len);
}
uint32_t LWIPMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
{
return pbuf_copy_partial(static_cast<const struct pbuf *>(from_buf), ptr, len, 0);
}
void LWIPMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
{
pbuf_cat(static_cast<struct pbuf *>(to_buf), static_cast<struct pbuf *>(cat_buf));

View File

@ -86,6 +86,31 @@ public:
*/
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
/**
* Copy to a memory buffer chain
*
* Copies data to a buffer chain. Copy operation does not adjust the lengths
* of the copied-to memory buffer chain, so chain total length must match the
* copied length.
*
* @param to_buf Memory buffer chain to copy to
* @param ptr Pointer to data
* @param len Data length
*/
virtual void copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len);
/**
* Copy from a memory buffer chain
*
* Copies data from a memory buffer chain.
*
* @param len Data length
* @param ptr Pointer to data
* @param from_buf Memory buffer chain to copy from
* @return Length of the data that was copied
*/
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const;
/**
* Concatenate two memory buffer chains
*

View File

@ -62,6 +62,16 @@ public:
*/
virtual uint32_t get_mtu_size() const = 0;
/**
* Gets memory buffer alignment preference
*
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
* align link out memory buffer chains using the alignment.
*
* @return Memory alignment requirement in bytes
*/
virtual uint32_t get_align_preference() const = 0;
/**
* Return interface name
*

View File

@ -0,0 +1,62 @@
/* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "EMACMemoryManager.h"
void EMACMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
{
while (to_buf && len) {
void *copy_to_ptr = get_ptr(to_buf);
uint32_t copy_to_len = get_len(to_buf);
if (copy_to_len > len) {
copy_to_len = len;
len = 0;
} else {
len -= copy_to_len;
}
memcpy(copy_to_ptr, ptr, copy_to_len);
ptr = static_cast<const uint8_t *>(ptr) + copy_to_len;
to_buf = get_next(to_buf);
}
}
uint32_t EMACMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
{
uint32_t copied_len = 0;
while (from_buf && len) {
void *copy_from_ptr = get_ptr(from_buf);
uint32_t copy_from_len = get_len(from_buf);
if (copy_from_len > len) {
copy_from_len = len;
len = 0;
} else {
len -= copy_from_len;
}
memcpy(ptr, copy_from_ptr, copy_from_len);
ptr = static_cast<uint8_t *>(ptr) + copy_from_len;
copied_len += copy_from_len;
from_buf = get_next(from_buf);
}
return copied_len;
}

View File

@ -36,6 +36,8 @@
*
*/
#include "nsapi.h"
typedef void emac_mem_buf_t; // Memory buffer
class EMACMemoryManager {
@ -106,6 +108,31 @@ public:
*/
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf) = 0;
/**
* Copy to a memory buffer chain
*
* Copies data to a buffer chain. Copy operation does not adjust the lengths
* of the copied-to memory buffer chain, so chain total length must match the
* copied length.
*
* @param to_buf Memory buffer chain to copy to
* @param ptr Pointer to data
* @param len Data length
*/
virtual void copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len);
/**
* Copy from a memory buffer chain
*
* Copies data from a memory buffer chain.
*
* @param len Data length
* @param ptr Pointer to data
* @param from_buf Memory buffer chain to copy from
* @return Length of the data that was copied
*/
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const;
/**
* Concatenate two memory buffer chains
*

View File

@ -412,13 +412,19 @@ bool K64F_EMAC::link_out(emac_mem_buf_t *buf)
{
emac_mem_buf_t *temp_pbuf;
temp_pbuf = memory_manager->alloc_heap(memory_manager->get_total_len(buf), ENET_BUFF_ALIGNMENT);
if (NULL == temp_pbuf)
return false;
// If buffer is chained or not aligned then make a contiguous aligned copy of it
if (memory_manager->get_next(buf) ||
reinterpret_cast<uint32_t>(memory_manager->get_ptr(buf)) % ENET_BUFF_ALIGNMENT) {
temp_pbuf = memory_manager->alloc_heap(memory_manager->get_total_len(buf), ENET_BUFF_ALIGNMENT);
if (NULL == temp_pbuf)
return false;
// Copy to new buffer and free original
memory_manager->copy(temp_pbuf, buf);
memory_manager->free(buf);
// Copy to new buffer and free original
memory_manager->copy(temp_pbuf, buf);
memory_manager->free(buf);
} else {
temp_pbuf = buf;
}
/* Check if a descriptor is available for the transfer. */
if (xTXDCountSem.wait(0) == 0)
@ -525,6 +531,11 @@ uint32_t K64F_EMAC::get_mtu_size() const
return K64_ETH_MTU_SIZE;
}
uint32_t K64F_EMAC::get_align_preference() const
{
return ENET_BUFF_ALIGNMENT;
}
void K64F_EMAC::get_ifname(char *name, uint8_t size) const
{
memcpy(name, K64_ETH_IF_NAME, (size < sizeof(K64_ETH_IF_NAME)) ? size : sizeof(K64_ETH_IF_NAME));

View File

@ -22,6 +22,16 @@ public:
*/
virtual uint32_t get_mtu_size() const;
/**
* Gets memory buffer alignment preference
*
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
* align link out memory buffer chains using the alignment.
*
* @return Memory alignment requirement in bytes
*/
virtual uint32_t get_align_preference() const;
/**
* Return interface name
*

View File

@ -480,6 +480,11 @@ uint32_t STM32_EMAC::get_mtu_size() const
return STM_ETH_MTU_SIZE;
}
uint32_t STM32_EMAC::get_align_preference() const
{
return 0;
}
void STM32_EMAC::get_ifname(char *name, uint8_t size) const
{
memcpy(name, STM_ETH_IF_NAME, (size < sizeof(STM_ETH_IF_NAME)) ? size : sizeof(STM_ETH_IF_NAME));

View File

@ -33,6 +33,16 @@ public:
*/
virtual uint32_t get_mtu_size() const;
/**
* Gets memory buffer alignment preference
*
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
* align link out memory buffer chains using the alignment.
*
* @return Memory alignment requirement in bytes
*/
virtual uint32_t get_align_preference() const;
/**
* Return interface name
*