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:
patacongo 2012-02-18 22:09:09 +00:00
parent f8b785f10e
commit 6a2c6e13d6
5 changed files with 41 additions and 28 deletions

View file

@ -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.

View file

@ -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.
*/

View file

@ -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

View file

@ -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

View file

@ -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 */