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
+5 -1
View File
@@ -2468,4 +2468,8 @@
this is little more than a "skeleton" file. this is little more than a "skeleton" file.
* Various files: CAN ISO-11783 support contributed by Gary Teravskis. * 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 * 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.
+15 -9
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/stm32/stm32_eth.c * 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> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -140,21 +140,27 @@
#undef CONFIG_STM32_ETH_ENHANCEDDESC #undef CONFIG_STM32_ETH_ENHANCEDDESC
#undef CONFIG_STM32_ETH_HWCHECKSUM #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 #ifndef CONFIG_NET_MULTIBUFFER
# error "CONFIG_NET_MULTIBUFFER is required" # error "CONFIG_NET_MULTIBUFFER is required"
#endif #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 #ifndef CONFIG_STM32_ETH_BUFSIZE
# define CONFIG_STM32_ETH_BUFSIZE CONFIG_NET_BUFSIZE # define CONFIG_STM32_ETH_BUFSIZE OPTIMAL_ETH_BUFSIZE
#endif #endif
#if CONFIG_STM32_ETH_BUFSIZE > ETH_TDES1_TBS1_MASK #if CONFIG_STM32_ETH_BUFSIZE > ETH_TDES1_TBS1_MASK
# error "CONFIG_STM32_ETH_BUFSIZE is too large" # error "CONFIG_STM32_ETH_BUFSIZE is too large"
#endif #endif
#if CONFIG_STM32_ETH_BUFSIZE != CONFIG_NET_BUFSIZE #if CONFIG_STM32_ETH_BUFSIZE != OPTIMAL_ETH_BUFSIZE
# warning "You using an incomplete/untested configuration" # warning "You using an incomplete/untested configuration"
#endif #endif
@@ -872,11 +878,11 @@ static int stm32_transmit(FAR struct stm32_ethmac_s *priv)
struct eth_txdesc_s *txdesc; struct eth_txdesc_s *txdesc;
struct eth_txdesc_s *txfirst; struct eth_txdesc_s *txfirst;
/* The internal uIP buffer size may be configured to be larger than the /* The internal (optimal) uIP buffer size may be configured to be larger
* Ethernet buffer size. * than the Ethernet buffer size.
*/ */
#if CONFIG_NET_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE #if OPTIMAL_ETH_BUFSIZE > CONFIG_STM32_ETH_BUFSIZE
uint8_t *buffer; uint8_t *buffer;
int bufcount; int bufcount;
int lastsize; 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); 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) if (priv->dev.d_len > CONFIG_STM32_ETH_BUFSIZE)
{ {
/* Yes... how many buffers will be need to send the packet? */ /* 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. * 3) All of the TX descriptors are in flight.
* *
* This last case is obscure. It is due to that fact that each packet * 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 * to stop receiving when we can not longer transmit. In this case, the
* transmit logic should also have disabled further RX interrupts. * transmit logic should also have disabled further RX interrupts.
*/ */
+2 -2
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/net_timeo.c * net/net_timeo.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
+2 -2
View File
@@ -1,8 +1,8 @@
/**************************************************************************** /****************************************************************************
* net/uip/uip_chksum.c * net/uip/uip_chksum.c
* *
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
+17 -14
View File
@@ -2,8 +2,8 @@
* net/uip/uip_input.c * net/uip/uip_input.c
* The uIP TCP/IP stack code. * The uIP TCP/IP stack code.
* *
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Adapted for NuttX from logic in uIP which also has a BSD-like license: * 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) void uip_input(struct uip_driver_s *dev)
{ {
struct uip_ip_hdr *pbuf = BUF; struct uip_ip_hdr *pbuf = BUF;
uint16_t iplen;
/* This is where the input processing starts. */ /* 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. * 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 #ifdef CONFIG_NET_IPv6
/* The length reported in the IPv6 header is the length of the /* The length reported in the IPv6 header is the length of the payload
* payload that follows the header. However, uIP uses the d_len * that follows the header. However, uIP uses the d_len variable for
* variable for holding the size of the entire packet, including the * holding the size of the entire packet, including the IP header. For
* IP header. For IPv4 this is not a problem as the length field in * IPv4 this is not a problem as the length field in the IPv4 header
* the IPv4 header contains the length of the entire packet. But * contains the length of the entire packet. But for IPv6 we need to add
* for IPv6 we need to add the size of the IPv6 header (40 bytes). * 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 */ #endif /* CONFIG_NET_IPv6 */
if (iplen <= dev->d_len)
{
dev->d_len = iplen;
} }
else else
{ {
@@ -538,4 +542,3 @@ drop:
dev->d_len = 0; dev->d_len = 0;
} }
#endif /* CONFIG_NET */ #endif /* CONFIG_NET */