root/usr/src/uts/common/io/bnx/include/lm_defs.h
/*
 * Copyright 2014-2017 Cavium, Inc.
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License, v.1,  (the "License").
 *
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the License at available
 * at http://opensource.org/licenses/CDDL-1.0
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LM_DEFS_H
#define _LM_DEFS_H

#ifdef __cplusplus
extern "C" {
#endif

#include "bcmtype.h"

/*
 * Simple constants.
 */

#ifndef TRUE
#define TRUE    1
#endif

#ifndef FALSE
#define FALSE   0
#endif

#ifndef NULL
#define NULL    ((void *) 0)
#endif


/* Signatures for integrity checks. */
#define LM_DEVICE_SIG           0x6d635242      /* BRcm */
#define L2PACKET_RX_SIG         0x7872324c      /* L2rx */
#define L2PACKET_TX_SIG         0x7874324c      /* L2tx */
#define L4BUFFER_RX_SIG         0x7872344c      /* L4rx */
#define L4BUFFER_TX_SIG         0x7874344c      /* L4tx */
#define L4BUFFER_SIG            0x66754254      /* TBuf */
#define L4GEN_BUFFER_SIG        0x006e6567      /* gen  */
#define L4GEN_BUFFER_SIG_END    0x0067656e      /* neg  */

#define SIZEOF_SIG              16
#define SIG(_p)                 (*((u32_t *)((u8_t *)(_p) - sizeof (u32_t))))
#define END_SIG(_p, _size)      (*((u32_t *)((u8_t *)(_p) + (_size))))

/*
 * This macro rounds the given value to the next word boundary if it
 * is not already at a word boundary.
 */
#define ALIGN_VALUE_TO_WORD_BOUNDARY(_v) \
        (((_v) + (sizeof (void *) - 1)) & ~(sizeof (void *) - 1))

/*
 * This macro determines the delta to the next alignment which is
 * either 1, 2, 4, 8, 16, 32, etc.
 */
#define ALIGN_DELTA_TO_BOUNDARY(_p, _a) \
        (((((u8_t *)(_p) - (u8_t *)0) + ((_a) - 1)) & ~((_a) - 1)) - \
        ((u8_t *)(_p) - (u8_t *)0))

/*
 * This macro returns the pointer to the next alignment if the pointer
 * is not currently on the indicated alignment boundary.
 */
#define ALIGN_PTR_TO_BOUNDARY(_p, _a) \
        ((u8_t *)(_p) + ALIGN_DELTA_TO_BOUNDARY(_p, _a))



/*
 * Status codes.
 */

typedef enum
{
        LM_STATUS_SUCCESS               = 0,
        LM_STATUS_LINK_UNKNOWN          = 0,
        LM_STATUS_FAILURE               = 1,
        LM_STATUS_RESOURCE              = 2,
        LM_STATUS_ABORTED               = 3,
        LM_STATUS_PENDING               = 4,
        LM_STATUS_PAUSED                = 5,
        LM_STATUS_INVALID_PARAMETER     = 6,
        LM_STATUS_LINK_ACTIVE           = 7,
        LM_STATUS_LINK_DOWN             = 8,
        LM_STATUS_UNKNOWN_ADAPTER       = 9,
        LM_STATUS_UNKNOWN_PHY           = 10,
        LM_STATUS_UNKNOWN_MEDIUM        = 11,
        LM_STATUS_TOO_MANY_FRAGMENTS    = 12,
        LM_STATUS_BUFFER_TOO_SHORT      = 16,
        LM_STATUS_UPLOAD_IN_PROGRESS    = 17,
        LM_STATUS_BUSY                  = 18,
        LM_STATUS_INVALID_KEY           = 19,
        LM_STATUS_TIMEOUT               = 20,
        LM_STATUS_REQUEST_NOT_ACCEPTED  = 21,
        LM_STATUS_CONNECTION_CLOSED     = 22,
        LM_STATUS_BAD_SIGNATURE         = 23,
        LM_STATUS_CONNECTION_RESET      = 24,
        LM_STATUS_EXISTING_OBJECT       = 25,
        LM_STATUS_OBJECT_NOT_FOUND      = 26,
        LM_STATUS_CONNECTION_RM_DISC    = 27,
        LM_STATUS_VF_LAMAC_REJECTED     = 28,
        LM_STATUS_NOT_IMPLEMENTED       = 29,
        LM_STATUS_UNKNOWN_EVENT_CODE    = 30
} lm_status_t;


