#ifndef __pcb_h__
#define __pcb_h__
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: pcb.h$
* $Version : 3.0.4.0$
* $Date    : Jun-23-2009$
*
* Comments:
*
*   This file contains the definitions of the generic
*   PCB (Packet Control Block) structure.  
*   Since this structure is common to
*   various protocols, this file is distributed with
*   several products.
*
*END************************************************************************/

/*--------------------------------------------------------------------------*/
/*                        CONSTANT DEFINITIONS                              */


#define __PCB__

#define PCB_free(pcb_ptr)  ((pcb_ptr)->FREE(pcb_ptr))

/* Macros for byte exchanges between host and network */
#if (PSP_MEMORY_ADDRESSING_CAPABILITY == 8)
   #if (PSP_ENDIAN == MQX_BIG_ENDIAN) && (PSP_MEMORY_ACCESSING_CAPABILITY <= 8)

      #define _HOST_TO_BEOCT_32(p,x) (*(uint_32_ptr)(p) = (x))
      #define _HOST_TO_BEOCT_16(p,x) (*(uint_16_ptr)(p) = (x))
      #define _HOST_TO_BEOCT_8(p,x)  (*(  uchar_ptr)(p) = (x))

      #define _BEOCT_TO_HOST_32(p)   (*(uint_32_ptr)(p))
      #define _BEOCT_TO_HOST_16(p)   (*(uint_16_ptr)(p))
      #define _BEOCT_TO_HOST_8(p)    (*(  uchar_ptr)(p))

   #elif (PSP_ENDIAN == MQX_BIG_ENDIAN) && (PSP_MEMORY_ACCESSING_CAPABILITY <= 16)

      #define _HOST_TO_BEOCT_32(p,x) (  (((uint_32)(p) & 1) == 0) ?              \
                                             (*(uint_32_ptr)&(p)[0] = (x))       \
                                      :                                          \
                                             (*(  uchar_ptr)&(p)[0] = (x) >> 24, \
                                              *(uint_16_ptr)&(p)[1] = (x) >>  8, \
                                              *(  uchar_ptr)&(p)[3] = (x))       )
      #define _HOST_TO_BEOCT_16(p,x) (  (((uint_32)(p) & 1) == 0) ?              \
                                             (*(uint_16_ptr)&(p)[0] = (x))       \
                                      :                                          \
                                             (*(  uchar_ptr)&(p)[0] = (x) >>  8, \
                                              *(  uchar_ptr)&(p)[1] = (x))       )
      #define _HOST_TO_BEOCT_8(p,x)          (*(  uchar_ptr)&(p)[0] = (x))

      #define _BEOCT_TO_HOST_32(p) (  (((uint_32)(p) & 1) == 0) ?                    \
                                                     (*(uint_32_ptr)&(p)[0])         \
                                    :                                                \
                                           (((uint_32)*(  uchar_ptr)&(p)[0] << 24) | \
                                            ((uint_32)*(uint_16_ptr)&(p)[1] <<  8) | \
                                            ((uint_32)*(  uchar_ptr)&(p)[3]      ))  )
      #define _BEOCT_TO_HOST_16(p) (  (((uint_32)(p) & 1) == 0) ?                    \
                                                     (*(uint_16_ptr)&(p)[0])         \
                                    :                                                \
                                           (((uint_16)*(  uchar_ptr)&(p)[0] <<  8) | \
                                ((uint_16)*(  uchar_ptr)&(p)[1]      ))  )
      #define _BEOCT_TO_HOST_8(p)                    (*(  uchar_ptr)&(p)[0])

   #elif (PSP_ENDIAN == MQX_BIG_ENDIAN)

      #define _HOST_TO_BEOCT_32(p,x) (  (((uint_32)(p) & 3) == 0) ?            \
                                           (*(uint_32_ptr)&(p)[0] = (x))       \
                                      : (((uint_32)(p) & 1) == 0) ?            \
                                           (*(uint_16_ptr)&(p)[0] = (x) >> 16, \
                                            *(uint_16_ptr)&(p)[2] = (x))       \
                                      :                                        \
                                           (*(  uchar_ptr)&(p)[0] = (x) >> 24, \
                                            *(uint_16_ptr)&(p)[1] = (x) >>  8, \
                                            *(  uchar_ptr)&(p)[3] = (x))       )
      #define _HOST_TO_BEOCT_16(p,x) (  (((uint_32)(p) & 1) == 0) ?            \
                                           (*(uint_16_ptr)&(p)[0] = (x))       \
                                      :                                        \
                                           (*(  uchar_ptr)&(p)[0] = (x) >>  8, \
                                            *(  uchar_ptr)&(p)[1] = (x))       )
      #define _HOST_TO_BEOCT_8(p,x)        (*(  uchar_ptr)&(p)[0] = (x))

      #define _BEOCT_TO_HOST_32(p) (  (((uint_32)(p) & 3) == 0) ?                    \
                                                     (*(uint_32_ptr)&(p)[0])         \
                                    : (((uint_32)(p) & 1) == 0) ?                    \
                                           (((uint_32)*(uint_16_ptr)&(p)[0] << 16) | \
                                            ((uint_32)*(uint_16_ptr)&(p)[2]      ))  \
                                    :                                                \
                                           (((uint_32)*(  uchar_ptr)&(p)[0] << 24) | \
                                            ((uint_32)*(uint_16_ptr)&(p)[1] <<  8) | \
                                            ((uint_32)*(  uchar_ptr)&(p)[3]      ))  )
      #define _BEOCT_TO_HOST_16(p) (  (((uint_32)(p) & 1) == 0) ?                    \
                                                     (*(uint_16_ptr)&(p)[0])         \
                                    :                                                \
                                           (((uint_16)*(  uchar_ptr)&(p)[0] <<  8) | \
                                            ((uint_16)*(  uchar_ptr)&(p)[1]      ))  )
      #define _BEOCT_TO_HOST_8(p)                    (*(  uchar_ptr)&(p)[0])

   #else

