653 lines
22 KiB
C
653 lines
22 KiB
C
#ifndef __PKT_HDR_H_INCLUDED__
|
|
#define __PKT_HDR_H_INCLUDED__
|
|
|
|
/*
|
|
<:copyright-BRCM:2007:DUAL/GPL:standard
|
|
|
|
Copyright (c) 2007 Broadcom Corporation
|
|
All Rights Reserved
|
|
|
|
Unless you and Broadcom execute a separate written software license
|
|
agreement governing use of this software, this software is licensed
|
|
to you under the terms of the GNU General Public License version 2
|
|
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
|
|
with the following added to such license:
|
|
|
|
As a special exception, the copyright holders of this software give
|
|
you permission to link this software with independent modules, and
|
|
to copy and distribute the resulting executable under terms of your
|
|
choice, provided that you also meet, for each linked independent
|
|
module, the terms and conditions of the license of that module.
|
|
An independent module is a module which is not derived from this
|
|
software. The special exception does not apply to any modifications
|
|
of the software.
|
|
|
|
Not withstanding the above, under no circumstances may you combine
|
|
this software in any way with any other Broadcom software provided
|
|
under a license other than the GPL, without Broadcom's express prior
|
|
written consent.
|
|
|
|
:>
|
|
*/
|
|
|
|
#undef PRINT
|
|
#if defined( __KERNEL__ )
|
|
#include "bcm_OS_Deps.h"
|
|
#define PRINT printk
|
|
#else
|
|
#include <stdint.h> /* ISO C99 7.18 Integer types */
|
|
#include <stdio.h>
|
|
#define PRINT printf
|
|
#define __force
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#undef NULL
|
|
#define NULL ((void*)0)
|
|
#define NULL_IX8 ((__force uint8_t)0xFF)
|
|
#ifndef NULL_STMT
|
|
#define NULL_STMT do { /* EMPTY BODY */ } while (0)
|
|
#endif
|
|
|
|
#define SECONDS * HZ
|
|
#define MINUTES * 60 SECONDS
|
|
#define KBYTES * 1024
|
|
#define MBYTES * 1024 KBYTES
|
|
|
|
#define REG_RD(addr,val) (val)=(*(volatile uint32_t *)(addr))
|
|
#define REG_WR(addr,val) (*(volatile uint32_t *)(addr))=(val)
|
|
|
|
#define OFFSETOF(stype, member) ((size_t) &((struct stype *)0)->member)
|
|
#define RELOC(base, stype, member) ((base) + OFFSETOF(stype, member))
|
|
|
|
/* IP Dot Decimal Notation formating */
|
|
#define IP4DDN " <%03u.%03u.%03u.%03u>"
|
|
#define IP4PDDN " <%03u.%03u.%03u.%03u:%05u>"
|
|
#define IP4(ip) ((uint8_t*)&ip)[0], ((uint8_t*)&ip)[1], \
|
|
((uint8_t*)&ip)[2], ((uint8_t*)&ip)[3]
|
|
|
|
#define IP6HEX "<%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x>"
|
|
#define IP6PHEX "<%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u>"
|
|
#define IP6(ip) ((uint16_t*)&ip)[0], ((uint16_t*)&ip)[1], \
|
|
((uint16_t*)&ip)[2], ((uint16_t*)&ip)[3], \
|
|
((uint16_t*)&ip)[4], ((uint16_t*)&ip)[5], \
|
|
((uint16_t*)&ip)[6], ((uint16_t*)&ip)[7]
|
|
|
|
#define DIV32(ix) ((ix) >> 5)
|
|
#define MOD32(ix) ((ix) & 31)
|
|
#define MUL32(ix) ((ix) << 5)
|
|
|
|
#define CACHE_TO_NONCACHE(x) KSEG1ADDR(x) /* <asm/system.h> */
|
|
|
|
#define ROUNDDN(addr, align) ( (addr) & ~((align) - 1) )
|
|
#define ROUNDUP(addr, align) ( ((addr) + (align) - 1) & ~((align) - 1) )
|
|
|
|
/*
|
|
* Hooks: Generic Function Pointer
|
|
*/
|
|
typedef int (* HOOKV)( void ); /* int func ptr no args */
|
|
typedef int (* HOOKP)( void * arg_vp ); /* int func ptr with one void * arg */
|
|
typedef int (* HOOK16)( uint16_t arg16 ); /* int func ptr with uint16_t arg */
|
|
typedef int (* HOOK32)( uint32_t arg32 ); /* int func ptr with uint32_t arg */
|
|
typedef int (* HOOK3PARM)( uint32_t parm1, uint32_t parm2,
|
|
uint32_t parm3); /* int func ptr with three parameters */
|
|
typedef int (* HOOK4PARM)( uint32_t parm1, uint32_t parm2,
|
|
uint32_t parm3, void * parm4); /* int func ptr with four parameters */
|
|
|
|
|
|
/*
|
|
* 6 Byte BRCM tag and 4 byte BRCM tag. This structure provides a layout where
|
|
* the bcmhdr follws the 14byte ethhdr and the ether type now becomes h_proto.
|
|
*/
|
|
typedef uint16_t hProto_t;
|
|
|
|
struct bcmhdr {
|
|
uint32_t brcm_tag;
|
|
uint16_t h_proto;
|
|
} __attribute__((packed));
|
|
|
|
struct bcmhdr2 {
|
|
uint16_t brcm_tag;
|
|
uint16_t h_proto;
|
|
} __attribute__((packed));
|
|
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _short2buf
|
|
* Description : Read a short int into a character buffer.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline void _short2buf(uint8_t * buf, uint16_t val)
|
|
{
|
|
buf[0] = (__force uint8_t)(val >> 8);
|
|
buf[1] = (__force uint8_t)(val >> 0);
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _long2buf
|
|
* Description : Read an int into a character buffer.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
void _long2buf(uint8_t * buf, uint32_t val)
|
|
{
|
|
buf[0] = (__force uint8_t)(val >> 24);
|
|
buf[1] = (__force uint8_t)(val >> 16);
|
|
buf[2] = (__force uint8_t)(val >> 8);
|
|
buf[3] = (__force uint8_t)(val >> 0);
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _buf2short
|
|
* Description : Convert a character buffer of two bytes to a short int.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint16_t _buf2short(uint8_t * buf)
|
|
{
|
|
return ( (buf[0] << 8) | (buf[1] << 0) );
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _buf2long
|
|
* Description : Convert a character buffer of 4 bytes to an int.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint32_t _buf2long(uint8_t * buf)
|
|
{
|
|
return (__force uint32_t)
|
|
( (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0) );
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _read32_align16
|
|
* Description : Read a 32bit value from a 16 bit aligned data stream.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint32_t _read32_align16(uint16_t * from)
|
|
{
|
|
return (__force uint32_t)( (from[0] << 16) | (from[1]) );
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _write32_align16
|
|
* Description : Write a 32bit value to a 16bit aligned data stream.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
void _write32_align16( uint16_t * to, uint32_t from )
|
|
{
|
|
to[0] = (__force uint16_t)(from >> 16);
|
|
to[1] = (__force uint16_t)(from >> 0);
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : __u32cpy
|
|
* Description : 32bit aligned data copy of uncommon lengths.
|
|
* CAUTION : No check is done to ensure that bytes is even
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
void __u32cpy( uint32_t * dst_p, const uint32_t * src_p, uint32_t bytes )
|
|
{
|
|
// assuming: (bytes % sizeof(uint32_t) == 0 !!!
|
|
do {
|
|
*dst_p++ = *src_p++;
|
|
} while ( bytes -= sizeof(uint32_t) );
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : __u16cpy
|
|
* Description : 16bit aligned data copy of uncommon lengths.
|
|
* CAUTION : No check is done to ensure that bytes is even
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
void __u16cpy( uint16_t * dst_p, const uint16_t * src_p, uint32_t bytes )
|
|
{
|
|
// assuming: (bytes % sizeof(uint16_t) == 0 !!!
|
|
do {
|
|
*dst_p++ = *src_p++;
|
|
} while ( bytes -= sizeof(uint16_t) );
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _u16cpy
|
|
* Description : 16bit aligned data copy of a few small lengths.
|
|
* CAUTION : Code bloat. Use only for small sizes.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
void _u16cpy( uint16_t * dst, const uint16_t * src, const uint32_t bytes )
|
|
{
|
|
switch ( bytes ) /* common lengths, using half word alignment copy */
|
|
{
|
|
case 14: *(dst+ 6)=*(src+ 6);
|
|
case 12: *(dst+ 5)=*(src+ 5);
|
|
case 10: *(dst+ 4)=*(src+ 4);
|
|
case 8: *(dst+ 3)=*(src+ 3);
|
|
case 6: *(dst+ 2)=*(src+ 2);
|
|
case 4: *(dst+ 1)=*(src+ 1);
|
|
case 2: *(dst+ 0)=*(src+ 0);
|
|
break;
|
|
default:
|
|
__u16cpy( dst, src, (uint32_t)bytes );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _blkcpy
|
|
* Description : 32bit or 16bit aligned data copy when src is word aligned
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
void _blkcpy( void * dst, const void * src, const uint32_t bytes )
|
|
{
|
|
/* destination pointer is word aligned ? */
|
|
if ( ((uint32_t)dst & (sizeof(uint32_t)-1)) == 0 )
|
|
__u32cpy( (uint32_t*)dst, (const uint32_t *)src, bytes );
|
|
else
|
|
__u16cpy( (uint16_t*)dst, (const uint16_t *)src, bytes );
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : __u16cmp
|
|
* Description : 16bit aligned data compare of uncommon lengths.
|
|
* CAUTION : No check is done to ensure that bytes is even
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
int __u16cmp( uint16_t * dst_p, const uint16_t * src_p, uint32_t bytes )
|
|
{
|
|
// assuming: (bytes % sizeof(uint16_t) == 0 !!!
|
|
do {
|
|
if ( *dst_p++ != *src_p++ ) return -1;
|
|
} while ( bytes -= sizeof(uint16_t) );
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _u16cmp
|
|
* Description : 16bit aligned data compare of a few small lengths.
|
|
* CAUTION : Code bloat. Use only for small sizes.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
int _u16cmp( uint16_t * dst, const uint16_t * src, const uint32_t bytes )
|
|
{
|
|
switch ( bytes ) /* common lengths, using half word alignment copy */
|
|
{
|
|
case 14: if (*(dst+ 6) != *(src+ 6)) break;
|
|
case 12: if (*(dst+ 5) != *(src+ 5)) break;
|
|
case 10: if (*(dst+ 4) != *(src+ 4)) break;
|
|
case 8: if (*(dst+ 3) != *(src+ 3)) break;
|
|
case 6: if (*(dst+ 2) != *(src+ 2)) break;
|
|
case 4: if (*(dst+ 1) != *(src+ 1)) break;
|
|
case 2: if (*(dst+ 0) != *(src+ 0)) break;
|
|
return 0;
|
|
default:
|
|
return __u16cmp( dst, src, (uint32_t)bytes );
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Internet Checksum: 1's complement of "1's complement sum"
|
|
* Ref: http://www.netfor2.com/checksum.html
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _compute_icsum16
|
|
* Description : Compute delta checksum for an incremental 16bit modification.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint16_t _compute_icsum16(uint16_t csum16, uint16_t old16, uint16_t new16)
|
|
{
|
|
register uint32_t csum32;
|
|
|
|
/* build delta checksum */
|
|
csum32 = ( (__force uint32_t)(csum16 ^ 0xFFFF)
|
|
+ (__force uint32_t)(old16 ^ 0xFFFF)
|
|
+ (__force uint32_t)new16
|
|
);
|
|
while (csum32 >> 16)/* factor in carry over to effect 1's complement sum */
|
|
csum32 = (csum32 & 0xFFFF) + (csum32 >> 16);
|
|
|
|
return ((__force uint16_t)csum32 ^ 0xFFFF); /* 1's complement */
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _compute_icsum32
|
|
* Description : Compute delta checksum for an incremental 32bit modification.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint16_t _compute_icsum32(uint16_t csum16, uint32_t old32, uint32_t new32)
|
|
{
|
|
register uint16_t *optr = (uint16_t *)&old32;
|
|
register uint16_t *nptr = (uint16_t *)&new32;
|
|
register uint32_t csum32;
|
|
|
|
/* build delta checksum */
|
|
csum32 = ( (__force uint32_t)(csum16 ^ 0xFFFF)
|
|
+ (__force uint32_t)(optr[0] ^ 0xFFFF)
|
|
+ (__force uint32_t)(optr[1] ^ 0xFFFF)
|
|
+ (__force uint32_t)nptr[0]
|
|
+ (__force uint32_t)nptr[1]
|
|
);
|
|
while (csum32 >> 16)/* factor in carry over to effect 1's complement sum */
|
|
csum32 = (csum32 & 0xFFFF) + (csum32 >> 16);
|
|
|
|
return ((__force uint16_t)csum32 ^ 0xFFFF); /* 1's complement */
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _compute_icsum
|
|
* Description : Compute delta checksum for an incremental 16bit and a 32bit
|
|
* modification.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint16_t _compute_icsum(uint16_t csum16, uint32_t old32, uint32_t new32,
|
|
uint16_t old16, uint16_t new16)
|
|
{
|
|
register uint16_t *optr = (uint16_t *)&old32;
|
|
register uint16_t *nptr = (uint16_t *)&new32;
|
|
register uint32_t csum32;
|
|
|
|
/* build delta checksum */
|
|
csum32 = ( (__force uint32_t)(csum16 ^ 0xFFFF)
|
|
+ (__force uint32_t)(optr[0] ^ 0xFFFF)
|
|
+ (__force uint32_t)(optr[1] ^ 0xFFFF)
|
|
+ (__force uint32_t)(old16 ^ 0xFFFF)
|
|
+ (__force uint32_t)nptr[0]
|
|
+ (__force uint32_t)nptr[1]
|
|
+ (__force uint32_t)new16
|
|
);
|
|
while (csum32 >> 16)/* factor in carry over to effect 1's complement sum */
|
|
csum32 = (csum32 & 0xFFFF) + (csum32 >> 16);
|
|
|
|
return ((__force uint16_t)csum32 ^ 0xFFFF); /* 1's complement */
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _apply_icsum
|
|
* Description : Apply a delta checksum computed from incremental modifications
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint16_t _apply_icsum( uint16_t csum16, uint32_t delta32)
|
|
{
|
|
uint32_t csum32 = (__force uint32_t)csum16 + delta32;
|
|
|
|
while (csum32 >> 16)/* factor in carry over to effect 1's complement sum */
|
|
csum32 = (csum32 & 0xFFFF) + (csum32 >> 16);
|
|
|
|
return ((__force uint16_t)csum32);
|
|
}
|
|
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _crc16ccitt
|
|
* Description : Build a CCITT CRC16 of a character buffer of a specified size
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint16_t _crc16ccitt(uint8_t * pBuffer, uint32_t uBufSize)
|
|
{
|
|
uint32_t i;
|
|
uint16_t uCcitt16;
|
|
|
|
uCcitt16 = 0xFFFF;
|
|
|
|
for (i = 0; i < uBufSize; i++)
|
|
{
|
|
uCcitt16 = (uCcitt16 >> 8) | (uCcitt16 << 8);
|
|
uCcitt16 ^= pBuffer[i];
|
|
uCcitt16 ^= (uCcitt16 & 0xFF) >> 4;
|
|
uCcitt16 ^= (uCcitt16 << 8) << 4;
|
|
uCcitt16 ^= ((uCcitt16 & 0xFF) << 4) << 1;
|
|
}
|
|
|
|
return uCcitt16;
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _hash
|
|
* Description : Computes a simple hash from a 32bit value.
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
uint32_t _hash( uint32_t hash_val )
|
|
{
|
|
hash_val ^= ( hash_val >> 16 );
|
|
hash_val ^= ( hash_val >> 8 );
|
|
hash_val ^= ( hash_val >> 3 );
|
|
|
|
return ( hash_val );
|
|
}
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* Bit Manipulation routines
|
|
*******************************************************************************
|
|
*/
|
|
static inline
|
|
void _bitprint(uint32_t word)
|
|
{
|
|
int i;
|
|
uint32_t mask = 0x1 << 31;
|
|
for ( i=1; i <= 32; i++ )
|
|
{
|
|
if ( word & mask ) PRINT("1"); else PRINT("0");
|
|
if (( i % 8 ) == 0) PRINT(" ");
|
|
mask = mask >> 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _count_leading_zeros
|
|
* Description : Count Leading Zeros in a 32-bit bitmap
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
int _count_leading_zeros(uint32_t bitmap)
|
|
{
|
|
#if defined(__mips__) && defined (__GNUC__) && defined( __KERNEL__ )
|
|
register int zeros;
|
|
/* Count leading (higher order) zeros */
|
|
__asm__ volatile (
|
|
"clz %0, %1 \n"
|
|
: "=r" (zeros)
|
|
: "r" (bitmap));
|
|
return zeros;
|
|
#else
|
|
int shifts = 0;
|
|
while (bitmap) { shifts++; bitmap >>= 1; }
|
|
return (32U - shifts);
|
|
#endif /* ! defined(__KERNEL__) */
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
*
|
|
* Function : _find_trailing_set_bit
|
|
* Description :
|
|
* Find Trailing Set Bit in a 32bit bitmap
|
|
*
|
|
* Return the position of the trailing set bit in I, or -ve if none are set.
|
|
* The least-significant bit is position 0, the most-significant is 31
|
|
*
|
|
* E.g. Higher order ------- Lower order
|
|
* for a bitmap 0x0F0FF080 = 0b 00001111 00001111 11110000 10000000
|
|
* ^ ^ ^
|
|
* 31 7 0
|
|
* 7 = _find_trailing_set_bit(0x0F0FF080)
|
|
* -1 = _find_trailing_set_bit 0x0)
|
|
*
|
|
* PS. In the case of ffs() from string.h, the value returned is 1 .. 32.
|
|
* where a returned value 0 implies that no bit is set.
|
|
*
|
|
* Using MIPS assembly instruction clz, we need 5 compute shadow instructions
|
|
*
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
static inline
|
|
int _find_trailing_set_bit(uint32_t bitmap)
|
|
{
|
|
int zeros;
|
|
/* Clear all ones except for the trailing "lowest order" 1 */
|
|
bitmap = (bitmap ^ (bitmap - 1)) & bitmap;
|
|
/* bitmap would now have a single 1 bit and the rest all 0s */
|
|
zeros = _count_leading_zeros(bitmap);
|
|
return 31U - zeros; /* excluding the 1, trailing zeros */
|
|
}
|
|
|
|
/*
|
|
*------------------------------------------------------------------------------
|
|
* Function : _count_set_bits
|
|
* Description : Count set bits in a 32-bit bitmap
|
|
*------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static inline
|
|
uint32_t _count_set_bits(uint32_t bitmap)
|
|
{
|
|
register uint32_t count;
|
|
/* loops as many times as set bits, hence efficieny */
|
|
for (count=0; bitmap; count++)
|
|
bitmap &= bitmap - 1; /* Clear least significant bit */
|
|
return count;
|
|
}
|
|
|
|
|
|
static inline
|
|
uint32_t __count_set_bits(uint32_t bitmap)
|
|
{
|
|
uint32_t count = bitmap;
|
|
count = ((count & 0x55555555) + ((count >> 1) & 0x55555555));
|
|
count = ((count & 0x33333333) + ((count >> 2) & 0x33333333));
|
|
count = ((count & 0x0f0f0f0f) + ((count >> 4) & 0x0f0f0f0f));
|
|
count %= 255U;
|
|
return count;
|
|
}
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* Double Linked List Macros
|
|
*******************************************************************************
|
|
*
|
|
* All dll operations must be performed on a pre-initialized node.
|
|
* Inserting an uninitialized node into a list effectively initialized it.
|
|
*
|
|
* When a node is deleted from a list, you may initialize it to avoid corruption
|
|
* incurred by double deletion. You may skip initialization if the node is
|
|
* immediately inserted into another list.
|
|
*
|
|
* By placing a Dll_t element at the start of a struct, you may cast a PDll_t
|
|
* to the struct or vice versa.
|
|
*
|
|
* Example of declaring an initializing someList and inserting nodeA, nodeB
|
|
*
|
|
* typedef struct item {
|
|
* Dll_t node;
|
|
* int someData;
|
|
* } Item_t;
|
|
* Item_t nodeA, nodeB, nodeC;
|
|
* nodeA.someData = 11111, nodeB.someData = 22222, nodeC.someData = 33333;
|
|
*
|
|
* Dll_t someList;
|
|
* dll_init( &someList );
|
|
*
|
|
* dll_append( &someList, (PDll_t) &nodeA );
|
|
* dll_prepend( &someList, &nodeB.node );
|
|
* dll_insert( (PDll_t)&nodeC, &nodeA.node );
|
|
*
|
|
* dll_delete( (PDll_t) &nodeB );
|
|
*
|
|
* Example of a for loop to walk someList of node_p
|
|
*
|
|
* extern void mydisplay( Item_t * item_p );
|
|
*
|
|
* PDll_t item_p, next_p;
|
|
* for ( item_p = dll_head_p( &someList );
|
|
* ! dll_end( &someList, item_p);
|
|
* item_p = next_p )
|
|
* {
|
|
* next_p = dll_next_p(item_p);
|
|
* ... use item_p at will, including removing it from list ...
|
|
* mydisplay( (PItem_t)item_p );
|
|
* }
|
|
*
|
|
*/
|
|
#ifndef _dll_t_
|
|
#define _dll_t_
|
|
typedef struct dll_t {
|
|
struct dll_t * next_p;
|
|
struct dll_t * prev_p;
|
|
} Dll_t, * PDll_t;
|
|
|
|
#define dll_init(node_p) ((node_p)->next_p = (node_p)->prev_p = (node_p))
|
|
|
|
/* dll macros returing a PDll_t */
|
|
#define dll_head_p(list_p) ((list_p)->next_p)
|
|
#define dll_tail_p(list_p) ((list_p)->prev_p)
|
|
|
|
#define dll_next_p(node_p) ((node_p)->next_p)
|
|
#define dll_prev_p(node_p) ((node_p)->prev_p)
|
|
|
|
#define dll_empty(list_p) ((list_p)->next_p == (list_p))
|
|
#define dll_end(list_p, node_p) ((list_p) == (node_p))
|
|
|
|
/* inserts the node new_p "after" the node at_p */
|
|
#define dll_insert(new_p, at_p) ((new_p)->next_p = (at_p)->next_p, \
|
|
(new_p)->prev_p = (at_p), \
|
|
(at_p)->next_p = (new_p), \
|
|
(new_p)->next_p->prev_p = (new_p))
|
|
|
|
#define dll_append(list_p, node_p) dll_insert((node_p), dll_tail_p(list_p))
|
|
#define dll_prepend(list_p, node_p) dll_insert((node_p), (list_p))
|
|
|
|
/* deletes a node from any list that it "may" be in, if at all. */
|
|
#define dll_delete(node_p) ((node_p)->prev_p->next_p = (node_p)->next_p, \
|
|
(node_p)->next_p->prev_p = (node_p)->prev_p)
|
|
|
|
#endif /* ! defined(_dll_t_) */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* defined(__PKT_HDR_H_INCLUDED__) */
|
|
|