linux/arch/cris/arch-v10/lib/old_checksum.c
<<
>>
Prefs
   1/*
   2 * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3 *              operating system.  INET is implemented using the  BSD Socket
   4 *              interface as the means of communication with the user level.
   5 *
   6 *              IP/TCP/UDP checksumming routines
   7 *
   8 * Authors:     Jorge Cwik, <jorge@laser.satlink.net>
   9 *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  10 *              Tom May, <ftom@netcom.com>
  11 *              Lots of code moved from tcp.c and ip.c; see those files
  12 *              for more names.
  13 *
  14 *              This program is free software; you can redistribute it and/or
  15 *              modify it under the terms of the GNU General Public License
  16 *              as published by the Free Software Foundation; either version
  17 *              2 of the License, or (at your option) any later version.
  18 */
  19
  20#include <net/checksum.h>
  21#include <net/module.h>
  22
  23#undef PROFILE_CHECKSUM
  24
  25#ifdef PROFILE_CHECKSUM
  26/* these are just for profiling the checksum code with an oscillioscope.. uh */
  27#if 0
  28#define BITOFF *((unsigned char *)0xb0000030) = 0xff
  29#define BITON *((unsigned char *)0xb0000030) = 0x0
  30#endif
  31#include <asm/io.h>
  32#define CBITON LED_ACTIVE_SET(1)
  33#define CBITOFF LED_ACTIVE_SET(0)
  34#define BITOFF
  35#define BITON
  36#else
  37#define BITOFF
  38#define BITON
  39#define CBITOFF
  40#define CBITON
  41#endif
  42
  43/*
  44 * computes a partial checksum, e.g. for TCP/UDP fragments
  45 */
  46
  47#include <asm/delay.h>
  48
  49__wsum csum_partial(const void *p, int len, __wsum __sum)
  50{
  51        u32 sum = (__force u32)__sum;
  52        const u16 *buff = p;
  53        /*
  54        * Experiments with ethernet and slip connections show that buff
  55        * is aligned on either a 2-byte or 4-byte boundary.
  56        */
  57        const void *endMarker = p + len;
  58        const void *marker = endMarker - (len % 16);
  59#if 0
  60        if((int)buff & 0x3)
  61                printk("unaligned buff %p\n", buff);
  62        __delay(900); /* extra delay of 90 us to test performance hit */
  63#endif
  64        BITON;
  65        while (buff < marker) {
  66                sum += *buff++;
  67                sum += *buff++;
  68                sum += *buff++;
  69                sum += *buff++;
  70                sum += *buff++;
  71                sum += *buff++;
  72                sum += *buff++;
  73                sum += *buff++;
  74        }
  75        marker = endMarker - (len % 2);
  76        while (buff < marker)
  77                sum += *buff++;
  78
  79        if (endMarker > buff)
  80                sum += *(const u8 *)buff;       /* add extra byte separately */
  81
  82        BITOFF;
  83        return (__force __wsum)sum;
  84}
  85
  86EXPORT_SYMBOL(csum_partial);
  87