mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
task #7013: Added option LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only one pbuf to help MACs that don't support scatter-gather DMA.
This commit is contained in:
parent
105d72a3c2
commit
22d6558f13
@ -19,6 +19,11 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2009-05-10 Simon Goldschmidt
|
||||
* opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option
|
||||
LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only
|
||||
one pbuf to help MACs that don't support scatter-gather DMA.
|
||||
|
||||
2009-05-09 Simon Goldschmidt
|
||||
* icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming
|
||||
ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
|
||||
|
@ -668,7 +668,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
{
|
||||
struct lwip_socket *sock;
|
||||
struct ip_addr remote_addr;
|
||||
int err;
|
||||
err_t err;
|
||||
u16_t short_size;
|
||||
#if !LWIP_TCPIP_CORE_LOCKING
|
||||
struct netbuf buf;
|
||||
@ -738,17 +738,25 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
s, data, short_size, flags));
|
||||
ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
|
||||
|
||||
|
||||
/* make the buffer point to the data that should be sent */
|
||||
if ((err = netbuf_ref(&buf, data, short_size)) == ERR_OK) {
|
||||
#if LWIP_NETIF_TX_SINGLE_PBUF
|
||||
/* Allocate a new netbuf and copy the data into it. */
|
||||
if (netbuf_alloc(&buf, short_size) == NULL) {
|
||||
err = ERR_MEM;
|
||||
} else {
|
||||
err = netbuf_take(&buf, data, short_size);
|
||||
}
|
||||
#else /* LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
err = netbuf_ref(&buf, data, short_size);
|
||||
#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
if (err == ERR_OK) {
|
||||
/* send the data */
|
||||
err = netconn_send(sock->conn, &buf);
|
||||
}
|
||||
|
||||
/* deallocated the buffer */
|
||||
if (buf.p != NULL) {
|
||||
pbuf_free(buf.p);
|
||||
}
|
||||
netbuf_free(&buf);
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
sock_set_errno(sock, err_to_errno(err));
|
||||
return (err == ERR_OK ? short_size : -1);
|
||||
|
@ -790,8 +790,8 @@ pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
|
||||
u16_t buf_copy_len;
|
||||
u16_t copied_total = 0;
|
||||
|
||||
LWIP_ERROR("netbuf_copy_partial: invalid buf", (buf != NULL), return 0;);
|
||||
LWIP_ERROR("netbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;);
|
||||
LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;);
|
||||
LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;);
|
||||
|
||||
left = 0;
|
||||
|
||||
@ -819,3 +819,76 @@ pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
|
||||
}
|
||||
return copied_total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy application supplied data into a pbuf.
|
||||
* This function can only be used to copy the equivalent of buf->tot_len data.
|
||||
*
|
||||
* @param buf pbuf to fill with data
|
||||
* @param dataptr application supplied data buffer
|
||||
* @param len length of the application supplied data buffer
|
||||
*
|
||||
* @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough
|
||||
*/
|
||||
err_t
|
||||
pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
|
||||
{
|
||||
struct pbuf *p;
|
||||
u16_t buf_copy_len;
|
||||
u16_t total_copy_len = len;
|
||||
u16_t copied_total = 0;
|
||||
|
||||
LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;);
|
||||
LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;);
|
||||
|
||||
if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) {
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
/* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
|
||||
for(p = buf; total_copy_len != 0; p = p->next) {
|
||||
LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL);
|
||||
buf_copy_len = total_copy_len;
|
||||
if (buf_copy_len > p->len) {
|
||||
/* this pbuf cannot hold all remaining data */
|
||||
buf_copy_len = p->len;
|
||||
}
|
||||
/* copy the necessary parts of the buffer */
|
||||
MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len);
|
||||
total_copy_len -= buf_copy_len;
|
||||
copied_total += buf_copy_len;
|
||||
}
|
||||
LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single pbuf out of a queue of pbufs.
|
||||
*
|
||||
* @remark: The source pbuf 'p' is not freed by this function because that can
|
||||
* be illegal in some places!
|
||||
*
|
||||
* @param p the source pbuf
|
||||
* @param layer pbuf_layer of the new pbuf
|
||||
*
|
||||
* @return a new, single pbuf (p->next is NULL)
|
||||
* or the old pbuf if allocation fails
|
||||
*/
|
||||
struct pbuf*
|
||||
pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
|
||||
{
|
||||
struct pbuf *q;
|
||||
err_t err;
|
||||
if (p->next == NULL) {
|
||||
return p;
|
||||
}
|
||||
q = pbuf_alloc(layer, p->tot_len, PBUF_RAM);
|
||||
if (q == NULL) {
|
||||
/* @todo: what do we do now? */
|
||||
return p;
|
||||
}
|
||||
err = pbuf_copy(q, p);
|
||||
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
|
||||
pbuf_free(p);
|
||||
return q;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ void netbuf_first (struct netbuf *buf);
|
||||
#define netbuf_copy_partial(buf, dataptr, len, offset) \
|
||||
pbuf_copy_partial((buf)->p, (dataptr), (len), (offset))
|
||||
#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0)
|
||||
#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len)
|
||||
#define netbuf_len(buf) ((buf)->p->tot_len)
|
||||
#define netbuf_fromaddr(buf) ((buf)->addr)
|
||||
#define netbuf_fromport(buf) ((buf)->port)
|
||||
|
@ -965,6 +965,19 @@
|
||||
#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data
|
||||
* to be sent into one single pbuf. This is for compatibility with DMA-enabled
|
||||
* MACs that do not support scatter-gather.
|
||||
* Beware that this might involve CPU-memcpy before transmitting that would not
|
||||
* be needed without this flag! Use this only if you need to!
|
||||
*
|
||||
* @todo: TCP and IP-frag do not work with this, yet:
|
||||
*/
|
||||
#ifndef LWIP_NETIF_TX_SINGLE_PBUF
|
||||
#define LWIP_NETIF_TX_SINGLE_PBUF 0
|
||||
#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
|
||||
/*
|
||||
------------------------------------
|
||||
---------- LOOPIF options ----------
|
||||
|
@ -110,6 +110,8 @@ void pbuf_chain(struct pbuf *head, struct pbuf *tail);
|
||||
struct pbuf *pbuf_dechain(struct pbuf *p);
|
||||
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from);
|
||||
u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
|
||||
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
|
||||
struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user