/*
 * Receive filter masks.
 */

typedef u32_t lm_rx_mask_t;

#define LM_RX_MASK_ACCEPT_NONE                  0x0000
#define LM_RX_MASK_ACCEPT_UNICAST               0x0001
#define LM_RX_MASK_ACCEPT_MULTICAST             0x0002
#define LM_RX_MASK_ACCEPT_ALL_MULTICAST         0x0004
#define LM_RX_MASK_ACCEPT_BROADCAST             0x0008
#define LM_RX_MASK_ACCEPT_ERROR_PACKET          0x0010

#define LM_RX_MASK_PROMISCUOUS_MODE             0x10000



/*
 * Flow control.
 */

typedef u32_t lm_flow_control_t;

#define LM_FLOW_CONTROL_NONE                    0x00
#define LM_FLOW_CONTROL_RECEIVE_PAUSE           0x01
#define LM_FLOW_CONTROL_TRANSMIT_PAUSE          0x02

/*
 * This value can be or-ed with RECEIVE_PAUSE and TRANSMIT_PAUSE.  If the
 * auto-negotiation is disabled and the RECEIVE_PAUSE and TRANSMIT_PAUSE bits
 * are set, then flow control is enabled regardless of link partner's flow
 * control capability.  Otherwise, if this bit is set, then flow is negotiated
 * with the link partner.  Values 0x80000000 and 0x80000003 are equivalent.
 */
#define LM_FLOW_CONTROL_AUTO_PAUSE              0x80000000


/*
 * EEE control.
 */

/*
 * values match the registry values for EeeCtrlMode . Default is MED
 * ("Balanced")
 */
typedef enum
{
        LM_EEE_CONTROL_HIGH     = 0, // MaxPowerSave
        LM_EEE_CONTROL_MED      = 1, // Balance
        LM_EEE_CONTROL_LOW      = 2, // MaxPreformance
        LM_EEE_CONTROL_NVRAM    = 3, // use NVRAM
        LM_EEE_CONTROL_NA       = 4  // either N/A or disabled
} lm_eee_policy_t;

/*
 * media type.
 */

typedef u32_t lm_medium_t;

#define LM_MEDIUM_AUTO_DETECT                   0x0000

#define LM_MEDIUM_TYPE_UNKNOWN                  0x0000
#define LM_MEDIUM_TYPE_BNC                      0x0001
#define LM_MEDIUM_TYPE_UTP                      0x0002
#define LM_MEDIUM_TYPE_FIBER                    0x0003
#define LM_MEDIUM_TYPE_SERDES                   0x0004
#define LM_MEDIUM_TYPE_SERDES_SGMII             0x0005
#define LM_MEDIUM_TYPE_XGXS                     0x0006
#define LM_MEDIUM_TYPE_XGXS_SGMII               0x0007
#define LM_MEDIUM_TYPE_XMAC_LOOPBACK            0x0008
#define LM_MEDIUM_TYPE_UMAC_LOOPBACK            0x0009
#define LM_MEDIUM_TYPE_EXT_LOOPBACK             0x00f6
#define LM_MEDIUM_TYPE_EXT_PHY_LOOPBACK         0x00f7
#define LM_MEDIUM_TYPE_SERDES_LOOPBACK          0x00f8
#define LM_MEDIUM_TYPE_XGXS_LOOPBACK            0x00f9
#define LM_MEDIUM_TYPE_XGXS_10_LOOPBACK         0x00fa
#define LM_MEDIUM_TYPE_BMAC_LOOPBACK            0x00fb
#define LM_MEDIUM_TYPE_EMAC_LOOPBACK            0x00fc
#define LM_MEDIUM_TYPE_PHY_LOOPBACK             0x00fd
#define LM_MEDIUM_TYPE_MAC_LOOPBACK             0x00fe
#define LM_MEDIUM_TYPE_NULL                     0x00ff
#define LM_MEDIUM_TYPE_MASK                     0x00ff
#define GET_MEDIUM_TYPE(m)                      ((m) & LM_MEDIUM_TYPE_MASK)
#define SET_MEDIUM_TYPE(m, t) \
        (m) = ((m) & ~LM_MEDIUM_TYPE_MASK) | (t)

