Correct a buffer size error in the STM32 ethernet driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4403 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
f8b785f10e
commit
6a2c6e13d6
5 changed files with 41 additions and 28 deletions
|
|
@ -2468,4 +2468,8 @@
|
|||
this is little more than a "skeleton" file.
|
||||
* Various files: CAN ISO-11783 support contributed by Gary Teravskis.
|
||||
* net/recv.c and net/recvfrom.c: Correct a bug in return value: The the peer
|
||||
gracefully closes the connections, needs to return zero and not ENOTCONN
|
||||
gracefully closes the connections, needs to return zero and not ENOTCONN.
|
||||
* arch/arm/src/stm32/stm32_eth.c: Fix an error in the STM32 ethernet driver.
|
||||
The received buffer size must be two bytes larger to account for the two byte
|
||||
checksum that is appended to the packet. Otherwise, the last two bytes of
|
||||
real data in the packet will get clobbered.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/stm32/stm32_eth.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -140,21 +140,27 @@
|
|||
#undef CONFIG_STM32_ETH_ENHANCEDDESC
|
||||
#undef CONFIG_STM32_ETH_HWCHECKSUM
|
||||
|
||||
/* Ethernet buffer sizes, nubmer of buffers, and number of descriptors */
|
||||
/* Ethernet buffer sizes, number of buffers, and number of descriptors */
|
||||
|
||||
#ifndef CONFIG_NET_MULTIBUFFER
|
||||
# error "CONFIG_NET_MULTIBUFFER is required"
|
||||
#endif
|
||||
|
||||
/* Add 4 to the configured buffer size to account for the 2 byte checksum
|
||||
* memory needed at the end of the maximum size packet.
|
||||
*/
|
||||
|
||||
#define OPTIMAL_ETH_BUFSIZE (CONFIG_NET_BUFSIZE+4)
|
||||
|
||||
#ifndef CONFIG_STM32_ETH_BUFSIZE
|
||||
# define CONFIG_STM32_ETH_BUFSIZE CONFIG_NET_BUFSIZE
|
||||
# define CONFIG_STM32_ETH_BUFSIZE OPTIMAL_ETH_BUFSIZE
|
||||
#endif
|
||||
|
||||
#if CONFIG_STM32_ETH_BUFSIZE > ETH_TDES1_TBS1_MASK
|
||||
# error "CONFIG_STM32_ETH_BUFSIZE is too large"
|
||||
#endif
|
||||
|
||||
#if CONFIG_STM32_ETH_BUFSIZE != CONFIG_NET_BUFSIZE
|
||||
#if CONFIG_STM32_ETH_BUFSIZE != OPTIMAL_ETH_BUFSIZE
|
||||
# warning "You using an incomplete/untested configuration"
|
||||
#endif
|
||||
|
||||
|
|
@ -872,11 +878,11 @@ static int stm32_transmit(FAR struct stm32_ethmac_s *priv)
|
|||
struct eth_txdesc_s *txdesc;
|
||||
struct eth_txdesc_s *txfirst;
|
||||
|
||||
/* The internal uIP buffer size may be configured to be larger than the
|
||||
* Ethernet buffer size.
|
||||
/* The internal (optimal) uIP buffer size may be configured to be larger
|
||||
* than the Ethernet buffer size.
|
||||
*/
|
||||
|
||||
#if CONFIG_NET_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE
|
||||
#if OPTIMAL_ETH_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE
|
||||
uint8_t *buffer;
|
||||
int bufcount;
|
||||
int lastsize;
|
||||
|
|
@ -900,7 +906,7 @@ static int stm32_transmit(FAR struct stm32_ethmac_s *priv)
|
|||
|
||||
DEBUGASSERT(priv->dev.d_len > 0 && priv->dev.d_buf != NULL);
|
||||
|
||||
#if CONFIG_NET_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE
|
||||
#if OPTIMAL_ETH_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE
|
||||
if (priv->dev.d_len > CONFIG_STM32_ETH_BUFSIZE)
|
||||
{
|
||||
/* Yes... how many buffers will be need to send the packet? */
|
||||
|
|
@ -1369,7 +1375,7 @@ static int stm32_recvframe(FAR struct stm32_ethmac_s *priv)
|
|||
* 3) All of the TX descriptors are in flight.
|
||||
*
|
||||
* This last case is obscure. It is due to that fact that each packet
|
||||
* that we receive can generate and unstoppable transmisson. So we have
|
||||
* that we receive can generate an unstoppable transmisson. So we have
|
||||
* to stop receiving when we can not longer transmit. In this case, the
|
||||
* transmit logic should also have disabled further RX interrupts.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
/****************************************************************************
|
||||
* net/net_timeo.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
/****************************************************************************
|
||||
* net/uip/uip_chksum.c
|
||||
*
|
||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
* net/uip/uip_input.c
|
||||
* The uIP TCP/IP stack code.
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||
*
|
||||
|
|
@ -297,6 +297,7 @@ nullreturn:
|
|||
void uip_input(struct uip_driver_s *dev)
|
||||
{
|
||||
struct uip_ip_hdr *pbuf = BUF;
|
||||
uint16_t iplen;
|
||||
|
||||
/* This is where the input processing starts. */
|
||||
|
||||
|
|
@ -343,20 +344,23 @@ void uip_input(struct uip_driver_s *dev)
|
|||
* we set d_len to the correct value.
|
||||
*/
|
||||
|
||||
if ((pbuf->len[0] << 8) + pbuf->len[1] <= dev->d_len)
|
||||
{
|
||||
dev->d_len = (pbuf->len[0] << 8) + pbuf->len[1];
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* The length reported in the IPv6 header is the length of the
|
||||
* payload that follows the header. However, uIP uses the d_len
|
||||
* variable for holding the size of the entire packet, including the
|
||||
* IP header. For IPv4 this is not a problem as the length field in
|
||||
* the IPv4 header contains the length of the entire packet. But
|
||||
* for IPv6 we need to add the size of the IPv6 header (40 bytes).
|
||||
*/
|
||||
/* The length reported in the IPv6 header is the length of the payload
|
||||
* that follows the header. However, uIP uses the d_len variable for
|
||||
* holding the size of the entire packet, including the IP header. For
|
||||
* IPv4 this is not a problem as the length field in the IPv4 header
|
||||
* contains the length of the entire packet. But for IPv6 we need to add
|
||||
* the size of the IPv6 header (40 bytes).
|
||||
*/
|
||||
|
||||
dev->d_len += 40;
|
||||
iplen = (pbuf->len[0] << 8) + pbuf->len[1] + UIP_IPH_LEN;
|
||||
#else
|
||||
iplen = (pbuf->len[0] << 8) + pbuf->len[1];
|
||||
#endif /* CONFIG_NET_IPv6 */
|
||||
|
||||
if (iplen <= dev->d_len)
|
||||
{
|
||||
dev->d_len = iplen;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -538,4 +542,3 @@ drop:
|
|||
dev->d_len = 0;
|
||||
}
|
||||
#endif /* CONFIG_NET */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue