[U-Boot] [PATCH] Add simple IP/UDP fragmentation support

Ben Warren biggerbadderben at gmail.com
Tue Oct 28 07:25:08 CET 2008


Josh & Frank,

Sorry again for dropping the ball on this one.  This is a useful feature 
that we should add to U-boot, but I'm concerned about the memory footprint.

Josh Boyer wrote:
> From: Frank Haverkamp <haver at vnet.ibm.com>
>
> http://tools.ietf.org/html/rfc2348 describes the TFTP block size option
> which allows larger packtes than the 512 byte default. This reduces the
> number of TFTP ACKs significantly and improves performance.
>
> To get the most benefit out of the tftp block size option the support
> of defragementation of IP/UDP packet is helpful. The current implemenation
> should work even with packets received out of order. To enable the large
> packet size the user should set "tftp_block_size" so a value like 16352.
>
> We experimented with different packet sizes and found that more than those
> 16KiB do not contribute much to the performance anymore. Therefor I limited
> the defragmentation buffer to 16KiB no too waste memory.
>
> Signed-off-by: Frank Haverkamp <haver at vnet.ibm.com>
> Signed-off-by: Josh Boyer <jwboyer at linux.vnet.ibm.com>
>
>   
> ---
>  include/net.h |   17 ++++++
>  net/net.c     |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
>  net/tftp.c    |   22 ++++++++
>  net/tftp.h    |   10 +++
>  4 files changed, 185 insertions(+), 20 deletions(-)
>
> --- u-boot.git.orig/include/net.h
> +++ u-boot.git/include/net.h
> @@ -200,6 +200,13 @@ typedef struct {
>  	ushort		udp_xsum;	/* Checksum			*/
>  } IP_t;
>  
> +#define IP_OFFS			 0x1FFF	/* ip offset *= 8 */
> +#define	  IP_OFFS_SHIFT	  3	/* in 8 byte steps */
> +#define IP_FLAGS	 0xE000	/* first 3 bits */
> +#define		 IP_FLAGS_RES	 0x8000	/* reserved */
> +#define		 IP_FLAGS_DFRAG	 0x4000	/* don't fragments */
> +#define		 IP_FLAGS_MFRAG	 0x2000	/* more fragments */
> +
>  #define IP_HDR_SIZE_NO_UDP	(sizeof (IP_t) - 8)
>  #define IP_HDR_SIZE		(sizeof (IP_t))
>  
> @@ -282,6 +289,16 @@ typedef struct icmphdr {
>  #define PKTSIZE_ALIGN		1536
>  /*#define PKTSIZE		608*/
>  
> + /*
> +  * IP/UDP Fragmentation support
> +  * See: http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly
> +  * MAX possible UDP packet size is 64 KiB, if there is memory available.
> +  */
> +#define NET_ETH_MTU		1500
> +#define NET_FRAG_BUF_SIZE	(16 * 1024) /* MAX is 64 KiB */
> +#define NET_UDP_FRAG_SIZE	(NET_ETH_MTU - IP_HDR_SIZE_NO_UDP) /* 1480 */
> +#define NET_FRAG_BUF_USED	(NET_FRAG_BUF_SIZE / NET_UDP_FRAG_SIZE + 1)
> +
>  /*
>   * Maximum receive ring size; that is, the number of packets
>   * we can buffer before overflow happens. Basically, this just
> --- u-boot.git.orig/net/net.c
> +++ u-boot.git/net/net.c
> @@ -192,6 +192,15 @@ volatile uchar	PktBuf[(PKTBUFSRX+1) * PK
>  
>  volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets			*/
>  
> +/* Packet fragmentation support */
> +static uint16_t ip_id = 0; /* sequence number */
> +static uint16_t udp_len = 0;
> +static uint16_t udp_src = 0;
> +static uint16_t udp_dst = 0;
> +static int max_idx = 0;
> +static uchar NetFragBuf[NET_FRAG_BUF_SIZE];
>   
Allocating a 16k buffer should be optional.  Please consider wrapping 
this feature in a CONFIG.
> +static char NetFragBufUsed[NET_FRAG_BUF_USED] = { 0, };
> +
>  static rxhand_f *packetHandler;		/* Current RX packet handler		*/
>  static thand_f *timeHandler;		/* Current timeout handler		*/
>  static ulong	timeStart;		/* Time base value			*/
> @@ -288,6 +297,13 @@ NetLoop(proto_t protocol)
>  {
>  	bd_t *bd = gd->bd;
>  
> +	/* Packet fragmentation support */
> +	ip_id = udp_len = udp_src = udp_dst = max_idx = 0;
> +	memset(NetFragBuf, 0xFF, sizeof(NetFragBuf));
> +	memset(NetFragBufUsed, 0, sizeof(NetFragBufUsed));
> +	printf("NetFragBuf @ %08x max tftp_block_size=%d udp_frag_size=%d\n",
> +	       NetFragBuf, TFTP_BLOCK_SIZE_MAX, NET_UDP_FRAG_SIZE);
>   
I get a compiler warning here that a simple cast should fix:
net.c: In function 'NetLoop':
net.c:300: warning: format '%08x' expects type 'unsigned int', but 
argument 2 has type 'uchar *'

regards,
Ben


More information about the U-Boot mailing list