#define LM_MEDIUM_IS_LOOPBACK(_medium) \
        (((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_BMAC_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_UMAC_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_XMAC_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_EXT_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_EXT_PHY_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_SERDES_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_XGXS_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_XGXS_10_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_PHY_LOOPBACK) || \
        ((GET_MEDIUM_TYPE(_medium)) == LM_MEDIUM_TYPE_MAC_LOOPBACK))

#define LM_MEDIUM_SPEED_AUTONEG                 0x0000

#define LM_MEDIUM_SPEED_UNKNOWN                 0x0000
#define LM_MEDIUM_SPEED_10MBPS                  0x0100
#define LM_MEDIUM_SPEED_100MBPS                 0x0200
#define LM_MEDIUM_SPEED_1000MBPS                0x0300
#define LM_MEDIUM_SPEED_2500MBPS                0x0400
#define LM_MEDIUM_SPEED_10GBPS                  0x0600
#define LM_MEDIUM_SPEED_12GBPS                  0x0700
#define LM_MEDIUM_SPEED_12_5GBPS                0x0800
#define LM_MEDIUM_SPEED_13GBPS                  0x0900
#define LM_MEDIUM_SPEED_15GBPS                  0x0a00
#define LM_MEDIUM_SPEED_16GBPS                  0x0b00
#define LM_MEDIUM_SPEED_20GBPS                  0x0c00
#define LM_MEDIUM_SPEED_25GBPS                  0x0d00
#define LM_MEDIUM_SPEED_40GBPS                  0x0e00
#define LM_MEDIUM_SPEED_50GBPS                  0x0f00
#define LM_MEDIUM_SPEED_SEQ_START               0x1d00  // 100Mbps
#define LM_MEDIUM_SPEED_SEQ_END                 0xE400  // 20Gbps
#define LM_MEDIUM_SPEED_AUTONEG_1G_FALLBACK     0xFD00  /* Serdes */
#define LM_MEDIUM_SPEED_AUTONEG_2_5G_FALLBACK   0xFE00  /* Serdes */
#define LM_MEDIUM_SPEED_HARDWARE_DEFAULT        0xff00  /* Serdes nvram def. */
#define LM_MEDIUM_SPEED_MASK                    0xff00
#define GET_MEDIUM_SPEED(m)                     ((m) & LM_MEDIUM_SPEED_MASK)
#define SET_MEDIUM_SPEED(m, s) \
        (m) = ((m) & ~LM_MEDIUM_SPEED_MASK) | (s)

#define LM_MEDIUM_FULL_DUPLEX           0x00000
#define LM_MEDIUM_HALF_DUPLEX           0x10000
#define GET_MEDIUM_DUPLEX(m)            ((m) & LM_MEDIUM_HALF_DUPLEX)
#define SET_MEDIUM_DUPLEX(m, d) \
        (m) = ((m) & ~LM_MEDIUM_HALF_DUPLEX) | (d)

#define LM_MEDIUM_SELECTIVE_AUTONEG             0x01000000
#define GET_MEDIUM_AUTONEG_MODE(m)              ((m) & 0xff000000)

typedef struct _lm_link_settings_t
{
        u32_t flag;
#define LINK_FLAG_SELECTIVE_AUTONEG_MASK                        0x0f
#define LINK_FLAG_SELECTIVE_AUTONEG_ONE_SPEED                   0x01
#define LINK_FLAG_SELECTIVE_AUTONEG_ENABLE_SLOWER_SPEEDS        0x02
#define LINK_FLAG_WIRE_SPEED                                    0x10

        lm_medium_t req_medium;
        lm_flow_control_t flow_ctrl;

        u32_t _reserved;
} lm_link_settings_t;



/*
 * Power state.
 */

typedef enum
{
        LM_POWER_STATE_D0 = 0,
        LM_POWER_STATE_D1 = 1,
        LM_POWER_STATE_D2 = 2,
        LM_POWER_STATE_D3 = 3
} lm_power_state_t;



/*
 * offloading.
 */

typedef u32_t lm_offload_t;

#define LM_OFFLOAD_NONE                 0x00000000
#define LM_OFFLOAD_TX_IP_CKSUM          0x00000001
#define LM_OFFLOAD_RX_IP_CKSUM          0x00000002
#define LM_OFFLOAD_TX_TCP_CKSUM         0x00000004
#define LM_OFFLOAD_RX_TCP_CKSUM         0x00000008
#define LM_OFFLOAD_TX_UDP_CKSUM         0x00000010
#define LM_OFFLOAD_RX_UDP_CKSUM         0x00000020
#define LM_OFFLOAD_IPV4_TCP_LSO         0x00000040
#define LM_OFFLOAD_IPV6_TCP_LSO         0x00000080
#define LM_OFFLOAD_CHIMNEY              0x00000100
#define LM_OFFLOAD_IPV6_CHIMNEY         0x00000200
#define LM_OFFLOAD_TX_TCP6_CKSUM        0x00001000
#define LM_OFFLOAD_RX_TCP6_CKSUM        0x00002000
#define LM_OFFLOAD_TX_UDP6_CKSUM        0x00004000
#define LM_OFFLOAD_RX_UDP6_CKSUM        0x00008000
#define LM_OFFLOAD_RSC_IPV4             0x00010000
#define LM_OFFLOAD_RSC_IPV6             0x00020000
#define LM_OFFLOAD_ENCAP_PACKET         0x00040000



/*
 * RSS Hash Types
 */

typedef u32_t lm_rss_hash_t;

#define LM_RSS_HASH_IPV4                0x00000100
#define LM_RSS_HASH_TCP_IPV4            0x00000200
#define LM_RSS_HASH_IPV6                0x00000400
#define LM_RSS_HASH_IPV6_EX             0x00000800
#define LM_RSS_HASH_TCP_IPV6            0x00001000
#define LM_RSS_HASH_TCP_IPV6_EX         0x00002000



/*
 * Chip reset reasons.
 */

typedef enum
{
        LM_REASON_NONE                          = 0,
        LM_REASON_DRIVER_RESET                  = 1,
        LM_REASON_DRIVER_UNLOAD                 = 2,
        LM_REASON_DRIVER_SHUTDOWN               = 3,
        LM_REASON_WOL_SUSPEND                   = 4,
        LM_REASON_NO_WOL_SUSPEND                = 5,
        LM_REASON_DIAG                          = 6,
        /* Power down phy/serdes */
        LM_REASON_DRIVER_UNLOAD_POWER_DOWN      = 7,
        LM_REASON_ERROR_RECOVERY                = 8
} lm_reason_t;



/*
 * Wake up mode.
 */

typedef u32_t lm_wake_up_mode_t;

#define LM_WAKE_UP_MODE_NONE            0
#define LM_WAKE_UP_MODE_MAGIC_PACKET    1
#define LM_WAKE_UP_MODE_NWUF            2
#define LM_WAKE_UP_MODE_LINK_CHANGE     4



/*
 * Event code.
 */
typedef enum
{
        LM_EVENT_CODE_LINK_CHANGE               = 0,
        LM_EVENT_CODE_PAUSE_OFFLOAD             = 1,
        LM_EVENT_CODE_RESUME_OFFLOAD            = 2,
        /* For Error Recovery Flow */
        LM_EVENT_CODE_STOP_CHIP_ACCESS          = 3,
        /* For Error Recovery Flow */
        LM_EVENT_CODE_RESTART_CHIP_ACCESS       = 4,
        LM_EVENT_CODE_UPLOAD_ALL                = 5,
        LM_EVENT_CODE_DCBX_OPERA_CHANGE         = 6,
        LM_EVENT_CODE_DCBX_REMOTE_CHANGE        = 7,
        LM_EVENT_CODE_INVALIDATE_VF_BLOCK       = 8,
} lm_event_code_t;


/*
 * Transmit control flags.
 */

typedef u32_t lm_tx_flag_t;

#define LM_TX_FLAG_INSERT_VLAN_TAG              0x01
#define LM_TX_FLAG_COMPUTE_IP_CKSUM             0x02
#define LM_TX_FLAG_COMPUTE_TCP_UDP_CKSUM        0x04
#define LM_TX_FLAG_TCP_LSO_FRAME                0x08
#define LM_TX_FLAG_TCP_LSO_SNAP_FRAME           0x10
#define LM_TX_FLAG_COAL_NOW                     0x20
#define LM_TX_FLAG_DONT_COMPUTE_CRC             0x40
#define LM_TX_FLAG_SKIP_MBQ_WRITE               0x80
#define LM_TX_FLAG_IPV6_PACKET                  0x100
#define LM_TX_FLAG_VLAN_TAG_EXISTS              0x200
/*
 * If this flag is set, the firmware will ignore global
 * configuration (except Outer VLAN)and will handle inner Vlan
 * only according to driver instructions on the bd:
 * 1. LM_TX_FLAG_VLAN_TAG_EXISTS.
 * 2. LM_TX_FLAG_INSERT_VLAN_TAG.
 * Note that if set the firmware will not handle default vlan /
 * NIV tag / DCB.
 */
#define LM_TX_FLAG_FORCE_VLAN_MODE              0x400
/* Encapsulated packet offload flags. */
#define LM_TX_FLAG_IS_ENCAP_PACKET              0x800
#define LM_TX_FLAG_ENCAP_PACKET_IS_INNER_IPV6   0x1000

typedef struct _lm_pkt_tx_info_t
{
        lm_tx_flag_t flags;

        u16_t vlan_tag;
        u16_t lso_mss;
        u16_t lso_ip_hdr_len;
        u16_t lso_tcp_hdr_len;
        u32_t lso_payload_len;

        /* Everest only fields. */
        u32_t lso_tcp_send_seq;
        u16_t lso_ipid;
        u16_t tcp_pseudo_csum;
        u8_t  lso_tcp_flags;
        u8_t  tcp_nonce_sum_bit;
        u16_t fw_ip_csum;

        u8_t dst_mac_addr[8];
        s8_t cs_any_offset;
        u8_t src_mac_addr[8];
        u8_t _unused1;
        u8_t eth_type[4];

        /*
         * Encapsulated packet offsets.  These fields are only valid when
         * LM_TX_FLAG_IS_ENCAP_PACKET is set.
         */
        u8_t  encap_packet_inner_frame_offset;
        u8_t  encap_packet_inner_ip_relative_offset;
        u16_t encap_packet_inner_tcp_relative_offset;
} lm_pkt_tx_info_t;



/*
 * Receive control flags.
 */

typedef u32_t lm_rx_flag_t;

#define LM_RX_FLAG_VALID_VLAN_TAG               0x00000001
#define LM_RX_FLAG_VALID_HASH_VALUE             0x00000010

#define LM_RX_FLAG_IS_IPV4_DATAGRAM             0x00000100
#define LM_RX_FLAG_IS_IPV6_DATAGRAM             0x00000200
#define LM_RX_FLAG_IP_CKSUM_IS_GOOD             0x00000400
#define LM_RX_FLAG_IP_CKSUM_IS_BAD              0x00000800

#define LM_RX_FLAG_IS_UDP_DATAGRAM              0x00001000
#define LM_RX_FLAG_UDP_CKSUM_IS_GOOD            0x00002000
#define LM_RX_FLAG_UDP_CKSUM_IS_BAD             0x00004000

#define LM_RX_FLAG_IS_TCP_SEGMENT               0x00010000
#define LM_RX_FLAG_TCP_CKSUM_IS_GOOD            0x00020000
#define LM_RX_FLAG_TCP_CKSUM_IS_BAD             0x00040000
#define LM_RX_FLAG_START_RSC_TPA                0x00080000

#define LM_RX_FLAG_HASH_TYPE_IPV4               0x00100000
#define LM_RX_FLAG_HASH_TYPE_TCP_IPV4           0x00200000
#define LM_RX_FLAG_HASH_TYPE_IPV6               0x00400000
#define LM_RX_FLAG_HASH_TYPE_TCP_IPV6           0x00800000
#define LM_RX_FLAG_HASH_TYPE_MASK               0x00f00000

typedef struct _lm_pkt_rx_info_t
{
        lm_rx_flag_t flags;

        u32_t size;

        u16_t vlan_tag;
        u16_t _pad;

        /*
         * Virtual address corresponding to the first byte of the first SGL
         * entry.  This is the starting location of the packet which may begin
         * with some control information.
         */
        u8_t *mem_virt;
        u32_t mem_size;

        /* these fields only valid when LM_RX_FLAG_START_RSC_TPA is set */
        u16_t coal_seg_cnt;
        u16_t dup_ack_cnt;
        u32_t ts_delta;  /* valid when timestamp is enabled */
        /*
         * if the packet is RSC, this field will hold the total size of the
         * RSC SCU
         */
        u32_t total_packet_size;

        u32_t unused;
} lm_pkt_rx_info_t;



/*
 * various type of counters.
 */

typedef enum
{
        LM_STATS_BASE                           = 0x686b3000,
        LM_STATS_FRAMES_XMITTED_OK              = 0x686b3001,
        LM_STATS_FRAMES_RECEIVED_OK             = 0x686b3002,
        LM_STATS_ERRORED_TRANSMIT_CNT           = 0x686b3003,
        LM_STATS_ERRORED_RECEIVE_CNT            = 0x686b3004,
        LM_STATS_RCV_CRC_ERROR                  = 0x686b3005,
        LM_STATS_ALIGNMENT_ERROR                = 0x686b3006,
        LM_STATS_SINGLE_COLLISION_FRAMES        = 0x686b3007,
        LM_STATS_MULTIPLE_COLLISION_FRAMES      = 0x686b3008,
        LM_STATS_FRAMES_DEFERRED                = 0x686b3009,
        LM_STATS_MAX_COLLISIONS                 = 0x686b300a,
        LM_STATS_RCV_OVERRUN                    = 0x686b300b,
        LM_STATS_XMIT_UNDERRUN                  = 0x686b300c,
        LM_STATS_UNICAST_FRAMES_XMIT            = 0x686b300d,
        LM_STATS_MULTICAST_FRAMES_XMIT          = 0x686b300e,
        LM_STATS_BROADCAST_FRAMES_XMIT          = 0x686b300f,
        LM_STATS_UNICAST_FRAMES_RCV             = 0x686b3010,
        LM_STATS_MULTICAST_FRAMES_RCV           = 0x686b3011,
        LM_STATS_BROADCAST_FRAMES_RCV           = 0x686b3012,
        LM_STATS_RCV_NO_BUFFER_DROP             = 0x686b3013,
        LM_STATS_BYTES_RCV                      = 0x686b3014,
        LM_STATS_BYTES_XMIT                     = 0x686b3015,
        LM_STATS_IP4_OFFLOAD                    = 0x686b3016,
        LM_STATS_TCP_OFFLOAD                    = 0x686b3017,
        LM_STATS_IF_IN_DISCARDS                 = 0x686b3018,
        LM_STATS_IF_IN_ERRORS                   = 0x686b3019,
        LM_STATS_IF_OUT_ERRORS                  = 0x686b301a,
        LM_STATS_IP6_OFFLOAD                    = 0x686b301b,
        LM_STATS_TCP6_OFFLOAD                   = 0x686b301c,
        LM_STATS_XMIT_DISCARDS                  = 0x686b301d,
        LM_STATS_DIRECTED_BYTES_RCV             = 0x686b301e,
        LM_STATS_MULTICAST_BYTES_RCV            = 0x686b301f,
        LM_STATS_BROADCAST_BYTES_RCV            = 0x686b3020,
        LM_STATS_DIRECTED_BYTES_XMIT            = 0x686b3021,
        LM_STATS_MULTICAST_BYTES_XMIT           = 0x686b3022,
        LM_STATS_BROADCAST_BYTES_XMIT           = 0x686b3023,
} lm_stats_t;

#define NUM_OF_LM_STATS         36


/*
 * 64-bit value.
 */

typedef union _lm_u64_t
{
        struct _lm_u64_as_u32_t
        {
#ifdef BIG_ENDIAN_HOST
                u32_t high;
                u32_t low;
#else
                u32_t low;
                u32_t high;
#endif
        } as_u32;

        u64_t as_u64;

        void *as_ptr;
} lm_u64_t;


typedef lm_u64_t lm_address_t;


/* 64-bit increment.  The second argument is a 32-bit value. */
#define LM_INC64(result, addend32)                      \
        {                                               \
                u32_t low;                              \
                                                        \
                low = (result)->as_u32.low;             \
                (result)->as_u32.low += (addend32);     \
                if ((result)->as_u32.low < low)         \
                {                                       \
                    (result)->as_u32.high++;            \
                }                                       \
        }


/* 64-bit decrement.  The second argument is a 32-bit value. */
#define LM_DEC64(result, addend32)                      \
        {                                               \
                u32_t low;                              \
                                                        \
                low = (result)->as_u32.low;             \
                (result)->as_u32.low -= (addend32);     \
                if ((result)->as_u32.low > low)         \
                {                                       \
                        (result)->as_u32.high--;        \
                }                                       \
        }

/*
 * IP4 and TCP offload stats.
 */

typedef struct _lm_ip4_offload_stats_t
{
    u64_t in_receives;
    u64_t in_delivers;
    u64_t out_requests;
    u32_t in_header_errors;
    u32_t in_discards;
    u32_t out_discards;
    u32_t out_no_routes;

    u32_t _pad[8];
} lm_ip4_offload_stats_t;


typedef struct _lm_tcp_offload_stats_t
{
    u64_t in_segments;
    u64_t out_segments;
    u32_t retran_segments;
    u32_t in_errors;
    u32_t out_resets;

    u32_t _pad[8];
} lm_tcp_offload_stats_t;



/*
 * Host to network order conversion.
 */

#ifdef BIG_ENDIAN_HOST

#ifndef HTON16
#define HTON16(_val16)  (_val16)
#endif
#ifndef HTON32
#define HTON32(_val32)  (_val32)
#ifndef NTOH16
#endif
#define NTOH16(_val16)  (_val16)
#endif
#ifndef NTOH32
#define NTOH32(_val32)  (_val32)
#endif

#else

#ifndef HTON16
#define HTON16(_val16)  (((_val16 & 0xff00) >> 8) | ((_val16 & 0xff) << 8))
#endif
#ifndef HTON32
#define HTON32(_val32)  ((HTON16(_val32) << 16) | (HTON16(_val32 >> 16)))
#endif
#ifndef NTOH16
#define NTOH16(_val16)  HTON16(_val16)
#endif
#ifndef NTOH32
#define NTOH32(_val32)  HTON32(_val32)
#endif

#endif



/*
 * Fragment structure.
 */

typedef struct _lm_frag_t
{
    lm_address_t addr;
    u32_t size;
    u32_t _reserved;
} lm_frag_t;

typedef struct _lm_frag_list_t
{
    u32_t cnt;
    u32_t size;

    lm_frag_t frag_arr[1];
} lm_frag_list_t;

/* a macro for declaring 'lm_frag_list_t' with various array sizes. */
#define DECLARE_FRAG_LIST_BUFFER_TYPE(_FRAG_LIST_TYPE_NAME, _MAX_FRAG_CNT) \
        typedef struct _##_FRAG_LIST_TYPE_NAME                          \
        {                                                               \
                lm_frag_list_t list;                                    \
                lm_frag_t frag_arr[_MAX_FRAG_CNT-1];                    \
        } _FRAG_LIST_TYPE_NAME

/*
 * DCBX indicate event parameters.
 */
typedef enum _dcb_condition_selector_t
{
    DCB_CONDITION_RESERVED,
    DCB_CONDITION_DEFAULT,
    DCB_CONDITION_TCP_PORT,
    DCB_CONDITION_UDP_PORT,
    DCB_CONDITION_TCP_OR_UDP_PORT,
    DCB_CONDITION_ETHERTYPE,
    DCB_CONDITION_NETDIRECT_PORT,
    DCB_CONDITION_MAX,
}dcb_condition_selector_t;

typedef enum _action_selector_t
{
    DCB_ACTION_PRIORITY,
    DCB_ACTION_MAX,
} action_selector_t;

typedef struct _dcb_classif_elem_t
{
    u32_t flags;
#define DCB_CLASSIF_ENFORCED_BY_VBD     0x1
    dcb_condition_selector_t condition_selector;
    u16_t condition_field;
    action_selector_t action_selector;
    u16_t action_field;
}dcb_classif_elem_t;

typedef enum _dcb_classif_version_t
{
    DCB_CLASSIFI_VER_SIMPLE_ELEM,
    DCB_CLASSIFI_VER_SIMPLE_ELEM_MAX,
}dcb_classif_version_t;

typedef struct _dcb_classif_params_t
{
    u16_t num_classif_elements;
    u16_t _pad;
    dcb_classif_version_t classif_version;
    void *classif_table;
}dcb_classif_params_t;

typedef struct _dcb_pfc_param_t
{
    u32_t pfc_enable;
#define DCB_PFC_MAX_BIT_ENABLE_MASK     (0xFF)
}dcb_pfc_param_t;

typedef enum _tsa_assignment
{
    TSA_ASSIGNMENT_DCB_TSA_STRICT,
    TSA_ASSIGNMENT_DCB_TSA_CBS,
    TSA_ASSIGNMENT_DCB_TSA_ETS,
} tsa_assignment;

typedef struct _dcb_ets_tsa_param_t
{
    u32_t num_traffic_classes;
    u8_t priority_assignment_table[8];
    u8_t tc_bw_assignment_table[8];
    tsa_assignment tsa_assignment_table[8];
} dcb_ets_tsa_param_t;

typedef struct _dcb_indicate_event_params_t
{
    u32_t flags;
#define DCB_PARAMS_ETS_ENABLED          0x00000001
#define DCB_PARAMS_ETS_CHANGED          0x00000002
#define DCB_PARAMS_PFC_ENABLED          0x00000004
#define DCB_PARAMS_PFC_CHANGED          0x00000008
#define DCB_PARAMS_CLASSIF_ENABLED      0x00000020
#define DCB_PARAMS_CLASSIF_CHANGED      0x00000040
#define DCB_PARAMS_WILLING              0x00000080

    dcb_ets_tsa_param_t ets_params;
    dcb_pfc_param_t pfc_params;
    dcb_classif_params_t classif_params;
    u32_t reserved[4];
} dcb_indicate_event_params_t;

/*
 * Macro fore calculating the address of the base of the structure given its
 * type, and an address of a field within the structure.
 */

#define GET_CONTAINING_RECORD(address, type, field) \
        ((type *)((u8_t *)(address) - (u8_t *)(&((type *)0)->field)))



/*
 * Simple macros.
 */

#define IS_ETH_BROADCAST(eth_addr)                                      \
        (((unsigned char *) (eth_addr))[0] == ((unsigned char) 0xff))

#define IS_ETH_MULTICAST(eth_addr)                                      \
        (((unsigned char *) (eth_addr))[0] & ((unsigned char) 0x01))

#define IS_ETH_ADDRESS_EQUAL(eth_addr1, eth_addr2)                      \
        ((((unsigned char *) (eth_addr1))[0] ==                         \
        ((unsigned char *) (eth_addr2))[0]) &&                          \
        (((unsigned char *) (eth_addr1))[1] ==                          \
        ((unsigned char *) (eth_addr2))[1]) &&                          \
        (((unsigned char *) (eth_addr1))[2] ==                          \
        ((unsigned char *) (eth_addr2))[2]) &&                          \
        (((unsigned char *) (eth_addr1))[3] ==                          \
        ((unsigned char *) (eth_addr2))[3]) &&                          \
        (((unsigned char *) (eth_addr1))[4] ==                          \
        ((unsigned char *) (eth_addr2))[4]) &&                          \
        (((unsigned char *) (eth_addr1))[5] ==                          \
        ((unsigned char *) (eth_addr2))[5]))

#define COPY_ETH_ADDRESS(src, dst)                                      \
        ((unsigned char *) (dst))[0] = ((unsigned char *) (src))[0];    \
        ((unsigned char *) (dst))[1] = ((unsigned char *) (src))[1];    \
        ((unsigned char *) (dst))[2] = ((unsigned char *) (src))[2];    \
        ((unsigned char *) (dst))[3] = ((unsigned char *) (src))[3];    \
        ((unsigned char *) (dst))[4] = ((unsigned char *) (src))[4];    \
        ((unsigned char *) (dst))[5] = ((unsigned char *) (src))[5];

#ifdef __cplusplus
}
#endif

#endif /* _LM_DEFS_H */