Skip to content

Commit 6d71ded

Browse files
Mika Leppänenkjbracey
authored andcommitted
Added preferred alignment to emac and copy to/from to memory manager
1 parent 94e07bf commit 6d71ded

File tree

9 files changed

+177
-7
lines changed

9 files changed

+177
-7
lines changed

features/FEATURE_LWIP/lwip-interface/LWIPMemoryManager.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ void LWIPMemoryManager::copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_
6363
pbuf_copy(static_cast<struct pbuf *>(to_buf), static_cast<const struct pbuf *>(from_buf));
6464
}
6565

66+
void LWIPMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
67+
{
68+
pbuf_take(static_cast<struct pbuf *>(to_buf), ptr, len);
69+
}
70+
71+
uint32_t LWIPMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
72+
{
73+
return pbuf_copy_partial(static_cast<const struct pbuf *>(from_buf), ptr, len, 0);
74+
}
75+
6676
void LWIPMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
6777
{
6878
pbuf_cat(static_cast<struct pbuf *>(to_buf), static_cast<struct pbuf *>(cat_buf));

features/FEATURE_LWIP/lwip-interface/LWIPMemoryManager.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,31 @@ class LWIPMemoryManager : public EMACMemoryManager {
8686
*/
8787
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
8888

89+
/**
90+
* Copy to a memory buffer chain
91+
*
92+
* Copies data to a buffer chain. Copy operation does not adjust the lengths
93+
* of the copied-to memory buffer chain, so chain total length must match the
94+
* copied length.
95+
*
96+
* @param to_buf Memory buffer chain to copy to
97+
* @param ptr Pointer to data
98+
* @param len Data length
99+
*/
100+
virtual void copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len);
101+
102+
/**
103+
* Copy from a memory buffer chain
104+
*
105+
* Copies data from a memory buffer chain.
106+
*
107+
* @param len Data length
108+
* @param ptr Pointer to data
109+
* @param from_buf Memory buffer chain to copy from
110+
* @return Length of the data that was copied
111+
*/
112+
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const;
113+
89114
/**
90115
* Concatenate two memory buffer chains
91116
*

features/netsocket/EMAC.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ class EMAC {
6262
*/
6363
virtual uint32_t get_mtu_size() const = 0;
6464

65+
/**
66+
* Gets memory buffer alignment preference
67+
*
68+
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
69+
* align link out memory buffer chains using the alignment.
70+
*
71+
* @return Memory alignment requirement in bytes
72+
*/
73+
virtual uint32_t get_align_preference() const = 0;
74+
6575
/**
6676
* Return interface name
6777
*
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* Copyright (c) 2018 ARM Limited
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include "EMACMemoryManager.h"
17+
18+
void EMACMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
19+
{
20+
while (to_buf && len) {
21+
void *copy_to_ptr = get_ptr(to_buf);
22+
uint32_t copy_to_len = get_len(to_buf);
23+
24+
if (copy_to_len > len) {
25+
copy_to_len = len;
26+
len = 0;
27+
} else {
28+
len -= copy_to_len;
29+
}
30+
31+
memcpy(copy_to_ptr, ptr, copy_to_len);
32+
ptr = static_cast<const uint8_t *>(ptr) + copy_to_len;
33+
34+
to_buf = get_next(to_buf);
35+
}
36+
}
37+
38+
uint32_t EMACMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
39+
{
40+
uint32_t copied_len = 0;
41+
42+
while (from_buf && len) {
43+
void *copy_from_ptr = get_ptr(from_buf);
44+
uint32_t copy_from_len = get_len(from_buf);
45+
46+
if (copy_from_len > len) {
47+
copy_from_len = len;
48+
len = 0;
49+
} else {
50+
len -= copy_from_len;
51+
}
52+
53+
memcpy(ptr, copy_from_ptr, copy_from_len);
54+
ptr = static_cast<uint8_t *>(ptr) + copy_from_len;
55+
copied_len += copy_from_len;
56+
57+
from_buf = get_next(from_buf);
58+
}
59+
60+
return copied_len;
61+
}
62+

features/netsocket/EMACMemoryManager.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
*
3737
*/
3838

39+
#include "nsapi.h"
40+
3941
typedef void emac_mem_buf_t; // Memory buffer
4042

4143
class EMACMemoryManager {
@@ -106,6 +108,31 @@ class EMACMemoryManager {
106108
*/
107109
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf) = 0;
108110

111+
/**
112+
* Copy to a memory buffer chain
113+
*
114+
* Copies data to a buffer chain. Copy operation does not adjust the lengths
115+
* of the copied-to memory buffer chain, so chain total length must match the
116+
* copied length.
117+
*
118+
* @param to_buf Memory buffer chain to copy to
119+
* @param ptr Pointer to data
120+
* @param len Data length
121+
*/
122+
virtual void copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len);
123+
124+
/**
125+
* Copy from a memory buffer chain
126+
*
127+
* Copies data from a memory buffer chain.
128+
*
129+
* @param len Data length
130+
* @param ptr Pointer to data
131+
* @param from_buf Memory buffer chain to copy from
132+
* @return Length of the data that was copied
133+
*/
134+
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const;
135+
109136
/**
110137
* Concatenate two memory buffer chains
111138
*

features/netsocket/emac-drivers/TARGET_Freescale/k64f_emac.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,19 @@ bool K64F_EMAC::link_out(emac_mem_buf_t *buf)
412412
{
413413
emac_mem_buf_t *temp_pbuf;
414414

415-
temp_pbuf = memory_manager->alloc_heap(memory_manager->get_total_len(buf), ENET_BUFF_ALIGNMENT);
416-
if (NULL == temp_pbuf)
417-
return false;
418-
419-
// Copy to new buffer and free original
420-
memory_manager->copy(temp_pbuf, buf);
421-
memory_manager->free(buf);
415+
// If buffer is chained or not aligned then make a contiguous aligned copy of it
416+
if (memory_manager->get_next(buf) ||
417+
reinterpret_cast<uint32_t>(memory_manager->get_ptr(buf)) % ENET_BUFF_ALIGNMENT) {
418+
temp_pbuf = memory_manager->alloc_heap(memory_manager->get_total_len(buf), ENET_BUFF_ALIGNMENT);
419+
if (NULL == temp_pbuf)
420+
return false;
421+
422+
// Copy to new buffer and free original
423+
memory_manager->copy(temp_pbuf, buf);
424+
memory_manager->free(buf);
425+
} else {
426+
temp_pbuf = buf;
427+
}
422428

423429
/* Check if a descriptor is available for the transfer. */
424430
if (xTXDCountSem.wait(0) == 0)
@@ -525,6 +531,11 @@ uint32_t K64F_EMAC::get_mtu_size() const
525531
return K64_ETH_MTU_SIZE;
526532
}
527533