/* Start CR 1150 */
      #define _HOST_TO_BEOCT_32(p,x) (((uchar_ptr)(p))[0] = (x) >> 24, \
                                      ((uchar_ptr)(p))[1] = (x) >> 16, \
                                      ((uchar_ptr)(p))[2] = (x) >>  8, \
                                      ((uchar_ptr)(p))[3] = (x))

      #define _HOST_TO_BEOCT_16(p,x) (((uchar_ptr)(p))[0] = (x) >>  8, \
                                      ((uchar_ptr)(p))[1] = (x))

      #define _HOST_TO_BEOCT_8(p,x)  (((uchar_ptr)(p))[0] = (x))

      #define _BEOCT_TO_HOST_32(p)   ((((uint_32)(p)[0]) << 24) | \
                                      (((uint_32)(p)[1]) << 16) | \
                                      (((uint_32)(p)[2]) <<  8) | \
                                      (((uint_32)(p)[3])      ))

      #define _BEOCT_TO_HOST_16(p)   ((((uint_16)(p)[0]) <<  8) | \
                                      (((uint_16)(p)[1])      ))

      #define _BEOCT_TO_HOST_8(p)    (((  uchar)(p)[0]        ))
/* End   CR 1150 */

   #endif

#else

   /*
   ** This set of macros will always work on all processors.
   ** The sets of macros above are just optimizations for
   ** specific architectures.
   */

   #define _HOST_TO_BEOCT_32(p,x) ((p)[0] = ((uint_32)(x)) >> 24 & 0xFF, \
                                   (p)[1] = ((uint_32)(x)) >> 16 & 0xFF, \
                                   (p)[2] = ((uint_32)(x)) >>  8 & 0xFF, \
                                   (p)[3] = ((uint_32)(x))       & 0xFF)

   #define _HOST_TO_BEOCT_16(p,x) ((p)[0] = ((uint_16)(x)) >>  8 & 0xFF, \
                                   (p)[1] = ((uint_16)(x))       & 0xFF)

   #define _HOST_TO_BEOCT_8(p,x)  ((p)[0] = ((uint_8)(x))       & 0xFF)

   #define _BEOCT_TO_HOST_32(p)   ((((uint_32)(p)[0] & 0xFF) << 24) | \
                                   (((uint_32)(p)[1] & 0xFF) << 16) | \
                                   (((uint_32)(p)[2] & 0xFF) <<  8) | \
                                   (((uint_32)(p)[3] & 0xFF)      ))

   #define _BEOCT_TO_HOST_16(p)   ((((uint_16)(p)[0] & 0xFF) <<  8) | \
                                   (((uint_16)(p)[1] & 0xFF)      ))

   #define _BEOCT_TO_HOST_8(p)    ((((  uchar)(p)[0] & 0xFF)      ))

#endif

/* Backwards compatibility macros */
#define htonl _HOST_TO_BEOCT_32
#define htons _HOST_TO_BEOCT_16
#define htonc _HOST_TO_BEOCT_8 
#define ntohl _BEOCT_TO_HOST_32  
#define ntohs _BEOCT_TO_HOST_16  
#define ntohc _BEOCT_TO_HOST_8   

/*--------------------------------------------------------------------------*/
/*
**                          DATA STRUCTURES
*/

/*
** The PCB (Packet Control Block)
** 
** One PCB contains exactly one packet, possibly split over several areas of
** memory.
** 
** The PCB structure consists of two pointers (FREE and PRIVATE) followed by a
** variable-length array of PCB_FRAGMENT structures.  The array is terminated
** by an entry with LENGTH=0 and FRAGMENT=NULL.
**
** The PCB's owner (i.e. the module that allocated it) must initialize the
** FREE field to point to a function to free the PCB.  PRIVATE can be used by
** the PCB's owner to store any information it wishes.
*/

struct pcb;
typedef void (_CODE_PTR_  _pcb_free_fn)(struct pcb _PTR_);

typedef struct pcb_fragment 
{
   uint_32           LENGTH;
   uchar_ptr         FRAGMENT;
} PCB_FRAGMENT, _PTR_ PCB_FRAGMENT_PTR;

typedef struct pcb 
{
//   void (_CODE_PTR_  FREE)(struct pcb _PTR_);
   _pcb_free_fn      FREE;

   pointer           PRIVATE;
   PCB_FRAGMENT      FRAG[1];
} PCB, _PTR_ PCB_PTR;

// The minimum size of a PCB must contain two fragments, so the following represents
// the smallest PCB
typedef struct pcb2
{
   _pcb_free_fn      FREE;
   pointer           PRIVATE;
   PCB_FRAGMENT      FRAG[2];
} PCB2, _PTR_ PCB2_PTR;

#define PCB_MINIMUM_SIZE (sizeof(PCB2))

/*--------------------------------------------------------------------------*/
/*                           EXTERNAL DECLARATIONS                          */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif
/* EOF */