534+
uint32_t K64F_EMAC::get_align_preference() const
535+
{
536+
return ENET_BUFF_ALIGNMENT;
537+
}
538+
528539
void K64F_EMAC::get_ifname(char *name, uint8_t size) const
529540
{
530541
memcpy(name, K64_ETH_IF_NAME, (size < sizeof(K64_ETH_IF_NAME)) ? size : sizeof(K64_ETH_IF_NAME));

features/netsocket/emac-drivers/TARGET_Freescale/k64f_emac.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ class K64F_EMAC : public EMAC {
2222
*/
2323
virtual uint32_t get_mtu_size() const;
2424

25+
/**
26+
* Gets memory buffer alignment preference
27+
*
28+
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
29+
* align link out memory buffer chains using the alignment.
30+
*
31+
* @return Memory alignment requirement in bytes
32+
*/
33+
virtual uint32_t get_align_preference() const;
34+
2535
/**
2636
* Return interface name
2737
*

features/netsocket/emac-drivers/TARGET_STM/stm32xx_emac.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@ uint32_t STM32_EMAC::get_mtu_size() const
480480
return STM_ETH_MTU_SIZE;
481481
}
482482

483+
uint32_t STM32_EMAC::get_align_preference() const
484+
{
485+
return 0;
486+
}
487+
483488
void STM32_EMAC::get_ifname(char *name, uint8_t size) const
484489
{
485490
memcpy(name, STM_ETH_IF_NAME, (size < sizeof(STM_ETH_IF_NAME)) ? size : sizeof(STM_ETH_IF_NAME));

features/netsocket/emac-drivers/TARGET_STM/stm32xx_emac.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ class STM32_EMAC : public EMAC {
3333
*/
3434
virtual uint32_t get_mtu_size() const;
3535

36+
/**
37+
* Gets memory buffer alignment preference
38+
*
39+
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
40+
* align link out memory buffer chains using the alignment.
41+
*
42+
* @return Memory alignment requirement in bytes
43+
*/
44+
virtual uint32_t get_align_preference() const;
45+
3646
/**
3747
* Return interface name
3848
*

0 commit comments

Comments
 (0)